Coverage Report

Created: 2024-06-28 06:19

/src/wolfssl/wolfcrypt/src/aes.c
Line
Count
Source (jump to first uncovered line)
1
/* aes.c
2
 *
3
 * Copyright (C) 2006-2023 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
#ifdef HAVE_CONFIG_H
32
    #include <config.h>
33
#endif
34
35
#include <wolfssl/wolfcrypt/settings.h>
36
#include <wolfssl/wolfcrypt/error-crypt.h>
37
38
#if !defined(NO_AES)
39
40
/* Tip: Locate the software cipher modes by searching for "Software AES" */
41
42
#if defined(HAVE_FIPS) && \
43
    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
44
45
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
46
    #define FIPS_NO_WRAPPERS
47
48
    #ifdef USE_WINDOWS_API
49
        #pragma code_seg(".fipsA$g")
50
        #pragma const_seg(".fipsB$g")
51
    #endif
52
#endif
53
54
#include <wolfssl/wolfcrypt/aes.h>
55
56
#ifdef WOLFSSL_AESNI
57
#include <wmmintrin.h>
58
#include <emmintrin.h>
59
#include <smmintrin.h>
60
#endif /* WOLFSSL_AESNI */
61
62
#include <wolfssl/wolfcrypt/cpuid.h>
63
64
#ifdef WOLF_CRYPTO_CB
65
    #include <wolfssl/wolfcrypt/cryptocb.h>
66
#endif
67
68
#ifdef WOLFSSL_SECO_CAAM
69
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
70
#endif
71
72
#ifdef WOLFSSL_IMXRT_DCP
73
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
74
#endif
75
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
76
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
77
#endif
78
79
#if defined(WOLFSSL_AES_SIV)
80
    #include <wolfssl/wolfcrypt/cmac.h>
81
#endif /* WOLFSSL_AES_SIV */
82
83
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
84
    #include <wolfssl/wolfcrypt/port/psa/psa.h>
85
#endif
86
87
#if defined(WOLFSSL_TI_CRYPT)
88
    #include <wolfcrypt/src/port/ti/ti-aes.c>
89
#else
90
91
#include <wolfssl/wolfcrypt/logging.h>
92
93
#ifdef NO_INLINE
94
    #include <wolfssl/wolfcrypt/misc.h>
95
#else
96
    #define WOLFSSL_MISC_INCLUDED
97
    #include <wolfcrypt/src/misc.c>
98
#endif
99
100
#ifndef WOLFSSL_ARMASM
101
102
#ifdef WOLFSSL_IMX6_CAAM_BLOB
103
    /* case of possibly not using hardware acceleration for AES but using key
104
       blobs */
105
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
106
#endif
107
108
#ifdef DEBUG_AESNI
109
    #include <stdio.h>
110
#endif
111
112
#ifdef _MSC_VER
113
    /* 4127 warning constant while(1)  */
114
    #pragma warning(disable: 4127)
115
#endif
116
117
/* Define AES implementation includes and functions */
118
#if defined(STM32_CRYPTO)
119
     /* STM32F2/F4/F7/L4/L5/H7/WB55 hardware AES support for ECB, CBC, CTR and GCM modes */
120
121
#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
122
123
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
124
        Aes* aes, const byte* inBlock, byte* outBlock)
125
    {
126
        int ret = 0;
127
    #ifdef WOLFSSL_STM32_CUBEMX
128
        CRYP_HandleTypeDef hcryp;
129
    #else
130
        CRYP_InitTypeDef cryptInit;
131
        CRYP_KeyInitTypeDef keyInit;
132
    #endif
133
134
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
135
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
136
        if (ret < 0)
137
            return ret;
138
#endif
139
140
    #ifdef WOLFSSL_STM32_CUBEMX
141
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
142
        if (ret != 0)
143
            return ret;
144
145
        ret = wolfSSL_CryptHwMutexLock();
146
        if (ret != 0)
147
            return ret;
148
149
    #if defined(STM32_HAL_V2)
150
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
151
    #elif defined(STM32_CRYPTO_AES_ONLY)
152
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
153
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
154
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
155
    #endif
156
        HAL_CRYP_Init(&hcryp);
157
158
    #if defined(STM32_HAL_V2)
159
        ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,
160
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
161
    #elif defined(STM32_CRYPTO_AES_ONLY)
162
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
163
            outBlock, STM32_HAL_TIMEOUT);
164
    #else
165
        ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
166
            outBlock, STM32_HAL_TIMEOUT);
167
    #endif
168
        if (ret != HAL_OK) {
169
            ret = WC_TIMEOUT_E;
170
        }
171
        HAL_CRYP_DeInit(&hcryp);
172
173
    #else /* Standard Peripheral Library */
174
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
175
        if (ret != 0)
176
            return ret;
177
178
        ret = wolfSSL_CryptHwMutexLock();
179
        if (ret != 0)
180
            return ret;
181
182
        /* reset registers to their default values */
183
        CRYP_DeInit();
184
185
        /* setup key */
186
        CRYP_KeyInit(&keyInit);
187
188
        /* set direction and mode */
189
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
190
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
191
        CRYP_Init(&cryptInit);
192
193
        /* enable crypto processor */
194
        CRYP_Cmd(ENABLE);
195
196
        /* flush IN/OUT FIFOs */
197
        CRYP_FIFOFlush();
198
199
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
200
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
201
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
202
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
203
204
        /* wait until the complete message has been processed */
205
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
206
207
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
208
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
209
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
210
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
211
212
        /* disable crypto processor */
213
        CRYP_Cmd(DISABLE);
214
    #endif /* WOLFSSL_STM32_CUBEMX */
215
        wolfSSL_CryptHwMutexUnLock();
216
        wc_Stm32_Aes_Cleanup();
217
218
        return ret;
219
    }
220
#endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */
221
222
#ifdef HAVE_AES_DECRYPT
223
    #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM)
224
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
225
        Aes* aes, const byte* inBlock, byte* outBlock)
226
    {
227
        int ret = 0;
228
    #ifdef WOLFSSL_STM32_CUBEMX
229
        CRYP_HandleTypeDef hcryp;
230
    #else
231
        CRYP_InitTypeDef cryptInit;
232
        CRYP_KeyInitTypeDef keyInit;
233
    #endif
234
235
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
236
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
237
        if (ret < 0)
238
            return ret;
239
#endif
240
241
    #ifdef WOLFSSL_STM32_CUBEMX
242
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
243
        if (ret != 0)
244
            return ret;
245
246
        ret = wolfSSL_CryptHwMutexLock();
247
        if (ret != 0)
248
            return ret;
249
250
    #if defined(STM32_HAL_V2)
251
        hcryp.Init.Algorithm  = CRYP_AES_ECB;
252
    #elif defined(STM32_CRYPTO_AES_ONLY)
253
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
254
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_ECB;
255
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
256
    #endif
257
        HAL_CRYP_Init(&hcryp);
258
259
    #if defined(STM32_HAL_V2)
260
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)inBlock, AES_BLOCK_SIZE,
261
            (uint32_t*)outBlock, STM32_HAL_TIMEOUT);
262
    #elif defined(STM32_CRYPTO_AES_ONLY)
263
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
264
            outBlock, STM32_HAL_TIMEOUT);
265
    #else
266
        ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)inBlock, AES_BLOCK_SIZE,
267
            outBlock, STM32_HAL_TIMEOUT);
268
    #endif
269
        if (ret != HAL_OK) {
270
            ret = WC_TIMEOUT_E;
271
        }
272
        HAL_CRYP_DeInit(&hcryp);
273
274
    #else /* Standard Peripheral Library */
275
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
276
        if (ret != 0)
277
            return ret;
278
279
        ret = wolfSSL_CryptHwMutexLock();
280
        if (ret != 0)
281
            return ret;
282
283
        /* reset registers to their default values */
284
        CRYP_DeInit();
285
286
        /* set direction and key */
287
        CRYP_KeyInit(&keyInit);
288
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
289
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
290
        CRYP_Init(&cryptInit);
291
292
        /* enable crypto processor */
293
        CRYP_Cmd(ENABLE);
294
295
        /* wait until decrypt key has been initialized */
296
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
297
298
        /* set direction and mode */
299
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
300
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_ECB;
301
        CRYP_Init(&cryptInit);
302
303
        /* enable crypto processor */
304
        CRYP_Cmd(ENABLE);
305
306
        /* flush IN/OUT FIFOs */
307
        CRYP_FIFOFlush();
308
309
        CRYP_DataIn(*(uint32_t*)&inBlock[0]);
310
        CRYP_DataIn(*(uint32_t*)&inBlock[4]);
311
        CRYP_DataIn(*(uint32_t*)&inBlock[8]);
312
        CRYP_DataIn(*(uint32_t*)&inBlock[12]);
313
314
        /* wait until the complete message has been processed */
315
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
316
317
        *(uint32_t*)&outBlock[0]  = CRYP_DataOut();
318
        *(uint32_t*)&outBlock[4]  = CRYP_DataOut();
319
        *(uint32_t*)&outBlock[8]  = CRYP_DataOut();
320
        *(uint32_t*)&outBlock[12] = CRYP_DataOut();
321
322
        /* disable crypto processor */
323
        CRYP_Cmd(DISABLE);
324
    #endif /* WOLFSSL_STM32_CUBEMX */
325
        wolfSSL_CryptHwMutexUnLock();
326
        wc_Stm32_Aes_Cleanup();
327
328
        return ret;
329
    }
330
    #endif /* WOLFSSL_AES_DIRECT || HAVE_AESCCM */
331
#endif /* HAVE_AES_DECRYPT */
332
333
#elif defined(HAVE_COLDFIRE_SEC)
334
    /* Freescale Coldfire SEC support for CBC mode.
335
     * NOTE: no support for AES-CTR/GCM/CCM/Direct */
336
    #include <wolfssl/wolfcrypt/types.h>
337
    #include "sec.h"
338
    #include "mcf5475_sec.h"
339
    #include "mcf5475_siu.h"
340
#elif defined(FREESCALE_LTC)
341
    #include "fsl_ltc.h"
342
    #if defined(FREESCALE_LTC_AES_GCM)
343
        #undef NEED_AES_TABLES
344
        #undef GCM_TABLE
345
    #endif
346
347
        /* if LTC doesn't have GCM, use software with LTC AES ECB mode */
348
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
349
            Aes* aes, const byte* inBlock, byte* outBlock)
350
        {
351
            word32 keySize = 0;
352
            byte* key = (byte*)aes->key;
353
            int ret = wc_AesGetKeySize(aes, &keySize);
354
            if (ret != 0)
355
                return ret;
356
357
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
358
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
359
            if (ret < 0)
360
                return ret;
361
#endif
362
363
            if (wolfSSL_CryptHwMutexLock() == 0) {
364
                LTC_AES_EncryptEcb(LTC_BASE, inBlock, outBlock, AES_BLOCK_SIZE,
365
                    key, keySize);
366
                wolfSSL_CryptHwMutexUnLock();
367
            }
368
            return 0;
369
        }
370
        #ifdef HAVE_AES_DECRYPT
371
        static WARN_UNUSED_RESULT int wc_AesDecrypt(
372
            Aes* aes, const byte* inBlock, byte* outBlock)
373
        {
374
            word32 keySize = 0;
375
            byte* key = (byte*)aes->key;
376
            int ret = wc_AesGetKeySize(aes, &keySize);
377
            if (ret != 0)
378
                return ret;
379
380
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
381
            ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
382
            if (ret < 0)
383
                return ret;
384
#endif
385
386
            if (wolfSSL_CryptHwMutexLock() == 0) {
387
                LTC_AES_DecryptEcb(LTC_BASE, inBlock, outBlock, AES_BLOCK_SIZE,
388
                    key, keySize, kLTC_EncryptKey);
389
                wolfSSL_CryptHwMutexUnLock();
390
            }
391
            return 0;
392
        }
393
        #endif
394
395
#elif defined(FREESCALE_MMCAU)
396
    /* Freescale mmCAU hardware AES support for Direct, CBC, CCM, GCM modes
397
     * through the CAU/mmCAU library. Documentation located in
398
     * ColdFire/ColdFire+ CAU and Kinetis mmCAU Software Library User
399
     * Guide (See note in README). */
400
    #ifdef FREESCALE_MMCAU_CLASSIC
401
        /* MMCAU 1.4 library used with non-KSDK / classic MQX builds */
402
        #include "cau_api.h"
403
    #else
404
        #include "fsl_mmcau.h"
405
    #endif
406
407
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
408
        Aes* aes, const byte* inBlock, byte* outBlock)
409
    {
410
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
411
        {
412
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
413
            if (ret < 0)
414
                return ret;
415
        }
416
#endif
417
418
        if (wolfSSL_CryptHwMutexLock() == 0) {
419
        #ifdef FREESCALE_MMCAU_CLASSIC
420
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
421
                WOLFSSL_MSG("Bad cau_aes_encrypt alignment");
422
                return BAD_ALIGN_E;
423
            }
424
            cau_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
425
        #else
426
            MMCAU_AES_EncryptEcb(inBlock, (byte*)aes->key, aes->rounds,
427
                                 outBlock);
428
        #endif
429
            wolfSSL_CryptHwMutexUnLock();
430
        }
431
        return 0;
432
    }
433
    #ifdef HAVE_AES_DECRYPT
434
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
435
        Aes* aes, const byte* inBlock, byte* outBlock)
436
    {
437
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
438
        {
439
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
440
            if (ret < 0)
441
                return ret;
442
        }
443
#endif
444
        if (wolfSSL_CryptHwMutexLock() == 0) {
445
        #ifdef FREESCALE_MMCAU_CLASSIC
446
            if ((wc_ptr_t)outBlock % WOLFSSL_MMCAU_ALIGNMENT) {
447
                WOLFSSL_MSG("Bad cau_aes_decrypt alignment");
448
                return BAD_ALIGN_E;
449
            }
450
            cau_aes_decrypt(inBlock, (byte*)aes->key, aes->rounds, outBlock);
451
        #else
452
            MMCAU_AES_DecryptEcb(inBlock, (byte*)aes->key, aes->rounds,
453
                                 outBlock);
454
        #endif
455
            wolfSSL_CryptHwMutexUnLock();
456
        }
457
        return 0;
458
    }
459
    #endif /* HAVE_AES_DECRYPT */
460
461
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
462
463
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
464
465
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
466
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
467
        Aes* aes, const byte* inBlock, byte* outBlock)
468
    {
469
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
470
        {
471
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
472
            if (ret < 0)
473
                return ret;
474
        }
475
#endif
476
        /* Thread mutex protection handled in Pic32Crypto */
477
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
478
            outBlock, inBlock, AES_BLOCK_SIZE,
479
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
480
    }
481
    #endif
482
483
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
484
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
485
        Aes* aes, const byte* inBlock, byte* outBlock)
486
    {
487
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
488
        {
489
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
490
            if (ret < 0)
491
                return ret;
492
        }
493
#endif
494
        /* Thread mutex protection handled in Pic32Crypto */
495
        return wc_Pic32AesCrypt(aes->key, aes->keylen, NULL, 0,
496
            outBlock, inBlock, AES_BLOCK_SIZE,
497
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RECB);
498
    }
499
    #endif
500
501
#elif defined(WOLFSSL_NRF51_AES)
502
    /* Use built-in AES hardware - AES 128 ECB Encrypt Only */
503
    #include "wolfssl/wolfcrypt/port/nrf51.h"
504
505
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
506
        Aes* aes, const byte* inBlock, byte* outBlock)
507
    {
508
        int ret;
509
510
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
511
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
512
        if (ret < 0)
513
            return ret;
514
#endif
515
516
        ret = wolfSSL_CryptHwMutexLock();
517
        if (ret == 0) {
518
            ret = nrf51_aes_encrypt(inBlock, (byte*)aes->key, aes->rounds,
519
                                    outBlock);
520
            wolfSSL_CryptHwMutexUnLock();
521
        }
522
        return ret;
523
    }
524
525
    #ifdef HAVE_AES_DECRYPT
526
        #error nRF51 AES Hardware does not support decrypt
527
    #endif /* HAVE_AES_DECRYPT */
528
529
#elif defined(WOLFSSL_ESP32_CRYPT) && \
530
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
531
    #include <esp_log.h>
532
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
533
    const char* TAG = "aes";
534
535
    /* We'll use SW for fallback:
536
     *   unsupported key lengths. (e.g. ESP32-S3)
537
     *   chipsets not implemented.
538
     *   hardware busy. */
539
    #define NEED_AES_TABLES
540
    #define NEED_AES_HW_FALLBACK
541
    #define NEED_SOFTWARE_AES_SETKEY
542
    #undef  WOLFSSL_AES_DIRECT
543
    #define WOLFSSL_AES_DIRECT
544
545
    /* Encrypt: If we choose to never have a fallback to SW: */
546
    #if !defined(NEED_AES_HW_FALLBACK) && (defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT))
547
    static WARN_UNUSED_RESULT int wc_AesEncrypt( /* calling this one when NO_AES_192 is defined */
548
        Aes* aes, const byte* inBlock, byte* outBlock)
549
    {
550
        int ret;
551
552
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
553
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
554
        if (ret < 0)
555
            return ret;
556
#endif
557
558
        /* Thread mutex protection handled in esp_aes_hw_InUse */
559
    #ifdef NEED_AES_HW_FALLBACK
560
        if (wc_esp32AesSupportedKeyLen(aes)) {
561
            ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
562
        }
563
    #else
564
        ret = wc_esp32AesEncrypt(aes, inBlock, outBlock);
565
    #endif
566
        return ret;
567
    }
568
    #endif
569
570
    /* Decrypt: If we choose to never have a fallback to SW: */
571
    #if !defined(NEED_AES_HW_FALLBACK) && (defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT))
572
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
573
        Aes* aes, const byte* inBlock, byte* outBlock)
574
    {
575
        int ret = 0;
576
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
577
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
578
        if (ret < 0)
579
            return ret;
580
#endif
581
        /* Thread mutex protection handled in esp_aes_hw_InUse */
582
    #ifdef NEED_AES_HW_FALLBACK
583
        if (wc_esp32AesSupportedKeyLen(aes)) {
584
            ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
585
        }
586
        else {
587
            ret = wc_AesDecrypt_SW(aes, inBlock, outBlock);
588
        }
589
    #else
590
        /* if we don't need fallback, always use HW */
591
        ret = wc_esp32AesDecrypt(aes, inBlock, outBlock);
592
    #endif
593
        return ret;
594
    }
595
    #endif
596
597
#elif defined(WOLFSSL_AESNI)
598
599
    #define NEED_AES_TABLES
600
601
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
602
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
603
     */
604
605
    #ifndef AESNI_ALIGN
606
        #define AESNI_ALIGN 16
607
    #endif
608
609
    static int checkedAESNI = 0;
610
    static int haveAESNI  = 0;
611
    static word32 intel_flags = 0;
612
613
    static WARN_UNUSED_RESULT int Check_CPU_support_AES(void)
614
    {
615
        intel_flags = cpuid_get_flags();
616
617
        return IS_INTEL_AESNI(intel_flags) != 0;
618
    }
619
620
621
    /* tell C compiler these are asm functions in case any mix up of ABI underscore
622
       prefix between clang/gcc/llvm etc */
623
    #ifdef HAVE_AES_CBC
624
        void AES_CBC_encrypt_AESNI(const unsigned char* in, unsigned char* out,
625
                             unsigned char* ivec, unsigned long length,
626
                             const unsigned char* KS, int nr)
627
                             XASM_LINK("AES_CBC_encrypt_AESNI");
628
629
        #ifdef HAVE_AES_DECRYPT
630
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
631
                void AES_CBC_decrypt_AESNI_by4(const unsigned char* in, unsigned char* out,
632
                                         unsigned char* ivec, unsigned long length,
633
                                         const unsigned char* KS, int nr)
634
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by4");
635
            #elif defined(WOLFSSL_AESNI_BY6)
636
                void AES_CBC_decrypt_AESNI_by6(const unsigned char* in, unsigned char* out,
637
                                         unsigned char* ivec, unsigned long length,
638
                                         const unsigned char* KS, int nr)
639
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by6");
640
            #else /* WOLFSSL_AESNI_BYx */
641
                void AES_CBC_decrypt_AESNI_by8(const unsigned char* in, unsigned char* out,
642
                                         unsigned char* ivec, unsigned long length,
643
                                         const unsigned char* KS, int nr)
644
                                         XASM_LINK("AES_CBC_decrypt_AESNI_by8");
645
            #endif /* WOLFSSL_AESNI_BYx */
646
        #endif /* HAVE_AES_DECRYPT */
647
    #endif /* HAVE_AES_CBC */
648
649
    void AES_ECB_encrypt_AESNI(const unsigned char* in, unsigned char* out,
650
                         unsigned long length, const unsigned char* KS, int nr)
651
                         XASM_LINK("AES_ECB_encrypt_AESNI");
652
653
    #ifdef HAVE_AES_DECRYPT
654
        void AES_ECB_decrypt_AESNI(const unsigned char* in, unsigned char* out,
655
                             unsigned long length, const unsigned char* KS, int nr)
656
                             XASM_LINK("AES_ECB_decrypt_AESNI");
657
    #endif
658
659
    void AES_128_Key_Expansion_AESNI(const unsigned char* userkey,
660
                               unsigned char* key_schedule)
661
                               XASM_LINK("AES_128_Key_Expansion_AESNI");
662
663
    void AES_192_Key_Expansion_AESNI(const unsigned char* userkey,
664
                               unsigned char* key_schedule)
665
                               XASM_LINK("AES_192_Key_Expansion_AESNI");
666
667
    void AES_256_Key_Expansion_AESNI(const unsigned char* userkey,
668
                               unsigned char* key_schedule)
669
                               XASM_LINK("AES_256_Key_Expansion_AESNI");
670
671
672
    static WARN_UNUSED_RESULT int AES_set_encrypt_key_AESNI(
673
        const unsigned char *userKey, const int bits, Aes* aes)
674
    {
675
        int ret;
676
677
        ASSERT_SAVED_VECTOR_REGISTERS();
678
679
        if (!userKey || !aes)
680
            return BAD_FUNC_ARG;
681
682
        switch (bits) {
683
            case 128:
684
               AES_128_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 10;
685
               return 0;
686
            case 192:
687
               AES_192_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 12;
688
               return 0;
689
            case 256:
690
               AES_256_Key_Expansion_AESNI (userKey,(byte*)aes->key); aes->rounds = 14;
691
               return 0;
692
            default:
693
                ret = BAD_FUNC_ARG;
694
        }
695
696
        return ret;
697
    }
698
699
    #ifdef HAVE_AES_DECRYPT
700
        static WARN_UNUSED_RESULT int AES_set_decrypt_key_AESNI(
701
            const unsigned char* userKey, const int bits, Aes* aes)
702
        {
703
            word32 nr;
704
#ifdef WOLFSSL_SMALL_STACK
705
            Aes *temp_key;
706
#else
707
            Aes temp_key[1];
708
#endif
709
            __m128i *Key_Schedule;
710
            __m128i *Temp_Key_Schedule;
711
712
            ASSERT_SAVED_VECTOR_REGISTERS();
713
714
            if (!userKey || !aes)
715
                return BAD_FUNC_ARG;
716
717
#ifdef WOLFSSL_SMALL_STACK
718
            if ((temp_key = (Aes *)XMALLOC(sizeof *aes, aes->heap,
719
                                           DYNAMIC_TYPE_AES)) == NULL)
720
                return MEMORY_E;
721
#endif
722
723
            if (AES_set_encrypt_key_AESNI(userKey,bits,temp_key) == BAD_FUNC_ARG) {
724
#ifdef WOLFSSL_SMALL_STACK
725
                XFREE(temp_key, aes->heap, DYNAMIC_TYPE_AES);
726
#endif
727
                return BAD_FUNC_ARG;
728
            }
729
730
            Key_Schedule = (__m128i*)aes->key;
731
            Temp_Key_Schedule = (__m128i*)temp_key->key;
732
733
            nr = temp_key->rounds;
734
            aes->rounds = nr;
735
736
            Key_Schedule[nr] = Temp_Key_Schedule[0];
737
            Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
738
            Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
739
            Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
740
            Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
741
            Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
742
            Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
743
            Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
744
            Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
745
            Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
746
747
            if (nr>10) {
748
                Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
749
                Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
750
            }
751
752
            if (nr>12) {
753
                Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
754
                Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
755
            }
756
757
            Key_Schedule[0] = Temp_Key_Schedule[nr];
758
759
#ifdef WOLFSSL_SMALL_STACK
760
            XFREE(temp_key, aes->heap, DYNAMIC_TYPE_AES);
761
#endif
762
763
            return 0;
764
        }
765
    #endif /* HAVE_AES_DECRYPT */
766
767
#elif (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
768
        && !defined(WOLFSSL_QNX_CAAM)) || \
769
      ((defined(WOLFSSL_AFALG) || defined(WOLFSSL_DEVCRYPTO_AES)) && \
770
        defined(HAVE_AESCCM))
771
        static WARN_UNUSED_RESULT int wc_AesEncrypt(
772
            Aes* aes, const byte* inBlock, byte* outBlock)
773
        {
774
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
775
            {
776
                int ret =
777
                    wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
778
                if (ret < 0)
779
                    return ret;
780
            }
781
#endif
782
            return wc_AesEncryptDirect(aes, outBlock, inBlock);
783
        }
784
785
#elif defined(WOLFSSL_AFALG)
786
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
787
788
#elif defined(WOLFSSL_DEVCRYPTO_AES)
789
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
790
791
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
792
    #include "hal_data.h"
793
794
    #ifndef WOLFSSL_SCE_AES256_HANDLE
795
        #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256
796
    #endif
797
798
    #ifndef WOLFSSL_SCE_AES192_HANDLE
799
        #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192
800
    #endif
801
802
    #ifndef WOLFSSL_SCE_AES128_HANDLE
803
        #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128
804
    #endif
805
806
    static WARN_UNUSED_RESULT int AES_ECB_encrypt(
807
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
808
    {
809
        word32 ret;
810
811
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
812
                CRYPTO_WORD_ENDIAN_BIG) {
813
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
814
        }
815
816
        switch (aes->keylen) {
817
        #ifdef WOLFSSL_AES_128
818
            case AES_128_KEY_SIZE:
819
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(
820
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key,
821
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
822
                        (word32*)outBlock);
823
                break;
824
        #endif
825
        #ifdef WOLFSSL_AES_192
826
            case AES_192_KEY_SIZE:
827
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(
828
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key,
829
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
830
                        (word32*)outBlock);
831
                break;
832
        #endif
833
        #ifdef WOLFSSL_AES_256
834
            case AES_256_KEY_SIZE:
835
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(
836
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key,
837
                        NULL, (sz / sizeof(word32)), (word32*)inBlock,
838
                        (word32*)outBlock);
839
                break;
840
        #endif
841
            default:
842
                WOLFSSL_MSG("Unknown key size");
843
                return BAD_FUNC_ARG;
844
        }
845
846
        if (ret != SSP_SUCCESS) {
847
            /* revert input */
848
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
849
            return WC_HW_E;
850
        }
851
852
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
853
                CRYPTO_WORD_ENDIAN_BIG) {
854
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
855
            if (inBlock != outBlock) {
856
                /* revert input */
857
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
858
            }
859
        }
860
        return 0;
861
    }
862
863
    #if defined(HAVE_AES_DECRYPT)
864
    static WARN_UNUSED_RESULT int AES_ECB_decrypt(
865
        Aes* aes, const byte* inBlock, byte* outBlock, int sz)
866
    {
867
        word32 ret;
868
869
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
870
                CRYPTO_WORD_ENDIAN_BIG) {
871
            ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
872
        }
873
874
        switch (aes->keylen) {
875
        #ifdef WOLFSSL_AES_128
876
            case AES_128_KEY_SIZE:
877
                ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(
878
                        WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg,
879
                        (sz / sizeof(word32)), (word32*)inBlock,
880
                        (word32*)outBlock);
881
                break;
882
        #endif
883
        #ifdef WOLFSSL_AES_192
884
            case AES_192_KEY_SIZE:
885
                ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(
886
                        WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg,
887
                        (sz / sizeof(word32)), (word32*)inBlock,
888
                        (word32*)outBlock);
889
                break;
890
        #endif
891
        #ifdef WOLFSSL_AES_256
892
            case AES_256_KEY_SIZE:
893
                ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(
894
                        WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg,
895
                        (sz / sizeof(word32)), (word32*)inBlock,
896
                        (word32*)outBlock);
897
                break;
898
        #endif
899
            default:
900
                WOLFSSL_MSG("Unknown key size");
901
                return BAD_FUNC_ARG;
902
        }
903
        if (ret != SSP_SUCCESS) {
904
            return WC_HW_E;
905
        }
906
907
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
908
                CRYPTO_WORD_ENDIAN_BIG) {
909
            ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz);
910
            if (inBlock != outBlock) {
911
                /* revert input */
912
                ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz);
913
            }
914
        }
915
916
        return 0;
917
    }
918
    #endif /* HAVE_AES_DECRYPT */
919
920
    #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT)
921
    static WARN_UNUSED_RESULT int wc_AesEncrypt(
922
        Aes* aes, const byte* inBlock, byte* outBlock)
923
    {
924
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
925
        {
926
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
927
            if (ret < 0)
928
                return ret;
929
        }
930
#endif
931
        return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
932
    }
933
    #endif
934
935
    #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT)
936
    static WARN_UNUSED_RESULT int wc_AesDecrypt(
937
        Aes* aes, const byte* inBlock, byte* outBlock)
938
    {
939
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
940
        {
941
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
942
            if (ret < 0)
943
                return ret;
944
        }
945
#endif
946
        return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
947
    }
948
    #endif
949
950
#elif defined(WOLFSSL_KCAPI_AES)
951
    /* Only CBC and GCM are in wolfcrypt/src/port/kcapi/kcapi_aes.c */
952
    #if defined(WOLFSSL_AES_COUNTER) || defined(HAVE_AESCCM) || \
953
        defined(WOLFSSL_CMAC) || defined(WOLFSSL_AES_OFB) || \
954
        defined(WOLFSSL_AES_CFB) || defined(HAVE_AES_ECB) || \
955
        defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_XTS) || \
956
        (defined(HAVE_AES_CBC) && defined(WOLFSSL_NO_KCAPI_AES_CBC))
957
958
        #define NEED_AES_TABLES
959
    #endif
960
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
961
/* implemented in wolfcrypt/src/port/psa/psa_aes.c */
962
963
#else
964
965
    /* using wolfCrypt software implementation */
966
    #define NEED_AES_TABLES
967
#endif
968
969
970
971
#ifdef NEED_AES_TABLES
972
973
#ifndef WC_AES_BITSLICED
974
#if !defined(WOLFSSL_SILABS_SE_ACCEL) ||  \
975
     defined(NO_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES) || \
976
     defined(NEED_AES_HW_FALLBACK)
977
static const FLASH_QUALIFIER word32 rcon[] = {
978
    0x01000000, 0x02000000, 0x04000000, 0x08000000,
979
    0x10000000, 0x20000000, 0x40000000, 0x80000000,
980
    0x1B000000, 0x36000000,
981
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
982
};
983
#endif
984
985
#ifndef WOLFSSL_AES_SMALL_TABLES
986
static const FLASH_QUALIFIER word32 Te[4][256] = {
987
{
988
    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
989
    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
990
    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
991
    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
992
    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
993
    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
994
    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
995
    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
996
    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
997
    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
998
    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
999
    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
1000
    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
1001
    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
1002
    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
1003
    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
1004
    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
1005
    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
1006
    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
1007
    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
1008
    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
1009
    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
1010
    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
1011
    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
1012
    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
1013
    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
1014
    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
1015
    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
1016
    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
1017
    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
1018
    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
1019
    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
1020
    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
1021
    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
1022
    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
1023
    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
1024
    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
1025
    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
1026
    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
1027
    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
1028
    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
1029
    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
1030
    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
1031
    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
1032
    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
1033
    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
1034
    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
1035
    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
1036
    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
1037
    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
1038
    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
1039
    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
1040
    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
1041
    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
1042
    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
1043
    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
1044
    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
1045
    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
1046
    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
1047
    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
1048
    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
1049
    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
1050
    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
1051
    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
1052
},
1053
{
1054
    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
1055
    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
1056
    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
1057
    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
1058
    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
1059
    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
1060
    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
1061
    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
1062
    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
1063
    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
1064
    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
1065
    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
1066
    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
1067
    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
1068
    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
1069
    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
1070
    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
1071
    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
1072
    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
1073
    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
1074
    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
1075
    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
1076
    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
1077
    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
1078
    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
1079
    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
1080
    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
1081
    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
1082
    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
1083
    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
1084
    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
1085
    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
1086
    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
1087
    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
1088
    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
1089
    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
1090
    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
1091
    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
1092
    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
1093
    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
1094
    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
1095
    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
1096
    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
1097
    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
1098
    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
1099
    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
1100
    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
1101
    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
1102
    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
1103
    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
1104
    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
1105
    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
1106
    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
1107
    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
1108
    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
1109
    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
1110
    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
1111
    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
1112
    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
1113
    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
1114
    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
1115
    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
1116
    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
1117
    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
1118
},
1119
{
1120
    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
1121
    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
1122
    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
1123
    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
1124
    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
1125
    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
1126
    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
1127
    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
1128
    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
1129
    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
1130
    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
1131
    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
1132
    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
1133
    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
1134
    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
1135
    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
1136
    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
1137
    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
1138
    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
1139
    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
1140
    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
1141
    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
1142
    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
1143
    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
1144
    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
1145
    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
1146
    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
1147
    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
1148
    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
1149
    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
1150
    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
1151
    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
1152
    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
1153
    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
1154
    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
1155
    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
1156
    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
1157
    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
1158
    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
1159
    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
1160
    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
1161
    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
1162
    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
1163
    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
1164
    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
1165
    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
1166
    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
1167
    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
1168
    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
1169
    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
1170
    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
1171
    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
1172
    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
1173
    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
1174
    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
1175
    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
1176
    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
1177
    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
1178
    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
1179
    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
1180
    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
1181
    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
1182
    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
1183
    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
1184
},
1185
{
1186
    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
1187
    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
1188
    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
1189
    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
1190
    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
1191
    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
1192
    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
1193
    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
1194
    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
1195
    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
1196
    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
1197
    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
1198
    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
1199
    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
1200
    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
1201
    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
1202
    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
1203
    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
1204
    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
1205
    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
1206
    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
1207
    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
1208
    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
1209
    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
1210
    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
1211
    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
1212
    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
1213
    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
1214
    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
1215
    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
1216
    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
1217
    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
1218
    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
1219
    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
1220
    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
1221
    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
1222
    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
1223
    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
1224
    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
1225
    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
1226
    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
1227
    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
1228
    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
1229
    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
1230
    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
1231
    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
1232
    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
1233
    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
1234
    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
1235
    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
1236
    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
1237
    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
1238
    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
1239
    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
1240
    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
1241
    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
1242
    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
1243
    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
1244
    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
1245
    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
1246
    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
1247
    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
1248
    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
1249
    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
1250
}
1251
};
1252
1253
#if defined(HAVE_AES_DECRYPT) && !defined(WOLFSSL_SILABS_SE_ACCEL)
1254
static const FLASH_QUALIFIER word32 Td[4][256] = {
1255
{
1256
    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
1257
    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
1258
    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
1259
    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
1260
    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
1261
    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
1262
    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
1263
    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
1264
    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
1265
    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
1266
    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
1267
    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
1268
    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
1269
    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
1270
    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
1271
    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
1272
    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
1273
    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
1274
    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
1275
    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
1276
    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
1277
    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
1278
    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
1279
    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
1280
    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
1281
    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
1282
    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
1283
    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
1284
    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
1285
    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
1286
    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
1287
    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
1288
    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
1289
    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
1290
    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
1291
    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
1292
    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
1293
    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
1294
    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
1295
    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
1296
    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
1297
    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
1298
    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
1299
    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
1300
    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
1301
    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
1302
    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
1303
    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
1304
    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
1305
    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
1306
    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
1307
    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
1308
    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
1309
    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
1310
    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
1311
    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
1312
    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
1313
    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
1314
    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
1315
    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
1316
    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
1317
    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
1318
    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
1319
    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
1320
},
1321
{
1322
    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
1323
    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
1324
    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
1325
    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
1326
    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
1327
    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
1328
    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
1329
    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
1330
    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
1331
    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
1332
    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
1333
    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
1334
    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
1335
    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
1336
    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
1337
    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
1338
    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
1339
    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
1340
    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
1341
    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
1342
    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
1343
    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
1344
    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
1345
    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
1346
    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
1347
    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
1348
    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
1349
    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
1350
    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
1351
    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
1352
    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
1353
    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
1354
    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
1355
    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
1356
    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
1357
    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
1358
    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
1359
    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
1360
    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
1361
    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
1362
    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
1363
    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
1364
    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
1365
    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
1366
    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
1367
    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
1368
    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
1369
    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
1370
    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
1371
    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
1372
    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
1373
    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
1374
    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
1375
    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
1376
    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
1377
    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
1378
    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
1379
    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
1380
    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
1381
    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
1382
    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
1383
    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
1384
    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
1385
    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
1386
},
1387
{
1388
    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
1389
    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
1390
    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
1391
    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
1392
    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
1393
    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
1394
    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
1395
    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
1396
    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
1397
    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
1398
    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
1399
    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
1400
    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
1401
    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
1402
    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
1403
    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
1404
    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
1405
    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
1406
    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
1407
    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
1408
1409
    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
1410
    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
1411
    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
1412
    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
1413
    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
1414
    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
1415
    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
1416
    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
1417
    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
1418
    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
1419
    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
1420
    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
1421
    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
1422
    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
1423
    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
1424
    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
1425
    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
1426
    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
1427
    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
1428
    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
1429
    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
1430
    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
1431
    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
1432
    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
1433
    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
1434
    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
1435
    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
1436
    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
1437
    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
1438
    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
1439
    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
1440
    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
1441
    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
1442
    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
1443
    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
1444
    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
1445
    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
1446
    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
1447
    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
1448
    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
1449
    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
1450
    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
1451
    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
1452
    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
1453
},
1454
{
1455
    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
1456
    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
1457
    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
1458
    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
1459
    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
1460
    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
1461
    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
1462
    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
1463
    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
1464
    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
1465
    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
1466
    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
1467
    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
1468
    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
1469
    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
1470
    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
1471
    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
1472
    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
1473
    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
1474
    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
1475
    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
1476
    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
1477
    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
1478
    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
1479
    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
1480
    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
1481
    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
1482
    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
1483
    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
1484
    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
1485
    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
1486
    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
1487
    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
1488
    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
1489
    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
1490
    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
1491
    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
1492
    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
1493
    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
1494
    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
1495
    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
1496
    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
1497
    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
1498
    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
1499
    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
1500
    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
1501
    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
1502
    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
1503
    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
1504
    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
1505
    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
1506
    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
1507
    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
1508
    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
1509
    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
1510
    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
1511
    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
1512
    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
1513
    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
1514
    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
1515
    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
1516
    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
1517
    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
1518
    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
1519
}
1520
};
1521
#endif /* HAVE_AES_DECRYPT */
1522
#endif /* WOLFSSL_AES_SMALL_TABLES */
1523
1524
#ifdef HAVE_AES_DECRYPT
1525
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC) && \
1526
                              !defined(WOLFSSL_SILABS_SE_ACCEL)) || \
1527
    defined(WOLFSSL_AES_DIRECT)
1528
static const FLASH_QUALIFIER byte Td4[256] =
1529
{
1530
    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
1531
    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
1532
    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
1533
    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
1534
    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
1535
    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
1536
    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
1537
    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
1538
    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
1539
    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
1540
    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
1541
    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
1542
    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
1543
    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
1544
    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
1545
    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
1546
    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
1547
    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
1548
    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
1549
    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
1550
    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
1551
    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
1552
    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
1553
    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
1554
    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
1555
    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
1556
    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
1557
    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
1558
    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
1559
    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
1560
    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
1561
    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
1562
};
1563
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1564
#endif /* HAVE_AES_DECRYPT */
1565
1566
#define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y))))
1567
1568
#ifdef WOLFSSL_AES_SMALL_TABLES
1569
static const byte Tsbox[256] = {
1570
    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
1571
    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
1572
    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
1573
    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
1574
    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
1575
    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
1576
    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
1577
    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
1578
    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
1579
    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
1580
    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
1581
    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
1582
    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
1583
    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
1584
    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
1585
    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
1586
    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
1587
    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
1588
    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
1589
    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
1590
    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
1591
    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
1592
    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
1593
    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
1594
    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
1595
    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
1596
    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
1597
    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
1598
    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
1599
    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
1600
    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
1601
    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
1602
};
1603
1604
#define AES_XTIME(x)    ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b)))
1605
1606
static WARN_UNUSED_RESULT word32 col_mul(
1607
    word32 t, int i2, int i3, int ia, int ib)
1608
{
1609
    byte t3 = GETBYTE(t, i3);
1610
    byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3);
1611
1612
    return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm;
1613
}
1614
1615
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
1616
static WARN_UNUSED_RESULT word32 inv_col_mul(
1617
    word32 t, int i9, int ib, int id, int ie)
1618
{
1619
    byte t9 = GETBYTE(t, i9);
1620
    byte tb = GETBYTE(t, ib);
1621
    byte td = GETBYTE(t, id);
1622
    byte te = GETBYTE(t, ie);
1623
    byte t0 = t9 ^ tb ^ td;
1624
    return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te);
1625
}
1626
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
1627
#endif /* WOLFSSL_AES_SMALL_TABLES */
1628
#endif
1629
1630
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || \
1631
                                    defined(HAVE_AESCCM) || defined(HAVE_AESGCM)
1632
1633
#ifndef WC_AES_BITSLICED
1634
1635
#ifndef WC_CACHE_LINE_SZ
1636
    #if defined(__x86_64__) || defined(_M_X64) || \
1637
       (defined(__ILP32__) && (__ILP32__ >= 1))
1638
0
        #define WC_CACHE_LINE_SZ 64
1639
    #else
1640
        /* default cache line size */
1641
        #define WC_CACHE_LINE_SZ 32
1642
    #endif
1643
#endif
1644
1645
#ifndef WC_NO_CACHE_RESISTANT
1646
1647
#if defined(__riscv) && !defined(WOLFSSL_AES_TOUCH_LINES)
1648
    #define WOLFSSL_AES_TOUCH_LINES
1649
#endif
1650
1651
#ifndef WOLFSSL_AES_SMALL_TABLES
1652
/* load 4 Te Tables into cache by cache line stride */
1653
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTe(void)
1654
0
{
1655
0
#ifndef WOLFSSL_AES_TOUCH_LINES
1656
0
    word32 x = 0;
1657
0
    int i,j;
1658
1659
0
    for (i = 0; i < 4; i++) {
1660
        /* 256 elements, each one is 4 bytes */
1661
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
1662
0
            x &= Te[i][j];
1663
0
        }
1664
0
    }
1665
0
    return x;
1666
#else
1667
    return 0;
1668
#endif
1669
0
}
1670
#else
1671
/* load sbox into cache by cache line stride */
1672
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchSBox(void)
1673
{
1674
#ifndef WOLFSSL_AES_TOUCH_LINES
1675
    word32 x = 0;
1676
    int i;
1677
1678
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) {
1679
        x &= Tsbox[i];
1680
    }
1681
    return x;
1682
#else
1683
    return 0;
1684
#endif
1685
}
1686
#endif
1687
#endif
1688
1689
#ifdef WOLFSSL_AES_TOUCH_LINES
1690
#if WC_CACHE_LINE_SZ == 128
1691
    #define WC_CACHE_LINE_BITS      5
1692
    #define WC_CACHE_LINE_MASK_HI   0xe0
1693
    #define WC_CACHE_LINE_MASK_LO   0x1f
1694
    #define WC_CACHE_LINE_ADD       0x20
1695
#elif WC_CACHE_LINE_SZ == 64
1696
    #define WC_CACHE_LINE_BITS      4
1697
    #define WC_CACHE_LINE_MASK_HI   0xf0
1698
    #define WC_CACHE_LINE_MASK_LO   0x0f
1699
    #define WC_CACHE_LINE_ADD       0x10
1700
#elif WC_CACHE_LINE_SZ == 32
1701
    #define WC_CACHE_LINE_BITS      3
1702
    #define WC_CACHE_LINE_MASK_HI   0xf8
1703
    #define WC_CACHE_LINE_MASK_LO   0x07
1704
    #define WC_CACHE_LINE_ADD       0x08
1705
#elif WC_CACHE_LINE_SZ == 16
1706
    #define WC_CACHE_LINE_BITS      2
1707
    #define WC_CACHE_LINE_MASK_HI   0xfc
1708
    #define WC_CACHE_LINE_MASK_LO   0x03
1709
    #define WC_CACHE_LINE_ADD       0x04
1710
#else
1711
    #error Cache line size not supported
1712
#endif
1713
1714
#ifndef WOLFSSL_AES_SMALL_TABLES
1715
static word32 GetTable(const word32* t, byte o)
1716
{
1717
#if WC_CACHE_LINE_SZ == 64
1718
    word32 e;
1719
    byte hi = o & 0xf0;
1720
    byte lo = o & 0x0f;
1721
1722
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1723
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1724
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1725
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1726
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1727
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1728
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1729
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1730
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1731
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1732
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1733
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1734
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1735
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1736
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1737
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1738
1739
    return e;
1740
#else
1741
    word32 e = 0;
1742
    int i;
1743
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1744
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1745
1746
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1747
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1748
        hi -= WC_CACHE_LINE_ADD;
1749
    }
1750
1751
    return e;
1752
#endif
1753
}
1754
#endif
1755
1756
#ifdef WOLFSSL_AES_SMALL_TABLES
1757
static byte GetTable8(const byte* t, byte o)
1758
{
1759
#if WC_CACHE_LINE_SZ == 64
1760
    byte e;
1761
    byte hi = o & 0xf0;
1762
    byte lo = o & 0x0f;
1763
1764
    e  = t[lo + 0x00] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1765
    e |= t[lo + 0x10] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1766
    e |= t[lo + 0x20] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1767
    e |= t[lo + 0x30] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1768
    e |= t[lo + 0x40] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1769
    e |= t[lo + 0x50] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1770
    e |= t[lo + 0x60] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1771
    e |= t[lo + 0x70] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1772
    e |= t[lo + 0x80] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1773
    e |= t[lo + 0x90] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1774
    e |= t[lo + 0xa0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1775
    e |= t[lo + 0xb0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1776
    e |= t[lo + 0xc0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1777
    e |= t[lo + 0xd0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1778
    e |= t[lo + 0xe0] & ((word32)0 - (((word32)hi - 0x01) >> 31)); hi -= 0x10;
1779
    e |= t[lo + 0xf0] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1780
1781
    return e;
1782
#else
1783
    byte e = 0;
1784
    int i;
1785
    byte hi = o & WC_CACHE_LINE_MASK_HI;
1786
    byte lo = o & WC_CACHE_LINE_MASK_LO;
1787
1788
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1789
        e |= t[lo + i] & ((word32)0 - (((word32)hi - 0x01) >> 31));
1790
        hi -= WC_CACHE_LINE_ADD;
1791
    }
1792
1793
    return e;
1794
#endif
1795
}
1796
#endif
1797
1798
#ifndef WOLFSSL_AES_SMALL_TABLES
1799
static void GetTable_Multi(const word32* t, word32* t0, byte o0,
1800
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
1801
{
1802
    word32 e0 = 0;
1803
    word32 e1 = 0;
1804
    word32 e2 = 0;
1805
    word32 e3 = 0;
1806
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
1807
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
1808
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
1809
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
1810
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
1811
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
1812
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
1813
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
1814
    int i;
1815
1816
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1817
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
1818
        hi0 -= WC_CACHE_LINE_ADD;
1819
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
1820
        hi1 -= WC_CACHE_LINE_ADD;
1821
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
1822
        hi2 -= WC_CACHE_LINE_ADD;
1823
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
1824
        hi3 -= WC_CACHE_LINE_ADD;
1825
    }
1826
    *t0 = e0;
1827
    *t1 = e1;
1828
    *t2 = e2;
1829
    *t3 = e3;
1830
}
1831
static void XorTable_Multi(const word32* t, word32* t0, byte o0,
1832
    word32* t1, byte o1, word32* t2, byte o2, word32* t3, byte o3)
1833
{
1834
    word32 e0 = 0;
1835
    word32 e1 = 0;
1836
    word32 e2 = 0;
1837
    word32 e3 = 0;
1838
    byte hi0 = o0 & 0xf0;
1839
    byte lo0 = o0 & 0x0f;
1840
    byte hi1 = o1 & 0xf0;
1841
    byte lo1 = o1 & 0x0f;
1842
    byte hi2 = o2 & 0xf0;
1843
    byte lo2 = o2 & 0x0f;
1844
    byte hi3 = o3 & 0xf0;
1845
    byte lo3 = o3 & 0x0f;
1846
    int i;
1847
1848
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1849
        e0 |= t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31));
1850
        hi0 -= WC_CACHE_LINE_ADD;
1851
        e1 |= t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31));
1852
        hi1 -= WC_CACHE_LINE_ADD;
1853
        e2 |= t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31));
1854
        hi2 -= WC_CACHE_LINE_ADD;
1855
        e3 |= t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31));
1856
        hi3 -= WC_CACHE_LINE_ADD;
1857
    }
1858
    *t0 ^= e0;
1859
    *t1 ^= e1;
1860
    *t2 ^= e2;
1861
    *t3 ^= e3;
1862
}
1863
static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3)
1864
{
1865
    word32 e = 0;
1866
    int i;
1867
    byte hi0 = o0 & WC_CACHE_LINE_MASK_HI;
1868
    byte lo0 = o0 & WC_CACHE_LINE_MASK_LO;
1869
    byte hi1 = o1 & WC_CACHE_LINE_MASK_HI;
1870
    byte lo1 = o1 & WC_CACHE_LINE_MASK_LO;
1871
    byte hi2 = o2 & WC_CACHE_LINE_MASK_HI;
1872
    byte lo2 = o2 & WC_CACHE_LINE_MASK_LO;
1873
    byte hi3 = o3 & WC_CACHE_LINE_MASK_HI;
1874
    byte lo3 = o3 & WC_CACHE_LINE_MASK_LO;
1875
1876
    for (i = 0; i < 256; i += (1 << WC_CACHE_LINE_BITS)) {
1877
        e |= (word32)(t[lo0 + i] & ((word32)0 - (((word32)hi0 - 0x01) >> 31)))
1878
             << 24;
1879
        hi0 -= WC_CACHE_LINE_ADD;
1880
        e |= (word32)(t[lo1 + i] & ((word32)0 - (((word32)hi1 - 0x01) >> 31)))
1881
             << 16;
1882
        hi1 -= WC_CACHE_LINE_ADD;
1883
        e |= (word32)(t[lo2 + i] & ((word32)0 - (((word32)hi2 - 0x01) >> 31)))
1884
             <<  8;
1885
        hi2 -= WC_CACHE_LINE_ADD;
1886
        e |= (word32)(t[lo3 + i] & ((word32)0 - (((word32)hi3 - 0x01) >> 31)))
1887
             <<  0;
1888
        hi3 -= WC_CACHE_LINE_ADD;
1889
    }
1890
1891
    return e;
1892
}
1893
#endif
1894
#else
1895
1896
0
#define GetTable(t, o)  t[o]
1897
#define GetTable8(t, o) t[o]
1898
#define GetTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
1899
    *(t0) = (t)[o0]; *(t1) = (t)[o1]; *(t2) = (t)[o2]; *(t3) = (t)[o3]
1900
#define XorTable_Multi(t, t0, o0, t1, o1, t2, o2, t3, o3)  \
1901
    *(t0) ^= (t)[o0]; *(t1) ^= (t)[o1]; *(t2) ^= (t)[o2]; *(t3) ^= (t)[o3]
1902
#define GetTable8_4(t, o0, o1, o2, o3) \
1903
0
    (((word32)(t)[o0] << 24) | ((word32)(t)[o1] << 16) |   \
1904
0
     ((word32)(t)[o2] <<  8) | ((word32)(t)[o3] <<  0))
1905
#endif
1906
1907
/* Encrypt a block using AES.
1908
 *
1909
 * @param [in]  aes       AES object.
1910
 * @param [in]  inBlock   Block to encrypt.
1911
 * @param [out] outBlock  Encrypted block.
1912
 * @param [in]  r         Rounds divided by 2.
1913
 */
1914
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
1915
        word32 r)
1916
0
{
1917
0
    word32 s0, s1, s2, s3;
1918
0
    word32 t0, t1, t2, t3;
1919
0
    const word32* rk;
1920
1921
#ifdef WC_AES_C_DYNAMIC_FALLBACK
1922
    rk = aes->key_C_fallback;
1923
#else
1924
0
    rk = aes->key;
1925
0
#endif
1926
1927
    /*
1928
     * map byte array block to cipher state
1929
     * and add initial round key:
1930
     */
1931
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
1932
0
    XMEMCPY(&s1, inBlock +     sizeof(s0), sizeof(s1));
1933
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
1934
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
1935
1936
0
#ifdef LITTLE_ENDIAN_ORDER
1937
0
    s0 = ByteReverseWord32(s0);
1938
0
    s1 = ByteReverseWord32(s1);
1939
0
    s2 = ByteReverseWord32(s2);
1940
0
    s3 = ByteReverseWord32(s3);
1941
0
#endif
1942
1943
    /* AddRoundKey */
1944
0
    s0 ^= rk[0];
1945
0
    s1 ^= rk[1];
1946
0
    s2 ^= rk[2];
1947
0
    s3 ^= rk[3];
1948
1949
0
#ifndef WOLFSSL_AES_SMALL_TABLES
1950
0
#ifndef WC_NO_CACHE_RESISTANT
1951
0
    s0 |= PreFetchTe();
1952
0
#endif
1953
1954
0
#ifndef WOLFSSL_AES_TOUCH_LINES
1955
0
#define ENC_ROUND_T_S(o)                                                       \
1956
0
    t0 = GetTable(Te[0], GETBYTE(s0, 3)) ^ GetTable(Te[1], GETBYTE(s1, 2)) ^   \
1957
0
         GetTable(Te[2], GETBYTE(s2, 1)) ^ GetTable(Te[3], GETBYTE(s3, 0)) ^   \
1958
0
         rk[(o)+4];                                                            \
1959
0
    t1 = GetTable(Te[0], GETBYTE(s1, 3)) ^ GetTable(Te[1], GETBYTE(s2, 2)) ^   \
1960
0
         GetTable(Te[2], GETBYTE(s3, 1)) ^ GetTable(Te[3], GETBYTE(s0, 0)) ^   \
1961
0
         rk[(o)+5];                                                            \
1962
0
    t2 = GetTable(Te[0], GETBYTE(s2, 3)) ^ GetTable(Te[1], GETBYTE(s3, 2)) ^   \
1963
0
         GetTable(Te[2], GETBYTE(s0, 1)) ^ GetTable(Te[3], GETBYTE(s1, 0)) ^   \
1964
0
         rk[(o)+6];                                                            \
1965
0
    t3 = GetTable(Te[0], GETBYTE(s3, 3)) ^ GetTable(Te[1], GETBYTE(s0, 2)) ^   \
1966
0
         GetTable(Te[2], GETBYTE(s1, 1)) ^ GetTable(Te[3], GETBYTE(s2, 0)) ^   \
1967
0
         rk[(o)+7]
1968
0
#define ENC_ROUND_S_T(o)                                                       \
1969
0
    s0 = GetTable(Te[0], GETBYTE(t0, 3)) ^ GetTable(Te[1], GETBYTE(t1, 2)) ^   \
1970
0
         GetTable(Te[2], GETBYTE(t2, 1)) ^ GetTable(Te[3], GETBYTE(t3, 0)) ^   \
1971
0
         rk[(o)+0];                                                            \
1972
0
    s1 = GetTable(Te[0], GETBYTE(t1, 3)) ^ GetTable(Te[1], GETBYTE(t2, 2)) ^   \
1973
0
         GetTable(Te[2], GETBYTE(t3, 1)) ^ GetTable(Te[3], GETBYTE(t0, 0)) ^   \
1974
0
         rk[(o)+1];                                                            \
1975
0
    s2 = GetTable(Te[0], GETBYTE(t2, 3)) ^ GetTable(Te[1], GETBYTE(t3, 2)) ^   \
1976
0
         GetTable(Te[2], GETBYTE(t0, 1)) ^ GetTable(Te[3], GETBYTE(t1, 0)) ^   \
1977
0
         rk[(o)+2];                                                            \
1978
0
    s3 = GetTable(Te[0], GETBYTE(t3, 3)) ^ GetTable(Te[1], GETBYTE(t0, 2)) ^   \
1979
0
         GetTable(Te[2], GETBYTE(t1, 1)) ^ GetTable(Te[3], GETBYTE(t2, 0)) ^   \
1980
0
         rk[(o)+3]
1981
#else
1982
#define ENC_ROUND_T_S(o)                                                       \
1983
    GetTable_Multi(Te[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
1984
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
1985
    XorTable_Multi(Te[1], &t0, GETBYTE(s1, 2), &t1, GETBYTE(s2, 2),            \
1986
                          &t2, GETBYTE(s3, 2), &t3, GETBYTE(s0, 2));           \
1987
    XorTable_Multi(Te[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
1988
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
1989
    XorTable_Multi(Te[3], &t0, GETBYTE(s3, 0), &t1, GETBYTE(s0, 0),            \
1990
                          &t2, GETBYTE(s1, 0), &t3, GETBYTE(s2, 0));           \
1991
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
1992
1993
#define ENC_ROUND_S_T(o)                                                       \
1994
    GetTable_Multi(Te[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
1995
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
1996
    XorTable_Multi(Te[1], &s0, GETBYTE(t1, 2), &s1, GETBYTE(t2, 2),            \
1997
                          &s2, GETBYTE(t3, 2), &s3, GETBYTE(t0, 2));           \
1998
    XorTable_Multi(Te[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
1999
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2000
    XorTable_Multi(Te[3], &s0, GETBYTE(t3, 0), &s1, GETBYTE(t0, 0),            \
2001
                          &s2, GETBYTE(t1, 0), &s3, GETBYTE(t2, 0));           \
2002
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2003
#endif
2004
2005
0
#ifndef WOLFSSL_AES_NO_UNROLL
2006
/* Unroll the loop. */
2007
0
                       ENC_ROUND_T_S( 0);
2008
0
    ENC_ROUND_S_T( 8); ENC_ROUND_T_S( 8);
2009
0
    ENC_ROUND_S_T(16); ENC_ROUND_T_S(16);
2010
0
    ENC_ROUND_S_T(24); ENC_ROUND_T_S(24);
2011
0
    ENC_ROUND_S_T(32); ENC_ROUND_T_S(32);
2012
0
    if (r > 5) {
2013
0
        ENC_ROUND_S_T(40); ENC_ROUND_T_S(40);
2014
0
        if (r > 6) {
2015
0
            ENC_ROUND_S_T(48); ENC_ROUND_T_S(48);
2016
0
        }
2017
0
    }
2018
0
    rk += r * 8;
2019
#else
2020
    /*
2021
     * Nr - 1 full rounds:
2022
     */
2023
2024
    for (;;) {
2025
        ENC_ROUND_T_S(0);
2026
2027
        rk += 8;
2028
        if (--r == 0) {
2029
            break;
2030
        }
2031
2032
        ENC_ROUND_S_T(0);
2033
    }
2034
#endif
2035
2036
    /*
2037
     * apply last round and
2038
     * map cipher state to byte array block:
2039
     */
2040
2041
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2042
0
    s0 =
2043
0
        (GetTable(Te[2], GETBYTE(t0, 3)) & 0xff000000) ^
2044
0
        (GetTable(Te[3], GETBYTE(t1, 2)) & 0x00ff0000) ^
2045
0
        (GetTable(Te[0], GETBYTE(t2, 1)) & 0x0000ff00) ^
2046
0
        (GetTable(Te[1], GETBYTE(t3, 0)) & 0x000000ff) ^
2047
0
        rk[0];
2048
0
    s1 =
2049
0
        (GetTable(Te[2], GETBYTE(t1, 3)) & 0xff000000) ^
2050
0
        (GetTable(Te[3], GETBYTE(t2, 2)) & 0x00ff0000) ^
2051
0
        (GetTable(Te[0], GETBYTE(t3, 1)) & 0x0000ff00) ^
2052
0
        (GetTable(Te[1], GETBYTE(t0, 0)) & 0x000000ff) ^
2053
0
        rk[1];
2054
0
    s2 =
2055
0
        (GetTable(Te[2], GETBYTE(t2, 3)) & 0xff000000) ^
2056
0
        (GetTable(Te[3], GETBYTE(t3, 2)) & 0x00ff0000) ^
2057
0
        (GetTable(Te[0], GETBYTE(t0, 1)) & 0x0000ff00) ^
2058
0
        (GetTable(Te[1], GETBYTE(t1, 0)) & 0x000000ff) ^
2059
0
        rk[2];
2060
0
    s3 =
2061
0
        (GetTable(Te[2], GETBYTE(t3, 3)) & 0xff000000) ^
2062
0
        (GetTable(Te[3], GETBYTE(t0, 2)) & 0x00ff0000) ^
2063
0
        (GetTable(Te[0], GETBYTE(t1, 1)) & 0x0000ff00) ^
2064
0
        (GetTable(Te[1], GETBYTE(t2, 0)) & 0x000000ff) ^
2065
0
        rk[3];
2066
#else
2067
{
2068
    word32 u0;
2069
    word32 u1;
2070
    word32 u2;
2071
    word32 u3;
2072
2073
    s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3];
2074
    GetTable_Multi(Te[2], &u0, GETBYTE(t0, 3), &u1, GETBYTE(t1, 3),
2075
                          &u2, GETBYTE(t2, 3), &u3, GETBYTE(t3, 3));
2076
    s0 ^= u0 & 0xff000000; s1 ^= u1 & 0xff000000;
2077
    s2 ^= u2 & 0xff000000; s3 ^= u3 & 0xff000000;
2078
    GetTable_Multi(Te[3], &u0, GETBYTE(t1, 2), &u1, GETBYTE(t2, 2),
2079
                          &u2, GETBYTE(t3, 2), &u3, GETBYTE(t0, 2));
2080
    s0 ^= u0 & 0x00ff0000; s1 ^= u1 & 0x00ff0000;
2081
    s2 ^= u2 & 0x00ff0000; s3 ^= u3 & 0x00ff0000;
2082
    GetTable_Multi(Te[0], &u0, GETBYTE(t2, 1), &u1, GETBYTE(t3, 1),
2083
                          &u2, GETBYTE(t0, 1), &u3, GETBYTE(t1, 1));
2084
    s0 ^= u0 & 0x0000ff00; s1 ^= u1 & 0x0000ff00;
2085
    s2 ^= u2 & 0x0000ff00; s3 ^= u3 & 0x0000ff00;
2086
    GetTable_Multi(Te[1], &u0, GETBYTE(t3, 0), &u1, GETBYTE(t0, 0),
2087
                          &u2, GETBYTE(t1, 0), &u3, GETBYTE(t2, 0));
2088
    s0 ^= u0 & 0x000000ff; s1 ^= u1 & 0x000000ff;
2089
    s2 ^= u2 & 0x000000ff; s3 ^= u3 & 0x000000ff;
2090
}
2091
#endif
2092
#else
2093
#ifndef WC_NO_CACHE_RESISTANT
2094
    s0 |= PreFetchSBox();
2095
#endif
2096
2097
    r *= 2;
2098
    /* Two rounds at a time */
2099
    for (rk += 4; r > 1; r--, rk += 4) {
2100
        t0 =
2101
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2102
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2103
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2104
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2105
        t1 =
2106
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2107
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2108
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2109
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2110
        t2 =
2111
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2112
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2113
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2114
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2115
        t3 =
2116
            ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2117
            ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2118
            ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2119
            ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2120
2121
        s0 =
2122
            (col_mul(t0, 3, 2, 0, 1) << 24) ^
2123
            (col_mul(t0, 2, 1, 0, 3) << 16) ^
2124
            (col_mul(t0, 1, 0, 2, 3) <<  8) ^
2125
            (col_mul(t0, 0, 3, 2, 1)      ) ^
2126
            rk[0];
2127
        s1 =
2128
            (col_mul(t1, 3, 2, 0, 1) << 24) ^
2129
            (col_mul(t1, 2, 1, 0, 3) << 16) ^
2130
            (col_mul(t1, 1, 0, 2, 3) <<  8) ^
2131
            (col_mul(t1, 0, 3, 2, 1)      ) ^
2132
            rk[1];
2133
        s2 =
2134
            (col_mul(t2, 3, 2, 0, 1) << 24) ^
2135
            (col_mul(t2, 2, 1, 0, 3) << 16) ^
2136
            (col_mul(t2, 1, 0, 2, 3) <<  8) ^
2137
            (col_mul(t2, 0, 3, 2, 1)      ) ^
2138
            rk[2];
2139
        s3 =
2140
            (col_mul(t3, 3, 2, 0, 1) << 24) ^
2141
            (col_mul(t3, 2, 1, 0, 3) << 16) ^
2142
            (col_mul(t3, 1, 0, 2, 3) <<  8) ^
2143
            (col_mul(t3, 0, 3, 2, 1)      ) ^
2144
            rk[3];
2145
    }
2146
2147
    t0 =
2148
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 3)) << 24) ^
2149
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 2)) << 16) ^
2150
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 1)) <<  8) ^
2151
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 0)));
2152
    t1 =
2153
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 3)) << 24) ^
2154
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 2)) << 16) ^
2155
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 1)) <<  8) ^
2156
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 0)));
2157
    t2 =
2158
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 3)) << 24) ^
2159
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 2)) << 16) ^
2160
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 1)) <<  8) ^
2161
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 0)));
2162
    t3 =
2163
        ((word32)GetTable8(Tsbox, GETBYTE(s3, 3)) << 24) ^
2164
        ((word32)GetTable8(Tsbox, GETBYTE(s0, 2)) << 16) ^
2165
        ((word32)GetTable8(Tsbox, GETBYTE(s1, 1)) <<  8) ^
2166
        ((word32)GetTable8(Tsbox, GETBYTE(s2, 0)));
2167
    s0 = t0 ^ rk[0];
2168
    s1 = t1 ^ rk[1];
2169
    s2 = t2 ^ rk[2];
2170
    s3 = t3 ^ rk[3];
2171
#endif
2172
2173
    /* write out */
2174
0
#ifdef LITTLE_ENDIAN_ORDER
2175
0
    s0 = ByteReverseWord32(s0);
2176
0
    s1 = ByteReverseWord32(s1);
2177
0
    s2 = ByteReverseWord32(s2);
2178
0
    s3 = ByteReverseWord32(s3);
2179
0
#endif
2180
2181
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
2182
0
    XMEMCPY(outBlock +     sizeof(s0), &s1, sizeof(s1));
2183
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
2184
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
2185
0
}
2186
2187
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2188
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
2189
/* Encrypt a number of blocks using AES.
2190
 *
2191
 * @param [in]  aes  AES object.
2192
 * @param [in]  in   Block to encrypt.
2193
 * @param [out] out  Encrypted block.
2194
 * @param [in]  sz   Number of blocks to encrypt.
2195
 */
2196
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2197
0
{
2198
0
    word32 i;
2199
2200
0
    for (i = 0; i < sz; i += AES_BLOCK_SIZE) {
2201
0
        AesEncrypt_C(aes, in, out, aes->rounds >> 1);
2202
0
        in += AES_BLOCK_SIZE;
2203
0
        out += AES_BLOCK_SIZE;
2204
0
    }
2205
0
}
2206
#endif
2207
2208
#else
2209
2210
/* Bit-sliced implementation based on work by "circuit minimization team" (CMT):
2211
 *   http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
2212
 */
2213
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt */
2214
static void bs_sub_bytes(bs_word u[8])
2215
{
2216
    bs_word y1, y2, y3, y4, y5, y6, y7, y8, y9;
2217
    bs_word y10, y11, y12, y13, y14, y15, y16, y17, y18, y19;
2218
    bs_word y20, y21;
2219
    bs_word t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;
2220
    bs_word t10, t11, t12, t13, t14, t15, t16, t17, t18, t19;
2221
    bs_word t20, t21, t22, t23, t24, t25, t26, t27, t28, t29;
2222
    bs_word t30, t31, t32, t33, t34, t35, t36, t37, t38, t39;
2223
    bs_word t40, t41, t42, t43, t44, t45;
2224
    bs_word z0, z1, z2, z3, z4, z5, z6, z7, z8, z9;
2225
    bs_word z10, z11, z12, z13, z14, z15, z16, z17;
2226
    bs_word tc1, tc2, tc3, tc4, tc5, tc6, tc7, tc8, tc9;
2227
    bs_word tc10, tc11, tc12, tc13, tc14, tc16, tc17, tc18;
2228
    bs_word tc20, tc21, tc26;
2229
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
2230
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
2231
2232
    U0 = u[7];
2233
    U1 = u[6];
2234
    U2 = u[5];
2235
    U3 = u[4];
2236
    U4 = u[3];
2237
    U5 = u[2];
2238
    U6 = u[1];
2239
    U7 = u[0];
2240
2241
    y14 = U3 ^ U5;
2242
    y13 = U0 ^ U6;
2243
    y9 = U0 ^ U3;
2244
    y8 = U0 ^ U5;
2245
    t0 = U1 ^ U2;
2246
    y1 = t0 ^ U7;
2247
    y4 = y1 ^ U3;
2248
    y12 = y13 ^ y14;
2249
    y2 = y1 ^ U0;
2250
    y5 = y1 ^ U6;
2251
    y3 = y5 ^ y8;
2252
    t1 = U4 ^ y12;
2253
    y15 = t1 ^ U5;
2254
    y20 = t1 ^ U1;
2255
    y6 = y15 ^ U7;
2256
    y10 = y15 ^ t0;
2257
    y11 = y20 ^ y9;
2258
    y7 = U7 ^ y11;
2259
    y17 = y10 ^ y11;
2260
    y19 = y10 ^ y8;
2261
    y16 = t0 ^ y11;
2262
    y21 = y13 ^ y16;
2263
    y18 = U0 ^ y16;
2264
    t2 = y12 & y15;
2265
    t3 = y3 & y6;
2266
    t4 = t3 ^ t2;
2267
    t5 = y4 & U7;
2268
    t6 = t5 ^ t2;
2269
    t7 = y13 & y16;
2270
    t8 = y5 & y1;
2271
    t9 = t8 ^ t7;
2272
    t10 = y2 & y7;
2273
    t11 = t10 ^ t7;
2274
    t12 = y9 & y11;
2275
    t13 = y14 & y17;
2276
    t14 = t13 ^ t12;
2277
    t15 = y8 & y10;
2278
    t16 = t15 ^ t12;
2279
    t17 = t4 ^ y20;
2280
    t18 = t6 ^ t16;
2281
    t19 = t9 ^ t14;
2282
    t20 = t11 ^ t16;
2283
    t21 = t17 ^ t14;
2284
    t22 = t18 ^ y19;
2285
    t23 = t19 ^ y21;
2286
    t24 = t20 ^ y18;
2287
    t25 = t21 ^ t22;
2288
    t26 = t21 & t23;
2289
    t27 = t24 ^ t26;
2290
    t28 = t25 & t27;
2291
    t29 = t28 ^ t22;
2292
    t30 = t23 ^ t24;
2293
    t31 = t22 ^ t26;
2294
    t32 = t31 & t30;
2295
    t33 = t32 ^ t24;
2296
    t34 = t23 ^ t33;
2297
    t35 = t27 ^ t33;
2298
    t36 = t24 & t35;
2299
    t37 = t36 ^ t34;
2300
    t38 = t27 ^ t36;
2301
    t39 = t29 & t38;
2302
    t40 = t25 ^ t39;
2303
    t41 = t40 ^ t37;
2304
    t42 = t29 ^ t33;
2305
    t43 = t29 ^ t40;
2306
    t44 = t33 ^ t37;
2307
    t45 = t42 ^ t41;
2308
    z0 = t44 & y15;
2309
    z1 = t37 & y6;
2310
    z2 = t33 & U7;
2311
    z3 = t43 & y16;
2312
    z4 = t40 & y1;
2313
    z5 = t29 & y7;
2314
    z6 = t42 & y11;
2315
    z7 = t45 & y17;
2316
    z8 = t41 & y10;
2317
    z9 = t44 & y12;
2318
    z10 = t37 & y3;
2319
    z11 = t33 & y4;
2320
    z12 = t43 & y13;
2321
    z13 = t40 & y5;
2322
    z14 = t29 & y2;
2323
    z15 = t42 & y9;
2324
    z16 = t45 & y14;
2325
    z17 = t41 & y8;
2326
    tc1 = z15 ^ z16;
2327
    tc2 = z10 ^ tc1;
2328
    tc3 = z9 ^ tc2;
2329
    tc4 = z0 ^ z2;
2330
    tc5 = z1 ^ z0;
2331
    tc6 = z3 ^ z4;
2332
    tc7 = z12 ^ tc4;
2333
    tc8 = z7 ^ tc6;
2334
    tc9 = z8 ^ tc7;
2335
    tc10 = tc8 ^ tc9;
2336
    tc11 = tc6 ^ tc5;
2337
    tc12 = z3 ^ z5;
2338
    tc13 = z13 ^ tc1;
2339
    tc14 = tc4 ^ tc12;
2340
    S3 = tc3 ^ tc11;
2341
    tc16 = z6 ^ tc8;
2342
    tc17 = z14 ^ tc10;
2343
    tc18 = tc13 ^ tc14;
2344
    S7 = ~(z12 ^ tc18);
2345
    tc20 = z15 ^ tc16;
2346
    tc21 = tc2 ^ z11;
2347
    S0 = tc3 ^ tc16;
2348
    S6 = ~(tc10 ^ tc18);
2349
    S4 = tc14 ^ S3;
2350
    S1 = ~(S3 ^ tc16);
2351
    tc26 = tc17 ^ tc20;
2352
    S2 = ~(tc26 ^ z17);
2353
    S5 = tc21 ^ tc17;
2354
2355
    u[0] = S7;
2356
    u[1] = S6;
2357
    u[2] = S5;
2358
    u[3] = S4;
2359
    u[4] = S3;
2360
    u[5] = S2;
2361
    u[6] = S1;
2362
    u[7] = S0;
2363
}
2364
2365
#define BS_MASK_BIT_SET(w, j, bmask) \
2366
    (((bs_word)0 - (((w) >> (j)) & (bs_word)1)) & (bmask))
2367
2368
#define BS_TRANS_8(t, o, w, bmask, s)                   \
2369
    t[o + s + 0] |= BS_MASK_BIT_SET(w, s + 0, bmask);   \
2370
    t[o + s + 1] |= BS_MASK_BIT_SET(w, s + 1, bmask);   \
2371
    t[o + s + 2] |= BS_MASK_BIT_SET(w, s + 2, bmask);   \
2372
    t[o + s + 3] |= BS_MASK_BIT_SET(w, s + 3, bmask);   \
2373
    t[o + s + 4] |= BS_MASK_BIT_SET(w, s + 4, bmask);   \
2374
    t[o + s + 5] |= BS_MASK_BIT_SET(w, s + 5, bmask);   \
2375
    t[o + s + 6] |= BS_MASK_BIT_SET(w, s + 6, bmask);   \
2376
    t[o + s + 7] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2377
2378
static void bs_transpose(bs_word* t, bs_word* blocks)
2379
{
2380
    bs_word bmask = 1;
2381
    int i;
2382
2383
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2384
2385
    for (i = 0; i < BS_WORD_SIZE; i++) {
2386
        int j;
2387
        int o = 0;
2388
        for (j = 0; j < BS_BLOCK_WORDS; j++) {
2389
        #ifdef LITTLE_ENDIAN_ORDER
2390
            bs_word w = blocks[i * BS_BLOCK_WORDS + j];
2391
        #else
2392
            bs_word w = bs_bswap(blocks[i * BS_BLOCK_WORDS + j]);
2393
        #endif
2394
    #ifdef WOLFSSL_AES_NO_UNROLL
2395
            int k;
2396
            for (k = 0; k < BS_WORD_SIZE; k++) {
2397
                t[o + k] |= BS_MASK_BIT_SET(w, k, bmask);
2398
            }
2399
    #else
2400
            BS_TRANS_8(t, o, w, bmask,  0);
2401
        #if BS_WORD_SIZE >= 16
2402
            BS_TRANS_8(t, o, w, bmask,  8);
2403
        #endif
2404
        #if BS_WORD_SIZE >= 32
2405
            BS_TRANS_8(t, o, w, bmask, 16);
2406
            BS_TRANS_8(t, o, w, bmask, 24);
2407
        #endif
2408
        #if BS_WORD_SIZE >= 64
2409
            BS_TRANS_8(t, o, w, bmask, 32);
2410
            BS_TRANS_8(t, o, w, bmask, 40);
2411
            BS_TRANS_8(t, o, w, bmask, 48);
2412
            BS_TRANS_8(t, o, w, bmask, 56);
2413
        #endif
2414
    #endif
2415
            o += BS_WORD_SIZE;
2416
        }
2417
        bmask <<= 1;
2418
    }
2419
}
2420
2421
#define BS_INV_TRANS_8(t, o, w, bmask, s)                                   \
2422
    t[o + (s + 0) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 0, bmask);    \
2423
    t[o + (s + 1) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 1, bmask);    \
2424
    t[o + (s + 2) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 2, bmask);    \
2425
    t[o + (s + 3) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 3, bmask);    \
2426
    t[o + (s + 4) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 4, bmask);    \
2427
    t[o + (s + 5) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 5, bmask);    \
2428
    t[o + (s + 6) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 6, bmask);    \
2429
    t[o + (s + 7) * BS_BLOCK_WORDS] |= BS_MASK_BIT_SET(w, s + 7, bmask)
2430
2431
static void bs_inv_transpose(bs_word* t, bs_word* blocks)
2432
{
2433
    int o;
2434
2435
    XMEMSET(t, 0, sizeof(bs_word) * AES_BLOCK_BITS);
2436
2437
    for (o = 0; o < BS_BLOCK_WORDS; o++) {
2438
        int i;
2439
        for (i = 0; i < BS_WORD_SIZE; i++) {
2440
        #ifdef LITTLE_ENDIAN_ORDER
2441
            bs_word bmask = (bs_word)1 << i;
2442
        #else
2443
            bs_word bmask = bs_bswap((bs_word)1 << i);
2444
        #endif
2445
            bs_word w = blocks[(o << BS_WORD_SHIFT) + i];
2446
    #ifdef WOLFSSL_AES_NO_UNROLL
2447
            int j;
2448
            for (j = 0; j < BS_WORD_SIZE; j++) {
2449
                t[j * BS_BLOCK_WORDS + o] |= BS_MASK_BIT_SET(w, j, bmask);
2450
            }
2451
    #else
2452
            BS_INV_TRANS_8(t, o, w, bmask, 0);
2453
        #if BS_WORD_SIZE >= 16
2454
            BS_INV_TRANS_8(t, o, w, bmask, 8);
2455
        #endif
2456
        #if BS_WORD_SIZE >= 32
2457
            BS_INV_TRANS_8(t, o, w, bmask, 16);
2458
            BS_INV_TRANS_8(t, o, w, bmask, 24);
2459
        #endif
2460
        #if BS_WORD_SIZE >= 64
2461
            BS_INV_TRANS_8(t, o, w, bmask, 32);
2462
            BS_INV_TRANS_8(t, o, w, bmask, 40);
2463
            BS_INV_TRANS_8(t, o, w, bmask, 48);
2464
            BS_INV_TRANS_8(t, o, w, bmask, 56);
2465
        #endif
2466
    #endif
2467
        }
2468
    }
2469
}
2470
2471
#define BS_ROW_OFF_0    0
2472
#define BS_ROW_OFF_1    32
2473
#define BS_ROW_OFF_2    64
2474
#define BS_ROW_OFF_3    96
2475
2476
#define BS_ROW_ADD      (AES_BLOCK_BITS / 16 + AES_BLOCK_BITS / 4)
2477
#define BS_IDX_MASK     0x7f
2478
2479
#define BS_ASSIGN_8(d, od, s, os)   \
2480
    d[(od) + 0] = s[(os) + 0];      \
2481
    d[(od) + 1] = s[(os) + 1];      \
2482
    d[(od) + 2] = s[(os) + 2];      \
2483
    d[(od) + 3] = s[(os) + 3];      \
2484
    d[(od) + 4] = s[(os) + 4];      \
2485
    d[(od) + 5] = s[(os) + 5];      \
2486
    d[(od) + 6] = s[(os) + 6];      \
2487
    d[(od) + 7] = s[(os) + 7]
2488
2489
static void bs_shift_rows(bs_word* t, bs_word* b)
2490
{
2491
    int i;
2492
2493
    for (i = 0; i < 128; i += 32) {
2494
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
2495
        BS_ASSIGN_8(t, i +  8, b, ( 40 + i) & BS_IDX_MASK);
2496
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
2497
        BS_ASSIGN_8(t, i + 24, b, (120 + i) & BS_IDX_MASK);
2498
    }
2499
}
2500
2501
#define BS_SHIFT_OFF_0  0
2502
#define BS_SHIFT_OFF_1  8
2503
#define BS_SHIFT_OFF_2  16
2504
#define BS_SHIFT_OFF_3  24
2505
2506
/* Shift rows and mix columns.
2507
 * See: See https://eprint.iacr.org/2009/129.pdf - Appendix A
2508
 */
2509
2510
#define BS_SHIFT_MIX_8(t, o, br0, br1, br2, br3, of)                \
2511
        of      = br0[7] ^ br1[7];                                  \
2512
        t[o+0] =                   br1[0] ^ br2[0] ^ br3[0] ^ of;   \
2513
        t[o+1] = br0[0] ^ br1[0] ^ br1[1] ^ br2[1] ^ br3[1] ^ of;   \
2514
        t[o+2] = br0[1] ^ br1[1] ^ br1[2] ^ br2[2] ^ br3[2];        \
2515
        t[o+3] = br0[2] ^ br1[2] ^ br1[3] ^ br2[3] ^ br3[3] ^ of;   \
2516
        t[o+4] = br0[3] ^ br1[3] ^ br1[4] ^ br2[4] ^ br3[4] ^ of;   \
2517
        t[o+5] = br0[4] ^ br1[4] ^ br1[5] ^ br2[5] ^ br3[5];        \
2518
        t[o+6] = br0[5] ^ br1[5] ^ br1[6] ^ br2[6] ^ br3[6];        \
2519
        t[o+7] = br0[6] ^ br1[6] ^ br1[7] ^ br2[7] ^ br3[7]
2520
2521
static void bs_shift_mix(bs_word* t, bs_word* b)
2522
{
2523
    int i;
2524
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
2525
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
2526
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
2527
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
2528
2529
    for (i = 0; i < AES_BLOCK_BITS; i += AES_BLOCK_BITS / 4) {
2530
        bs_word* br0 = b + or0;
2531
        bs_word* br1 = b + or1;
2532
        bs_word* br2 = b + or2;
2533
        bs_word* br3 = b + or3;
2534
        bs_word of;
2535
2536
        BS_SHIFT_MIX_8(t, i +  0, br0, br1, br2, br3, of);
2537
        BS_SHIFT_MIX_8(t, i +  8, br1, br2, br3, br0, of);
2538
        BS_SHIFT_MIX_8(t, i + 16, br2, br3, br0, br1, of);
2539
        BS_SHIFT_MIX_8(t, i + 24, br3, br0, br1, br2, of);
2540
2541
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2542
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2543
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2544
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
2545
    }
2546
}
2547
2548
static void bs_add_round_key(bs_word* out, bs_word* b, bs_word* rk)
2549
{
2550
    xorbufout((byte*)out, (byte*)b, (byte*)rk, BS_BLOCK_SIZE);
2551
}
2552
2553
static void bs_sub_bytes_blocks(bs_word* b)
2554
{
2555
    int i;
2556
2557
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
2558
        bs_sub_bytes(b + i);
2559
    }
2560
}
2561
2562
static const FLASH_QUALIFIER byte bs_rcon[] = {
2563
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
2564
    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
2565
};
2566
2567
static void bs_ke_sub_bytes(unsigned char* out, unsigned char *in) {
2568
    bs_word block[AES_BLOCK_BITS];
2569
    bs_word trans[AES_BLOCK_BITS];
2570
2571
    XMEMSET(block, 0, sizeof(block));
2572
    XMEMCPY(block, in, 4);
2573
2574
    bs_transpose(trans, block);
2575
    bs_sub_bytes_blocks(trans);
2576
    bs_inv_transpose(block, trans);
2577
2578
    XMEMCPY(out, block, 4);
2579
}
2580
2581
static void bs_ke_transform(unsigned char* out, unsigned char *in, word8 i) {
2582
    /* Rotate the input 8 bits to the left */
2583
#ifdef LITTLE_ENDIAN_ORDER
2584
    *(word32*)out = rotrFixed(*(word32*)in, 8);
2585
#else
2586
    *(word32*)out = rotlFixed(*(word32*)in, 8);
2587
#endif
2588
    bs_ke_sub_bytes(out, out);
2589
    /* On just the first byte, add 2^i to the byte */
2590
    out[0] ^= bs_rcon[i];
2591
}
2592
2593
static void bs_expand_key(unsigned char *in, word32 sz) {
2594
    unsigned char t[4];
2595
    word32 o;
2596
    word8 i = 0;
2597
2598
    if (sz == 176) {
2599
        /* Total of 11 rounds - AES-128. */
2600
        for (o = 16; o < sz; o += 16) {
2601
            bs_ke_transform(t, in + o - 4, i);
2602
            i++;
2603
            *(word32*)(in + o +  0) = *(word32*)(in + o - 16) ^
2604
                                      *(word32*) t;
2605
            *(word32*)(in + o +  4) = *(word32*)(in + o - 12) ^
2606
                                      *(word32*)(in + o +  0);
2607
            *(word32*)(in + o +  8) = *(word32*)(in + o -  8) ^
2608
                                      *(word32*)(in + o +  4);
2609
            *(word32*)(in + o + 12) = *(word32*)(in + o -  4) ^
2610
                                      *(word32*)(in + o +  8);
2611
        }
2612
    }
2613
    else if (sz == 208) {
2614
        /* Total of 13 rounds - AES-192. */
2615
        for (o = 24; o < sz; o += 24) {
2616
            bs_ke_transform(t, in + o - 4, i);
2617
            i++;
2618
            *(word32*)(in + o +  0) = *(word32*)(in + o - 24) ^
2619
                                      *(word32*) t;
2620
            *(word32*)(in + o +  4) = *(word32*)(in + o - 20) ^
2621
                                      *(word32*)(in + o +  0);
2622
            *(word32*)(in + o +  8) = *(word32*)(in + o - 16) ^
2623
                                      *(word32*)(in + o +  4);
2624
            *(word32*)(in + o + 12) = *(word32*)(in + o - 12) ^
2625
                                      *(word32*)(in + o +  8);
2626
            *(word32*)(in + o + 16) = *(word32*)(in + o -  8) ^
2627
                                      *(word32*)(in + o + 12);
2628
            *(word32*)(in + o + 20) = *(word32*)(in + o -  4) ^
2629
                                      *(word32*)(in + o + 16);
2630
        }
2631
    }
2632
    else if (sz == 240) {
2633
        /* Total of 15 rounds - AES-256. */
2634
        for (o = 32; o < sz; o += 16) {
2635
            if ((o & 0x1f) == 0) {
2636
                bs_ke_transform(t, in + o - 4, i);
2637
                i++;
2638
            }
2639
            else {
2640
                bs_ke_sub_bytes(t, in + o - 4);
2641
            }
2642
            *(word32*)(in + o +  0) = *(word32*)(in + o - 32) ^
2643
                                      *(word32*) t;
2644
            *(word32*)(in + o +  4) = *(word32*)(in + o - 28) ^
2645
                                      *(word32*)(in + o +  0);
2646
            *(word32*)(in + o +  8) = *(word32*)(in + o - 24) ^
2647
                                      *(word32*)(in + o +  4);
2648
            *(word32*)(in + o + 12) = *(word32*)(in + o - 20) ^
2649
                                      *(word32*)(in + o +  8);
2650
        }
2651
    }
2652
}
2653
2654
static void bs_set_key(bs_word* rk, const byte* key, word32 keyLen,
2655
    word32 rounds)
2656
{
2657
    int i;
2658
    byte bs_key[15 * AES_BLOCK_SIZE];
2659
    int ksSz = (rounds + 1) * AES_BLOCK_SIZE;
2660
    bs_word block[AES_BLOCK_BITS];
2661
2662
    /* Fist round. */
2663
    XMEMCPY(bs_key, key, keyLen);
2664
    bs_expand_key(bs_key, ksSz);
2665
2666
    for (i = 0; i < ksSz; i += AES_BLOCK_SIZE) {
2667
        int k;
2668
2669
        XMEMCPY(block, bs_key + i, AES_BLOCK_SIZE);
2670
        for (k = BS_BLOCK_WORDS; k < AES_BLOCK_BITS; k += BS_BLOCK_WORDS) {
2671
            int l;
2672
            for (l = 0; l < BS_BLOCK_WORDS; l++) {
2673
                block[k + l] = block[l];
2674
            }
2675
        }
2676
        bs_transpose(rk, block);
2677
        rk += AES_BLOCK_BITS;
2678
    }
2679
}
2680
2681
static void bs_encrypt(bs_word* state, bs_word* rk, word32 r)
2682
{
2683
    word32 i;
2684
    bs_word trans[AES_BLOCK_BITS];
2685
2686
    bs_transpose(trans, state);
2687
2688
    bs_add_round_key(trans, trans, rk);
2689
    for (i = 1; i < r; i++) {
2690
        bs_sub_bytes_blocks(trans);
2691
        bs_shift_mix(state, trans);
2692
        rk += AES_BLOCK_BITS;
2693
        bs_add_round_key(trans, state, rk);
2694
    }
2695
    bs_sub_bytes_blocks(trans);
2696
    bs_shift_rows(state, trans);
2697
    rk += AES_BLOCK_BITS;
2698
    bs_add_round_key(trans, state, rk);
2699
    bs_inv_transpose(state, trans);
2700
}
2701
2702
/* Encrypt a block using AES.
2703
 *
2704
 * @param [in]  aes       AES object.
2705
 * @param [in]  inBlock   Block to encrypt.
2706
 * @param [out] outBlock  Encrypted block.
2707
 * @param [in]  r         Rounds divided by 2.
2708
 */
2709
static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2710
        word32 r)
2711
{
2712
    bs_word state[AES_BLOCK_BITS];
2713
2714
    (void)r;
2715
2716
    XMEMCPY(state, inBlock, AES_BLOCK_SIZE);
2717
    XMEMSET(((byte*)state) + AES_BLOCK_SIZE, 0, sizeof(state) - AES_BLOCK_SIZE);
2718
2719
    bs_encrypt(state, aes->bs_key, aes->rounds);
2720
2721
    XMEMCPY(outBlock, state, AES_BLOCK_SIZE);
2722
}
2723
2724
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
2725
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
2726
/* Encrypt a number of blocks using AES.
2727
 *
2728
 * @param [in]  aes  AES object.
2729
 * @param [in]  in   Block to encrypt.
2730
 * @param [out] out  Encrypted block.
2731
 * @param [in]  sz   Number of blocks to encrypt.
2732
 */
2733
static void AesEncryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
2734
{
2735
    bs_word state[AES_BLOCK_BITS];
2736
2737
    while (sz >= BS_BLOCK_SIZE) {
2738
        XMEMCPY(state, in, BS_BLOCK_SIZE);
2739
        bs_encrypt(state, aes->bs_key, aes->rounds);
2740
        XMEMCPY(out, state, BS_BLOCK_SIZE);
2741
        sz  -= BS_BLOCK_SIZE;
2742
        in  += BS_BLOCK_SIZE;
2743
        out += BS_BLOCK_SIZE;
2744
    }
2745
    if (sz > 0) {
2746
        XMEMCPY(state, in, sz);
2747
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
2748
        bs_encrypt(state, aes->bs_key, aes->rounds);
2749
        XMEMCPY(out, state, sz);
2750
    }
2751
}
2752
#endif
2753
2754
#endif /* !WC_AES_BITSLICED */
2755
2756
/* this section disabled with NO_AES_192 */
2757
/* calling this one when missing NO_AES_192  */
2758
static WARN_UNUSED_RESULT int wc_AesEncrypt(
2759
    Aes* aes, const byte* inBlock, byte* outBlock)
2760
0
{
2761
0
    word32 r;
2762
2763
0
    if (aes == NULL) {
2764
0
        return BAD_FUNC_ARG;
2765
0
    }
2766
2767
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
2768
    {
2769
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
2770
        if (ret < 0)
2771
            return ret;
2772
    }
2773
#endif
2774
2775
0
    r = aes->rounds >> 1;
2776
2777
0
    if (r > 7 || r == 0) {
2778
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
2779
0
        return KEYUSAGE_E;
2780
0
    }
2781
2782
#ifdef WOLFSSL_AESNI
2783
    if (aes->use_aesni) {
2784
        ASSERT_SAVED_VECTOR_REGISTERS();
2785
2786
        #ifdef DEBUG_AESNI
2787
            printf("about to aes encrypt\n");
2788
            printf("in  = %p\n", inBlock);
2789
            printf("out = %p\n", outBlock);
2790
            printf("aes->key = %p\n", aes->key);
2791
            printf("aes->rounds = %d\n", aes->rounds);
2792
            printf("sz = %d\n", AES_BLOCK_SIZE);
2793
        #endif
2794
2795
        /* check alignment, decrypt doesn't need alignment */
2796
        if ((wc_ptr_t)inBlock % AESNI_ALIGN) {
2797
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
2798
            byte* tmp = (byte*)XMALLOC(AES_BLOCK_SIZE + AESNI_ALIGN, aes->heap,
2799
                                                      DYNAMIC_TYPE_TMP_BUFFER);
2800
            byte* tmp_align;
2801
            if (tmp == NULL)
2802
                return MEMORY_E;
2803
2804
            tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
2805
2806
            XMEMCPY(tmp_align, inBlock, AES_BLOCK_SIZE);
2807
            AES_ECB_encrypt_AESNI(tmp_align, tmp_align, AES_BLOCK_SIZE,
2808
                    (byte*)aes->key, (int)aes->rounds);
2809
            XMEMCPY(outBlock, tmp_align, AES_BLOCK_SIZE);
2810
            XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
2811
            return 0;
2812
        #else
2813
            WOLFSSL_MSG("AES-ECB encrypt with bad alignment");
2814
            WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
2815
            return BAD_ALIGN_E;
2816
        #endif
2817
        }
2818
2819
        AES_ECB_encrypt_AESNI(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
2820
                        (int)aes->rounds);
2821
2822
        return 0;
2823
    }
2824
    else {
2825
        #ifdef DEBUG_AESNI
2826
            printf("Skipping AES-NI\n");
2827
        #endif
2828
    }
2829
#endif /* WOLFSSL_AESNI */
2830
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
2831
    AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
2832
    return 0;
2833
#endif
2834
2835
#if defined(WOLFSSL_IMXRT_DCP)
2836
    if (aes->keylen == 16) {
2837
        DCPAesEcbEncrypt(aes, outBlock, inBlock, AES_BLOCK_SIZE);
2838
        return 0;
2839
    }
2840
#endif
2841
2842
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
2843
    if (aes->useSWCrypt == 0) {
2844
        return se050_aes_crypt(aes, inBlock, outBlock, AES_BLOCK_SIZE,
2845
                               AES_ENCRYPTION, kAlgorithm_SSS_AES_ECB);
2846
    }
2847
#endif
2848
2849
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
2850
    ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
2851
    if (wc_esp32AesSupportedKeyLen(aes)) {
2852
        return wc_esp32AesEncrypt(aes, inBlock, outBlock);
2853
    }
2854
    else {
2855
        /* For example, the ESP32-S3 does not support HW for len = 24,
2856
         * so fall back to SW */
2857
    #ifdef DEBUG_WOLFSSL
2858
        ESP_LOGW(TAG, "wc_AesEncrypt HW Falling back, unsupported keylen = %d",
2859
                      aes->keylen);
2860
    #endif
2861
    }
2862
#endif
2863
2864
0
    AesEncrypt_C(aes, inBlock, outBlock, r);
2865
2866
0
    return 0;
2867
0
} /* wc_AesEncrypt */
2868
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT || HAVE_AESGCM */
2869
2870
#if defined(HAVE_AES_DECRYPT)
2871
#if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC) && \
2872
                              !defined(WOLFSSL_SILABS_SE_ACCEL)) || \
2873
    defined(WOLFSSL_AES_DIRECT)
2874
2875
#ifndef WC_AES_BITSLICED
2876
#ifndef WC_NO_CACHE_RESISTANT
2877
#ifndef WOLFSSL_AES_SMALL_TABLES
2878
/* load 4 Td Tables into cache by cache line stride */
2879
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd(void)
2880
0
{
2881
0
    word32 x = 0;
2882
0
    int i,j;
2883
2884
0
    for (i = 0; i < 4; i++) {
2885
        /* 256 elements, each one is 4 bytes */
2886
0
        for (j = 0; j < 256; j += WC_CACHE_LINE_SZ/4) {
2887
0
            x &= Td[i][j];
2888
0
        }
2889
0
    }
2890
0
    return x;
2891
0
}
2892
#endif
2893
2894
/* load Td Table4 into cache by cache line stride */
2895
static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void)
2896
0
{
2897
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2898
0
    word32 x = 0;
2899
0
    int i;
2900
2901
0
    for (i = 0; i < 256; i += WC_CACHE_LINE_SZ) {
2902
0
        x &= (word32)Td4[i];
2903
0
    }
2904
0
    return x;
2905
#else
2906
    return 0;
2907
#endif
2908
0
}
2909
#endif
2910
2911
/* Decrypt a block using AES.
2912
 *
2913
 * @param [in]  aes       AES object.
2914
 * @param [in]  inBlock   Block to encrypt.
2915
 * @param [out] outBlock  Encrypted block.
2916
 * @param [in]  r         Rounds divided by 2.
2917
 */
2918
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
2919
    word32 r)
2920
0
{
2921
0
    word32 s0, s1, s2, s3;
2922
0
    word32 t0, t1, t2, t3;
2923
0
    const word32* rk;
2924
2925
#ifdef WC_AES_C_DYNAMIC_FALLBACK
2926
    rk = aes->key_C_fallback;
2927
#else
2928
0
    rk = aes->key;
2929
0
#endif
2930
2931
    /*
2932
     * map byte array block to cipher state
2933
     * and add initial round key:
2934
     */
2935
0
    XMEMCPY(&s0, inBlock,                  sizeof(s0));
2936
0
    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
2937
0
    XMEMCPY(&s2, inBlock + 2 * sizeof(s0), sizeof(s2));
2938
0
    XMEMCPY(&s3, inBlock + 3 * sizeof(s0), sizeof(s3));
2939
2940
0
#ifdef LITTLE_ENDIAN_ORDER
2941
0
    s0 = ByteReverseWord32(s0);
2942
0
    s1 = ByteReverseWord32(s1);
2943
0
    s2 = ByteReverseWord32(s2);
2944
0
    s3 = ByteReverseWord32(s3);
2945
0
#endif
2946
2947
0
    s0 ^= rk[0];
2948
0
    s1 ^= rk[1];
2949
0
    s2 ^= rk[2];
2950
0
    s3 ^= rk[3];
2951
2952
0
#ifndef WOLFSSL_AES_SMALL_TABLES
2953
0
#ifndef WC_NO_CACHE_RESISTANT
2954
0
    s0 |= PreFetchTd();
2955
0
#endif
2956
2957
0
#ifndef WOLFSSL_AES_TOUCH_LINES
2958
/* Unroll the loop. */
2959
0
#define DEC_ROUND_T_S(o)                                            \
2960
0
    t0 = GetTable(Td[0], GETBYTE(s0, 3)) ^ GetTable(Td[1], GETBYTE(s3, 2)) ^            \
2961
0
         GetTable(Td[2], GETBYTE(s2, 1)) ^ GetTable(Td[3], GETBYTE(s1, 0)) ^ rk[(o)+4]; \
2962
0
    t1 = GetTable(Td[0], GETBYTE(s1, 3)) ^ GetTable(Td[1], GETBYTE(s0, 2)) ^            \
2963
0
         GetTable(Td[2], GETBYTE(s3, 1)) ^ GetTable(Td[3], GETBYTE(s2, 0)) ^ rk[(o)+5]; \
2964
0
    t2 = GetTable(Td[0], GETBYTE(s2, 3)) ^ GetTable(Td[1], GETBYTE(s1, 2)) ^            \
2965
0
         GetTable(Td[2], GETBYTE(s0, 1)) ^ GetTable(Td[3], GETBYTE(s3, 0)) ^ rk[(o)+6]; \
2966
0
    t3 = GetTable(Td[0], GETBYTE(s3, 3)) ^ GetTable(Td[1], GETBYTE(s2, 2)) ^            \
2967
0
         GetTable(Td[2], GETBYTE(s1, 1)) ^ GetTable(Td[3], GETBYTE(s0, 0)) ^ rk[(o)+7]
2968
0
#define DEC_ROUND_S_T(o)                                            \
2969
0
    s0 = GetTable(Td[0], GETBYTE(t0, 3)) ^ GetTable(Td[1], GETBYTE(t3, 2)) ^            \
2970
0
         GetTable(Td[2], GETBYTE(t2, 1)) ^ GetTable(Td[3], GETBYTE(t1, 0)) ^ rk[(o)+0]; \
2971
0
    s1 = GetTable(Td[0], GETBYTE(t1, 3)) ^ GetTable(Td[1], GETBYTE(t0, 2)) ^            \
2972
0
         GetTable(Td[2], GETBYTE(t3, 1)) ^ GetTable(Td[3], GETBYTE(t2, 0)) ^ rk[(o)+1]; \
2973
0
    s2 = GetTable(Td[0], GETBYTE(t2, 3)) ^ GetTable(Td[1], GETBYTE(t1, 2)) ^            \
2974
0
         GetTable(Td[2], GETBYTE(t0, 1)) ^ GetTable(Td[3], GETBYTE(t3, 0)) ^ rk[(o)+2]; \
2975
0
    s3 = GetTable(Td[0], GETBYTE(t3, 3)) ^ GetTable(Td[1], GETBYTE(t2, 2)) ^            \
2976
0
         GetTable(Td[2], GETBYTE(t1, 1)) ^ GetTable(Td[3], GETBYTE(t0, 0)) ^ rk[(o)+3]
2977
#else
2978
#define DEC_ROUND_T_S(o)                                                       \
2979
    GetTable_Multi(Td[0], &t0, GETBYTE(s0, 3), &t1, GETBYTE(s1, 3),            \
2980
                          &t2, GETBYTE(s2, 3), &t3, GETBYTE(s3, 3));           \
2981
    XorTable_Multi(Td[1], &t0, GETBYTE(s3, 2), &t1, GETBYTE(s0, 2),            \
2982
                          &t2, GETBYTE(s1, 2), &t3, GETBYTE(s2, 2));           \
2983
    XorTable_Multi(Td[2], &t0, GETBYTE(s2, 1), &t1, GETBYTE(s3, 1),            \
2984
                          &t2, GETBYTE(s0, 1), &t3, GETBYTE(s1, 1));           \
2985
    XorTable_Multi(Td[3], &t0, GETBYTE(s1, 0), &t1, GETBYTE(s2, 0),            \
2986
                          &t2, GETBYTE(s3, 0), &t3, GETBYTE(s0, 0));           \
2987
    t0 ^= rk[(o)+4]; t1 ^= rk[(o)+5]; t2 ^= rk[(o)+6]; t3 ^= rk[(o)+7];
2988
2989
#define DEC_ROUND_S_T(o)                                                       \
2990
    GetTable_Multi(Td[0], &s0, GETBYTE(t0, 3), &s1, GETBYTE(t1, 3),            \
2991
                          &s2, GETBYTE(t2, 3), &s3, GETBYTE(t3, 3));           \
2992
    XorTable_Multi(Td[1], &s0, GETBYTE(t3, 2), &s1, GETBYTE(t0, 2),            \
2993
                          &s2, GETBYTE(t1, 2), &s3, GETBYTE(t2, 2));           \
2994
    XorTable_Multi(Td[2], &s0, GETBYTE(t2, 1), &s1, GETBYTE(t3, 1),            \
2995
                          &s2, GETBYTE(t0, 1), &s3, GETBYTE(t1, 1));           \
2996
    XorTable_Multi(Td[3], &s0, GETBYTE(t1, 0), &s1, GETBYTE(t2, 0),            \
2997
                          &s2, GETBYTE(t3, 0), &s3, GETBYTE(t0, 0));           \
2998
    s0 ^= rk[(o)+0]; s1 ^= rk[(o)+1]; s2 ^= rk[(o)+2]; s3 ^= rk[(o)+3];
2999
#endif
3000
3001
0
#ifndef WOLFSSL_AES_NO_UNROLL
3002
0
                       DEC_ROUND_T_S( 0);
3003
0
    DEC_ROUND_S_T( 8); DEC_ROUND_T_S( 8);
3004
0
    DEC_ROUND_S_T(16); DEC_ROUND_T_S(16);
3005
0
    DEC_ROUND_S_T(24); DEC_ROUND_T_S(24);
3006
0
    DEC_ROUND_S_T(32); DEC_ROUND_T_S(32);
3007
0
    if (r > 5) {
3008
0
        DEC_ROUND_S_T(40); DEC_ROUND_T_S(40);
3009
0
        if (r > 6) {
3010
0
            DEC_ROUND_S_T(48); DEC_ROUND_T_S(48);
3011
0
        }
3012
0
    }
3013
0
    rk += r * 8;
3014
#else
3015
3016
    /*
3017
     * Nr - 1 full rounds:
3018
     */
3019
3020
    for (;;) {
3021
        DEC_ROUND_T_S(0);
3022
3023
        rk += 8;
3024
        if (--r == 0) {
3025
            break;
3026
        }
3027
3028
        DEC_ROUND_S_T(0);
3029
    }
3030
#endif
3031
    /*
3032
     * apply last round and
3033
     * map cipher state to byte array block:
3034
     */
3035
3036
0
#ifndef WC_NO_CACHE_RESISTANT
3037
0
    t0 |= PreFetchTd4();
3038
0
#endif
3039
3040
0
    s0 = GetTable8_4(Td4, GETBYTE(t0, 3), GETBYTE(t3, 2),
3041
0
                          GETBYTE(t2, 1), GETBYTE(t1, 0)) ^ rk[0];
3042
0
    s1 = GetTable8_4(Td4, GETBYTE(t1, 3), GETBYTE(t0, 2),
3043
0
                          GETBYTE(t3, 1), GETBYTE(t2, 0)) ^ rk[1];
3044
0
    s2 = GetTable8_4(Td4, GETBYTE(t2, 3), GETBYTE(t1, 2),
3045
0
                          GETBYTE(t0, 1), GETBYTE(t3, 0)) ^ rk[2];
3046
0
    s3 = GetTable8_4(Td4, GETBYTE(t3, 3), GETBYTE(t2, 2),
3047
0
                          GETBYTE(t1, 1), GETBYTE(t0, 0)) ^ rk[3];
3048
#else
3049
#ifndef WC_NO_CACHE_RESISTANT
3050
    s0 |= PreFetchTd4();
3051
#endif
3052
3053
    r *= 2;
3054
    for (rk += 4; r > 1; r--, rk += 4) {
3055
        t0 =
3056
            ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3057
            ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3058
            ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3059
            ((word32)GetTable8(Td4, GETBYTE(s1, 0))) ^
3060
            rk[0];
3061
        t1 =
3062
            ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3063
            ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3064
            ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3065
            ((word32)GetTable8(Td4, GETBYTE(s2, 0))) ^
3066
            rk[1];
3067
        t2 =
3068
            ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3069
            ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3070
            ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3071
            ((word32)GetTable8(Td4, GETBYTE(s3, 0))) ^
3072
            rk[2];
3073
        t3 =
3074
            ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3075
            ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3076
            ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3077
            ((word32)GetTable8(Td4, GETBYTE(s0, 0))) ^
3078
            rk[3];
3079
3080
        s0 =
3081
            (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^
3082
            (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^
3083
            (inv_col_mul(t0, 2, 0, 3, 1) <<  8) ^
3084
            (inv_col_mul(t0, 1, 3, 2, 0)      );
3085
        s1 =
3086
            (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^
3087
            (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^
3088
            (inv_col_mul(t1, 2, 0, 3, 1) <<  8) ^
3089
            (inv_col_mul(t1, 1, 3, 2, 0)      );
3090
        s2 =
3091
            (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^
3092
            (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^
3093
            (inv_col_mul(t2, 2, 0, 3, 1) <<  8) ^
3094
            (inv_col_mul(t2, 1, 3, 2, 0)      );
3095
        s3 =
3096
            (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^
3097
            (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^
3098
            (inv_col_mul(t3, 2, 0, 3, 1) <<  8) ^
3099
            (inv_col_mul(t3, 1, 3, 2, 0)      );
3100
    }
3101
3102
    t0 =
3103
        ((word32)GetTable8(Td4, GETBYTE(s0, 3)) << 24) ^
3104
        ((word32)GetTable8(Td4, GETBYTE(s3, 2)) << 16) ^
3105
        ((word32)GetTable8(Td4, GETBYTE(s2, 1)) <<  8) ^
3106
        ((word32)GetTable8(Td4, GETBYTE(s1, 0)));
3107
    t1 =
3108
        ((word32)GetTable8(Td4, GETBYTE(s1, 3)) << 24) ^
3109
        ((word32)GetTable8(Td4, GETBYTE(s0, 2)) << 16) ^
3110
        ((word32)GetTable8(Td4, GETBYTE(s3, 1)) <<  8) ^
3111
        ((word32)GetTable8(Td4, GETBYTE(s2, 0)));
3112
    t2 =
3113
        ((word32)GetTable8(Td4, GETBYTE(s2, 3)) << 24) ^
3114
        ((word32)GetTable8(Td4, GETBYTE(s1, 2)) << 16) ^
3115
        ((word32)GetTable8(Td4, GETBYTE(s0, 1)) <<  8) ^
3116
        ((word32)GetTable8(Td4, GETBYTE(s3, 0)));
3117
    t3 =
3118
        ((word32)GetTable8(Td4, GETBYTE(s3, 3)) << 24) ^
3119
        ((word32)GetTable8(Td4, GETBYTE(s2, 2)) << 16) ^
3120
        ((word32)GetTable8(Td4, GETBYTE(s1, 1)) <<  8) ^
3121
        ((word32)GetTable8(Td4, GETBYTE(s0, 0)));
3122
    s0 = t0 ^ rk[0];
3123
    s1 = t1 ^ rk[1];
3124
    s2 = t2 ^ rk[2];
3125
    s3 = t3 ^ rk[3];
3126
#endif
3127
3128
    /* write out */
3129
0
#ifdef LITTLE_ENDIAN_ORDER
3130
0
    s0 = ByteReverseWord32(s0);
3131
0
    s1 = ByteReverseWord32(s1);
3132
0
    s2 = ByteReverseWord32(s2);
3133
0
    s3 = ByteReverseWord32(s3);
3134
0
#endif
3135
3136
0
    XMEMCPY(outBlock,                  &s0, sizeof(s0));
3137
0
    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
3138
0
    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
3139
0
    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
3140
3141
0
}
3142
3143
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3144
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3145
/* Decrypt a number of blocks using AES.
3146
 *
3147
 * @param [in]  aes  AES object.
3148
 * @param [in]  in   Block to encrypt.
3149
 * @param [out] out  Encrypted block.
3150
 * @param [in]  sz   Number of blocks to encrypt.
3151
 */
3152
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3153
0
{
3154
0
    word32 i;
3155
3156
0
    for (i = 0; i < sz; i += AES_BLOCK_SIZE) {
3157
0
        AesDecrypt_C(aes, in, out, aes->rounds >> 1);
3158
0
        in += AES_BLOCK_SIZE;
3159
0
        out += AES_BLOCK_SIZE;
3160
0
    }
3161
0
}
3162
#endif
3163
3164
#else
3165
3166
/* http://cs-www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt */
3167
static void bs_inv_sub_bytes(bs_word u[8])
3168
{
3169
    bs_word U0, U1, U2, U3, U4, U5, U6, U7;
3170
    bs_word Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7;
3171
    bs_word RTL0, RTL1, RTL2;
3172
    bs_word sa0, sa1;
3173
    bs_word sb0, sb1;
3174
    bs_word ab0, ab1, ab2, ab3;
3175
    bs_word ab20, ab21, ab22, ab23;
3176
    bs_word al, ah, aa, bl, bh, bb;
3177
    bs_word abcd1, abcd2, abcd3, abcd4, abcd5, abcd6;
3178
    bs_word ph11, ph12, ph13, ph01, ph02, ph03;
3179
    bs_word pl01, pl02, pl03, pl11, pl12, pl13;
3180
    bs_word r1, r2, r3, r4, r5, r6, r7, r8, r9;
3181
    bs_word rr1, rr2;
3182
    bs_word r10, r11;
3183
    bs_word cp1, cp2, cp3, cp4;
3184
    bs_word vr1, vr2, vr3;
3185
    bs_word pr1, pr2, pr3;
3186
    bs_word wr1, wr2, wr3;
3187
    bs_word qr1, qr2, qr3;
3188
    bs_word tinv1, tinv2, tinv3, tinv4, tinv5, tinv6, tinv7, tinv8, tinv9;
3189
    bs_word tinv10, tinv11, tinv12, tinv13;
3190
    bs_word t01, t02;
3191
    bs_word d0, d1, d2, d3;
3192
    bs_word dl, dd, dh;
3193
    bs_word sd0, sd1;
3194
    bs_word p0, p1, p2, p3, p4, p6, p7;
3195
    bs_word X11, X13, X14, X16, X18, X19;
3196
    bs_word S0, S1, S2, S3, S4, S5, S6, S7;
3197
3198
    U0 = u[7];
3199
    U1 = u[6];
3200
    U2 = u[5];
3201
    U3 = u[4];
3202
    U4 = u[3];
3203
    U5 = u[2];
3204
    U6 = u[1];
3205
    U7 = u[0];
3206
3207
    Y0 = U0 ^ U3;
3208
    Y2 = ~(U1 ^ U3);
3209
    Y4 = U0 ^ Y2;
3210
    RTL0 = U6 ^ U7;
3211
    Y1 = Y2 ^ RTL0;
3212
    Y7 = ~(U2 ^ Y1);
3213
    RTL1 = U3 ^ U4;
3214
    Y6 = ~(U7 ^ RTL1);
3215
    Y3 = Y1 ^ RTL1;
3216
    RTL2 = ~(U0 ^ U2);
3217
    Y5 = U5 ^ RTL2;
3218
    sa1 = Y0 ^ Y2;
3219
    sa0 = Y1 ^ Y3;
3220
    sb1 = Y4 ^ Y6;
3221
    sb0 = Y5 ^ Y7;
3222
    ah = Y0 ^ Y1;
3223
    al = Y2 ^ Y3;
3224
    aa = sa0 ^ sa1;
3225
    bh = Y4 ^ Y5;
3226
    bl = Y6 ^ Y7;
3227
    bb = sb0 ^ sb1;
3228
    ab20 = sa0 ^ sb0;
3229
    ab22 = al ^ bl;
3230
    ab23 = Y3 ^ Y7;
3231
    ab21 = sa1 ^ sb1;
3232
    abcd1 = ah & bh;
3233
    rr1 = Y0 & Y4;
3234
    ph11 = ab20 ^ abcd1;
3235
    t01 = Y1 & Y5;
3236
    ph01 = t01 ^ abcd1;
3237
    abcd2 = al & bl;
3238
    r1 = Y2 & Y6;
3239
    pl11 = ab22 ^ abcd2;
3240
    r2 = Y3 & Y7;
3241
    pl01 = r2 ^ abcd2;
3242
    r3 = sa0 & sb0;
3243
    vr1 = aa & bb;
3244
    pr1 = vr1 ^ r3;
3245
    wr1 = sa1 & sb1;
3246
    qr1 = wr1 ^ r3;
3247
    ab0 = ph11 ^ rr1;
3248
    ab1 = ph01 ^ ab21;
3249
    ab2 = pl11 ^ r1;
3250
    ab3 = pl01 ^ qr1;
3251
    cp1 = ab0 ^ pr1;
3252
    cp2 = ab1 ^ qr1;
3253
    cp3 = ab2 ^ pr1;
3254
    cp4 = ab3 ^ ab23;
3255
    tinv1 = cp3 ^ cp4;
3256
    tinv2 = cp3 & cp1;
3257
    tinv3 = cp2 ^ tinv2;
3258
    tinv4 = cp1 ^ cp2;
3259
    tinv5 = cp4 ^ tinv2;
3260
    tinv6 = tinv5 & tinv4;
3261
    tinv7 = tinv3 & tinv1;
3262
    d2 = cp4 ^ tinv7;
3263
    d0 = cp2 ^ tinv6;
3264
    tinv8 = cp1 & cp4;
3265
    tinv9 = tinv4 & tinv8;
3266
    tinv10 = tinv4 ^ tinv2;
3267
    d1 = tinv9 ^ tinv10;
3268
    tinv11 = cp2 & cp3;
3269
    tinv12 = tinv1 & tinv11;
3270
    tinv13 = tinv1 ^ tinv2;
3271
    d3 = tinv12 ^ tinv13;
3272
    sd1 = d1 ^ d3;
3273
    sd0 = d0 ^ d2;
3274
    dl = d0 ^ d1;
3275
    dh = d2 ^ d3;
3276
    dd = sd0 ^ sd1;
3277
    abcd3 = dh & bh;
3278
    rr2 = d3 & Y4;
3279
    t02 = d2 & Y5;
3280
    abcd4 = dl & bl;
3281
    r4 = d1 & Y6;
3282
    r5 = d0 & Y7;
3283
    r6 = sd0 & sb0;
3284
    vr2 = dd & bb;
3285
    wr2 = sd1 & sb1;
3286
    abcd5 = dh & ah;
3287
    r7 = d3 & Y0;
3288
    r8 = d2 & Y1;
3289
    abcd6 = dl & al;
3290
    r9 = d1 & Y2;
3291
    r10 = d0 & Y3;
3292
    r11 = sd0 & sa0;
3293
    vr3 = dd & aa;
3294
    wr3 = sd1 & sa1;
3295
    ph12 = rr2 ^ abcd3;
3296
    ph02 = t02 ^ abcd3;
3297
    pl12 = r4 ^ abcd4;
3298
    pl02 = r5 ^ abcd4;
3299
    pr2 = vr2 ^ r6;
3300
    qr2 = wr2 ^ r6;
3301
    p0 = ph12 ^ pr2;
3302
    p1 = ph02 ^ qr2;
3303
    p2 = pl12 ^ pr2;
3304
    p3 = pl02 ^ qr2;
3305
    ph13 = r7 ^ abcd5;
3306
    ph03 = r8 ^ abcd5;
3307
    pl13 = r9 ^ abcd6;
3308
    pl03 = r10 ^ abcd6;
3309
    pr3 = vr3 ^ r11;
3310
    qr3 = wr3 ^ r11;
3311
    p4 = ph13 ^ pr3;
3312
    S7 = ph03 ^ qr3;
3313
    p6 = pl13 ^ pr3;
3314
    p7 = pl03 ^ qr3;
3315
    S3 = p1 ^ p6;
3316
    S6 = p2 ^ p6;
3317
    S0 = p3 ^ p6;
3318
    X11 = p0 ^ p2;
3319
    S5 = S0 ^ X11;
3320
    X13 = p4 ^ p7;
3321
    X14 = X11 ^ X13;
3322
    S1 = S3 ^ X14;
3323
    X16 = p1 ^ S7;
3324
    S2 = X14 ^ X16;
3325
    X18 = p0 ^ p4;
3326
    X19 = S5 ^ X16;
3327
    S4 = X18 ^ X19;
3328
3329
    u[0] = S7;
3330
    u[1] = S6;
3331
    u[2] = S5;
3332
    u[3] = S4;
3333
    u[4] = S3;
3334
    u[5] = S2;
3335
    u[6] = S1;
3336
    u[7] = S0;
3337
}
3338
3339
static void bs_inv_shift_rows(bs_word* b)
3340
{
3341
    bs_word t[AES_BLOCK_BITS];
3342
    int i;
3343
3344
    for (i = 0; i < 128; i += 32) {
3345
        BS_ASSIGN_8(t, i +  0, b, (  0 + i) & BS_IDX_MASK);
3346
        BS_ASSIGN_8(t, i +  8, b, (104 + i) & BS_IDX_MASK);
3347
        BS_ASSIGN_8(t, i + 16, b, ( 80 + i) & BS_IDX_MASK);
3348
        BS_ASSIGN_8(t, i + 24, b, ( 56 + i) & BS_IDX_MASK);
3349
    }
3350
3351
    XMEMCPY(b, t, sizeof(t));
3352
}
3353
3354
#define O0  0
3355
#define O1  8
3356
#define O2  16
3357
#define O3  24
3358
3359
#define BS_INV_MIX_SHIFT_8(br, b, O0, O1, O2, O3, of0, of1, of2)            \
3360
    of0 = b[O0+7] ^ b[O0+6] ^ b[O0+5] ^ b[O1 + 7] ^ b[O1+5] ^               \
3361
          b[O2+6] ^ b[O2+5] ^ b[O3+5];                                      \
3362
    of1 =           b[O0+7] ^ b[O0+6] ^             b[O1+6] ^               \
3363
          b[O2+7] ^ b[O2+6] ^ b[O3+6];                                      \
3364
    of2 =                     b[O0+7] ^             b[O1+7] ^               \
3365
                    b[O2+7] ^ b[O3+7];                                      \
3366
                                                                            \
3367
    br[0] =                                                   b[O1+0] ^     \
3368
            b[O2+0]                     ^ b[O3+0]           ^ of0;          \
3369
    br[1] = b[O0+0]                               ^ b[O1+0] ^ b[O1+1] ^     \
3370
            b[O2+1]                     ^ b[O3+1]           ^ of0 ^ of1;    \
3371
    br[2] = b[O0+1] ^ b[O0+0]                     ^ b[O1+1] ^ b[O1+2] ^     \
3372
            b[O2+2] ^ b[O2+0]           ^ b[O3+2]           ^ of1 ^ of2;    \
3373
    br[3] = b[O0+2] ^ b[O0+1] ^ b[O0+0] ^ b[O1+0] ^ b[O1+2] ^ b[O1+3] ^     \
3374
            b[O2+3] ^ b[O2+1] ^ b[O2+0] ^ b[O3+3] ^ b[O3+0] ^ of0 ^ of2;    \
3375
    br[4] = b[O0+3] ^ b[O0+2] ^ b[O0+1] ^ b[O1+1] ^ b[O1+3] ^ b[O1+4] ^     \
3376
            b[O2+4] ^ b[O2+2] ^ b[O2+1] ^ b[O3+4] ^ b[O3+1] ^ of0 ^ of1;    \
3377
    br[5] = b[O0+4] ^ b[O0+3] ^ b[O0+2] ^ b[O1+2] ^ b[O1+4] ^ b[O1+5] ^     \
3378
            b[O2+5] ^ b[O2+3] ^ b[O2+2] ^ b[O3+5] ^ b[O3+2] ^ of1 ^ of2;    \
3379
    br[6] = b[O0+5] ^ b[O0+4] ^ b[O0+3] ^ b[O1+3] ^ b[O1+5] ^ b[O1+6] ^     \
3380
            b[O2+6] ^ b[O2+4] ^ b[O2+3] ^ b[O3+6] ^ b[O3+3] ^ of2;          \
3381
    br[7] = b[O0+6] ^ b[O0+5] ^ b[O0+4] ^ b[O1+4] ^ b[O1+6] ^ b[O1+7] ^     \
3382
            b[O2+7] ^ b[O2+5] ^ b[O2+4] ^ b[O3+7] ^ b[O3+4]
3383
3384
/* Inverse mix columns and shift rows. */
3385
static void bs_inv_mix_shift(bs_word* t, bs_word* b)
3386
{
3387
    bs_word* bp = b;
3388
    word8 or0 = BS_ROW_OFF_0 + BS_SHIFT_OFF_0;
3389
    word8 or1 = BS_ROW_OFF_1 + BS_SHIFT_OFF_1;
3390
    word8 or2 = BS_ROW_OFF_2 + BS_SHIFT_OFF_2;
3391
    word8 or3 = BS_ROW_OFF_3 + BS_SHIFT_OFF_3;
3392
    int i;
3393
3394
    for (i = 0; i < AES_BLOCK_BITS / 4; i += AES_BLOCK_BITS / 16) {
3395
        bs_word* br;
3396
        bs_word of0;
3397
        bs_word of1;
3398
        bs_word of2;
3399
3400
        br = t + or0;
3401
        BS_INV_MIX_SHIFT_8(br, bp, O0, O1, O2, O3, of0, of1, of2);
3402
        br = t + or1;
3403
        BS_INV_MIX_SHIFT_8(br, bp, O1, O2, O3, O0, of0, of1, of2);
3404
        br = t + or2;
3405
        BS_INV_MIX_SHIFT_8(br, bp, O2, O3, O0, O1, of0, of1, of2);
3406
        br = t + or3;
3407
        BS_INV_MIX_SHIFT_8(br, bp, O3, O0, O1, O2, of0, of1, of2);
3408
3409
        or0 = (or0 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3410
        or1 = (or1 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3411
        or2 = (or2 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3412
        or3 = (or3 + AES_BLOCK_BITS / 4) & BS_IDX_MASK;
3413
3414
        bp += AES_BLOCK_BITS / 4;
3415
    }
3416
}
3417
3418
static void bs_inv_sub_bytes_blocks(bs_word* b)
3419
{
3420
    int i;
3421
3422
    for (i = 0; i < AES_BLOCK_BITS; i += 8) {
3423
        bs_inv_sub_bytes(b + i);
3424
    }
3425
}
3426
3427
static void bs_decrypt(bs_word* state, bs_word* rk, word32 r)
3428
{
3429
    int i;
3430
    bs_word trans[AES_BLOCK_BITS];
3431
3432
    bs_transpose(trans, state);
3433
3434
    rk += r * AES_BLOCK_BITS;
3435
    bs_add_round_key(trans, trans, rk);
3436
    bs_inv_shift_rows(trans);
3437
    bs_inv_sub_bytes_blocks(trans);
3438
    rk -= AES_BLOCK_BITS;
3439
    bs_add_round_key(trans, trans, rk);
3440
    for (i = (int)r - 2; i >= 0; i--) {
3441
        bs_inv_mix_shift(state, trans);
3442
        bs_inv_sub_bytes_blocks(state);
3443
        rk -= AES_BLOCK_BITS;
3444
        bs_add_round_key(trans, state, rk);
3445
    }
3446
3447
    bs_inv_transpose(state, trans);
3448
}
3449
3450
#ifdef WOLFSSL_AES_DIRECT
3451
/* Decrypt a block using AES.
3452
 *
3453
 * @param [in]  aes       AES object.
3454
 * @param [in]  inBlock   Block to encrypt.
3455
 * @param [out] outBlock  Encrypted block.
3456
 * @param [in]  r         Rounds divided by 2.
3457
 */
3458
static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock,
3459
    word32 r)
3460
{
3461
    bs_word state[AES_BLOCK_BITS];
3462
3463
    (void)r;
3464
3465
    XMEMCPY(state, inBlock, AES_BLOCK_SIZE);
3466
    XMEMSET(((byte*)state) + AES_BLOCK_SIZE, 0, sizeof(state) - AES_BLOCK_SIZE);
3467
3468
    bs_decrypt(state, aes->bs_key, aes->rounds);
3469
3470
    XMEMCPY(outBlock, state, AES_BLOCK_SIZE);
3471
}
3472
#endif
3473
3474
#if defined(HAVE_AES_ECB) && !(defined(WOLFSSL_IMX6_CAAM) && \
3475
    !defined(NO_IMX6_CAAM_AES) && !defined(WOLFSSL_QNX_CAAM))
3476
/* Decrypt a number of blocks using AES.
3477
 *
3478
 * @param [in]  aes  AES object.
3479
 * @param [in]  in   Block to encrypt.
3480
 * @param [out] out  Encrypted block.
3481
 * @param [in]  sz   Number of blocks to encrypt.
3482
 */
3483
static void AesDecryptBlocks_C(Aes* aes, const byte* in, byte* out, word32 sz)
3484
{
3485
    bs_word state[AES_BLOCK_BITS];
3486
3487
    while (sz >= BS_BLOCK_SIZE) {
3488
        XMEMCPY(state, in, BS_BLOCK_SIZE);
3489
        bs_decrypt(state, aes->bs_key, aes->rounds);
3490
        XMEMCPY(out, state, BS_BLOCK_SIZE);
3491
        sz  -= BS_BLOCK_SIZE;
3492
        in  += BS_BLOCK_SIZE;
3493
        out += BS_BLOCK_SIZE;
3494
    }
3495
    if (sz > 0) {
3496
        XMEMCPY(state, in, sz);
3497
        XMEMSET(((byte*)state) + sz, 0, sizeof(state) - sz);
3498
        bs_decrypt(state, aes->bs_key, aes->rounds);
3499
        XMEMCPY(out, state, sz);
3500
    }
3501
}
3502
#endif
3503
3504
#endif
3505
3506
#if !defined(WC_AES_BITSLICED) || defined(WOLFSSL_AES_DIRECT)
3507
/* Software AES - ECB Decrypt */
3508
static WARN_UNUSED_RESULT int wc_AesDecrypt(
3509
    Aes* aes, const byte* inBlock, byte* outBlock)
3510
0
{
3511
0
    word32 r;
3512
3513
0
    if (aes == NULL) {
3514
0
        return BAD_FUNC_ARG;
3515
0
    }
3516
3517
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3518
    {
3519
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3520
        if (ret < 0)
3521
            return ret;
3522
    }
3523
#endif
3524
3525
0
    r = aes->rounds >> 1;
3526
3527
0
    if (r > 7 || r == 0) {
3528
0
        WOLFSSL_ERROR_VERBOSE(KEYUSAGE_E);
3529
0
        return KEYUSAGE_E;
3530
0
    }
3531
3532
#ifdef WOLFSSL_AESNI
3533
    if (aes->use_aesni) {
3534
        ASSERT_SAVED_VECTOR_REGISTERS();
3535
3536
        #ifdef DEBUG_AESNI
3537
            printf("about to aes decrypt\n");
3538
            printf("in  = %p\n", inBlock);
3539
            printf("out = %p\n", outBlock);
3540
            printf("aes->key = %p\n", aes->key);
3541
            printf("aes->rounds = %d\n", aes->rounds);
3542
            printf("sz = %d\n", AES_BLOCK_SIZE);
3543
        #endif
3544
3545
        /* if input and output same will overwrite input iv */
3546
        if ((const byte*)aes->tmp != inBlock)
3547
            XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
3548
        AES_ECB_decrypt_AESNI(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
3549
                        (int)aes->rounds);
3550
        return 0;
3551
    }
3552
    else {
3553
        #ifdef DEBUG_AESNI
3554
            printf("Skipping AES-NI\n");
3555
        #endif
3556
    }
3557
#endif /* WOLFSSL_AESNI */
3558
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
3559
    return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
3560
#endif
3561
#if defined(WOLFSSL_IMXRT_DCP)
3562
    if (aes->keylen == 16) {
3563
        DCPAesEcbDecrypt(aes, outBlock, inBlock, AES_BLOCK_SIZE);
3564
        return 0;
3565
    }
3566
#endif
3567
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
3568
    if (aes->useSWCrypt == 0) {
3569
        return se050_aes_crypt(aes, inBlock, outBlock, AES_BLOCK_SIZE,
3570
                               AES_DECRYPTION, kAlgorithm_SSS_AES_ECB);
3571
    }
3572
#endif
3573
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
3574
    if (wc_esp32AesSupportedKeyLen(aes)) {
3575
        return wc_esp32AesDecrypt(aes, inBlock, outBlock);
3576
    }
3577
    else {
3578
        /* For example, the ESP32-S3 does not support HW for len = 24,
3579
         * so fall back to SW */
3580
    #ifdef DEBUG_WOLFSSL
3581
        ESP_LOGW(TAG, "wc_AesDecrypt HW Falling back, "
3582
                        "unsupported keylen = %d", aes->keylen);
3583
    #endif
3584
    } /* else !wc_esp32AesSupportedKeyLen for ESP32 */
3585
#endif
3586
3587
0
    AesDecrypt_C(aes, inBlock, outBlock, r);
3588
3589
0
    return 0;
3590
0
} /* wc_AesDecrypt[_SW]() */
3591
#endif /* !WC_AES_BITSLICED || WOLFSSL_AES_DIRECT */
3592
#endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */
3593
#endif /* HAVE_AES_DECRYPT */
3594
3595
#endif /* NEED_AES_TABLES */
3596
3597
3598
3599
/* wc_AesSetKey */
3600
#if defined(STM32_CRYPTO)
3601
3602
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3603
            const byte* iv, int dir)
3604
    {
3605
        word32 *rk;
3606
3607
        (void)dir;
3608
3609
        if (aes == NULL || (keylen != 16 &&
3610
        #ifdef WOLFSSL_AES_192
3611
            keylen != 24 &&
3612
        #endif
3613
            keylen != 32)) {
3614
            return BAD_FUNC_ARG;
3615
        }
3616
3617
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3618
        {
3619
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3620
            if (ret < 0)
3621
                return ret;
3622
        }
3623
#endif
3624
3625
        rk = aes->key;
3626
        aes->keylen = keylen;
3627
        aes->rounds = keylen/4 + 6;
3628
        XMEMCPY(rk, userKey, keylen);
3629
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
3630
        ByteReverseWords(rk, rk, keylen);
3631
    #endif
3632
    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
3633
        defined(WOLFSSL_AES_OFB)
3634
        aes->left = 0;
3635
    #endif
3636
        return wc_AesSetIV(aes, iv);
3637
    }
3638
    #if defined(WOLFSSL_AES_DIRECT)
3639
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3640
                            const byte* iv, int dir)
3641
        {
3642
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3643
        }
3644
    #endif
3645
3646
#elif defined(HAVE_COLDFIRE_SEC)
3647
    #if defined (HAVE_THREADX)
3648
        #include "memory_pools.h"
3649
        extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
3650
    #endif
3651
3652
    #define AES_BUFFER_SIZE (AES_BLOCK_SIZE * 64)
3653
    static unsigned char *AESBuffIn = NULL;
3654
    static unsigned char *AESBuffOut = NULL;
3655
    static byte *secReg;
3656
    static byte *secKey;
3657
    static volatile SECdescriptorType *secDesc;
3658
3659
    static wolfSSL_Mutex Mutex_AesSEC;
3660
3661
    #define SEC_DESC_AES_CBC_ENCRYPT 0x60300010
3662
    #define SEC_DESC_AES_CBC_DECRYPT 0x60200010
3663
3664
    extern volatile unsigned char __MBAR[];
3665
3666
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3667
        const byte* iv, int dir)
3668
    {
3669
        if (AESBuffIn == NULL) {
3670
        #if defined (HAVE_THREADX)
3671
            int s1, s2, s3, s4, s5;
3672
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
3673
                                  sizeof(SECdescriptorType), TX_NO_WAIT);
3674
            s1 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffIn,
3675
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
3676
            s2 = tx_byte_allocate(&mp_ncached, (void *)&AESBuffOut,
3677
                                  AES_BUFFER_SIZE, TX_NO_WAIT);
3678
            s3 = tx_byte_allocate(&mp_ncached, (void *)&secKey,
3679
                                  AES_BLOCK_SIZE*2, TX_NO_WAIT);
3680
            s4 = tx_byte_allocate(&mp_ncached, (void *)&secReg,
3681
                                  AES_BLOCK_SIZE, TX_NO_WAIT);
3682
3683
            if (s1 || s2 || s3 || s4 || s5)
3684
                return BAD_FUNC_ARG;
3685
        #else
3686
            #warning "Allocate non-Cache buffers"
3687
        #endif
3688
3689
            wc_InitMutex(&Mutex_AesSEC);
3690
        }
3691
3692
        if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3693
            return BAD_FUNC_ARG;
3694
3695
        if (aes == NULL)
3696
            return BAD_FUNC_ARG;
3697
3698
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3699
        {
3700
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3701
            if (ret < 0)
3702
                return ret;
3703
        }
3704
#endif
3705
3706
        aes->keylen = keylen;
3707
        aes->rounds = keylen/4 + 6;
3708
        XMEMCPY(aes->key, userKey, keylen);
3709
3710
        if (iv)
3711
            XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
3712
3713
    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
3714
        defined(WOLFSSL_AES_OFB)
3715
        aes->left = 0;
3716
    #endif
3717
3718
        return 0;
3719
    }
3720
#elif defined(FREESCALE_LTC)
3721
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
3722
        const byte* iv, int dir, int checkKeyLen)
3723
    {
3724
        if (aes == NULL)
3725
            return BAD_FUNC_ARG;
3726
3727
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3728
        {
3729
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3730
            if (ret < 0)
3731
                return ret;
3732
        }
3733
#endif
3734
3735
        if (checkKeyLen) {
3736
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3737
                return BAD_FUNC_ARG;
3738
        }
3739
        (void)dir;
3740
3741
        aes->rounds = keylen/4 + 6;
3742
        XMEMCPY(aes->key, userKey, keylen);
3743
3744
    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
3745
        defined(WOLFSSL_AES_OFB)
3746
        aes->left = 0;
3747
    #endif
3748
3749
        return wc_AesSetIV(aes, iv);
3750
    }
3751
3752
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3753
        const byte* iv, int dir)
3754
    {
3755
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
3756
    }
3757
3758
3759
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3760
                        const byte* iv, int dir)
3761
    {
3762
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3763
    }
3764
#elif defined(FREESCALE_MMCAU)
3765
    int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
3766
        const byte* iv, int dir, int checkKeyLen)
3767
    {
3768
        int ret;
3769
        byte* rk;
3770
        byte* tmpKey = (byte*)userKey;
3771
        int tmpKeyDynamic = 0;
3772
        word32 alignOffset = 0;
3773
3774
        (void)dir;
3775
3776
        if (aes == NULL)
3777
            return BAD_FUNC_ARG;
3778
3779
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3780
        {
3781
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3782
            if (ret < 0)
3783
                return ret;
3784
        }
3785
#endif
3786
3787
        if (checkKeyLen) {
3788
            if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
3789
                return BAD_FUNC_ARG;
3790
        }
3791
3792
        rk = (byte*)aes->key;
3793
        if (rk == NULL)
3794
            return BAD_FUNC_ARG;
3795
3796
    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
3797
        defined(WOLFSSL_AES_OFB)
3798
        aes->left = 0;
3799
    #endif
3800
3801
        aes->rounds = keylen/4 + 6;
3802
3803
    #ifdef FREESCALE_MMCAU_CLASSIC
3804
        if ((wc_ptr_t)userKey % WOLFSSL_MMCAU_ALIGNMENT) {
3805
        #ifndef NO_WOLFSSL_ALLOC_ALIGN
3806
            byte* tmp = (byte*)XMALLOC(keylen + WOLFSSL_MMCAU_ALIGNMENT,
3807
                                       aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3808
            if (tmp == NULL) {
3809
                return MEMORY_E;
3810
            }
3811
            alignOffset = WOLFSSL_MMCAU_ALIGNMENT -
3812
                          ((wc_ptr_t)tmp % WOLFSSL_MMCAU_ALIGNMENT);
3813
            tmpKey = tmp + alignOffset;
3814
            XMEMCPY(tmpKey, userKey, keylen);
3815
            tmpKeyDynamic = 1;
3816
        #else
3817
            WOLFSSL_MSG("Bad cau_aes_set_key alignment");
3818
            return BAD_ALIGN_E;
3819
        #endif
3820
        }
3821
    #endif
3822
3823
        ret = wolfSSL_CryptHwMutexLock();
3824
        if(ret == 0) {
3825
        #ifdef FREESCALE_MMCAU_CLASSIC
3826
            cau_aes_set_key(tmpKey, keylen*8, rk);
3827
        #else
3828
            MMCAU_AES_SetKey(tmpKey, keylen, rk);
3829
        #endif
3830
            wolfSSL_CryptHwMutexUnLock();
3831
3832
            ret = wc_AesSetIV(aes, iv);
3833
        }
3834
3835
        if (tmpKeyDynamic == 1) {
3836
            XFREE(tmpKey - alignOffset, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
3837
        }
3838
3839
        return ret;
3840
    }
3841
3842
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3843
        const byte* iv, int dir)
3844
    {
3845
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
3846
    }
3847
3848
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3849
                        const byte* iv, int dir)
3850
    {
3851
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3852
    }
3853
3854
#elif defined(WOLFSSL_NRF51_AES)
3855
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
3856
        const byte* iv, int dir)
3857
    {
3858
        int ret;
3859
3860
        (void)dir;
3861
        (void)iv;
3862
3863
        if (aes == NULL || keylen != 16)
3864
            return BAD_FUNC_ARG;
3865
3866
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3867
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3868
        if (ret < 0)
3869
            return ret;
3870
#endif
3871
3872
        aes->keylen = keylen;
3873
        aes->rounds = keylen/4 + 6;
3874
        XMEMCPY(aes->key, userKey, keylen);
3875
        ret = nrf51_aes_set_key(userKey);
3876
3877
    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
3878
        defined(WOLFSSL_AES_OFB)
3879
        aes->left = 0;
3880
    #endif
3881
3882
        return ret;
3883
    }
3884
3885
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
3886
                        const byte* iv, int dir)
3887
    {
3888
        return wc_AesSetKey(aes, userKey, keylen, iv, dir);
3889
    }
3890
#elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
3891
    /* This is the only definition for HW only.
3892
     * but needs to be renamed when fallback needed.
3893
     * See call in wc_AesSetKey() */
3894
    int wc_AesSetKey_for_ESP32(Aes* aes, const byte* userKey, word32 keylen,
3895
        const byte* iv, int dir)
3896
    {
3897
        (void)dir;
3898
        (void)iv;
3899
        ESP_LOGV(TAG, "wc_AesSetKey_for_ESP32");
3900
        if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
3901
            return BAD_FUNC_ARG;
3902
        }
3903
3904
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3905
        {
3906
            int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3907
            if (ret < 0)
3908
                return ret;
3909
        }
3910
#endif
3911
3912
    #if !defined(WOLFSSL_AES_128)
3913
        if (keylen == 16) {
3914
            return BAD_FUNC_ARG;
3915
        }
3916
    #endif
3917
3918
    #if !defined(WOLFSSL_AES_192)
3919
        if (keylen == 24) {
3920
            return BAD_FUNC_ARG;
3921
        }
3922
    #endif
3923
3924
    #if !defined(WOLFSSL_AES_256)
3925
        if (keylen == 32) {
3926
            return BAD_FUNC_ARG;
3927
        }
3928
    #endif
3929
3930
        aes->keylen = keylen;
3931
        aes->rounds = keylen/4 + 6;
3932
3933
        XMEMCPY(aes->key, userKey, keylen);
3934
        #if defined(WOLFSSL_AES_COUNTER)
3935
            aes->left = 0;
3936
        #endif
3937
        return wc_AesSetIV(aes, iv);
3938
    } /* wc_AesSetKey */
3939
3940
    /* end #elif ESP32 */
3941
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
3942
3943
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
3944
                    int dir)
3945
    {
3946
        SaSiError_t ret = SASI_OK;
3947
        SaSiAesIv_t iv_aes;
3948
3949
        if (aes == NULL ||
3950
           (keylen != AES_128_KEY_SIZE &&
3951
            keylen != AES_192_KEY_SIZE &&
3952
            keylen != AES_256_KEY_SIZE)) {
3953
            return BAD_FUNC_ARG;
3954
        }
3955
3956
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
3957
        {
3958
            int ret2 =
3959
                wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
3960
            if (ret2 < 0)
3961
                return ret2;
3962
        }
3963
#endif
3964
3965
    #if defined(AES_MAX_KEY_SIZE)
3966
        if (keylen > (AES_MAX_KEY_SIZE/8)) {
3967
            return BAD_FUNC_ARG;
3968
        }
3969
    #endif
3970
        if (dir != AES_ENCRYPTION &&
3971
            dir != AES_DECRYPTION) {
3972
            return BAD_FUNC_ARG;
3973
        }
3974
3975
        if (dir == AES_ENCRYPTION) {
3976
            aes->ctx.mode = SASI_AES_ENCRYPT;
3977
            SaSi_AesInit(&aes->ctx.user_ctx,
3978
                         SASI_AES_ENCRYPT,
3979
                         SASI_AES_MODE_CBC,
3980
                         SASI_AES_PADDING_NONE);
3981
        }
3982
        else {
3983
            aes->ctx.mode = SASI_AES_DECRYPT;
3984
            SaSi_AesInit(&aes->ctx.user_ctx,
3985
                         SASI_AES_DECRYPT,
3986
                         SASI_AES_MODE_CBC,
3987
                         SASI_AES_PADDING_NONE);
3988
        }
3989
3990
        aes->keylen = keylen;
3991
        aes->rounds = keylen/4 + 6;
3992
        XMEMCPY(aes->key, userKey, keylen);
3993
3994
        aes->ctx.key.pKey = (byte*)aes->key;
3995
        aes->ctx.key.keySize= keylen;
3996
3997
        ret = SaSi_AesSetKey(&aes->ctx.user_ctx,
3998
                             SASI_AES_USER_KEY,
3999
                             &aes->ctx.key,
4000
                             sizeof(aes->ctx.key));
4001
        if (ret != SASI_OK) {
4002
            return BAD_FUNC_ARG;
4003
        }
4004
4005
        ret = wc_AesSetIV(aes, iv);
4006
4007
        if (iv)
4008
            XMEMCPY(iv_aes, iv, AES_BLOCK_SIZE);
4009
        else
4010
            XMEMSET(iv_aes,  0, AES_BLOCK_SIZE);
4011
4012
4013
        ret = SaSi_AesSetIv(&aes->ctx.user_ctx, iv_aes);
4014
        if (ret != SASI_OK) {
4015
            return ret;
4016
        }
4017
       return ret;
4018
    }
4019
    #if defined(WOLFSSL_AES_DIRECT)
4020
        int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4021
                            const byte* iv, int dir)
4022
        {
4023
            return wc_AesSetKey(aes, userKey, keylen, iv, dir);
4024
        }
4025
    #endif
4026
4027
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) \
4028
    && !defined(WOLFSSL_QNX_CAAM)
4029
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4030
4031
#elif defined(WOLFSSL_AFALG)
4032
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4033
4034
#elif defined(WOLFSSL_DEVCRYPTO_AES)
4035
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
4036
4037
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
4038
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
4039
4040
#elif defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
4041
     !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
4042
    /* implemented in wolfcrypt/src/port/renesas/renesas_fspsm_aes.c */
4043
4044
#else
4045
    #define NEED_SOFTWARE_AES_SETKEY
4046
#endif
4047
4048
/* Either we fell though with no HW support at all,
4049
 * or perhaps there's HW support for *some* keylengths
4050
 * and we need both HW and SW. */
4051
#ifdef NEED_SOFTWARE_AES_SETKEY
4052
4053
#ifdef NEED_AES_TABLES
4054
4055
#ifndef WC_AES_BITSLICED
4056
/* Set the AES key and expand.
4057
 *
4058
 * @param [in]  aes    AES object.
4059
 * @param [in]  key    Block to encrypt.
4060
 * @param [in]  keySz  Number of bytes in key.
4061
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4062
 */
4063
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4064
0
{
4065
#ifdef WC_AES_C_DYNAMIC_FALLBACK
4066
    word32* rk = aes->key_C_fallback;
4067
#else
4068
0
    word32* rk = aes->key;
4069
0
#endif
4070
0
    word32 temp;
4071
0
    unsigned int i = 0;
4072
4073
0
    XMEMCPY(rk, key, keySz);
4074
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4075
0
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_AES))
4076
    /* Always reverse words when using only SW */
4077
0
    {
4078
0
        ByteReverseWords(rk, rk, keySz);
4079
0
    }
4080
#else
4081
    /* Sometimes reverse words when using supported HW */
4082
    #if defined(WOLFSSL_ESPIDF)
4083
        /* Some platforms may need SW fallback (e.g. AES192) */
4084
        #if defined(NEED_AES_HW_FALLBACK)
4085
        {
4086
            ESP_LOGV(TAG, "wc_AesEncrypt fallback check");
4087
            if (wc_esp32AesSupportedKeyLen(aes)) {
4088
                /* don't reverse for HW supported key lengths */
4089
            }
4090
            else {
4091
                ByteReverseWords(rk, rk, keySz);
4092
            }
4093
        }
4094
        #else
4095
            /* If we don't need SW fallback, don't need to reverse words. */
4096
        #endif /* NEED_AES_HW_FALLBACK */
4097
    #endif /* WOLFSSL_ESPIDF */
4098
#endif /* LITTLE_ENDIAN_ORDER, etc */
4099
4100
0
    switch (keySz) {
4101
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \
4102
0
        defined(WOLFSSL_AES_128)
4103
0
    case 16:
4104
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4105
        temp = (word32)-1;
4106
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4107
    #endif
4108
0
        while (1)
4109
0
        {
4110
0
            temp  = rk[3];
4111
0
            rk[4] = rk[0] ^
4112
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4113
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4114
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4115
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4116
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4117
        #else
4118
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4119
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4120
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4121
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4122
        #endif
4123
0
                rcon[i];
4124
0
            rk[5] = rk[1] ^ rk[4];
4125
0
            rk[6] = rk[2] ^ rk[5];
4126
0
            rk[7] = rk[3] ^ rk[6];
4127
0
            if (++i == 10)
4128
0
                break;
4129
0
            rk += 4;
4130
0
        }
4131
0
        break;
4132
0
#endif /* 128 */
4133
4134
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 && \
4135
0
        defined(WOLFSSL_AES_192)
4136
0
    case 24:
4137
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4138
        temp = (word32)-1;
4139
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4140
    #endif
4141
        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
4142
0
        while (1)
4143
0
        {
4144
0
            temp = rk[ 5];
4145
0
            rk[ 6] = rk[ 0] ^
4146
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4147
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4148
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4149
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4150
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4151
        #else
4152
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4153
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4154
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4155
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4156
        #endif
4157
0
                rcon[i];
4158
0
            rk[ 7] = rk[ 1] ^ rk[ 6];
4159
0
            rk[ 8] = rk[ 2] ^ rk[ 7];
4160
0
            rk[ 9] = rk[ 3] ^ rk[ 8];
4161
0
            if (++i == 8)
4162
0
                break;
4163
0
            rk[10] = rk[ 4] ^ rk[ 9];
4164
0
            rk[11] = rk[ 5] ^ rk[10];
4165
0
            rk += 6;
4166
0
        }
4167
0
        break;
4168
0
#endif /* 192 */
4169
4170
0
#if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 && \
4171
0
        defined(WOLFSSL_AES_256)
4172
0
    case 32:
4173
    #ifdef WOLFSSL_CHECK_MEM_ZERO
4174
        temp = (word32)-1;
4175
        wc_MemZero_Add("wc_AesSetKeyLocal temp", &temp, sizeof(temp));
4176
    #endif
4177
0
        while (1)
4178
0
        {
4179
0
            temp = rk[ 7];
4180
0
            rk[ 8] = rk[ 0] ^
4181
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4182
0
                (GetTable(Te[2], GETBYTE(temp, 2)) & 0xff000000) ^
4183
0
                (GetTable(Te[3], GETBYTE(temp, 1)) & 0x00ff0000) ^
4184
0
                (GetTable(Te[0], GETBYTE(temp, 0)) & 0x0000ff00) ^
4185
0
                (GetTable(Te[1], GETBYTE(temp, 3)) & 0x000000ff) ^
4186
        #else
4187
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 24) ^
4188
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) << 16) ^
4189
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)) <<  8) ^
4190
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3))) ^
4191
        #endif
4192
0
                rcon[i];
4193
0
            rk[ 9] = rk[ 1] ^ rk[ 8];
4194
0
            rk[10] = rk[ 2] ^ rk[ 9];
4195
0
            rk[11] = rk[ 3] ^ rk[10];
4196
0
            if (++i == 7)
4197
0
                break;
4198
0
            temp = rk[11];
4199
0
            rk[12] = rk[ 4] ^
4200
0
        #ifndef WOLFSSL_AES_SMALL_TABLES
4201
0
                (GetTable(Te[2], GETBYTE(temp, 3)) & 0xff000000) ^
4202
0
                (GetTable(Te[3], GETBYTE(temp, 2)) & 0x00ff0000) ^
4203
0
                (GetTable(Te[0], GETBYTE(temp, 1)) & 0x0000ff00) ^
4204
0
                (GetTable(Te[1], GETBYTE(temp, 0)) & 0x000000ff);
4205
        #else
4206
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 3)) << 24) ^
4207
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 2)) << 16) ^
4208
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 1)) <<  8) ^
4209
                ((word32)GetTable8(Tsbox, GETBYTE(temp, 0)));
4210
        #endif
4211
0
            rk[13] = rk[ 5] ^ rk[12];
4212
0
            rk[14] = rk[ 6] ^ rk[13];
4213
0
            rk[15] = rk[ 7] ^ rk[14];
4214
4215
0
            rk += 8;
4216
0
        }
4217
0
        break;
4218
0
#endif /* 256 */
4219
0
    } /* switch */
4220
0
    ForceZero(&temp, sizeof(temp));
4221
4222
0
#if defined(HAVE_AES_DECRYPT)
4223
0
    if (dir == AES_DECRYPTION) {
4224
0
        unsigned int j;
4225
4226
#ifdef WC_AES_C_DYNAMIC_FALLBACK
4227
        rk = aes->key_C_fallback;
4228
#else
4229
0
        rk = aes->key;
4230
0
#endif
4231
4232
        /* invert the order of the round keys: */
4233
0
        for (i = 0, j = 4* aes->rounds; i < j; i += 4, j -= 4) {
4234
0
            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
4235
0
            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
4236
0
            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
4237
0
            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
4238
0
        }
4239
0
        ForceZero(&temp, sizeof(temp));
4240
0
    #if !defined(WOLFSSL_AES_SMALL_TABLES)
4241
        /* apply the inverse MixColumn transform to all round keys but the
4242
           first and the last: */
4243
0
        for (i = 1; i < aes->rounds; i++) {
4244
0
            rk += 4;
4245
0
            rk[0] =
4246
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[0], 3)) & 0xff) ^
4247
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[0], 2)) & 0xff) ^
4248
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[0], 1)) & 0xff) ^
4249
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[0], 0)) & 0xff);
4250
0
            rk[1] =
4251
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[1], 3)) & 0xff) ^
4252
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[1], 2)) & 0xff) ^
4253
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[1], 1)) & 0xff) ^
4254
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[1], 0)) & 0xff);
4255
0
            rk[2] =
4256
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[2], 3)) & 0xff) ^
4257
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[2], 2)) & 0xff) ^
4258
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[2], 1)) & 0xff) ^
4259
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[2], 0)) & 0xff);
4260
0
            rk[3] =
4261
0
                GetTable(Td[0], GetTable(Te[1], GETBYTE(rk[3], 3)) & 0xff) ^
4262
0
                GetTable(Td[1], GetTable(Te[1], GETBYTE(rk[3], 2)) & 0xff) ^
4263
0
                GetTable(Td[2], GetTable(Te[1], GETBYTE(rk[3], 1)) & 0xff) ^
4264
0
                GetTable(Td[3], GetTable(Te[1], GETBYTE(rk[3], 0)) & 0xff);
4265
0
        }
4266
0
    #endif
4267
0
    }
4268
#else
4269
    (void)dir;
4270
#endif /* HAVE_AES_DECRYPT */
4271
4272
#ifdef WOLFSSL_CHECK_MEM_ZERO
4273
    wc_MemZero_Check(&temp, sizeof(temp));
4274
#else
4275
0
    (void)temp;
4276
0
#endif
4277
0
}
4278
#else /* WC_AES_BITSLICED */
4279
/* Set the AES key and expand.
4280
 *
4281
 * @param [in]  aes    AES object.
4282
 * @param [in]  key    Block to encrypt.
4283
 * @param [in]  keySz  Number of bytes in key.
4284
 * @param [in]  dir    Direction of crypt: AES_ENCRYPTION or AES_DECRYPTION.
4285
 */
4286
static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
4287
{
4288
    /* No need to invert when decrypting. */
4289
    (void)dir;
4290
4291
    bs_set_key(aes->bs_key, key, keySz, aes->rounds);
4292
}
4293
#endif /* WC_AES_BITSLICED */
4294
4295
#endif /* NEED_AES_TABLES */
4296
4297
    /* Software AES - SetKey */
4298
    static WARN_UNUSED_RESULT int wc_AesSetKeyLocal(
4299
        Aes* aes, const byte* userKey, word32 keylen, const byte* iv, int dir,
4300
        int checkKeyLen)
4301
0
    {
4302
0
        int ret;
4303
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4304
        byte   local[32];
4305
        word32 localSz = 32;
4306
    #endif
4307
4308
0
        if (aes == NULL)
4309
0
            return BAD_FUNC_ARG;
4310
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4311
        ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4312
        if (ret < 0)
4313
            return ret;
4314
#endif
4315
4316
0
        switch (keylen) {
4317
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 &&     \
4318
0
        defined(WOLFSSL_AES_128)
4319
0
        case 16:
4320
0
    #endif
4321
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 192 &&     \
4322
0
        defined(WOLFSSL_AES_192)
4323
0
        case 24:
4324
0
    #endif
4325
0
    #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 256 &&     \
4326
0
        defined(WOLFSSL_AES_256)
4327
0
        case 32:
4328
0
    #endif
4329
0
            break;
4330
0
        default:
4331
0
            return BAD_FUNC_ARG;
4332
0
        }
4333
4334
    #ifdef WOLFSSL_MAXQ10XX_CRYPTO
4335
        if (wc_MAXQ10XX_AesSetKey(aes, userKey, keylen) != 0) {
4336
            return WC_HW_E;
4337
        }
4338
    #endif
4339
4340
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4341
        if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
4342
            keylen == (24 + WC_CAAM_BLOB_SZ) ||
4343
            keylen == (32 + WC_CAAM_BLOB_SZ)) {
4344
            if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
4345
                return BAD_FUNC_ARG;
4346
            }
4347
4348
            /* set local values */
4349
            userKey = local;
4350
            keylen = localSz;
4351
        }
4352
    #endif
4353
4354
    #ifdef WOLFSSL_SECO_CAAM
4355
        /* if set to use hardware than import the key */
4356
        if (aes->devId == WOLFSSL_SECO_DEVID) {
4357
            int keyGroup = 1; /* group one was chosen arbitrarily */
4358
            unsigned int keyIdOut;
4359
            byte importiv[GCM_NONCE_MID_SZ];
4360
            int importivSz = GCM_NONCE_MID_SZ;
4361
            int keyType = 0;
4362
            WC_RNG rng;
4363
4364
            if (wc_InitRng(&rng) != 0) {
4365
                WOLFSSL_MSG("RNG init for IV failed");
4366
                return WC_HW_E;
4367
            }
4368
4369
            if (wc_RNG_GenerateBlock(&rng, importiv, importivSz) != 0) {
4370
                WOLFSSL_MSG("Generate IV failed");
4371
                wc_FreeRng(&rng);
4372
                return WC_HW_E;
4373
            }
4374
            wc_FreeRng(&rng);
4375
4376
            if (iv)
4377
                XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
4378
            else
4379
                XMEMSET(aes->reg, 0, AES_BLOCK_SIZE);
4380
4381
            switch (keylen) {
4382
                case AES_128_KEY_SIZE: keyType = CAAM_KEYTYPE_AES128; break;
4383
                case AES_192_KEY_SIZE: keyType = CAAM_KEYTYPE_AES192; break;
4384
                case AES_256_KEY_SIZE: keyType = CAAM_KEYTYPE_AES256; break;
4385
            }
4386
4387
            keyIdOut = wc_SECO_WrapKey(0, (byte*)userKey, keylen, importiv,
4388
                importivSz, keyType, CAAM_KEY_TRANSIENT, keyGroup);
4389
            if (keyIdOut == 0) {
4390
                return WC_HW_E;
4391
            }
4392
            aes->blackKey = keyIdOut;
4393
            return 0;
4394
        }
4395
    #endif
4396
4397
0
    #if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
4398
0
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
4399
0
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
4400
0
        #ifdef WOLF_CRYPTO_CB
4401
0
        if (aes->devId != INVALID_DEVID)
4402
0
        #endif
4403
0
        {
4404
0
            if (keylen > sizeof(aes->devKey)) {
4405
0
                return BAD_FUNC_ARG;
4406
0
            }
4407
0
            XMEMCPY(aes->devKey, userKey, keylen);
4408
0
        }
4409
0
    #endif
4410
4411
0
        if (checkKeyLen) {
4412
0
            if (keylen != 16 && keylen != 24 && keylen != 32) {
4413
0
                return BAD_FUNC_ARG;
4414
0
            }
4415
        #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE < 256
4416
            /* Check key length only when AES_MAX_KEY_SIZE doesn't allow
4417
             * all key sizes. Otherwise this condition is never true. */
4418
            if (keylen > (AES_MAX_KEY_SIZE / 8)) {
4419
                return BAD_FUNC_ARG;
4420
            }
4421
        #endif
4422
0
        }
4423
4424
0
    #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
4425
0
        defined(WOLFSSL_AES_OFB)
4426
0
        aes->left = 0;
4427
0
    #endif
4428
4429
0
        aes->keylen = (int)keylen;
4430
0
        aes->rounds = (keylen/4) + 6;
4431
0
        ret = wc_AesSetIV(aes, iv);
4432
0
        if (ret != 0)
4433
0
            return ret;
4434
4435
#ifdef WC_AES_C_DYNAMIC_FALLBACK
4436
#ifdef NEED_AES_TABLES
4437
        AesSetKey_C(aes, userKey, keylen, dir);
4438
#endif /* NEED_AES_TABLES */
4439
#endif /* WC_AES_C_DYNAMIC_FALLBACK */
4440
4441
    #ifdef WOLFSSL_AESNI
4442
        aes->use_aesni = 0;
4443
        if (checkedAESNI == 0) {
4444
            haveAESNI  = Check_CPU_support_AES();
4445
            checkedAESNI = 1;
4446
        }
4447
        if (haveAESNI) {
4448
            #ifdef WOLFSSL_LINUXKM
4449
            /* runtime alignment check */
4450
            if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) {
4451
                return BAD_ALIGN_E;
4452
            }
4453
            #endif /* WOLFSSL_LINUXKM */
4454
            ret = SAVE_VECTOR_REGISTERS2();
4455
            if (ret == 0) {
4456
                if (dir == AES_ENCRYPTION)
4457
                    ret = AES_set_encrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4458
#ifdef HAVE_AES_DECRYPT
4459
                else
4460
                    ret = AES_set_decrypt_key_AESNI(userKey, (int)keylen * 8, aes);
4461
#endif
4462
4463
                RESTORE_VECTOR_REGISTERS();
4464
4465
                if (ret == 0)
4466
                    aes->use_aesni = 1;
4467
                else {
4468
#ifdef WC_AES_C_DYNAMIC_FALLBACK
4469
                    ret = 0;
4470
#endif
4471
                }
4472
                return ret;
4473
            } else {
4474
#ifdef WC_AES_C_DYNAMIC_FALLBACK
4475
                return 0;
4476
#else
4477
                return ret;
4478
#endif
4479
            }
4480
        }
4481
    #endif /* WOLFSSL_AESNI */
4482
4483
    #ifdef WOLFSSL_KCAPI_AES
4484
        XMEMCPY(aes->devKey, userKey, keylen);
4485
        if (aes->init != 0) {
4486
            kcapi_cipher_destroy(aes->handle);
4487
            aes->handle = NULL;
4488
            aes->init = 0;
4489
        }
4490
        (void)dir;
4491
    #endif
4492
4493
0
        if (keylen > sizeof(aes->key)) {
4494
0
            return BAD_FUNC_ARG;
4495
0
        }
4496
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
4497
        return wc_psa_aes_set_key(aes, userKey, keylen, (uint8_t*)iv,
4498
                                  ((psa_algorithm_t)0), dir);
4499
#endif
4500
4501
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
4502
        /* wolfSSL HostCrypto in SE05x SDK can request to use SW crypto
4503
         * instead of SE05x crypto by setting useSWCrypt */
4504
        if (aes->useSWCrypt == 0) {
4505
            ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
4506
            if (ret == 0) {
4507
                ret = wc_AesSetIV(aes, iv);
4508
            }
4509
            return ret;
4510
        }
4511
#endif
4512
4513
0
        XMEMCPY(aes->key, userKey, keylen);
4514
4515
0
#ifndef WC_AES_BITSLICED
4516
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
4517
0
        (!defined(WOLFSSL_ESP32_CRYPT) || \
4518
0
          defined(NO_WOLFSSL_ESP32_CRYPT_AES))
4519
4520
        /* software */
4521
0
        ByteReverseWords(aes->key, aes->key, keylen);
4522
4523
    #elif defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
4524
        if (wc_esp32AesSupportedKeyLen(aes)) {
4525
            /* supported lengths don't get reversed */
4526
            ESP_LOGV(TAG, "wc_AesSetKeyLocal (no ByteReverseWords)");
4527
        }
4528
        else {
4529
            word32* rk = aes->key;
4530
4531
            /* For example, the ESP32-S3 does not support HW for len = 24,
4532
             * so fall back to SW */
4533
        #ifdef DEBUG_WOLFSSL
4534
            ESP_LOGW(TAG, "wc_AesSetKeyLocal ByteReverseWords");
4535
        #endif
4536
            XMEMCPY(rk, userKey, keylen);
4537
            /* When not ESP32 HW, we need to reverse endianness */
4538
            ByteReverseWords(rk, rk, keylen);
4539
        }
4540
    #endif
4541
4542
    #ifdef WOLFSSL_IMXRT_DCP
4543
        {
4544
            /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
4545
            word32 temp = 0;
4546
            if (keylen == 16)
4547
                temp = DCPAesSetKey(aes, userKey, keylen, iv, dir);
4548
            if (temp != 0)
4549
                return WC_HW_E;
4550
        }
4551
    #endif
4552
0
#endif /* !WC_AES_BITSLICED */
4553
4554
0
#ifdef NEED_AES_TABLES
4555
0
        AesSetKey_C(aes, userKey, keylen, dir);
4556
0
#endif /* NEED_AES_TABLES */
4557
4558
#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
4559
        XMEMCPY((byte*)aes->key, userKey, keylen);
4560
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) {
4561
            ByteReverseWords(aes->key, aes->key, 32);
4562
        }
4563
#endif
4564
4565
0
        ret = wc_AesSetIV(aes, iv);
4566
4567
    #if defined(WOLFSSL_DEVCRYPTO) && \
4568
        (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
4569
        aes->ctx.cfd = -1;
4570
    #endif
4571
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
4572
        ForceZero(local, sizeof(local));
4573
    #endif
4574
0
        return ret;
4575
0
    } /* wc_AesSetKeyLocal */
4576
4577
    int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
4578
            const byte* iv, int dir)
4579
0
    {
4580
0
        if (aes == NULL) {
4581
0
            return BAD_FUNC_ARG;
4582
0
        }
4583
0
        if (keylen > sizeof(aes->key)) {
4584
0
            return BAD_FUNC_ARG;
4585
0
        }
4586
4587
    /* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
4588
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
4589
        ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
4590
        if (wc_esp32AesSupportedKeyLenValue(keylen)) {
4591
            ESP_LOGV(TAG, "wc_AesSetKey calling wc_AesSetKey_for_ESP32");
4592
            return wc_AesSetKey_for_ESP32(aes, userKey, keylen, iv, dir);
4593
        }
4594
        else {
4595
        #if  defined(WOLFSSL_HW_METRICS)
4596
            /* It is interesting to know how many times we could not complete
4597
             * AES in hardware due to unsupported lengths. */
4598
            wc_esp32AesUnupportedLengthCountAdd();
4599
        #endif
4600
        #ifdef DEBUG_WOLFSSL
4601
            ESP_LOGW(TAG, "wc_AesSetKey HW Fallback, unsupported keylen = %d",
4602
                           keylen);
4603
        #endif
4604
        }
4605
    #endif /* WOLFSSL_ESPIDF && NEED_AES_HW_FALLBACK */
4606
4607
0
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 1);
4608
4609
0
    } /* wc_AesSetKey() */
4610
4611
    #if defined(WOLFSSL_AES_DIRECT) || defined(WOLFSSL_AES_COUNTER)
4612
        /* AES-CTR and AES-DIRECT need to use this for key setup */
4613
        /* This function allows key sizes that are not 128/192/256 bits */
4614
    int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
4615
                           const byte* iv, int dir)
4616
0
    {
4617
0
        if (aes == NULL) {
4618
0
            return BAD_FUNC_ARG;
4619
0
        }
4620
0
        if (keylen > sizeof(aes->key)) {
4621
0
            return BAD_FUNC_ARG;
4622
0
        }
4623
4624
0
        return wc_AesSetKeyLocal(aes, userKey, keylen, iv, dir, 0);
4625
0
    }
4626
    #endif /* WOLFSSL_AES_DIRECT || WOLFSSL_AES_COUNTER */
4627
#endif /* wc_AesSetKey block */
4628
4629
4630
/* wc_AesSetIV is shared between software and hardware */
4631
int wc_AesSetIV(Aes* aes, const byte* iv)
4632
0
{
4633
0
    if (aes == NULL)
4634
0
        return BAD_FUNC_ARG;
4635
4636
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
4637
    {
4638
        int ret = wc_debug_CipherLifecycleCheck(aes->CipherLifecycleTag, 0);
4639
        if (ret < 0)
4640
            return ret;
4641
    }
4642
#endif
4643
4644
0
    if (iv)
4645
0
        XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
4646
0
    else
4647
0
        XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
4648
4649
0
#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \
4650
0
    defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS)
4651
    /* Clear any unused bytes from last cipher op. */
4652
0
    aes->left = 0;
4653
0
#endif
4654
4655
0
    return 0;
4656
0
}
4657
4658
#ifdef WOLFSSL_AESNI
4659
4660
#ifdef WC_AES_C_DYNAMIC_FALLBACK
4661
4662
#define VECTOR_REGISTERS_PUSH { \
4663
        int orig_use_aesni = aes->use_aesni;                         \
4664
        if (aes->use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {     \
4665
            aes->use_aesni = 0;                                      \
4666
        }                                                            \
4667
        WC_DO_NOTHING
4668
4669
#define VECTOR_REGISTERS_POP                                         \
4670
        if (aes->use_aesni)                                          \
4671
            RESTORE_VECTOR_REGISTERS();                              \
4672
        else                                                         \
4673
            aes->use_aesni = orig_use_aesni;                         \
4674
    }                                                                \
4675
    WC_DO_NOTHING
4676
4677
#else
4678
4679
#define VECTOR_REGISTERS_PUSH { \
4680
        if (aes->use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) { \
4681
            return ret;                                                  \
4682
        }                                                                \
4683
        WC_DO_NOTHING
4684
4685
#define VECTOR_REGISTERS_POP \
4686
        if (aes->use_aesni) {                                            \
4687
            RESTORE_VECTOR_REGISTERS();                                  \
4688
        }                                                                \
4689
    }                                                                    \
4690
    WC_DO_NOTHING
4691
4692
#endif
4693
4694
#else /* !WOLFSSL_AESNI */
4695
4696
0
#define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
4697
0
#define VECTOR_REGISTERS_POP } WC_DO_NOTHING
4698
4699
#endif /* !WOLFSSL_AESNI */
4700
4701
4702
/* AES-DIRECT */
4703
#if defined(WOLFSSL_AES_DIRECT)
4704
    #if defined(HAVE_COLDFIRE_SEC)
4705
        #error "Coldfire SEC doesn't yet support AES direct"
4706
4707
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
4708
        !defined(WOLFSSL_QNX_CAAM)
4709
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
4710
4711
    #elif defined(WOLFSSL_AFALG)
4712
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
4713
4714
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
4715
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
4716
4717
    #else
4718
4719
        /* Allow direct access to one block encrypt */
4720
        int wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
4721
0
        {
4722
0
            int ret;
4723
4724
0
            if (aes == NULL)
4725
0
                return BAD_FUNC_ARG;
4726
0
            VECTOR_REGISTERS_PUSH;
4727
0
            ret = wc_AesEncrypt(aes, in, out);
4728
0
            VECTOR_REGISTERS_POP;
4729
0
            return ret;
4730
0
        }
4731
4732
        /* vector reg save/restore is explicit in all below calls to
4733
         * wc_Aes{En,De}cryptDirect(), so bypass the public version with a
4734
         * macro.
4735
         */
4736
0
        #define wc_AesEncryptDirect(aes, out, in) wc_AesEncrypt(aes, in, out)
4737
4738
        #ifdef HAVE_AES_DECRYPT
4739
        /* Allow direct access to one block decrypt */
4740
        int wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
4741
0
        {
4742
0
            int ret;
4743
4744
0
            if (aes == NULL)
4745
0
                return BAD_FUNC_ARG;
4746
0
            VECTOR_REGISTERS_PUSH;
4747
0
            ret = wc_AesDecrypt(aes, in, out);
4748
0
            VECTOR_REGISTERS_POP;
4749
0
            return ret;
4750
0
        }
4751
4752
0
        #define wc_AesDecryptDirect(aes, out, in) wc_AesDecrypt(aes, in, out)
4753
4754
        #endif /* HAVE_AES_DECRYPT */
4755
    #endif /* AES direct block */
4756
#endif /* WOLFSSL_AES_DIRECT */
4757
4758
4759
/* AES-CBC */
4760
#ifdef HAVE_AES_CBC
4761
#if defined(STM32_CRYPTO)
4762
4763
#ifdef WOLFSSL_STM32_CUBEMX
4764
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
4765
    {
4766
        int ret = 0;
4767
        CRYP_HandleTypeDef hcryp;
4768
        word32 blocks = (sz / AES_BLOCK_SIZE);
4769
4770
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
4771
        if (sz % AES_BLOCK_SIZE) {
4772
            return BAD_LENGTH_E;
4773
        }
4774
#endif
4775
        if (blocks == 0)
4776
            return 0;
4777
4778
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
4779
        if (ret != 0)
4780
            return ret;
4781
4782
        ret = wolfSSL_CryptHwMutexLock();
4783
        if (ret != 0) {
4784
            return ret;
4785
        }
4786
4787
    #if defined(STM32_HAL_V2)
4788
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
4789
        ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);
4790
    #elif defined(STM32_CRYPTO_AES_ONLY)
4791
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
4792
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
4793
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
4794
    #endif
4795
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
4796
        HAL_CRYP_Init(&hcryp);
4797
4798
    #if defined(STM32_HAL_V2)
4799
        ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, blocks * AES_BLOCK_SIZE,
4800
            (uint32_t*)out, STM32_HAL_TIMEOUT);
4801
    #elif defined(STM32_CRYPTO_AES_ONLY)
4802
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * AES_BLOCK_SIZE,
4803
            out, STM32_HAL_TIMEOUT);
4804
    #else
4805
        ret = HAL_CRYP_AESCBC_Encrypt(&hcryp, (uint8_t*)in,
4806
                                      blocks * AES_BLOCK_SIZE,
4807
                                      out, STM32_HAL_TIMEOUT);
4808
    #endif
4809
        if (ret != HAL_OK) {
4810
            ret = WC_TIMEOUT_E;
4811
        }
4812
4813
        /* store iv for next call */
4814
        XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
4815
4816
        HAL_CRYP_DeInit(&hcryp);
4817
4818
        wolfSSL_CryptHwMutexUnLock();
4819
        wc_Stm32_Aes_Cleanup();
4820
4821
        return ret;
4822
    }
4823
    #ifdef HAVE_AES_DECRYPT
4824
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
4825
    {
4826
        int ret = 0;
4827
        CRYP_HandleTypeDef hcryp;
4828
        word32 blocks = (sz / AES_BLOCK_SIZE);
4829
4830
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
4831
        if (sz % AES_BLOCK_SIZE) {
4832
            return BAD_LENGTH_E;
4833
        }
4834
#endif
4835
        if (blocks == 0)
4836
            return 0;
4837
4838
        ret = wc_Stm32_Aes_Init(aes, &hcryp);
4839
        if (ret != 0)
4840
            return ret;
4841
4842
        ret = wolfSSL_CryptHwMutexLock();
4843
        if (ret != 0) {
4844
            return ret;
4845
        }
4846
4847
        /* if input and output same will overwrite input iv */
4848
        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
4849
4850
    #if defined(STM32_HAL_V2)
4851
        hcryp.Init.Algorithm  = CRYP_AES_CBC;
4852
        ByteReverseWords(aes->reg, aes->reg, AES_BLOCK_SIZE);
4853
    #elif defined(STM32_CRYPTO_AES_ONLY)
4854
        hcryp.Init.OperatingMode = CRYP_ALGOMODE_KEYDERIVATION_DECRYPT;
4855
        hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CBC;
4856
        hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
4857
    #endif
4858
4859
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
4860
        HAL_CRYP_Init(&hcryp);
4861
4862
    #if defined(STM32_HAL_V2)
4863
        ret = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, blocks * AES_BLOCK_SIZE,
4864
            (uint32_t*)out, STM32_HAL_TIMEOUT);
4865
    #elif defined(STM32_CRYPTO_AES_ONLY)
4866
        ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)in, blocks * AES_BLOCK_SIZE,
4867
            out, STM32_HAL_TIMEOUT);
4868
    #else
4869
        ret = HAL_CRYP_AESCBC_Decrypt(&hcryp, (uint8_t*)in,
4870
                                      blocks * AES_BLOCK_SIZE,
4871
            out, STM32_HAL_TIMEOUT);
4872
    #endif
4873
        if (ret != HAL_OK) {
4874
            ret = WC_TIMEOUT_E;
4875
        }
4876
4877
        /* store iv for next call */
4878
        XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
4879
4880
        HAL_CRYP_DeInit(&hcryp);
4881
        wolfSSL_CryptHwMutexUnLock();
4882
        wc_Stm32_Aes_Cleanup();
4883
4884
        return ret;
4885
    }
4886
    #endif /* HAVE_AES_DECRYPT */
4887
4888
#else /* Standard Peripheral Library */
4889
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
4890
    {
4891
        int ret;
4892
        word32 *iv;
4893
        CRYP_InitTypeDef cryptInit;
4894
        CRYP_KeyInitTypeDef keyInit;
4895
        CRYP_IVInitTypeDef ivInit;
4896
        word32 blocks = (sz / AES_BLOCK_SIZE);
4897
4898
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
4899
        if (sz % AES_BLOCK_SIZE) {
4900
            return BAD_LENGTH_E;
4901
        }
4902
#endif
4903
        if (blocks == 0)
4904
            return 0;
4905
4906
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
4907
        if (ret != 0)
4908
            return ret;
4909
4910
        ret = wolfSSL_CryptHwMutexLock();
4911
        if (ret != 0) {
4912
            return ret;
4913
        }
4914
4915
        /* reset registers to their default values */
4916
        CRYP_DeInit();
4917
4918
        /* set key */
4919
        CRYP_KeyInit(&keyInit);
4920
4921
        /* set iv */
4922
        iv = aes->reg;
4923
        CRYP_IVStructInit(&ivInit);
4924
        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
4925
        ivInit.CRYP_IV0Left  = iv[0];
4926
        ivInit.CRYP_IV0Right = iv[1];
4927
        ivInit.CRYP_IV1Left  = iv[2];
4928
        ivInit.CRYP_IV1Right = iv[3];
4929
        CRYP_IVInit(&ivInit);
4930
4931
        /* set direction and mode */
4932
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
4933
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
4934
        CRYP_Init(&cryptInit);
4935
4936
        /* enable crypto processor */
4937
        CRYP_Cmd(ENABLE);
4938
4939
        while (blocks--) {
4940
            /* flush IN/OUT FIFOs */
4941
            CRYP_FIFOFlush();
4942
4943
            CRYP_DataIn(*(uint32_t*)&in[0]);
4944
            CRYP_DataIn(*(uint32_t*)&in[4]);
4945
            CRYP_DataIn(*(uint32_t*)&in[8]);
4946
            CRYP_DataIn(*(uint32_t*)&in[12]);
4947
4948
            /* wait until the complete message has been processed */
4949
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
4950
4951
            *(uint32_t*)&out[0]  = CRYP_DataOut();
4952
            *(uint32_t*)&out[4]  = CRYP_DataOut();
4953
            *(uint32_t*)&out[8]  = CRYP_DataOut();
4954
            *(uint32_t*)&out[12] = CRYP_DataOut();
4955
4956
            /* store iv for next call */
4957
            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
4958
4959
            sz  -= AES_BLOCK_SIZE;
4960
            in  += AES_BLOCK_SIZE;
4961
            out += AES_BLOCK_SIZE;
4962
        }
4963
4964
        /* disable crypto processor */
4965
        CRYP_Cmd(DISABLE);
4966
        wolfSSL_CryptHwMutexUnLock();
4967
        wc_Stm32_Aes_Cleanup();
4968
4969
        return ret;
4970
    }
4971
4972
    #ifdef HAVE_AES_DECRYPT
4973
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
4974
    {
4975
        int ret;
4976
        word32 *iv;
4977
        CRYP_InitTypeDef cryptInit;
4978
        CRYP_KeyInitTypeDef keyInit;
4979
        CRYP_IVInitTypeDef ivInit;
4980
        word32 blocks = (sz / AES_BLOCK_SIZE);
4981
4982
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
4983
        if (sz % AES_BLOCK_SIZE) {
4984
            return BAD_LENGTH_E;
4985
        }
4986
#endif
4987
        if (blocks == 0)
4988
            return 0;
4989
4990
        ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
4991
        if (ret != 0)
4992
            return ret;
4993
4994
        ret = wolfSSL_CryptHwMutexLock();
4995
        if (ret != 0) {
4996
            return ret;
4997
        }
4998
4999
        /* if input and output same will overwrite input iv */
5000
        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5001
5002
        /* reset registers to their default values */
5003
        CRYP_DeInit();
5004
5005
        /* set direction and key */
5006
        CRYP_KeyInit(&keyInit);
5007
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5008
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_Key;
5009
        CRYP_Init(&cryptInit);
5010
5011
        /* enable crypto processor */
5012
        CRYP_Cmd(ENABLE);
5013
5014
        /* wait until key has been prepared */
5015
        while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5016
5017
        /* set direction and mode */
5018
        cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
5019
        cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CBC;
5020
        CRYP_Init(&cryptInit);
5021
5022
        /* set iv */
5023
        iv = aes->reg;
5024
        CRYP_IVStructInit(&ivInit);
5025
        ByteReverseWords(iv, iv, AES_BLOCK_SIZE);
5026
        ivInit.CRYP_IV0Left  = iv[0];
5027
        ivInit.CRYP_IV0Right = iv[1];
5028
        ivInit.CRYP_IV1Left  = iv[2];
5029
        ivInit.CRYP_IV1Right = iv[3];
5030
        CRYP_IVInit(&ivInit);
5031
5032
        /* enable crypto processor */
5033
        CRYP_Cmd(ENABLE);
5034
5035
        while (blocks--) {
5036
            /* flush IN/OUT FIFOs */
5037
            CRYP_FIFOFlush();
5038
5039
            CRYP_DataIn(*(uint32_t*)&in[0]);
5040
            CRYP_DataIn(*(uint32_t*)&in[4]);
5041
            CRYP_DataIn(*(uint32_t*)&in[8]);
5042
            CRYP_DataIn(*(uint32_t*)&in[12]);
5043
5044
            /* wait until the complete message has been processed */
5045
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5046
5047
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5048
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5049
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5050
            *(uint32_t*)&out[12] = CRYP_DataOut();
5051
5052
            /* store iv for next call */
5053
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
5054
5055
            in  += AES_BLOCK_SIZE;
5056
            out += AES_BLOCK_SIZE;
5057
        }
5058
5059
        /* disable crypto processor */
5060
        CRYP_Cmd(DISABLE);
5061
        wolfSSL_CryptHwMutexUnLock();
5062
        wc_Stm32_Aes_Cleanup();
5063
5064
        return ret;
5065
    }
5066
    #endif /* HAVE_AES_DECRYPT */
5067
#endif /* WOLFSSL_STM32_CUBEMX */
5068
5069
#elif defined(HAVE_COLDFIRE_SEC)
5070
    static WARN_UNUSED_RESULT int wc_AesCbcCrypt(
5071
        Aes* aes, byte* po, const byte* pi, word32 sz, word32 descHeader)
5072
    {
5073
        #ifdef DEBUG_WOLFSSL
5074
            int i; int stat1, stat2; int ret;
5075
        #endif
5076
5077
        int size;
5078
        volatile int v;
5079
5080
        if ((pi == NULL) || (po == NULL))
5081
            return BAD_FUNC_ARG;    /*wrong pointer*/
5082
5083
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5084
        if (sz % AES_BLOCK_SIZE) {
5085
            return BAD_LENGTH_E;
5086
        }
5087
#endif
5088
5089
        wc_LockMutex(&Mutex_AesSEC);
5090
5091
        /* Set descriptor for SEC */
5092
        secDesc->length1 = 0x0;
5093
        secDesc->pointer1 = NULL;
5094
5095
        secDesc->length2 = AES_BLOCK_SIZE;
5096
        secDesc->pointer2 = (byte *)secReg; /* Initial Vector */
5097
5098
        switch(aes->rounds) {
5099
            case 10: secDesc->length3 = 16; break;
5100
            case 12: secDesc->length3 = 24; break;
5101
            case 14: secDesc->length3 = 32; break;
5102
        }
5103
        XMEMCPY(secKey, aes->key, secDesc->length3);
5104
5105
        secDesc->pointer3 = (byte *)secKey;
5106
        secDesc->pointer4 = AESBuffIn;
5107
        secDesc->pointer5 = AESBuffOut;
5108
        secDesc->length6 = 0x0;
5109
        secDesc->pointer6 = NULL;
5110
        secDesc->length7 = 0x0;
5111
        secDesc->pointer7 = NULL;
5112
        secDesc->nextDescriptorPtr = NULL;
5113
5114
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5115
        size = AES_BUFFER_SIZE;
5116
#endif
5117
        while (sz) {
5118
            secDesc->header = descHeader;
5119
            XMEMCPY(secReg, aes->reg, AES_BLOCK_SIZE);
5120
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5121
            sz -= AES_BUFFER_SIZE;
5122
#else
5123
            if (sz < AES_BUFFER_SIZE) {
5124
                size = sz;
5125
                sz = 0;
5126
            } else {
5127
                size = AES_BUFFER_SIZE;
5128
                sz -= AES_BUFFER_SIZE;
5129
            }
5130
#endif
5131
5132
            secDesc->length4 = size;
5133
            secDesc->length5 = size;
5134
5135
            XMEMCPY(AESBuffIn, pi, size);
5136
            if(descHeader == SEC_DESC_AES_CBC_DECRYPT) {
5137
                XMEMCPY((void*)aes->tmp, (void*)&(pi[size-AES_BLOCK_SIZE]),
5138
                        AES_BLOCK_SIZE);
5139
            }
5140
5141
            /* Point SEC to the location of the descriptor */
5142
            MCF_SEC_FR0 = (uint32)secDesc;
5143
            /* Initialize SEC and wait for encryption to complete */
5144
            MCF_SEC_CCCR0 = 0x0000001a;
5145
            /* poll SISR to determine when channel is complete */
5146
            v=0;
5147
5148
            while ((secDesc->header>> 24) != 0xff) v++;
5149
5150
            #ifdef DEBUG_WOLFSSL
5151
                ret = MCF_SEC_SISRH;
5152
                stat1 = MCF_SEC_AESSR;
5153
                stat2 = MCF_SEC_AESISR;
5154
                if (ret & 0xe0000000) {
5155
                    db_printf("Aes_Cbc(i=%d):ISRH=%08x, AESSR=%08x, "
5156
                              "AESISR=%08x\n", i, ret, stat1, stat2);
5157
                }
5158
            #endif
5159
5160
            XMEMCPY(po, AESBuffOut, size);
5161
5162
            if (descHeader == SEC_DESC_AES_CBC_ENCRYPT) {
5163
                XMEMCPY((void*)aes->reg, (void*)&(po[size-AES_BLOCK_SIZE]),
5164
                        AES_BLOCK_SIZE);
5165
            } else {
5166
                XMEMCPY((void*)aes->reg, (void*)aes->tmp, AES_BLOCK_SIZE);
5167
            }
5168
5169
            pi += size;
5170
            po += size;
5171
        }
5172
5173
        wc_UnLockMutex(&Mutex_AesSEC);
5174
        return 0;
5175
    }
5176
5177
    int wc_AesCbcEncrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5178
    {
5179
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_ENCRYPT));
5180
    }
5181
5182
    #ifdef HAVE_AES_DECRYPT
5183
    int wc_AesCbcDecrypt(Aes* aes, byte* po, const byte* pi, word32 sz)
5184
    {
5185
        return (wc_AesCbcCrypt(aes, po, pi, sz, SEC_DESC_AES_CBC_DECRYPT));
5186
    }
5187
    #endif /* HAVE_AES_DECRYPT */
5188
5189
#elif defined(FREESCALE_LTC)
5190
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5191
    {
5192
        word32 keySize;
5193
        status_t status;
5194
        byte *iv, *enc_key;
5195
        word32 blocks = (sz / AES_BLOCK_SIZE);
5196
5197
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5198
        if (sz % AES_BLOCK_SIZE) {
5199
            return BAD_LENGTH_E;
5200
        }
5201
#endif
5202
        if (blocks == 0)
5203
            return 0;
5204
5205
        iv      = (byte*)aes->reg;
5206
        enc_key = (byte*)aes->key;
5207
5208
        status = wc_AesGetKeySize(aes, &keySize);
5209
        if (status != 0) {
5210
            return status;
5211
        }
5212
5213
        status = wolfSSL_CryptHwMutexLock();
5214
        if (status != 0)
5215
            return status;
5216
        status = LTC_AES_EncryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
5217
            iv, enc_key, keySize);
5218
        wolfSSL_CryptHwMutexUnLock();
5219
5220
        /* store iv for next call */
5221
        if (status == kStatus_Success) {
5222
            XMEMCPY(iv, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5223
        }
5224
5225
        return (status == kStatus_Success) ? 0 : -1;
5226
    }
5227
5228
    #ifdef HAVE_AES_DECRYPT
5229
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5230
    {
5231
        word32 keySize;
5232
        status_t status;
5233
        byte* iv, *dec_key;
5234
        byte temp_block[AES_BLOCK_SIZE];
5235
        word32 blocks = (sz / AES_BLOCK_SIZE);
5236
5237
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5238
        if (sz % AES_BLOCK_SIZE) {
5239
            return BAD_LENGTH_E;
5240
        }
5241
#endif
5242
        if (blocks == 0)
5243
            return 0;
5244
5245
        iv      = (byte*)aes->reg;
5246
        dec_key = (byte*)aes->key;
5247
5248
        status = wc_AesGetKeySize(aes, &keySize);
5249
        if (status != 0) {
5250
            return status;
5251
        }
5252
5253
        /* get IV for next call */
5254
        XMEMCPY(temp_block, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5255
5256
        status = wolfSSL_CryptHwMutexLock();
5257
        if (status != 0)
5258
            return status;
5259
        status = LTC_AES_DecryptCbc(LTC_BASE, in, out, blocks * AES_BLOCK_SIZE,
5260
            iv, dec_key, keySize, kLTC_EncryptKey);
5261
        wolfSSL_CryptHwMutexUnLock();
5262
5263
        /* store IV for next call */
5264
        if (status == kStatus_Success) {
5265
            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
5266
        }
5267
5268
        return (status == kStatus_Success) ? 0 : -1;
5269
    }
5270
    #endif /* HAVE_AES_DECRYPT */
5271
5272
#elif defined(FREESCALE_MMCAU)
5273
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5274
    {
5275
        int offset = 0;
5276
        byte *iv;
5277
        byte temp_block[AES_BLOCK_SIZE];
5278
        word32 blocks = (sz / AES_BLOCK_SIZE);
5279
        int ret;
5280
5281
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5282
        if (sz % AES_BLOCK_SIZE) {
5283
            return BAD_LENGTH_E;
5284
        }
5285
#endif
5286
        if (blocks == 0)
5287
            return 0;
5288
5289
        iv = (byte*)aes->reg;
5290
5291
        while (blocks--) {
5292
            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
5293
5294
            /* XOR block with IV for CBC */
5295
            xorbuf(temp_block, iv, AES_BLOCK_SIZE);
5296
5297
            ret = wc_AesEncrypt(aes, temp_block, out + offset);
5298
            if (ret != 0)
5299
                return ret;
5300
5301
            offset += AES_BLOCK_SIZE;
5302
5303
            /* store IV for next block */
5304
            XMEMCPY(iv, out + offset - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5305
        }
5306
5307
        return 0;
5308
    }
5309
    #ifdef HAVE_AES_DECRYPT
5310
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5311
    {
5312
        int ret;
5313
        int offset = 0;
5314
        byte* iv;
5315
        byte temp_block[AES_BLOCK_SIZE];
5316
        word32 blocks = (sz / AES_BLOCK_SIZE);
5317
5318
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5319
        if (sz % AES_BLOCK_SIZE) {
5320
            return BAD_LENGTH_E;
5321
        }
5322
#endif
5323
        if (blocks == 0)
5324
            return 0;
5325
5326
        iv = (byte*)aes->reg;
5327
5328
        while (blocks--) {
5329
            XMEMCPY(temp_block, in + offset, AES_BLOCK_SIZE);
5330
5331
            ret = wc_AesDecrypt(aes, in + offset, out + offset);
5332
            if (ret != 0)
5333
                return ret;
5334
5335
            /* XOR block with IV for CBC */
5336
            xorbuf(out + offset, iv, AES_BLOCK_SIZE);
5337
5338
            /* store IV for next block */
5339
            XMEMCPY(iv, temp_block, AES_BLOCK_SIZE);
5340
5341
            offset += AES_BLOCK_SIZE;
5342
        }
5343
5344
        return 0;
5345
    }
5346
    #endif /* HAVE_AES_DECRYPT */
5347
5348
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
5349
5350
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5351
    {
5352
        int ret;
5353
5354
        if (sz == 0)
5355
            return 0;
5356
5357
        /* hardware fails on input that is not a multiple of AES block size */
5358
        if (sz % AES_BLOCK_SIZE != 0) {
5359
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5360
            return BAD_LENGTH_E;
5361
#else
5362
            return BAD_FUNC_ARG;
5363
#endif
5364
        }
5365
5366
        ret = wc_Pic32AesCrypt(
5367
            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
5368
            out, in, sz, PIC32_ENCRYPTION,
5369
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
5370
5371
        /* store iv for next call */
5372
        if (ret == 0) {
5373
            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5374
        }
5375
5376
        return ret;
5377
    }
5378
    #ifdef HAVE_AES_DECRYPT
5379
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5380
    {
5381
        int ret;
5382
        byte scratch[AES_BLOCK_SIZE];
5383
5384
        if (sz == 0)
5385
            return 0;
5386
5387
        /* hardware fails on input that is not a multiple of AES block size */
5388
        if (sz % AES_BLOCK_SIZE != 0) {
5389
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5390
            return BAD_LENGTH_E;
5391
#else
5392
            return BAD_FUNC_ARG;
5393
#endif
5394
        }
5395
        XMEMCPY(scratch, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5396
5397
        ret = wc_Pic32AesCrypt(
5398
            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
5399
            out, in, sz, PIC32_DECRYPTION,
5400
            PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCBC);
5401
5402
        /* store iv for next call */
5403
        if (ret == 0) {
5404
            XMEMCPY((byte*)aes->reg, scratch, AES_BLOCK_SIZE);
5405
        }
5406
5407
        return ret;
5408
    }
5409
    #endif /* HAVE_AES_DECRYPT */
5410
#elif defined(WOLFSSL_ESP32_CRYPT) && \
5411
    !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
5412
5413
    /* We'll use SW for fall back:
5414
     *   unsupported key lengths
5415
     *   hardware busy */
5416
    #define NEED_SW_AESCBC
5417
    #define NEED_AESCBC_HW_FALLBACK
5418
5419
#elif defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
5420
    int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5421
    {
5422
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
5423
    }
5424
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5425
    {
5426
        return SaSi_AesBlock(&aes->ctx.user_ctx, (uint8_t*)in, sz, out);
5427
    }
5428
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
5429
        !defined(WOLFSSL_QNX_CAAM)
5430
      /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5431
5432
#elif defined(WOLFSSL_AFALG)
5433
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5434
5435
#elif defined(WOLFSSL_KCAPI_AES) && !defined(WOLFSSL_NO_KCAPI_AES_CBC)
5436
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
5437
5438
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
5439
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
5440
5441
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
5442
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
5443
5444
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
5445
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
5446
5447
#else
5448
    /* Reminder: Some HW implementations may also define this as needed.
5449
     * (e.g. for unsupported key length fallback)  */
5450
    #define NEED_SW_AESCBC
5451
#endif
5452
5453
#ifdef NEED_SW_AESCBC
5454
    /* Software AES - CBC Encrypt */
5455
5456
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5457
0
    {
5458
0
        word32 blocks;
5459
0
        int ret;
5460
5461
0
        if (aes == NULL || out == NULL || in == NULL) {
5462
0
            return BAD_FUNC_ARG;
5463
0
        }
5464
5465
0
        if (sz == 0) {
5466
0
            return 0;
5467
0
        }
5468
5469
0
        blocks = sz / AES_BLOCK_SIZE;
5470
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5471
        if (sz % AES_BLOCK_SIZE) {
5472
            WOLFSSL_ERROR_VERBOSE(BAD_LENGTH_E);
5473
            return BAD_LENGTH_E;
5474
        }
5475
#endif
5476
5477
    #ifdef WOLFSSL_IMXRT_DCP
5478
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5479
        if (aes->keylen == 16)
5480
            return DCPAesCbcEncrypt(aes, out, in, sz);
5481
    #endif
5482
5483
0
    #ifdef WOLF_CRYPTO_CB
5484
0
        #ifndef WOLF_CRYPTO_CB_FIND
5485
0
        if (aes->devId != INVALID_DEVID)
5486
0
        #endif
5487
0
        {
5488
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcEncrypt(aes, out, in, sz);
5489
0
            if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
5490
0
                return crypto_cb_ret;
5491
            /* fall-through when unavailable */
5492
0
        }
5493
0
    #endif
5494
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
5495
        /* if async and byte count above threshold */
5496
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
5497
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
5498
        #if defined(HAVE_CAVIUM)
5499
            return NitroxAesCbcEncrypt(aes, out, in, sz);
5500
        #elif defined(HAVE_INTEL_QA)
5501
            return IntelQaSymAesCbcEncrypt(&aes->asyncDev, out, in, sz,
5502
                (const byte*)aes->devKey, aes->keylen,
5503
                (byte*)aes->reg, AES_BLOCK_SIZE);
5504
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5505
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_ENCRYPT)) {
5506
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
5507
                sw->aes.aes = aes;
5508
                sw->aes.out = out;
5509
                sw->aes.in = in;
5510
                sw->aes.sz = sz;
5511
                return WC_PENDING_E;
5512
            }
5513
        #endif
5514
        }
5515
    #endif /* WOLFSSL_ASYNC_CRYPT */
5516
5517
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5518
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
5519
        if (aes->useSWCrypt == 0) {
5520
            return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
5521
                                   kAlgorithm_SSS_AES_CBC);
5522
        }
5523
        else
5524
    #elif defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
5525
        if (wc_esp32AesSupportedKeyLen(aes)) {
5526
            ESP_LOGV(TAG, "wc_AesCbcEncrypt calling wc_esp32AesCbcEncrypt");
5527
            return wc_esp32AesCbcEncrypt(aes, out, in, sz);
5528
        }
5529
        else {
5530
            /* For example, the ESP32-S3 does not support HW for len = 24,
5531
             * so fall back to SW */
5532
        #ifdef DEBUG_WOLFSSL
5533
            ESP_LOGW(TAG, "wc_AesCbcEncrypt HW Falling back, "
5534
                          "unsupported keylen = %d", aes->keylen);
5535
        #endif
5536
        }
5537
    #elif defined(WOLFSSL_AESNI)
5538
        VECTOR_REGISTERS_PUSH;
5539
        if (aes->use_aesni) {
5540
            #ifdef DEBUG_AESNI
5541
                printf("about to aes cbc encrypt\n");
5542
                printf("in  = %p\n", in);
5543
                printf("out = %p\n", out);
5544
                printf("aes->key = %p\n", aes->key);
5545
                printf("aes->reg = %p\n", aes->reg);
5546
                printf("aes->rounds = %d\n", aes->rounds);
5547
                printf("sz = %d\n", sz);
5548
            #endif
5549
5550
            /* check alignment, decrypt doesn't need alignment */
5551
            if ((wc_ptr_t)in % AESNI_ALIGN) {
5552
            #ifndef NO_WOLFSSL_ALLOC_ALIGN
5553
                byte* tmp = (byte*)XMALLOC(sz + AES_BLOCK_SIZE + AESNI_ALIGN,
5554
                                            aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5555
                byte* tmp_align;
5556
                if (tmp == NULL)
5557
                    ret = MEMORY_E;
5558
                else {
5559
                    tmp_align = tmp + (AESNI_ALIGN - ((wc_ptr_t)tmp % AESNI_ALIGN));
5560
                    XMEMCPY(tmp_align, in, sz);
5561
                    AES_CBC_encrypt_AESNI(tmp_align, tmp_align, (byte*)aes->reg, sz,
5562
                                          (byte*)aes->key, (int)aes->rounds);
5563
                    /* store iv for next call */
5564
                    XMEMCPY(aes->reg, tmp_align + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5565
5566
                    XMEMCPY(out, tmp_align, sz);
5567
                    XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
5568
                    ret = 0;
5569
                }
5570
            #else
5571
                WOLFSSL_MSG("AES-CBC encrypt with bad alignment");
5572
                WOLFSSL_ERROR_VERBOSE(BAD_ALIGN_E);
5573
                ret = BAD_ALIGN_E;
5574
            #endif
5575
            } else {
5576
                AES_CBC_encrypt_AESNI(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
5577
                                      (int)aes->rounds);
5578
                /* store iv for next call */
5579
                XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5580
5581
                ret = 0;
5582
            }
5583
        }
5584
        else
5585
    #endif
5586
0
        {
5587
0
            ret = 0;
5588
0
            while (blocks--) {
5589
0
                xorbuf((byte*)aes->reg, in, AES_BLOCK_SIZE);
5590
0
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
5591
0
                if (ret != 0)
5592
0
                    break;
5593
0
                XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
5594
5595
0
                out += AES_BLOCK_SIZE;
5596
0
                in  += AES_BLOCK_SIZE;
5597
0
            }
5598
0
        }
5599
5600
    #ifdef WOLFSSL_AESNI
5601
        VECTOR_REGISTERS_POP;
5602
    #endif
5603
5604
0
        return ret;
5605
0
    } /* wc_AesCbcEncrypt */
5606
5607
#ifdef HAVE_AES_DECRYPT
5608
    /* Software AES - CBC Decrypt */
5609
    int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5610
0
    {
5611
0
        word32 blocks;
5612
0
        int ret;
5613
5614
0
        if (aes == NULL || out == NULL || in == NULL) {
5615
0
            return BAD_FUNC_ARG;
5616
0
        }
5617
5618
0
        if (sz == 0) {
5619
0
            return 0;
5620
0
        }
5621
5622
    #if defined(WOLFSSL_ESPIDF) && defined(NEED_AESCBC_HW_FALLBACK)
5623
        if (wc_esp32AesSupportedKeyLen(aes)) {
5624
            ESP_LOGV(TAG, "wc_AesCbcDecrypt calling wc_esp32AesCbcDecrypt");
5625
            return wc_esp32AesCbcDecrypt(aes, out, in, sz);
5626
        }
5627
        else {
5628
            /* For example, the ESP32-S3 does not support HW for len = 24,
5629
             * so fall back to SW */
5630
        #ifdef DEBUG_WOLFSSL
5631
            ESP_LOGW(TAG, "wc_AesCbcDecrypt HW Falling back, "
5632
                          "unsupported keylen = %d", aes->keylen);
5633
        #endif
5634
        }
5635
    #endif
5636
5637
0
        blocks = sz / AES_BLOCK_SIZE;
5638
0
        if (sz % AES_BLOCK_SIZE) {
5639
#ifdef WOLFSSL_AES_CBC_LENGTH_CHECKS
5640
            return BAD_LENGTH_E;
5641
#else
5642
0
            return BAD_FUNC_ARG;
5643
0
#endif
5644
0
        }
5645
5646
    #ifdef WOLFSSL_IMXRT_DCP
5647
        /* Implemented in wolfcrypt/src/port/nxp/dcp_port.c */
5648
        if (aes->keylen == 16)
5649
            return DCPAesCbcDecrypt(aes, out, in, sz);
5650
    #endif
5651
5652
0
    #ifdef WOLF_CRYPTO_CB
5653
0
        #ifndef WOLF_CRYPTO_CB_FIND
5654
0
        if (aes->devId != INVALID_DEVID)
5655
0
        #endif
5656
0
        {
5657
0
            int crypto_cb_ret = wc_CryptoCb_AesCbcDecrypt(aes, out, in, sz);
5658
0
            if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
5659
0
                return crypto_cb_ret;
5660
            /* fall-through when unavailable */
5661
0
        }
5662
0
    #endif
5663
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
5664
        /* if async and byte count above threshold */
5665
        if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
5666
                                                sz >= WC_ASYNC_THRESH_AES_CBC) {
5667
        #if defined(HAVE_CAVIUM)
5668
            return NitroxAesCbcDecrypt(aes, out, in, sz);
5669
        #elif defined(HAVE_INTEL_QA)
5670
            return IntelQaSymAesCbcDecrypt(&aes->asyncDev, out, in, sz,
5671
                (const byte*)aes->devKey, aes->keylen,
5672
                (byte*)aes->reg, AES_BLOCK_SIZE);
5673
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
5674
            if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_CBC_DECRYPT)) {
5675
                WC_ASYNC_SW* sw = &aes->asyncDev.sw;
5676
                sw->aes.aes = aes;
5677
                sw->aes.out = out;
5678
                sw->aes.in = in;
5679
                sw->aes.sz = sz;
5680
                return WC_PENDING_E;
5681
            }
5682
        #endif
5683
        }
5684
    #endif
5685
5686
    #if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
5687
        /* Implemented in wolfcrypt/src/port/nxp/se050_port.c */
5688
        if (aes->useSWCrypt == 0) {
5689
            return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
5690
                                   kAlgorithm_SSS_AES_CBC);
5691
        }
5692
    #endif
5693
5694
0
        VECTOR_REGISTERS_PUSH;
5695
5696
    #ifdef WOLFSSL_AESNI
5697
        if (aes->use_aesni) {
5698
            #ifdef DEBUG_AESNI
5699
                printf("about to aes cbc decrypt\n");
5700
                printf("in  = %p\n", in);
5701
                printf("out = %p\n", out);
5702
                printf("aes->key = %p\n", aes->key);
5703
                printf("aes->reg = %p\n", aes->reg);
5704
                printf("aes->rounds = %d\n", aes->rounds);
5705
                printf("sz = %d\n", sz);
5706
            #endif
5707
5708
            /* if input and output same will overwrite input iv */
5709
            XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
5710
            #if defined(WOLFSSL_AESNI_BY4) || defined(WOLFSSL_X86_BUILD)
5711
            AES_CBC_decrypt_AESNI_by4(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
5712
                            aes->rounds);
5713
            #elif defined(WOLFSSL_AESNI_BY6)
5714
            AES_CBC_decrypt_AESNI_by6(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
5715
                            aes->rounds);
5716
            #else /* WOLFSSL_AESNI_BYx */
5717
            AES_CBC_decrypt_AESNI_by8(in, out, (byte*)aes->reg, sz, (byte*)aes->key,
5718
                            (int)aes->rounds);
5719
            #endif /* WOLFSSL_AESNI_BYx */
5720
            /* store iv for next call */
5721
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
5722
            ret = 0;
5723
        }
5724
        else
5725
    #endif
5726
0
        {
5727
0
            ret = 0;
5728
#ifdef WC_AES_BITSLICED
5729
            if (in != out) {
5730
                unsigned char dec[AES_BLOCK_SIZE * BS_WORD_SIZE];
5731
5732
                while (blocks > BS_WORD_SIZE) {
5733
                    AesDecryptBlocks_C(aes, in, dec, AES_BLOCK_SIZE * BS_WORD_SIZE);
5734
                    xorbufout(out, dec, aes->reg, AES_BLOCK_SIZE);
5735
                    xorbufout(out + AES_BLOCK_SIZE, dec + AES_BLOCK_SIZE, in,
5736
                              AES_BLOCK_SIZE * (BS_WORD_SIZE - 1));
5737
                    XMEMCPY(aes->reg, in + (AES_BLOCK_SIZE * (BS_WORD_SIZE - 1)),
5738
                            AES_BLOCK_SIZE);
5739
                    in += AES_BLOCK_SIZE * BS_WORD_SIZE;
5740
                    out += AES_BLOCK_SIZE * BS_WORD_SIZE;
5741
                    blocks -= BS_WORD_SIZE;
5742
                }
5743
                if (blocks > 0) {
5744
                    AesDecryptBlocks_C(aes, in, dec, blocks * AES_BLOCK_SIZE);
5745
                    xorbufout(out, dec, aes->reg, AES_BLOCK_SIZE);
5746
                    xorbufout(out + AES_BLOCK_SIZE, dec + AES_BLOCK_SIZE, in,
5747
                              AES_BLOCK_SIZE * (blocks - 1));
5748
                    XMEMCPY(aes->reg, in + (AES_BLOCK_SIZE * (blocks - 1)),
5749
                            AES_BLOCK_SIZE);
5750
                    blocks = 0;
5751
                }
5752
            }
5753
            else {
5754
                unsigned char dec[AES_BLOCK_SIZE * BS_WORD_SIZE];
5755
                int i;
5756
5757
                while (blocks > BS_WORD_SIZE) {
5758
                    AesDecryptBlocks_C(aes, in, dec, AES_BLOCK_SIZE * BS_WORD_SIZE);
5759
                    XMEMCPY(aes->tmp, in + (BS_WORD_SIZE - 1) * AES_BLOCK_SIZE,
5760
                            AES_BLOCK_SIZE);
5761
                    for (i = BS_WORD_SIZE-1; i >= 1; i--) {
5762
                        xorbufout(out + i * AES_BLOCK_SIZE,
5763
                                  dec + i * AES_BLOCK_SIZE, in + (i - 1) * AES_BLOCK_SIZE,
5764
                                  AES_BLOCK_SIZE);
5765
                    }
5766
                    xorbufout(out, dec, aes->reg, AES_BLOCK_SIZE);
5767
                    XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
5768
5769
                    in += AES_BLOCK_SIZE * BS_WORD_SIZE;
5770
                    out += AES_BLOCK_SIZE * BS_WORD_SIZE;
5771
                    blocks -= BS_WORD_SIZE;
5772
                }
5773
                if (blocks > 0) {
5774
                    AesDecryptBlocks_C(aes, in, dec, blocks * AES_BLOCK_SIZE);
5775
                    XMEMCPY(aes->tmp, in + (blocks - 1) * AES_BLOCK_SIZE,
5776
                            AES_BLOCK_SIZE);
5777
                    for (i = blocks-1; i >= 1; i--) {
5778
                        xorbufout(out + i * AES_BLOCK_SIZE,
5779
                                  dec + i * AES_BLOCK_SIZE, in + (i - 1) * AES_BLOCK_SIZE,
5780
                                  AES_BLOCK_SIZE);
5781
                    }
5782
                    xorbufout(out, dec, aes->reg, AES_BLOCK_SIZE);
5783
                    XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
5784
5785
                    blocks = 0;
5786
                }
5787
            }
5788
#else
5789
0
            while (blocks--) {
5790
0
                XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
5791
0
                ret = wc_AesDecrypt(aes, in, out);
5792
0
                if (ret != 0)
5793
0
                    return ret;
5794
0
                xorbuf(out, (byte*)aes->reg, AES_BLOCK_SIZE);
5795
                /* store iv for next call */
5796
0
                XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
5797
5798
0
                out += AES_BLOCK_SIZE;
5799
0
                in  += AES_BLOCK_SIZE;
5800
0
            }
5801
0
#endif
5802
0
        }
5803
5804
0
        VECTOR_REGISTERS_POP;
5805
5806
0
        return ret;
5807
0
    }
5808
#endif /* HAVE_AES_DECRYPT */
5809
5810
#endif /* AES-CBC block */
5811
#endif /* HAVE_AES_CBC */
5812
5813
/* AES-CTR */
5814
#if defined(WOLFSSL_AES_COUNTER)
5815
5816
    #ifdef STM32_CRYPTO
5817
        #define NEED_AES_CTR_SOFT
5818
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
5819
5820
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
5821
        {
5822
            int ret = 0;
5823
        #ifdef WOLFSSL_STM32_CUBEMX
5824
            CRYP_HandleTypeDef hcryp;
5825
            #ifdef STM32_HAL_V2
5826
            word32 iv[AES_BLOCK_SIZE/sizeof(word32)];
5827
            #endif
5828
        #else
5829
            word32 *iv;
5830
            CRYP_InitTypeDef cryptInit;
5831
            CRYP_KeyInitTypeDef keyInit;
5832
            CRYP_IVInitTypeDef ivInit;
5833
        #endif
5834
5835
        #ifdef WOLFSSL_STM32_CUBEMX
5836
            ret = wc_Stm32_Aes_Init(aes, &hcryp);
5837
            if (ret != 0) {
5838
                return ret;
5839
            }
5840
5841
            ret = wolfSSL_CryptHwMutexLock();
5842
            if (ret != 0) {
5843
                return ret;
5844
            }
5845
5846
        #if defined(STM32_HAL_V2)
5847
            hcryp.Init.Algorithm  = CRYP_AES_CTR;
5848
            ByteReverseWords(iv, aes->reg, AES_BLOCK_SIZE);
5849
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)iv;
5850
        #elif defined(STM32_CRYPTO_AES_ONLY)
5851
            hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
5852
            hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_CTR;
5853
            hcryp.Init.KeyWriteFlag  = CRYP_KEY_WRITE_ENABLE;
5854
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5855
        #else
5856
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)aes->reg;
5857
        #endif
5858
            HAL_CRYP_Init(&hcryp);
5859
5860
        #if defined(STM32_HAL_V2)
5861
            ret = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, AES_BLOCK_SIZE,
5862
                (uint32_t*)out, STM32_HAL_TIMEOUT);
5863
        #elif defined(STM32_CRYPTO_AES_ONLY)
5864
            ret = HAL_CRYPEx_AES(&hcryp, (byte*)in, AES_BLOCK_SIZE,
5865
                out, STM32_HAL_TIMEOUT);
5866
        #else
5867
            ret = HAL_CRYP_AESCTR_Encrypt(&hcryp, (byte*)in, AES_BLOCK_SIZE,
5868
                out, STM32_HAL_TIMEOUT);
5869
        #endif
5870
            if (ret != HAL_OK) {
5871
                ret = WC_TIMEOUT_E;
5872
            }
5873
            HAL_CRYP_DeInit(&hcryp);
5874
5875
        #else /* Standard Peripheral Library */
5876
            ret = wc_Stm32_Aes_Init(aes, &cryptInit, &keyInit);
5877
            if (ret != 0) {
5878
                return ret;
5879
            }
5880
5881
            ret = wolfSSL_CryptHwMutexLock();
5882
            if (ret != 0) {
5883
                return ret;
5884
            }
5885
5886
            /* reset registers to their default values */
5887
            CRYP_DeInit();
5888
5889
            /* set key */
5890
            CRYP_KeyInit(&keyInit);
5891
5892
            /* set iv */
5893
            iv = aes->reg;
5894
            CRYP_IVStructInit(&ivInit);
5895
            ivInit.CRYP_IV0Left  = ByteReverseWord32(iv[0]);
5896
            ivInit.CRYP_IV0Right = ByteReverseWord32(iv[1]);
5897
            ivInit.CRYP_IV1Left  = ByteReverseWord32(iv[2]);
5898
            ivInit.CRYP_IV1Right = ByteReverseWord32(iv[3]);
5899
            CRYP_IVInit(&ivInit);
5900
5901
            /* set direction and mode */
5902
            cryptInit.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
5903
            cryptInit.CRYP_AlgoMode = CRYP_AlgoMode_AES_CTR;
5904
            CRYP_Init(&cryptInit);
5905
5906
            /* enable crypto processor */
5907
            CRYP_Cmd(ENABLE);
5908
5909
            /* flush IN/OUT FIFOs */
5910
            CRYP_FIFOFlush();
5911
5912
            CRYP_DataIn(*(uint32_t*)&in[0]);
5913
            CRYP_DataIn(*(uint32_t*)&in[4]);
5914
            CRYP_DataIn(*(uint32_t*)&in[8]);
5915
            CRYP_DataIn(*(uint32_t*)&in[12]);
5916
5917
            /* wait until the complete message has been processed */
5918
            while (CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
5919
5920
            *(uint32_t*)&out[0]  = CRYP_DataOut();
5921
            *(uint32_t*)&out[4]  = CRYP_DataOut();
5922
            *(uint32_t*)&out[8]  = CRYP_DataOut();
5923
            *(uint32_t*)&out[12] = CRYP_DataOut();
5924
5925
            /* disable crypto processor */
5926
            CRYP_Cmd(DISABLE);
5927
        #endif /* WOLFSSL_STM32_CUBEMX */
5928
5929
            wolfSSL_CryptHwMutexUnLock();
5930
            wc_Stm32_Aes_Cleanup();
5931
            return ret;
5932
        }
5933
5934
5935
    #elif defined(WOLFSSL_PIC32MZ_CRYPT)
5936
5937
        #define NEED_AES_CTR_SOFT
5938
        #define XTRANSFORM_AESCTRBLOCK wc_AesCtrEncryptBlock
5939
5940
        int wc_AesCtrEncryptBlock(Aes* aes, byte* out, const byte* in)
5941
        {
5942
            word32 tmpIv[AES_BLOCK_SIZE / sizeof(word32)];
5943
            XMEMCPY(tmpIv, aes->reg, AES_BLOCK_SIZE);
5944
            return wc_Pic32AesCrypt(
5945
                aes->key, aes->keylen, tmpIv, AES_BLOCK_SIZE,
5946
                out, in, AES_BLOCK_SIZE,
5947
                PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_RCTR);
5948
        }
5949
5950
    #elif defined(HAVE_COLDFIRE_SEC)
5951
        #error "Coldfire SEC doesn't currently support AES-CTR mode"
5952
5953
    #elif defined(FREESCALE_LTC)
5954
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
5955
        {
5956
            int ret = 0;
5957
            word32 keySize;
5958
            byte *iv, *enc_key;
5959
            byte* tmp;
5960
5961
            if (aes == NULL || out == NULL || in == NULL) {
5962
                return BAD_FUNC_ARG;
5963
            }
5964
5965
            /* consume any unused bytes left in aes->tmp */
5966
            tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
5967
            while (aes->left && sz) {
5968
                *(out++) = *(in++) ^ *(tmp++);
5969
                aes->left--;
5970
                sz--;
5971
            }
5972
5973
            if (sz) {
5974
                iv      = (byte*)aes->reg;
5975
                enc_key = (byte*)aes->key;
5976
5977
                ret = wc_AesGetKeySize(aes, &keySize);
5978
                if (ret != 0)
5979
                    return ret;
5980
5981
                ret = wolfSSL_CryptHwMutexLock();
5982
                if (ret != 0)
5983
                    return ret;
5984
                LTC_AES_CryptCtr(LTC_BASE, in, out, sz,
5985
                    iv, enc_key, keySize, (byte*)aes->tmp,
5986
                    (uint32_t*)&aes->left);
5987
                wolfSSL_CryptHwMutexUnLock();
5988
            }
5989
5990
            return ret;
5991
        }
5992
5993
    #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
5994
        !defined(WOLFSSL_QNX_CAAM)
5995
        /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
5996
5997
    #elif defined(WOLFSSL_AFALG)
5998
        /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
5999
6000
    #elif defined(WOLFSSL_DEVCRYPTO_AES)
6001
        /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6002
6003
    #elif defined(WOLFSSL_ESP32_CRYPT) && \
6004
        !defined(NO_WOLFSSL_ESP32_CRYPT_AES)
6005
        /* esp32 doesn't support CRT mode by hw.     */
6006
        /* use aes ecnryption plus sw implementation */
6007
        #define NEED_AES_CTR_SOFT
6008
6009
    #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
6010
    /* implemented in wolfcrypt/src/port/psa/psa_aes.c */
6011
    #else
6012
6013
        /* Use software based AES counter */
6014
        #define NEED_AES_CTR_SOFT
6015
    #endif
6016
6017
    #ifdef NEED_AES_CTR_SOFT
6018
        /* Increment AES counter */
6019
        static WC_INLINE void IncrementAesCounter(byte* inOutCtr)
6020
0
        {
6021
            /* in network byte order so start at end and work back */
6022
0
            int i;
6023
0
            for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
6024
0
                if (++inOutCtr[i])  /* we're done unless we overflow */
6025
0
                    return;
6026
0
            }
6027
0
        }
6028
6029
        /* Software AES - CTR Encrypt */
6030
        int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
6031
0
        {
6032
0
            byte scratch[AES_BLOCK_SIZE];
6033
0
            int ret = 0;
6034
0
            word32 processed;
6035
6036
0
            if (aes == NULL || out == NULL || in == NULL) {
6037
0
                return BAD_FUNC_ARG;
6038
0
            }
6039
6040
0
        #ifdef WOLF_CRYPTO_CB
6041
0
            #ifndef WOLF_CRYPTO_CB_FIND
6042
0
            if (aes->devId != INVALID_DEVID)
6043
0
            #endif
6044
0
            {
6045
0
                int crypto_cb_ret = wc_CryptoCb_AesCtrEncrypt(aes, out, in, sz);
6046
0
                if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
6047
0
                    return crypto_cb_ret;
6048
                /* fall-through when unavailable */
6049
0
            }
6050
0
        #endif
6051
6052
            /* consume any unused bytes left in aes->tmp */
6053
0
            processed = min(aes->left, sz);
6054
0
            xorbufout(out, in, (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left,
6055
0
                      processed);
6056
0
            out += processed;
6057
0
            in += processed;
6058
0
            aes->left -= processed;
6059
0
            sz -= processed;
6060
6061
0
            VECTOR_REGISTERS_PUSH;
6062
6063
0
        #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) && \
6064
0
            !defined(XTRANSFORM_AESCTRBLOCK)
6065
0
            if (in != out && sz >= AES_BLOCK_SIZE) {
6066
0
                word32 blocks = sz / AES_BLOCK_SIZE;
6067
0
                byte* counter = (byte*)aes->reg;
6068
0
                byte* c = out;
6069
0
                while (blocks--) {
6070
0
                    XMEMCPY(c, counter, AES_BLOCK_SIZE);
6071
0
                    c += AES_BLOCK_SIZE;
6072
0
                    IncrementAesCounter(counter);
6073
0
                }
6074
6075
                /* reset number of blocks and then do encryption */
6076
0
                blocks = sz / AES_BLOCK_SIZE;
6077
0
                wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
6078
0
                xorbuf(out, in, AES_BLOCK_SIZE * blocks);
6079
0
                in += AES_BLOCK_SIZE * blocks;
6080
0
                out += AES_BLOCK_SIZE * blocks;
6081
0
                sz -= blocks * AES_BLOCK_SIZE;
6082
0
            }
6083
0
            else
6084
0
        #endif
6085
0
            {
6086
            #ifdef WOLFSSL_CHECK_MEM_ZERO
6087
                wc_MemZero_Add("wc_AesCtrEncrypt scratch", scratch,
6088
                    AES_BLOCK_SIZE);
6089
            #endif
6090
                /* do as many block size ops as possible */
6091
0
                while (sz >= AES_BLOCK_SIZE) {
6092
                #ifdef XTRANSFORM_AESCTRBLOCK
6093
                    XTRANSFORM_AESCTRBLOCK(aes, out, in);
6094
                #else
6095
0
                    ret = wc_AesEncrypt(aes, (byte*)aes->reg, scratch);
6096
0
                    if (ret != 0)
6097
0
                        break;
6098
0
                    xorbuf(scratch, in, AES_BLOCK_SIZE);
6099
0
                    XMEMCPY(out, scratch, AES_BLOCK_SIZE);
6100
0
                #endif
6101
0
                    IncrementAesCounter((byte*)aes->reg);
6102
6103
0
                    out += AES_BLOCK_SIZE;
6104
0
                    in  += AES_BLOCK_SIZE;
6105
0
                    sz  -= AES_BLOCK_SIZE;
6106
0
                    aes->left = 0;
6107
0
                }
6108
0
                ForceZero(scratch, AES_BLOCK_SIZE);
6109
0
            }
6110
6111
            /* handle non block size remaining and store unused byte count in left */
6112
0
            if ((ret == 0) && sz) {
6113
0
                ret = wc_AesEncrypt(aes, (byte*)aes->reg, (byte*)aes->tmp);
6114
0
                if (ret == 0) {
6115
0
                    IncrementAesCounter((byte*)aes->reg);
6116
0
                    aes->left = AES_BLOCK_SIZE - sz;
6117
0
                    xorbufout(out, in, aes->tmp, sz);
6118
0
                }
6119
0
            }
6120
6121
0
            if (ret < 0)
6122
0
                ForceZero(scratch, AES_BLOCK_SIZE);
6123
6124
        #ifdef WOLFSSL_CHECK_MEM_ZERO
6125
            wc_MemZero_Check(scratch, AES_BLOCK_SIZE);
6126
        #endif
6127
6128
0
            VECTOR_REGISTERS_POP;
6129
6130
0
            return ret;
6131
0
        }
6132
6133
        int wc_AesCtrSetKey(Aes* aes, const byte* key, word32 len,
6134
                                        const byte* iv, int dir)
6135
0
        {
6136
0
            if (aes == NULL) {
6137
0
                return BAD_FUNC_ARG;
6138
0
            }
6139
0
            if (len > sizeof(aes->key)) {
6140
0
                return BAD_FUNC_ARG;
6141
0
            }
6142
6143
0
            return wc_AesSetKeyLocal(aes, key, len, iv, dir, 0);
6144
0
        }
6145
6146
    #endif /* NEED_AES_CTR_SOFT */
6147
6148
#endif /* WOLFSSL_AES_COUNTER */
6149
#endif /* !WOLFSSL_ARMASM */
6150
6151
6152
/*
6153
 * The IV for AES GCM and CCM, stored in struct Aes's member reg, is comprised
6154
 * of two parts in order:
6155
 *   1. The fixed field which may be 0 or 4 bytes long. In TLS, this is set
6156
 *      to the implicit IV.
6157
 *   2. The explicit IV is generated by wolfCrypt. It needs to be managed
6158
 *      by wolfCrypt to ensure the IV is unique for each call to encrypt.
6159
 * The IV may be a 96-bit random value, or the 32-bit fixed value and a
6160
 * 64-bit set of 0 or random data. The final 32-bits of reg is used as a
6161
 * block counter during the encryption.
6162
 */
6163
6164
#if (defined(HAVE_AESGCM) && !defined(WC_NO_RNG)) || defined(HAVE_AESCCM)
6165
static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz)
6166
0
{
6167
0
    int i;
6168
0
    for (i = (int)ctrSz - 1; i >= 0; i--) {
6169
0
        if (++ctr[i])
6170
0
            break;
6171
0
    }
6172
0
}
6173
#endif /* HAVE_AESGCM || HAVE_AESCCM */
6174
6175
6176
#ifdef HAVE_AESGCM
6177
6178
#ifdef WOLFSSL_AESGCM_STREAM
6179
    /* Access initialization counter data. */
6180
0
    #define AES_INITCTR(aes)        ((aes)->streamData + 0 * AES_BLOCK_SIZE)
6181
    /* Access counter data. */
6182
0
    #define AES_COUNTER(aes)        ((aes)->streamData + 1 * AES_BLOCK_SIZE)
6183
    /* Access tag data. */
6184
0
    #define AES_TAG(aes)            ((aes)->streamData + 2 * AES_BLOCK_SIZE)
6185
    /* Access last GHASH block. */
6186
    #define AES_LASTGBLOCK(aes)     ((aes)->streamData + 3 * AES_BLOCK_SIZE)
6187
    /* Access last encrypted block. */
6188
0
    #define AES_LASTBLOCK(aes)      ((aes)->streamData + 4 * AES_BLOCK_SIZE)
6189
#endif
6190
6191
#if defined(HAVE_COLDFIRE_SEC)
6192
    #error "Coldfire SEC doesn't currently support AES-GCM mode"
6193
6194
#endif
6195
6196
#ifdef WOLFSSL_ARMASM
6197
    /* implementation is located in wolfcrypt/src/port/arm/armv8-aes.c */
6198
6199
#elif defined(WOLFSSL_AFALG)
6200
    /* implemented in wolfcrypt/src/port/afalg/afalg_aes.c */
6201
6202
#elif defined(WOLFSSL_KCAPI_AES)
6203
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_aes.c */
6204
6205
#elif defined(WOLFSSL_DEVCRYPTO_AES)
6206
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
6207
6208
#else /* software + AESNI implementation */
6209
6210
#if !defined(FREESCALE_LTC_AES_GCM)
6211
static WC_INLINE void IncrementGcmCounter(byte* inOutCtr)
6212
0
{
6213
0
    int i;
6214
6215
    /* in network byte order so start at end and work back */
6216
0
    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
6217
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
6218
0
            return;
6219
0
    }
6220
0
}
6221
#endif /* !FREESCALE_LTC_AES_GCM */
6222
6223
#if defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
6224
6225
static WC_INLINE void FlattenSzInBits(byte* buf, word32 sz)
6226
0
{
6227
    /* Multiply the sz by 8 */
6228
0
    word32 szHi = (sz >> (8*sizeof(sz) - 3));
6229
0
    sz <<= 3;
6230
6231
    /* copy over the words of the sz into the destination buffer */
6232
0
    buf[0] = (byte)(szHi >> 24);
6233
0
    buf[1] = (byte)(szHi >> 16);
6234
0
    buf[2] = (byte)(szHi >>  8);
6235
0
    buf[3] = (byte)szHi;
6236
0
    buf[4] = (byte)(sz >> 24);
6237
0
    buf[5] = (byte)(sz >> 16);
6238
0
    buf[6] = (byte)(sz >>  8);
6239
0
    buf[7] = (byte)sz;
6240
0
}
6241
6242
6243
static WC_INLINE void RIGHTSHIFTX(byte* x)
6244
0
{
6245
0
    int i;
6246
0
    int carryIn = 0;
6247
0
    byte borrow = (0x00 - (x[15] & 0x01)) & 0xE1;
6248
6249
0
    for (i = 0; i < AES_BLOCK_SIZE; i++) {
6250
0
        int carryOut = (x[i] & 0x01) << 7;
6251
0
        x[i] = (byte) ((x[i] >> 1) | carryIn);
6252
0
        carryIn = carryOut;
6253
0
    }
6254
0
    x[0] ^= borrow;
6255
0
}
6256
6257
#endif /* defined(GCM_SMALL) || defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) */
6258
6259
6260
#ifdef GCM_TABLE
6261
6262
void GenerateM0(Gcm* gcm)
6263
{
6264
    int i, j;
6265
    byte (*m)[AES_BLOCK_SIZE] = gcm->M0;
6266
6267
    XMEMCPY(m[128], gcm->H, AES_BLOCK_SIZE);
6268
6269
    for (i = 64; i > 0; i /= 2) {
6270
        XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
6271
        RIGHTSHIFTX(m[i]);
6272
    }
6273
6274
    for (i = 2; i < 256; i *= 2) {
6275
        for (j = 1; j < i; j++) {
6276
            XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
6277
            xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
6278
        }
6279
    }
6280
6281
    XMEMSET(m[0], 0, AES_BLOCK_SIZE);
6282
}
6283
6284
#elif defined(GCM_TABLE_4BIT)
6285
6286
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
6287
static WC_INLINE void Shift4_M0(byte *r8, byte *z8)
6288
0
{
6289
0
    int i;
6290
0
    for (i = 15; i > 0; i--)
6291
0
        r8[i] = (byte)(z8[i-1] << 4) | (byte)(z8[i] >> 4);
6292
0
    r8[0] = (byte)(z8[0] >> 4);
6293
0
}
6294
#endif
6295
6296
void GenerateM0(Gcm* gcm)
6297
0
{
6298
0
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
6299
0
    int i;
6300
0
#endif
6301
0
    byte (*m)[AES_BLOCK_SIZE] = gcm->M0;
6302
6303
    /* 0 times -> 0x0 */
6304
0
    XMEMSET(m[0x0], 0, AES_BLOCK_SIZE);
6305
    /* 1 times -> 0x8 */
6306
0
    XMEMCPY(m[0x8], gcm->H, AES_BLOCK_SIZE);
6307
    /* 2 times -> 0x4 */
6308
0
    XMEMCPY(m[0x4], m[0x8], AES_BLOCK_SIZE);
6309
0
    RIGHTSHIFTX(m[0x4]);
6310
    /* 4 times -> 0x2 */
6311
0
    XMEMCPY(m[0x2], m[0x4], AES_BLOCK_SIZE);
6312
0
    RIGHTSHIFTX(m[0x2]);
6313
    /* 8 times -> 0x1 */
6314
0
    XMEMCPY(m[0x1], m[0x2], AES_BLOCK_SIZE);
6315
0
    RIGHTSHIFTX(m[0x1]);
6316
6317
    /* 0x3 */
6318
0
    XMEMCPY(m[0x3], m[0x2], AES_BLOCK_SIZE);
6319
0
    xorbuf (m[0x3], m[0x1], AES_BLOCK_SIZE);
6320
6321
    /* 0x5 -> 0x7 */
6322
0
    XMEMCPY(m[0x5], m[0x4], AES_BLOCK_SIZE);
6323
0
    xorbuf (m[0x5], m[0x1], AES_BLOCK_SIZE);
6324
0
    XMEMCPY(m[0x6], m[0x4], AES_BLOCK_SIZE);
6325
0
    xorbuf (m[0x6], m[0x2], AES_BLOCK_SIZE);
6326
0
    XMEMCPY(m[0x7], m[0x4], AES_BLOCK_SIZE);
6327
0
    xorbuf (m[0x7], m[0x3], AES_BLOCK_SIZE);
6328
6329
    /* 0x9 -> 0xf */
6330
0
    XMEMCPY(m[0x9], m[0x8], AES_BLOCK_SIZE);
6331
0
    xorbuf (m[0x9], m[0x1], AES_BLOCK_SIZE);
6332
0
    XMEMCPY(m[0xa], m[0x8], AES_BLOCK_SIZE);
6333
0
    xorbuf (m[0xa], m[0x2], AES_BLOCK_SIZE);
6334
0
    XMEMCPY(m[0xb], m[0x8], AES_BLOCK_SIZE);
6335
0
    xorbuf (m[0xb], m[0x3], AES_BLOCK_SIZE);
6336
0
    XMEMCPY(m[0xc], m[0x8], AES_BLOCK_SIZE);
6337
0
    xorbuf (m[0xc], m[0x4], AES_BLOCK_SIZE);
6338
0
    XMEMCPY(m[0xd], m[0x8], AES_BLOCK_SIZE);
6339
0
    xorbuf (m[0xd], m[0x5], AES_BLOCK_SIZE);
6340
0
    XMEMCPY(m[0xe], m[0x8], AES_BLOCK_SIZE);
6341
0
    xorbuf (m[0xe], m[0x6], AES_BLOCK_SIZE);
6342
0
    XMEMCPY(m[0xf], m[0x8], AES_BLOCK_SIZE);
6343
0
    xorbuf (m[0xf], m[0x7], AES_BLOCK_SIZE);
6344
6345
0
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_16BIT_CPU)
6346
0
    for (i = 0; i < 16; i++) {
6347
0
        Shift4_M0(m[16+i], m[i]);
6348
0
    }
6349
0
#endif
6350
0
}
6351
6352
#endif /* GCM_TABLE */
6353
6354
/* Software AES - GCM SetKey */
6355
int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
6356
0
{
6357
0
    int  ret;
6358
0
    byte iv[AES_BLOCK_SIZE];
6359
6360
    #ifdef WOLFSSL_IMX6_CAAM_BLOB
6361
        byte   local[32];
6362
        word32 localSz = 32;
6363
6364
        if (len == (16 + WC_CAAM_BLOB_SZ) ||
6365
          len == (24 + WC_CAAM_BLOB_SZ) ||
6366
          len == (32 + WC_CAAM_BLOB_SZ)) {
6367
            if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
6368
                 return BAD_FUNC_ARG;
6369
            }
6370
6371
            /* set local values */
6372
            key = local;
6373
            len = localSz;
6374
        }
6375
    #endif
6376
6377
0
    if (!((len == 16) || (len == 24) || (len == 32)))
6378
0
        return BAD_FUNC_ARG;
6379
6380
0
    if (aes == NULL) {
6381
#ifdef WOLFSSL_IMX6_CAAM_BLOB
6382
        ForceZero(local, sizeof(local));
6383
#endif
6384
0
        return BAD_FUNC_ARG;
6385
0
    }
6386
6387
#ifdef OPENSSL_EXTRA
6388
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
6389
    aes->gcm.aadLen = 0;
6390
#endif
6391
0
    XMEMSET(iv, 0, AES_BLOCK_SIZE);
6392
0
    ret = wc_AesSetKey(aes, key, len, iv, AES_ENCRYPTION);
6393
0
#ifdef WOLFSSL_AESGCM_STREAM
6394
0
    aes->gcmKeySet = 1;
6395
0
#endif
6396
    #if defined(WOLFSSL_SECO_CAAM)
6397
        if (aes->devId == WOLFSSL_SECO_DEVID) {
6398
            return ret;
6399
        }
6400
    #endif /* WOLFSSL_SECO_CAAM */
6401
6402
    #if defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY) && \
6403
        !defined(NO_WOLFSSL_RENESAS_FSPSM_AES)
6404
        return ret;
6405
    #endif /* WOLFSSL_RENESAS_RSIP && WOLFSSL_RENESAS_FSPSM_CRYPTONLY*/
6406
6407
0
#if !defined(FREESCALE_LTC_AES_GCM)
6408
0
    if (ret == 0) {
6409
0
        VECTOR_REGISTERS_PUSH;
6410
        /* AES-NI code generates its own H value, but generate it here too, to
6411
         * assure pure-C fallback is always usable.
6412
         */
6413
0
        ret = wc_AesEncrypt(aes, iv, aes->gcm.H);
6414
0
        VECTOR_REGISTERS_POP;
6415
0
    }
6416
0
    if (ret == 0) {
6417
0
    #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT)
6418
0
        GenerateM0(&aes->gcm);
6419
0
    #endif /* GCM_TABLE */
6420
0
    }
6421
0
#endif /* FREESCALE_LTC_AES_GCM */
6422
6423
#if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_AFALG_XILINX_AES)
6424
    wc_AesGcmSetKey_ex(aes, key, len, WOLFSSL_XILINX_AES_KEY_SRC);
6425
#endif
6426
6427
0
#ifdef WOLF_CRYPTO_CB
6428
0
    if (aes->devId != INVALID_DEVID) {
6429
0
        XMEMCPY(aes->devKey, key, len);
6430
0
    }
6431
0
#endif
6432
6433
#ifdef WOLFSSL_IMX6_CAAM_BLOB
6434
    ForceZero(local, sizeof(local));
6435
#endif
6436
0
    return ret;
6437
0
}
6438
6439
6440
#ifdef WOLFSSL_AESNI
6441
6442
#if defined(USE_INTEL_SPEEDUP)
6443
    #define HAVE_INTEL_AVX1
6444
    #define HAVE_INTEL_AVX2
6445
#endif /* USE_INTEL_SPEEDUP */
6446
6447
void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out,
6448
                     const unsigned char* addt, const unsigned char* ivec,
6449
                     unsigned char *tag, word32 nbytes,
6450
                     word32 abytes, word32 ibytes,
6451
                     word32 tbytes, const unsigned char* key, int nr)
6452
                     XASM_LINK("AES_GCM_encrypt_aesni");
6453
#ifdef HAVE_INTEL_AVX1
6454
void AES_GCM_encrypt_avx1(const unsigned char *in, unsigned char *out,
6455
                          const unsigned char* addt, const unsigned char* ivec,
6456
                          unsigned char *tag, word32 nbytes,
6457
                          word32 abytes, word32 ibytes,
6458
                          word32 tbytes, const unsigned char* key,
6459
                          int nr)
6460
                          XASM_LINK("AES_GCM_encrypt_avx1");
6461
#ifdef HAVE_INTEL_AVX2
6462
void AES_GCM_encrypt_avx2(const unsigned char *in, unsigned char *out,
6463
                          const unsigned char* addt, const unsigned char* ivec,
6464
                          unsigned char *tag, word32 nbytes,
6465
                          word32 abytes, word32 ibytes,
6466
                          word32 tbytes, const unsigned char* key,
6467
                          int nr)
6468
                          XASM_LINK("AES_GCM_encrypt_avx2");
6469
#endif /* HAVE_INTEL_AVX2 */
6470
#endif /* HAVE_INTEL_AVX1 */
6471
6472
#ifdef HAVE_AES_DECRYPT
6473
void AES_GCM_decrypt_aesni(const unsigned char *in, unsigned char *out,
6474
                     const unsigned char* addt, const unsigned char* ivec,
6475
                     const unsigned char *tag, word32 nbytes, word32 abytes,
6476
                     word32 ibytes, word32 tbytes, const unsigned char* key,
6477
                     int nr, int* res)
6478
                     XASM_LINK("AES_GCM_decrypt_aesni");
6479
#ifdef HAVE_INTEL_AVX1
6480
void AES_GCM_decrypt_avx1(const unsigned char *in, unsigned char *out,
6481
                          const unsigned char* addt, const unsigned char* ivec,
6482
                          const unsigned char *tag, word32 nbytes,
6483
                          word32 abytes, word32 ibytes, word32 tbytes,
6484
                          const unsigned char* key, int nr, int* res)
6485
                          XASM_LINK("AES_GCM_decrypt_avx1");
6486
#ifdef HAVE_INTEL_AVX2
6487
void AES_GCM_decrypt_avx2(const unsigned char *in, unsigned char *out,
6488
                          const unsigned char* addt, const unsigned char* ivec,
6489
                          const unsigned char *tag, word32 nbytes,
6490
                          word32 abytes, word32 ibytes, word32 tbytes,
6491
                          const unsigned char* key, int nr, int* res)
6492
                          XASM_LINK("AES_GCM_decrypt_avx2");
6493
#endif /* HAVE_INTEL_AVX2 */
6494
#endif /* HAVE_INTEL_AVX1 */
6495
#endif /* HAVE_AES_DECRYPT */
6496
6497
#endif /* WOLFSSL_AESNI */
6498
6499
#if defined(GCM_SMALL)
6500
static void GMULT(byte* X, byte* Y)
6501
{
6502
    byte Z[AES_BLOCK_SIZE];
6503
    byte V[AES_BLOCK_SIZE];
6504
    int i, j;
6505
6506
    XMEMSET(Z, 0, AES_BLOCK_SIZE);
6507
    XMEMCPY(V, X, AES_BLOCK_SIZE);
6508
    for (i = 0; i < AES_BLOCK_SIZE; i++)
6509
    {
6510
        byte y = Y[i];
6511
        for (j = 0; j < 8; j++)
6512
        {
6513
            if (y & 0x80) {
6514
                xorbuf(Z, V, AES_BLOCK_SIZE);
6515
            }
6516
6517
            RIGHTSHIFTX(V);
6518
            y = y << 1;
6519
        }
6520
    }
6521
    XMEMCPY(X, Z, AES_BLOCK_SIZE);
6522
}
6523
6524
6525
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
6526
    word32 cSz, byte* s, word32 sSz)
6527
{
6528
    byte x[AES_BLOCK_SIZE];
6529
    byte scratch[AES_BLOCK_SIZE];
6530
    word32 blocks, partial;
6531
    byte* h;
6532
6533
    if (gcm == NULL) {
6534
        return;
6535
    }
6536
6537
    h = gcm->H;
6538
    XMEMSET(x, 0, AES_BLOCK_SIZE);
6539
6540
    /* Hash in A, the Additional Authentication Data */
6541
    if (aSz != 0 && a != NULL) {
6542
        blocks = aSz / AES_BLOCK_SIZE;
6543
        partial = aSz % AES_BLOCK_SIZE;
6544
        while (blocks--) {
6545
            xorbuf(x, a, AES_BLOCK_SIZE);
6546
            GMULT(x, h);
6547
            a += AES_BLOCK_SIZE;
6548
        }
6549
        if (partial != 0) {
6550
            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
6551
            XMEMCPY(scratch, a, partial);
6552
            xorbuf(x, scratch, AES_BLOCK_SIZE);
6553
            GMULT(x, h);
6554
        }
6555
    }
6556
6557
    /* Hash in C, the Ciphertext */
6558
    if (cSz != 0 && c != NULL) {
6559
        blocks = cSz / AES_BLOCK_SIZE;
6560
        partial = cSz % AES_BLOCK_SIZE;
6561
        while (blocks--) {
6562
            xorbuf(x, c, AES_BLOCK_SIZE);
6563
            GMULT(x, h);
6564
            c += AES_BLOCK_SIZE;
6565
        }
6566
        if (partial != 0) {
6567
            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
6568
            XMEMCPY(scratch, c, partial);
6569
            xorbuf(x, scratch, AES_BLOCK_SIZE);
6570
            GMULT(x, h);
6571
        }
6572
    }
6573
6574
    /* Hash in the lengths of A and C in bits */
6575
    FlattenSzInBits(&scratch[0], aSz);
6576
    FlattenSzInBits(&scratch[8], cSz);
6577
    xorbuf(x, scratch, AES_BLOCK_SIZE);
6578
    GMULT(x, h);
6579
6580
    /* Copy the result into s. */
6581
    XMEMCPY(s, x, sSz);
6582
}
6583
6584
#ifdef WOLFSSL_AESGCM_STREAM
6585
/* No extra initialization for small implementation.
6586
 *
6587
 * @param [in] aes  AES GCM object.
6588
 */
6589
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
6590
6591
/* GHASH one block of data..
6592
 *
6593
 * XOR block into tag and GMULT with H.
6594
 *
6595
 * @param [in, out] aes    AES GCM object.
6596
 * @param [in]      block  Block of AAD or cipher text.
6597
 */
6598
#define GHASH_ONE_BLOCK(aes, block)                     \
6599
    do {                                                \
6600
        xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE);    \
6601
        GMULT(AES_TAG(aes), aes->gcm.H);                \
6602
    }                                                   \
6603
    while (0)
6604
#endif /* WOLFSSL_AESGCM_STREAM */
6605
/* end GCM_SMALL */
6606
#elif defined(GCM_TABLE)
6607
6608
ALIGN16 static const byte R[256][2] = {
6609
    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
6610
    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
6611
    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
6612
    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
6613
    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
6614
    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
6615
    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
6616
    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
6617
    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
6618
    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
6619
    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
6620
    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
6621
    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
6622
    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
6623
    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
6624
    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
6625
    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
6626
    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
6627
    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
6628
    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
6629
    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
6630
    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
6631
    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
6632
    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
6633
    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
6634
    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
6635
    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
6636
    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
6637
    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
6638
    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
6639
    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
6640
    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
6641
    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
6642
    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
6643
    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
6644
    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
6645
    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
6646
    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
6647
    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
6648
    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
6649
    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
6650
    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
6651
    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
6652
    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
6653
    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
6654
    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
6655
    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
6656
    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
6657
    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
6658
    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
6659
    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
6660
    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
6661
    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
6662
    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
6663
    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
6664
    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
6665
    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
6666
    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
6667
    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
6668
    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
6669
    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
6670
    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
6671
    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
6672
    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
6673
6674
6675
static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
6676
{
6677
#if !defined(WORD64_AVAILABLE) || defined(BIG_ENDIAN_ORDER)
6678
    int i, j;
6679
    byte Z[AES_BLOCK_SIZE];
6680
    byte a;
6681
6682
    XMEMSET(Z, 0, sizeof(Z));
6683
6684
    for (i = 15; i > 0; i--) {
6685
        xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
6686
        a = Z[15];
6687
6688
        for (j = 15; j > 0; j--) {
6689
            Z[j] = Z[j-1];
6690
        }
6691
6692
        Z[0]  = R[a][0];
6693
        Z[1] ^= R[a][1];
6694
    }
6695
    xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
6696
6697
    XMEMCPY(x, Z, AES_BLOCK_SIZE);
6698
#elif defined(WC_32BIT_CPU)
6699
    byte Z[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
6700
    byte a;
6701
    word32* pZ;
6702
    word32* pm;
6703
    word32* px = (word32*)(x);
6704
    int i;
6705
6706
    pZ = (word32*)(Z + 15 + 1);
6707
    pm = (word32*)(m[x[15]]);
6708
    pZ[0] = pm[0];
6709
    pZ[1] = pm[1];
6710
    pZ[2] = pm[2];
6711
    pZ[3] = pm[3];
6712
    a = Z[16 + 15];
6713
    Z[15]  = R[a][0];
6714
    Z[16] ^= R[a][1];
6715
    for (i = 14; i > 0; i--) {
6716
        pZ = (word32*)(Z + i + 1);
6717
        pm = (word32*)(m[x[i]]);
6718
        pZ[0] ^= pm[0];
6719
        pZ[1] ^= pm[1];
6720
        pZ[2] ^= pm[2];
6721
        pZ[3] ^= pm[3];
6722
        a = Z[16 + i];
6723
        Z[i]    = R[a][0];
6724
        Z[i+1] ^= R[a][1];
6725
    }
6726
    pZ = (word32*)(Z + 1);
6727
    pm = (word32*)(m[x[0]]);
6728
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
6729
    px[2] = pZ[2] ^ pm[2]; px[3] = pZ[3] ^ pm[3];
6730
#else
6731
    byte Z[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
6732
    byte a;
6733
    word64* pZ;
6734
    word64* pm;
6735
    word64* px = (word64*)(x);
6736
    int i;
6737
6738
    pZ = (word64*)(Z + 15 + 1);
6739
    pm = (word64*)(m[x[15]]);
6740
    pZ[0] = pm[0];
6741
    pZ[1] = pm[1];
6742
    a = Z[16 + 15];
6743
    Z[15]  = R[a][0];
6744
    Z[16] ^= R[a][1];
6745
    for (i = 14; i > 0; i--) {
6746
        pZ = (word64*)(Z + i + 1);
6747
        pm = (word64*)(m[x[i]]);
6748
        pZ[0] ^= pm[0];
6749
        pZ[1] ^= pm[1];
6750
        a = Z[16 + i];
6751
        Z[i]    = R[a][0];
6752
        Z[i+1] ^= R[a][1];
6753
    }
6754
    pZ = (word64*)(Z + 1);
6755
    pm = (word64*)(m[x[0]]);
6756
    px[0] = pZ[0] ^ pm[0]; px[1] = pZ[1] ^ pm[1];
6757
#endif
6758
}
6759
6760
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
6761
    word32 cSz, byte* s, word32 sSz)
6762
{
6763
    byte x[AES_BLOCK_SIZE];
6764
    byte scratch[AES_BLOCK_SIZE];
6765
    word32 blocks, partial;
6766
6767
    if (gcm == NULL) {
6768
        return;
6769
    }
6770
6771
    XMEMSET(x, 0, AES_BLOCK_SIZE);
6772
6773
    /* Hash in A, the Additional Authentication Data */
6774
    if (aSz != 0 && a != NULL) {
6775
        blocks = aSz / AES_BLOCK_SIZE;
6776
        partial = aSz % AES_BLOCK_SIZE;
6777
        while (blocks--) {
6778
            xorbuf(x, a, AES_BLOCK_SIZE);
6779
            GMULT(x, gcm->M0);
6780
            a += AES_BLOCK_SIZE;
6781
        }
6782
        if (partial != 0) {
6783
            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
6784
            XMEMCPY(scratch, a, partial);
6785
            xorbuf(x, scratch, AES_BLOCK_SIZE);
6786
            GMULT(x, gcm->M0);
6787
        }
6788
    }
6789
6790
    /* Hash in C, the Ciphertext */
6791
    if (cSz != 0 && c != NULL) {
6792
        blocks = cSz / AES_BLOCK_SIZE;
6793
        partial = cSz % AES_BLOCK_SIZE;
6794
        while (blocks--) {
6795
            xorbuf(x, c, AES_BLOCK_SIZE);
6796
            GMULT(x, gcm->M0);
6797
            c += AES_BLOCK_SIZE;
6798
        }
6799
        if (partial != 0) {
6800
            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
6801
            XMEMCPY(scratch, c, partial);
6802
            xorbuf(x, scratch, AES_BLOCK_SIZE);
6803
            GMULT(x, gcm->M0);
6804
        }
6805
    }
6806
6807
    /* Hash in the lengths of A and C in bits */
6808
    FlattenSzInBits(&scratch[0], aSz);
6809
    FlattenSzInBits(&scratch[8], cSz);
6810
    xorbuf(x, scratch, AES_BLOCK_SIZE);
6811
    GMULT(x, gcm->M0);
6812
6813
    /* Copy the result into s. */
6814
    XMEMCPY(s, x, sSz);
6815
}
6816
6817
#ifdef WOLFSSL_AESGCM_STREAM
6818
/* No extra initialization for table implementation.
6819
 *
6820
 * @param [in] aes  AES GCM object.
6821
 */
6822
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
6823
6824
/* GHASH one block of data..
6825
 *
6826
 * XOR block into tag and GMULT with H using pre-computed table.
6827
 *
6828
 * @param [in, out] aes    AES GCM object.
6829
 * @param [in]      block  Block of AAD or cipher text.
6830
 */
6831
#define GHASH_ONE_BLOCK(aes, block)                     \
6832
    do {                                                \
6833
        xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE);    \
6834
        GMULT(AES_TAG(aes), aes->gcm.M0);               \
6835
    }                                                   \
6836
    while (0)
6837
#endif /* WOLFSSL_AESGCM_STREAM */
6838
/* end GCM_TABLE */
6839
#elif defined(GCM_TABLE_4BIT)
6840
6841
/* remainder = x^7 + x^2 + x^1 + 1 => 0xe1
6842
 *  R shifts right a reverse bit pair of bytes such that:
6843
 *     R(b0, b1) => b1 = (b1 >> 1) | (b0 << 7); b0 >>= 1
6844
 *  0 => 0, 0, 0, 0 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ 00,00 = 00,00
6845
 *  8 => 0, 0, 0, 1 => R(R(R(00,00) ^ 00,00) ^ 00,00) ^ e1,00 = e1,00
6846
 *  4 => 0, 0, 1, 0 => R(R(R(00,00) ^ 00,00) ^ e1,00) ^ 00,00 = 70,80
6847
 *  2 => 0, 1, 0, 0 => R(R(R(00,00) ^ e1,00) ^ 00,00) ^ 00,00 = 38,40
6848
 *  1 => 1, 0, 0, 0 => R(R(R(e1,00) ^ 00,00) ^ 00,00) ^ 00,00 = 1c,20
6849
 *  To calculate te rest, XOR result for each bit.
6850
 *   e.g. 6 = 4 ^ 2 => 48,c0
6851
 *
6852
 * Second half is same values rotated by 4-bits.
6853
 */
6854
#if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU)
6855
static const byte R[16][2] = {
6856
    {0x00, 0x00}, {0x1c, 0x20}, {0x38, 0x40}, {0x24, 0x60},
6857
    {0x70, 0x80}, {0x6c, 0xa0}, {0x48, 0xc0}, {0x54, 0xe0},
6858
    {0xe1, 0x00}, {0xfd, 0x20}, {0xd9, 0x40}, {0xc5, 0x60},
6859
    {0x91, 0x80}, {0x8d, 0xa0}, {0xa9, 0xc0}, {0xb5, 0xe0},
6860
};
6861
#else
6862
static const word16 R[32] = {
6863
          0x0000,       0x201c,       0x4038,       0x6024,
6864
          0x8070,       0xa06c,       0xc048,       0xe054,
6865
          0x00e1,       0x20fd,       0x40d9,       0x60c5,
6866
          0x8091,       0xa08d,       0xc0a9,       0xe0b5,
6867
6868
          0x0000,       0xc201,       0x8403,       0x4602,
6869
          0x0807,       0xca06,       0x8c04,       0x4e05,
6870
          0x100e,       0xd20f,       0x940d,       0x560c,
6871
          0x1809,       0xda08,       0x9c0a,       0x5e0b,
6872
};
6873
#endif
6874
6875
/* Multiply in GF(2^128) defined by polynomial:
6876
 *   x^128 + x^7 + x^2 + x^1 + 1.
6877
 *
6878
 * H: hash key = encrypt(key, 0)
6879
 * x = x * H in field
6880
 *
6881
 * x: cumulative result
6882
 * m: 4-bit table
6883
 *    [0..15] * H
6884
 */
6885
#if defined(BIG_ENDIAN_ORDER) || defined(WC_16BIT_CPU)
6886
static void GMULT(byte *x, byte m[16][AES_BLOCK_SIZE])
6887
{
6888
    int i, j, n;
6889
    byte Z[AES_BLOCK_SIZE];
6890
    byte a;
6891
6892
    XMEMSET(Z, 0, sizeof(Z));
6893
6894
    for (i = 15; i >= 0; i--) {
6895
        for (n = 0; n < 2; n++) {
6896
            if (n == 0)
6897
                xorbuf(Z, m[x[i] & 0xf], AES_BLOCK_SIZE);
6898
            else {
6899
                xorbuf(Z, m[x[i] >> 4], AES_BLOCK_SIZE);
6900
                if (i == 0)
6901
                    break;
6902
            }
6903
            a = Z[15] & 0xf;
6904
6905
            for (j = 15; j > 0; j--)
6906
                Z[j] = (Z[j-1] << 4) | (Z[j] >> 4);
6907
            Z[0] >>= 4;
6908
6909
            Z[0] ^= R[a][0];
6910
            Z[1] ^= R[a][1];
6911
        }
6912
    }
6913
6914
    XMEMCPY(x, Z, AES_BLOCK_SIZE);
6915
}
6916
#elif defined(WC_32BIT_CPU)
6917
static WC_INLINE void GMULT(byte *x, byte m[32][AES_BLOCK_SIZE])
6918
{
6919
    int i;
6920
    word32 z8[4] = {0, 0, 0, 0};
6921
    byte a;
6922
    word32* x8 = (word32*)x;
6923
    word32* m8;
6924
    byte xi;
6925
    word32 n7, n6, n5, n4, n3, n2, n1, n0;
6926
6927
    for (i = 15; i > 0; i--) {
6928
        xi = x[i];
6929
6930
        /* XOR in (msn * H) */
6931
        m8 = (word32*)m[xi & 0xf];
6932
        z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
6933
6934
        /* Cache top byte for remainder calculations - lost in rotate. */
6935
        a = (byte)(z8[3] >> 24);
6936
6937
        /* Rotate Z by 8-bits */
6938
        z8[3] = (z8[2] >> 24) | (z8[3] << 8);
6939
        z8[2] = (z8[1] >> 24) | (z8[2] << 8);
6940
        z8[1] = (z8[0] >> 24) | (z8[1] << 8);
6941
        z8[0] <<= 8;
6942
6943
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
6944
        z8[0] ^= (word32)R[16 + (a & 0xf)];
6945
6946
        xi >>= 4;
6947
        /* XOR in next significant nibble (XORed with H) * remainder */
6948
        m8 = (word32*)m[xi];
6949
        a ^= (byte)(m8[3] >> 20);
6950
        z8[0] ^= (word32)R[a >> 4];
6951
6952
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
6953
        m8 = (word32*)m[16 + xi];
6954
        z8[0] ^= m8[0]; z8[1] ^= m8[1];
6955
        z8[2] ^= m8[2]; z8[3] ^= m8[3];
6956
    }
6957
6958
    xi = x[0];
6959
6960
    /* XOR in most significant nibble * H */
6961
    m8 = (word32*)m[xi & 0xf];
6962
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
6963
6964
    /* Cache top byte for remainder calculations - lost in rotate. */
6965
    a = (z8[3] >> 24) & 0xf;
6966
6967
    /* Rotate z by 4-bits */
6968
    n7 = z8[3] & 0xf0f0f0f0ULL;
6969
    n6 = z8[3] & 0x0f0f0f0fULL;
6970
    n5 = z8[2] & 0xf0f0f0f0ULL;
6971
    n4 = z8[2] & 0x0f0f0f0fULL;
6972
    n3 = z8[1] & 0xf0f0f0f0ULL;
6973
    n2 = z8[1] & 0x0f0f0f0fULL;
6974
    n1 = z8[0] & 0xf0f0f0f0ULL;
6975
    n0 = z8[0] & 0x0f0f0f0fULL;
6976
    z8[3] = (n7 >> 4) | (n6 << 12) | (n4 >> 20);
6977
    z8[2] = (n5 >> 4) | (n4 << 12) | (n2 >> 20);
6978
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 20);
6979
    z8[0] = (n1 >> 4) | (n0 << 12);
6980
6981
    /* XOR in most significant nibble * remainder */
6982
    z8[0] ^= (word32)R[a];
6983
    /* XOR in next significant nibble * H */
6984
    m8 = (word32*)m[xi >> 4];
6985
    z8[0] ^= m8[0]; z8[1] ^= m8[1]; z8[2] ^= m8[2]; z8[3] ^= m8[3];
6986
6987
    /* Write back result. */
6988
    x8[0] = z8[0]; x8[1] = z8[1]; x8[2] = z8[2]; x8[3] = z8[3];
6989
}
6990
#else
6991
static WC_INLINE void GMULT(byte *x, byte m[32][AES_BLOCK_SIZE])
6992
0
{
6993
0
    int i;
6994
0
    word64 z8[2] = {0, 0};
6995
0
    byte a;
6996
0
    word64* x8 = (word64*)x;
6997
0
    word64* m8;
6998
0
    word64 n0, n1, n2, n3;
6999
0
    byte xi;
7000
7001
0
    for (i = 15; i > 0; i--) {
7002
0
        xi = x[i];
7003
7004
        /* XOR in (msn * H) */
7005
0
        m8 = (word64*)m[xi & 0xf];
7006
0
        z8[0] ^= m8[0];
7007
0
        z8[1] ^= m8[1];
7008
7009
        /* Cache top byte for remainder calculations - lost in rotate. */
7010
0
        a = (byte)(z8[1] >> 56);
7011
7012
        /* Rotate Z by 8-bits */
7013
0
        z8[1] = (z8[0] >> 56) | (z8[1] << 8);
7014
0
        z8[0] <<= 8;
7015
7016
        /* XOR in (next significant nibble * H) [pre-rotated by 4 bits] */
7017
0
        m8 = (word64*)m[16 + (xi >> 4)];
7018
0
        z8[0] ^= m8[0];
7019
0
        z8[1] ^= m8[1];
7020
7021
        /* XOR in (msn * remainder) [pre-rotated by 4 bits] */
7022
0
        z8[0] ^= (word64)R[16 + (a & 0xf)];
7023
        /* XOR in next significant nibble (XORed with H) * remainder */
7024
0
        m8 = (word64*)m[xi >> 4];
7025
0
        a ^= (byte)(m8[1] >> 52);
7026
0
        z8[0] ^= (word64)R[a >> 4];
7027
0
    }
7028
7029
0
    xi = x[0];
7030
7031
    /* XOR in most significant nibble * H */
7032
0
    m8 = (word64*)m[xi & 0xf];
7033
0
    z8[0] ^= m8[0];
7034
0
    z8[1] ^= m8[1];
7035
7036
    /* Cache top byte for remainder calculations - lost in rotate. */
7037
0
    a = (z8[1] >> 56) & 0xf;
7038
7039
    /* Rotate z by 4-bits */
7040
0
    n3 = z8[1] & W64LIT(0xf0f0f0f0f0f0f0f0);
7041
0
    n2 = z8[1] & W64LIT(0x0f0f0f0f0f0f0f0f);
7042
0
    n1 = z8[0] & W64LIT(0xf0f0f0f0f0f0f0f0);
7043
0
    n0 = z8[0] & W64LIT(0x0f0f0f0f0f0f0f0f);
7044
0
    z8[1] = (n3 >> 4) | (n2 << 12) | (n0 >> 52);
7045
0
    z8[0] = (n1 >> 4) | (n0 << 12);
7046
7047
    /* XOR in next significant nibble * H */
7048
0
    m8 = (word64*)m[xi >> 4];
7049
0
    z8[0] ^= m8[0];
7050
0
    z8[1] ^= m8[1];
7051
    /* XOR in most significant nibble * remainder */
7052
0
    z8[0] ^= (word64)R[a];
7053
7054
    /* Write back result. */
7055
0
    x8[0] = z8[0];
7056
0
    x8[1] = z8[1];
7057
0
}
7058
#endif
7059
7060
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7061
    word32 cSz, byte* s, word32 sSz)
7062
0
{
7063
0
    byte x[AES_BLOCK_SIZE];
7064
0
    byte scratch[AES_BLOCK_SIZE];
7065
0
    word32 blocks, partial;
7066
7067
0
    if (gcm == NULL) {
7068
0
        return;
7069
0
    }
7070
7071
0
    XMEMSET(x, 0, AES_BLOCK_SIZE);
7072
7073
    /* Hash in A, the Additional Authentication Data */
7074
0
    if (aSz != 0 && a != NULL) {
7075
0
        blocks = aSz / AES_BLOCK_SIZE;
7076
0
        partial = aSz % AES_BLOCK_SIZE;
7077
0
        while (blocks--) {
7078
0
            xorbuf(x, a, AES_BLOCK_SIZE);
7079
0
            GMULT(x, gcm->M0);
7080
0
            a += AES_BLOCK_SIZE;
7081
0
        }
7082
0
        if (partial != 0) {
7083
0
            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
7084
0
            XMEMCPY(scratch, a, partial);
7085
0
            xorbuf(x, scratch, AES_BLOCK_SIZE);
7086
0
            GMULT(x, gcm->M0);
7087
0
        }
7088
0
    }
7089
7090
    /* Hash in C, the Ciphertext */
7091
0
    if (cSz != 0 && c != NULL) {
7092
0
        blocks = cSz / AES_BLOCK_SIZE;
7093
0
        partial = cSz % AES_BLOCK_SIZE;
7094
0
        while (blocks--) {
7095
0
            xorbuf(x, c, AES_BLOCK_SIZE);
7096
0
            GMULT(x, gcm->M0);
7097
0
            c += AES_BLOCK_SIZE;
7098
0
        }
7099
0
        if (partial != 0) {
7100
0
            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
7101
0
            XMEMCPY(scratch, c, partial);
7102
0
            xorbuf(x, scratch, AES_BLOCK_SIZE);
7103
0
            GMULT(x, gcm->M0);
7104
0
        }
7105
0
    }
7106
7107
    /* Hash in the lengths of A and C in bits */
7108
0
    FlattenSzInBits(&scratch[0], aSz);
7109
0
    FlattenSzInBits(&scratch[8], cSz);
7110
0
    xorbuf(x, scratch, AES_BLOCK_SIZE);
7111
0
    GMULT(x, gcm->M0);
7112
7113
    /* Copy the result into s. */
7114
0
    XMEMCPY(s, x, sSz);
7115
0
}
7116
7117
#ifdef WOLFSSL_AESGCM_STREAM
7118
/* No extra initialization for 4-bit table implementation.
7119
 *
7120
 * @param [in] aes  AES GCM object.
7121
 */
7122
0
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7123
7124
/* GHASH one block of data..
7125
 *
7126
 * XOR block into tag and GMULT with H using pre-computed table.
7127
 *
7128
 * @param [in, out] aes    AES GCM object.
7129
 * @param [in]      block  Block of AAD or cipher text.
7130
 */
7131
#define GHASH_ONE_BLOCK(aes, block)                     \
7132
0
    do {                                                \
7133
0
        xorbuf(AES_TAG(aes), block, AES_BLOCK_SIZE);    \
7134
0
        GMULT(AES_TAG(aes), (aes)->gcm.M0);             \
7135
0
    }                                                   \
7136
0
    while (0)
7137
#endif /* WOLFSSL_AESGCM_STREAM */
7138
#elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32)
7139
7140
#if !defined(FREESCALE_LTC_AES_GCM)
7141
static void GMULT(word64* X, word64* Y)
7142
{
7143
    word64 Z[2] = {0,0};
7144
    word64 V[2];
7145
    int i, j;
7146
    word64 v1;
7147
    V[0] = X[0];  V[1] = X[1];
7148
7149
    for (i = 0; i < 2; i++)
7150
    {
7151
        word64 y = Y[i];
7152
        for (j = 0; j < 64; j++)
7153
        {
7154
#ifndef AES_GCM_GMULT_NCT
7155
            word64 mask = 0 - (y >> 63);
7156
            Z[0] ^= V[0] & mask;
7157
            Z[1] ^= V[1] & mask;
7158
#else
7159
            if (y & 0x8000000000000000ULL) {
7160
                Z[0] ^= V[0];
7161
                Z[1] ^= V[1];
7162
            }
7163
#endif
7164
7165
            v1 = (0 - (V[1] & 1)) & 0xE100000000000000ULL;
7166
            V[1] >>= 1;
7167
            V[1] |= V[0] << 63;
7168
            V[0] >>= 1;
7169
            V[0] ^= v1;
7170
            y <<= 1;
7171
        }
7172
    }
7173
    X[0] = Z[0];
7174
    X[1] = Z[1];
7175
}
7176
7177
7178
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7179
    word32 cSz, byte* s, word32 sSz)
7180
{
7181
    word64 x[2] = {0,0};
7182
    word32 blocks, partial;
7183
    word64 bigH[2];
7184
7185
    if (gcm == NULL) {
7186
        return;
7187
    }
7188
7189
    XMEMCPY(bigH, gcm->H, AES_BLOCK_SIZE);
7190
    #ifdef LITTLE_ENDIAN_ORDER
7191
        ByteReverseWords64(bigH, bigH, AES_BLOCK_SIZE);
7192
    #endif
7193
7194
    /* Hash in A, the Additional Authentication Data */
7195
    if (aSz != 0 && a != NULL) {
7196
        word64 bigA[2];
7197
        blocks = aSz / AES_BLOCK_SIZE;
7198
        partial = aSz % AES_BLOCK_SIZE;
7199
        while (blocks--) {
7200
            XMEMCPY(bigA, a, AES_BLOCK_SIZE);
7201
            #ifdef LITTLE_ENDIAN_ORDER
7202
                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
7203
            #endif
7204
            x[0] ^= bigA[0];
7205
            x[1] ^= bigA[1];
7206
            GMULT(x, bigH);
7207
            a += AES_BLOCK_SIZE;
7208
        }
7209
        if (partial != 0) {
7210
            XMEMSET(bigA, 0, AES_BLOCK_SIZE);
7211
            XMEMCPY(bigA, a, partial);
7212
            #ifdef LITTLE_ENDIAN_ORDER
7213
                ByteReverseWords64(bigA, bigA, AES_BLOCK_SIZE);
7214
            #endif
7215
            x[0] ^= bigA[0];
7216
            x[1] ^= bigA[1];
7217
            GMULT(x, bigH);
7218
        }
7219
#ifdef OPENSSL_EXTRA
7220
        /* store AAD partial tag for next call */
7221
        gcm->aadH[0] = (word32)((x[0] & 0xFFFFFFFF00000000ULL) >> 32);
7222
        gcm->aadH[1] = (word32)(x[0] & 0xFFFFFFFF);
7223
        gcm->aadH[2] = (word32)((x[1] & 0xFFFFFFFF00000000ULL) >> 32);
7224
        gcm->aadH[3] = (word32)(x[1] & 0xFFFFFFFF);
7225
#endif
7226
    }
7227
7228
    /* Hash in C, the Ciphertext */
7229
    if (cSz != 0 && c != NULL) {
7230
        word64 bigC[2];
7231
        blocks = cSz / AES_BLOCK_SIZE;
7232
        partial = cSz % AES_BLOCK_SIZE;
7233
#ifdef OPENSSL_EXTRA
7234
        /* Start from last AAD partial tag */
7235
        if(gcm->aadLen) {
7236
            x[0] = ((word64)gcm->aadH[0]) << 32 | gcm->aadH[1];
7237
            x[1] = ((word64)gcm->aadH[2]) << 32 | gcm->aadH[3];
7238
         }
7239
#endif
7240
        while (blocks--) {
7241
            XMEMCPY(bigC, c, AES_BLOCK_SIZE);
7242
            #ifdef LITTLE_ENDIAN_ORDER
7243
                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
7244
            #endif
7245
            x[0] ^= bigC[0];
7246
            x[1] ^= bigC[1];
7247
            GMULT(x, bigH);
7248
            c += AES_BLOCK_SIZE;
7249
        }
7250
        if (partial != 0) {
7251
            XMEMSET(bigC, 0, AES_BLOCK_SIZE);
7252
            XMEMCPY(bigC, c, partial);
7253
            #ifdef LITTLE_ENDIAN_ORDER
7254
                ByteReverseWords64(bigC, bigC, AES_BLOCK_SIZE);
7255
            #endif
7256
            x[0] ^= bigC[0];
7257
            x[1] ^= bigC[1];
7258
            GMULT(x, bigH);
7259
        }
7260
    }
7261
7262
    /* Hash in the lengths in bits of A and C */
7263
    {
7264
        word64 len[2];
7265
        len[0] = aSz; len[1] = cSz;
7266
#ifdef OPENSSL_EXTRA
7267
        if (gcm->aadLen)
7268
            len[0] = (word64)gcm->aadLen;
7269
#endif
7270
        /* Lengths are in bytes. Convert to bits. */
7271
        len[0] *= 8;
7272
        len[1] *= 8;
7273
7274
        x[0] ^= len[0];
7275
        x[1] ^= len[1];
7276
        GMULT(x, bigH);
7277
    }
7278
    #ifdef LITTLE_ENDIAN_ORDER
7279
        ByteReverseWords64(x, x, AES_BLOCK_SIZE);
7280
    #endif
7281
    XMEMCPY(s, x, sSz);
7282
}
7283
#endif /* !FREESCALE_LTC_AES_GCM */
7284
7285
#ifdef WOLFSSL_AESGCM_STREAM
7286
7287
#ifdef LITTLE_ENDIAN_ORDER
7288
7289
/* No extra initialization for small implementation.
7290
 *
7291
 * @param [in] aes  AES GCM object.
7292
 */
7293
#define GHASH_INIT_EXTRA(aes)                                               \
7294
    ByteReverseWords64((word64*)aes->gcm.H, (word64*)aes->gcm.H, AES_BLOCK_SIZE)
7295
7296
/* GHASH one block of data..
7297
 *
7298
 * XOR block into tag and GMULT with H.
7299
 *
7300
 * @param [in, out] aes    AES GCM object.
7301
 * @param [in]      block  Block of AAD or cipher text.
7302
 */
7303
#define GHASH_ONE_BLOCK(aes, block)                             \
7304
    do {                                                        \
7305
        word64* x = (word64*)AES_TAG(aes);                      \
7306
        word64* h = (word64*)aes->gcm.H;                        \
7307
        word64 block64[2];                                      \
7308
        XMEMCPY(block64, block, AES_BLOCK_SIZE);                \
7309
        ByteReverseWords64(block64, block64, AES_BLOCK_SIZE);   \
7310
        x[0] ^= block64[0];                                     \
7311
        x[1] ^= block64[1];                                     \
7312
        GMULT(x, h);                                            \
7313
    }                                                           \
7314
    while (0)
7315
7316
#ifdef OPENSSL_EXTRA
7317
/* GHASH in AAD and cipher text lengths in bits.
7318
 *
7319
 * Convert tag back to little-endian.
7320
 *
7321
 * @param [in, out] aes  AES GCM object.
7322
 */
7323
#define GHASH_LEN_BLOCK(aes)                            \
7324
    do {                                                \
7325
        word64* x = (word64*)AES_TAG(aes);              \
7326
        word64* h = (word64*)aes->gcm.H;                \
7327
        word64 len[2];                                  \
7328
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7329
        if (aes->gcm.aadLen)                            \
7330
            len[0] = (word64)aes->gcm.aadLen;           \
7331
        /* Lengths are in bytes. Convert to bits. */    \
7332
        len[0] *= 8;                                    \
7333
        len[1] *= 8;                                    \
7334
                                                        \
7335
        x[0] ^= len[0];                                 \
7336
        x[1] ^= len[1];                                 \
7337
        GMULT(x, h);                                    \
7338
        ByteReverseWords64(x, x, AES_BLOCK_SIZE);       \
7339
    }                                                   \
7340
    while (0)
7341
#else
7342
/* GHASH in AAD and cipher text lengths in bits.
7343
 *
7344
 * Convert tag back to little-endian.
7345
 *
7346
 * @param [in, out] aes  AES GCM object.
7347
 */
7348
#define GHASH_LEN_BLOCK(aes)                            \
7349
    do {                                                \
7350
        word64* x = (word64*)AES_TAG(aes);              \
7351
        word64* h = (word64*)aes->gcm.H;                \
7352
        word64 len[2];                                  \
7353
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7354
        /* Lengths are in bytes. Convert to bits. */    \
7355
        len[0] *= 8;                                    \
7356
        len[1] *= 8;                                    \
7357
                                                        \
7358
        x[0] ^= len[0];                                 \
7359
        x[1] ^= len[1];                                 \
7360
        GMULT(x, h);                                    \
7361
        ByteReverseWords64(x, x, AES_BLOCK_SIZE);       \
7362
    }                                                   \
7363
    while (0)
7364
#endif
7365
7366
#else
7367
7368
/* No extra initialization for small implementation.
7369
 *
7370
 * @param [in] aes  AES GCM object.
7371
 */
7372
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7373
7374
/* GHASH one block of data..
7375
 *
7376
 * XOR block into tag and GMULT with H.
7377
 *
7378
 * @param [in, out] aes    AES GCM object.
7379
 * @param [in]      block  Block of AAD or cipher text.
7380
 */
7381
#define GHASH_ONE_BLOCK(aes, block)                     \
7382
    do {                                                \
7383
        word64* x = (word64*)AES_TAG(aes);              \
7384
        word64* h = (word64*)aes->gcm.H;                \
7385
        word64 block64[2];                              \
7386
        XMEMCPY(block64, block, AES_BLOCK_SIZE);        \
7387
        x[0] ^= block64[0];                             \
7388
        x[1] ^= block64[1];                             \
7389
        GMULT(x, h);                                    \
7390
    }                                                   \
7391
    while (0)
7392
7393
#ifdef OPENSSL_EXTRA
7394
/* GHASH in AAD and cipher text lengths in bits.
7395
 *
7396
 * Convert tag back to little-endian.
7397
 *
7398
 * @param [in, out] aes  AES GCM object.
7399
 */
7400
#define GHASH_LEN_BLOCK(aes)                            \
7401
    do {                                                \
7402
        word64* x = (word64*)AES_TAG(aes);              \
7403
        word64* h = (word64*)aes->gcm.H;                \
7404
        word64 len[2];                                  \
7405
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7406
        if (aes->gcm.aadLen)                            \
7407
            len[0] = (word64)aes->gcm.aadLen;           \
7408
        /* Lengths are in bytes. Convert to bits. */    \
7409
        len[0] *= 8;                                    \
7410
        len[1] *= 8;                                    \
7411
                                                        \
7412
        x[0] ^= len[0];                                 \
7413
        x[1] ^= len[1];                                 \
7414
        GMULT(x, h);                                    \
7415
    }                                                   \
7416
    while (0)
7417
#else
7418
/* GHASH in AAD and cipher text lengths in bits.
7419
 *
7420
 * Convert tag back to little-endian.
7421
 *
7422
 * @param [in, out] aes  AES GCM object.
7423
 */
7424
#define GHASH_LEN_BLOCK(aes)                            \
7425
    do {                                                \
7426
        word64* x = (word64*)AES_TAG(aes);              \
7427
        word64* h = (word64*)aes->gcm.H;                \
7428
        word64 len[2];                                  \
7429
        len[0] = aes->aSz; len[1] = aes->cSz;           \
7430
        /* Lengths are in bytes. Convert to bits. */    \
7431
        len[0] *= 8;                                    \
7432
        len[1] *= 8;                                    \
7433
                                                        \
7434
        x[0] ^= len[0];                                 \
7435
        x[1] ^= len[1];                                 \
7436
        GMULT(x, h);                                    \
7437
    }                                                   \
7438
    while (0)
7439
#endif
7440
7441
#endif /* !LITTLE_ENDIAN_ORDER */
7442
7443
#endif /* WOLFSSL_AESGCM_STREAM */
7444
/* end defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) */
7445
#else /* GCM_WORD32 */
7446
7447
static void GMULT(word32* X, word32* Y)
7448
{
7449
    word32 Z[4] = {0,0,0,0};
7450
    word32 V[4];
7451
    int i, j;
7452
7453
    V[0] = X[0];  V[1] = X[1]; V[2] =  X[2]; V[3] =  X[3];
7454
7455
    for (i = 0; i < 4; i++)
7456
    {
7457
        word32 y = Y[i];
7458
        for (j = 0; j < 32; j++)
7459
        {
7460
            if (y & 0x80000000) {
7461
                Z[0] ^= V[0];
7462
                Z[1] ^= V[1];
7463
                Z[2] ^= V[2];
7464
                Z[3] ^= V[3];
7465
            }
7466
7467
            if (V[3] & 0x00000001) {
7468
                V[3] >>= 1;
7469
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
7470
                V[2] >>= 1;
7471
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
7472
                V[1] >>= 1;
7473
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
7474
                V[0] >>= 1;
7475
                V[0] ^= 0xE1000000;
7476
            } else {
7477
                V[3] >>= 1;
7478
                V[3] |= ((V[2] & 0x00000001) ? 0x80000000 : 0);
7479
                V[2] >>= 1;
7480
                V[2] |= ((V[1] & 0x00000001) ? 0x80000000 : 0);
7481
                V[1] >>= 1;
7482
                V[1] |= ((V[0] & 0x00000001) ? 0x80000000 : 0);
7483
                V[0] >>= 1;
7484
            }
7485
            y <<= 1;
7486
        }
7487
    }
7488
    X[0] = Z[0];
7489
    X[1] = Z[1];
7490
    X[2] = Z[2];
7491
    X[3] = Z[3];
7492
}
7493
7494
7495
void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c,
7496
    word32 cSz, byte* s, word32 sSz)
7497
{
7498
    word32 x[4] = {0,0,0,0};
7499
    word32 blocks, partial;
7500
    word32 bigH[4];
7501
7502
    if (gcm == NULL) {
7503
        return;
7504
    }
7505
7506
    XMEMCPY(bigH, gcm->H, AES_BLOCK_SIZE);
7507
    #ifdef LITTLE_ENDIAN_ORDER
7508
        ByteReverseWords(bigH, bigH, AES_BLOCK_SIZE);
7509
    #endif
7510
7511
    /* Hash in A, the Additional Authentication Data */
7512
    if (aSz != 0 && a != NULL) {
7513
        word32 bigA[4];
7514
        blocks = aSz / AES_BLOCK_SIZE;
7515
        partial = aSz % AES_BLOCK_SIZE;
7516
        while (blocks--) {
7517
            XMEMCPY(bigA, a, AES_BLOCK_SIZE);
7518
            #ifdef LITTLE_ENDIAN_ORDER
7519
                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
7520
            #endif
7521
            x[0] ^= bigA[0];
7522
            x[1] ^= bigA[1];
7523
            x[2] ^= bigA[2];
7524
            x[3] ^= bigA[3];
7525
            GMULT(x, bigH);
7526
            a += AES_BLOCK_SIZE;
7527
        }
7528
        if (partial != 0) {
7529
            XMEMSET(bigA, 0, AES_BLOCK_SIZE);
7530
            XMEMCPY(bigA, a, partial);
7531
            #ifdef LITTLE_ENDIAN_ORDER
7532
                ByteReverseWords(bigA, bigA, AES_BLOCK_SIZE);
7533
            #endif
7534
            x[0] ^= bigA[0];
7535
            x[1] ^= bigA[1];
7536
            x[2] ^= bigA[2];
7537
            x[3] ^= bigA[3];
7538
            GMULT(x, bigH);
7539
        }
7540
    }
7541
7542
    /* Hash in C, the Ciphertext */
7543
    if (cSz != 0 && c != NULL) {
7544
        word32 bigC[4];
7545
        blocks = cSz / AES_BLOCK_SIZE;
7546
        partial = cSz % AES_BLOCK_SIZE;
7547
        while (blocks--) {
7548
            XMEMCPY(bigC, c, AES_BLOCK_SIZE);
7549
            #ifdef LITTLE_ENDIAN_ORDER
7550
                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
7551
            #endif
7552
            x[0] ^= bigC[0];
7553
            x[1] ^= bigC[1];
7554
            x[2] ^= bigC[2];
7555
            x[3] ^= bigC[3];
7556
            GMULT(x, bigH);
7557
            c += AES_BLOCK_SIZE;
7558
        }
7559
        if (partial != 0) {
7560
            XMEMSET(bigC, 0, AES_BLOCK_SIZE);
7561
            XMEMCPY(bigC, c, partial);
7562
            #ifdef LITTLE_ENDIAN_ORDER
7563
                ByteReverseWords(bigC, bigC, AES_BLOCK_SIZE);
7564
            #endif
7565
            x[0] ^= bigC[0];
7566
            x[1] ^= bigC[1];
7567
            x[2] ^= bigC[2];
7568
            x[3] ^= bigC[3];
7569
            GMULT(x, bigH);
7570
        }
7571
    }
7572
7573
    /* Hash in the lengths in bits of A and C */
7574
    {
7575
        word32 len[4];
7576
7577
        /* Lengths are in bytes. Convert to bits. */
7578
        len[0] = (aSz >> (8*sizeof(aSz) - 3));
7579
        len[1] = aSz << 3;
7580
        len[2] = (cSz >> (8*sizeof(cSz) - 3));
7581
        len[3] = cSz << 3;
7582
7583
        x[0] ^= len[0];
7584
        x[1] ^= len[1];
7585
        x[2] ^= len[2];
7586
        x[3] ^= len[3];
7587
        GMULT(x, bigH);
7588
    }
7589
    #ifdef LITTLE_ENDIAN_ORDER
7590
        ByteReverseWords(x, x, AES_BLOCK_SIZE);
7591
    #endif
7592
    XMEMCPY(s, x, sSz);
7593
}
7594
7595
#ifdef WOLFSSL_AESGCM_STREAM
7596
#ifdef LITTLE_ENDIAN_ORDER
7597
/* Little-endian 32-bit word implementation requires byte reversal of H.
7598
 *
7599
 * H is all-zeros block encrypted with key.
7600
 *
7601
 * @param [in, out] aes  AES GCM object.
7602
 */
7603
#define GHASH_INIT_EXTRA(aes) \
7604
    ByteReverseWords((word32*)aes->gcm.H, (word32*)aes->gcm.H, AES_BLOCK_SIZE)
7605
7606
/* GHASH one block of data..
7607
 *
7608
 * XOR block, in big-endian form, into tag and GMULT with H.
7609
 *
7610
 * @param [in, out] aes    AES GCM object.
7611
 * @param [in]      block  Block of AAD or cipher text.
7612
 */
7613
#define GHASH_ONE_BLOCK(aes, block)                         \
7614
    do {                                                    \
7615
        word32* x = (word32*)AES_TAG(aes);                  \
7616
        word32* h = (word32*)aes->gcm.H;                    \
7617
        word32 bigEnd[4];                                   \
7618
        XMEMCPY(bigEnd, block, AES_BLOCK_SIZE);             \
7619
        ByteReverseWords(bigEnd, bigEnd, AES_BLOCK_SIZE);   \
7620
        x[0] ^= bigEnd[0];                                  \
7621
        x[1] ^= bigEnd[1];                                  \
7622
        x[2] ^= bigEnd[2];                                  \
7623
        x[3] ^= bigEnd[3];                                  \
7624
        GMULT(x, h);                                        \
7625
    }                                                       \
7626
    while (0)
7627
7628
/* GHASH in AAD and cipher text lengths in bits.
7629
 *
7630
 * Convert tag back to little-endian.
7631
 *
7632
 * @param [in, out] aes  AES GCM object.
7633
 */
7634
#define GHASH_LEN_BLOCK(aes)                                \
7635
    do {                                                    \
7636
        word32 len[4];                                      \
7637
        word32* x = (word32*)AES_TAG(aes);                  \
7638
        word32* h = (word32*)aes->gcm.H;                    \
7639
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
7640
        len[1] = aes->aSz << 3;                             \
7641
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
7642
        len[3] = aes->cSz << 3;                             \
7643
        x[0] ^= len[0];                                     \
7644
        x[1] ^= len[1];                                     \
7645
        x[2] ^= len[2];                                     \
7646
        x[3] ^= len[3];                                     \
7647
        GMULT(x, h);                                        \
7648
        ByteReverseWords(x, x, AES_BLOCK_SIZE);             \
7649
    }                                                       \
7650
    while (0)
7651
#else
7652
/* No extra initialization for 32-bit word implementation.
7653
 *
7654
 * @param [in] aes  AES GCM object.
7655
 */
7656
#define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING
7657
7658
/* GHASH one block of data..
7659
 *
7660
 * XOR block into tag and GMULT with H.
7661
 *
7662
 * @param [in, out] aes    AES GCM object.
7663
 * @param [in]      block  Block of AAD or cipher text.
7664
 */
7665
#define GHASH_ONE_BLOCK(aes, block)                         \
7666
    do {                                                    \
7667
        word32* x = (word32*)AES_TAG(aes);                  \
7668
        word32* h = (word32*)aes->gcm.H;                    \
7669
        word32 block32[4];                                  \
7670
        XMEMCPY(block32, block, AES_BLOCK_SIZE);            \
7671
        x[0] ^= block32[0];                                 \
7672
        x[1] ^= block32[1];                                 \
7673
        x[2] ^= block32[2];                                 \
7674
        x[3] ^= block32[3];                                 \
7675
        GMULT(x, h);                                        \
7676
    }                                                       \
7677
    while (0)
7678
7679
/* GHASH in AAD and cipher text lengths in bits.
7680
 *
7681
 * @param [in, out] aes  AES GCM object.
7682
 */
7683
#define GHASH_LEN_BLOCK(aes)                                \
7684
    do {                                                    \
7685
        word32 len[4];                                      \
7686
        word32* x = (word32*)AES_TAG(aes);                  \
7687
        word32* h = (word32*)aes->gcm.H;                    \
7688
        len[0] = (aes->aSz >> (8*sizeof(aes->aSz) - 3));    \
7689
        len[1] = aes->aSz << 3;                             \
7690
        len[2] = (aes->cSz >> (8*sizeof(aes->cSz) - 3));    \
7691
        len[3] = aes->cSz << 3;                             \
7692
        x[0] ^= len[0];                                     \
7693
        x[1] ^= len[1];                                     \
7694
        x[2] ^= len[2];                                     \
7695
        x[3] ^= len[3];                                     \
7696
        GMULT(x, h);                                        \
7697
    }                                                       \
7698
    while (0)
7699
#endif /* LITTLE_ENDIAN_ORDER */
7700
#endif /* WOLFSSL_AESGCM_STREAM */
7701
#endif /* end GCM_WORD32 */
7702
7703
#if !defined(WOLFSSL_XILINX_CRYPT) && !defined(WOLFSSL_AFALG_XILINX_AES)
7704
#ifdef WOLFSSL_AESGCM_STREAM
7705
#ifndef GHASH_LEN_BLOCK
7706
/* Hash in the lengths of the AAD and cipher text in bits.
7707
 *
7708
 * Default implementation.
7709
 *
7710
 * @param [in, out] aes  AES GCM object.
7711
 */
7712
#define GHASH_LEN_BLOCK(aes)                      \
7713
0
    do {                                          \
7714
0
        byte scratch[AES_BLOCK_SIZE];             \
7715
0
        FlattenSzInBits(&scratch[0], (aes)->aSz); \
7716
0
        FlattenSzInBits(&scratch[8], (aes)->cSz); \
7717
0
        GHASH_ONE_BLOCK(aes, scratch);            \
7718
0
    }                                             \
7719
0
    while (0)
7720
#endif
7721
7722
/* Initialize a GHASH for streaming operations.
7723
 *
7724
 * @param [in, out] aes  AES GCM object.
7725
 */
7726
0
static void GHASH_INIT(Aes* aes) {
7727
    /* Set tag to all zeros as initial value. */
7728
0
    XMEMSET(AES_TAG(aes), 0, AES_BLOCK_SIZE);
7729
    /* Reset counts of AAD and cipher text. */
7730
0
    aes->aOver = 0;
7731
0
    aes->cOver = 0;
7732
    /* Extra initialization based on implementation. */
7733
0
    GHASH_INIT_EXTRA(aes);
7734
0
}
7735
7736
/* Update the GHASH with AAD and/or cipher text.
7737
 *
7738
 * @param [in,out] aes   AES GCM object.
7739
 * @param [in]     a     Additional authentication data buffer.
7740
 * @param [in]     aSz   Size of data in AAD buffer.
7741
 * @param [in]     c     Cipher text buffer.
7742
 * @param [in]     cSz   Size of data in cipher text buffer.
7743
 */
7744
static void GHASH_UPDATE(Aes* aes, const byte* a, word32 aSz, const byte* c,
7745
    word32 cSz)
7746
0
{
7747
0
    word32 blocks;
7748
0
    word32 partial;
7749
7750
    /* Hash in A, the Additional Authentication Data */
7751
0
    if (aSz != 0 && a != NULL) {
7752
        /* Update count of AAD we have hashed. */
7753
0
        aes->aSz += aSz;
7754
        /* Check if we have unprocessed data. */
7755
0
        if (aes->aOver > 0) {
7756
            /* Calculate amount we can use - fill up the block. */
7757
0
            byte sz = AES_BLOCK_SIZE - aes->aOver;
7758
0
            if (sz > aSz) {
7759
0
                sz = (byte)aSz;
7760
0
            }
7761
            /* Copy extra into last GHASH block array and update count. */
7762
0
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
7763
0
            aes->aOver += sz;
7764
0
            if (aes->aOver == AES_BLOCK_SIZE) {
7765
                /* We have filled up the block and can process. */
7766
0
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
7767
                /* Reset count. */
7768
0
                aes->aOver = 0;
7769
0
            }
7770
            /* Used up some data. */
7771
0
            aSz -= sz;
7772
0
            a += sz;
7773
0
        }
7774
7775
        /* Calculate number of blocks of AAD and the leftover. */
7776
0
        blocks = aSz / AES_BLOCK_SIZE;
7777
0
        partial = aSz % AES_BLOCK_SIZE;
7778
        /* GHASH full blocks now. */
7779
0
        while (blocks--) {
7780
0
            GHASH_ONE_BLOCK(aes, a);
7781
0
            a += AES_BLOCK_SIZE;
7782
0
        }
7783
0
        if (partial != 0) {
7784
            /* Cache the partial block. */
7785
0
            XMEMCPY(AES_LASTGBLOCK(aes), a, partial);
7786
0
            aes->aOver = (byte)partial;
7787
0
        }
7788
0
    }
7789
0
    if (aes->aOver > 0 && cSz > 0 && c != NULL) {
7790
        /* No more AAD coming and we have a partial block. */
7791
        /* Fill the rest of the block with zeros. */
7792
0
        byte sz = AES_BLOCK_SIZE - aes->aOver;
7793
0
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0, sz);
7794
        /* GHASH last AAD block. */
7795
0
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
7796
        /* Clear partial count for next time through. */
7797
0
        aes->aOver = 0;
7798
0
    }
7799
7800
    /* Hash in C, the Ciphertext */
7801
0
    if (cSz != 0 && c != NULL) {
7802
        /* Update count of cipher text we have hashed. */
7803
0
        aes->cSz += cSz;
7804
0
        if (aes->cOver > 0) {
7805
            /* Calculate amount we can use - fill up the block. */
7806
0
            byte sz = AES_BLOCK_SIZE - aes->cOver;
7807
0
            if (sz > cSz) {
7808
0
                sz = (byte)cSz;
7809
0
            }
7810
0
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
7811
            /* Update count of unused encrypted counter. */
7812
0
            aes->cOver += sz;
7813
0
            if (aes->cOver == AES_BLOCK_SIZE) {
7814
                /* We have filled up the block and can process. */
7815
0
                GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
7816
                /* Reset count. */
7817
0
                aes->cOver = 0;
7818
0
            }
7819
            /* Used up some data. */
7820
0
            cSz -= sz;
7821
0
            c += sz;
7822
0
        }
7823
7824
        /* Calculate number of blocks of cipher text and the leftover. */
7825
0
        blocks = cSz / AES_BLOCK_SIZE;
7826
0
        partial = cSz % AES_BLOCK_SIZE;
7827
        /* GHASH full blocks now. */
7828
0
        while (blocks--) {
7829
0
            GHASH_ONE_BLOCK(aes, c);
7830
0
            c += AES_BLOCK_SIZE;
7831
0
        }
7832
0
        if (partial != 0) {
7833
            /* Cache the partial block. */
7834
0
            XMEMCPY(AES_LASTGBLOCK(aes), c, partial);
7835
0
            aes->cOver = (byte)partial;
7836
0
        }
7837
0
    }
7838
0
}
7839
7840
/* Finalize the GHASH calculation.
7841
 *
7842
 * Complete hashing cipher text and hash the AAD and cipher text lengths.
7843
 *
7844
 * @param [in, out] aes  AES GCM object.
7845
 * @param [out]     s    Authentication tag.
7846
 * @param [in]      sSz  Size of authentication tag required.
7847
 */
7848
static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz)
7849
0
{
7850
    /* AAD block incomplete when > 0 */
7851
0
    byte over = aes->aOver;
7852
7853
0
    if (aes->cOver > 0) {
7854
        /* Cipher text block incomplete. */
7855
0
        over = aes->cOver;
7856
0
    }
7857
0
    if (over > 0) {
7858
        /* Zeroize the unused part of the block. */
7859
0
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, AES_BLOCK_SIZE - over);
7860
        /* Hash the last block of cipher text. */
7861
0
        GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes));
7862
0
    }
7863
    /* Hash in the lengths of AAD and cipher text in bits */
7864
0
    GHASH_LEN_BLOCK(aes);
7865
    /* Copy the result into s. */
7866
0
    XMEMCPY(s, AES_TAG(aes), sSz);
7867
0
}
7868
#endif /* WOLFSSL_AESGCM_STREAM */
7869
7870
7871
#ifdef FREESCALE_LTC_AES_GCM
7872
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
7873
                   const byte* iv, word32 ivSz,
7874
                   byte* authTag, word32 authTagSz,
7875
                   const byte* authIn, word32 authInSz)
7876
{
7877
    status_t status;
7878
    word32 keySize;
7879
7880
    /* argument checks */
7881
    if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) {
7882
        return BAD_FUNC_ARG;
7883
    }
7884
7885
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
7886
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
7887
        return BAD_FUNC_ARG;
7888
    }
7889
7890
    status = wc_AesGetKeySize(aes, &keySize);
7891
    if (status)
7892
        return status;
7893
7894
    status = wolfSSL_CryptHwMutexLock();
7895
    if (status != 0)
7896
        return status;
7897
7898
    status = LTC_AES_EncryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
7899
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
7900
    wolfSSL_CryptHwMutexUnLock();
7901
7902
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
7903
}
7904
7905
#else
7906
7907
#ifdef STM32_CRYPTO_AES_GCM
7908
7909
/* this function supports inline encrypt */
7910
/* define STM32_AESGCM_PARTIAL for STM HW that does not support authentication
7911
 * on byte multiples (see CRYP_HEADERWIDTHUNIT_BYTE) */
7912
static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32(
7913
                                  Aes* aes, byte* out, const byte* in, word32 sz,
7914
                                  const byte* iv, word32 ivSz,
7915
                                  byte* authTag, word32 authTagSz,
7916
                                  const byte* authIn, word32 authInSz)
7917
{
7918
    int ret;
7919
#ifdef WOLFSSL_STM32_CUBEMX
7920
    CRYP_HandleTypeDef hcryp;
7921
#else
7922
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
7923
#endif
7924
    word32 keySize;
7925
#ifdef WOLFSSL_STM32_CUBEMX
7926
    int status = HAL_OK;
7927
    word32 blocks = sz / AES_BLOCK_SIZE;
7928
    word32 partialBlock[AES_BLOCK_SIZE/sizeof(word32)];
7929
#else
7930
    int status = SUCCESS;
7931
#endif
7932
    word32 partial = sz % AES_BLOCK_SIZE;
7933
    word32 tag[AES_BLOCK_SIZE/sizeof(word32)];
7934
    word32 ctrInit[AES_BLOCK_SIZE/sizeof(word32)];
7935
    word32 ctr[AES_BLOCK_SIZE/sizeof(word32)];
7936
    word32 authhdr[AES_BLOCK_SIZE/sizeof(word32)];
7937
    byte* authInPadded = NULL;
7938
    int authPadSz, wasAlloc = 0, useSwGhash = 0;
7939
7940
    ret = wc_AesGetKeySize(aes, &keySize);
7941
    if (ret != 0)
7942
        return ret;
7943
7944
#ifdef WOLFSSL_STM32_CUBEMX
7945
    ret = wc_Stm32_Aes_Init(aes, &hcryp);
7946
    if (ret != 0)
7947
        return ret;
7948
#endif
7949
7950
    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
7951
    if (ivSz == GCM_NONCE_MID_SZ) {
7952
        byte* pCtr = (byte*)ctr;
7953
        XMEMCPY(ctr, iv, ivSz);
7954
        pCtr[AES_BLOCK_SIZE - 1] = 1;
7955
    }
7956
    else {
7957
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE);
7958
    }
7959
    XMEMCPY(ctrInit, ctr, sizeof(ctr)); /* save off initial counter for GMAC */
7960
7961
    /* Authentication buffer - must be 4-byte multiple zero padded */
7962
    authPadSz = authInSz % sizeof(word32);
7963
    if (authPadSz != 0) {
7964
        authPadSz = authInSz + sizeof(word32) - authPadSz;
7965
        if (authPadSz <= sizeof(authhdr)) {
7966
            authInPadded = (byte*)authhdr;
7967
        }
7968
        else {
7969
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
7970
                DYNAMIC_TYPE_TMP_BUFFER);
7971
            if (authInPadded == NULL) {
7972
                wolfSSL_CryptHwMutexUnLock();
7973
                return MEMORY_E;
7974
            }
7975
            wasAlloc = 1;
7976
        }
7977
        XMEMSET(authInPadded, 0, authPadSz);
7978
        XMEMCPY(authInPadded, authIn, authInSz);
7979
    } else {
7980
        authPadSz = authInSz;
7981
        authInPadded = (byte*)authIn;
7982
    }
7983
7984
    /* for cases where hardware cannot be used for authTag calculate it */
7985
    /* if IV is not 12 calculate GHASH using software */
7986
    if (ivSz != GCM_NONCE_MID_SZ
7987
    #ifndef CRYP_HEADERWIDTHUNIT_BYTE
7988
        /* or hardware that does not support partial block */
7989
        || sz == 0 || partial != 0
7990
    #endif
7991
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE) && !defined(STM32_AESGCM_PARTIAL)
7992
        /* or authIn is not a multiple of 4  */
7993
        || authPadSz != authInSz
7994
    #endif
7995
    ) {
7996
        useSwGhash = 1;
7997
    }
7998
7999
    /* Hardware requires counter + 1 */
8000
    IncrementGcmCounter((byte*)ctr);
8001
8002
    ret = wolfSSL_CryptHwMutexLock();
8003
    if (ret != 0) {
8004
        return ret;
8005
    }
8006
#ifdef WOLFSSL_STM32_CUBEMX
8007
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8008
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
8009
8010
#if defined(STM32_HAL_V2)
8011
    hcryp.Init.Algorithm = CRYP_AES_GCM;
8012
    #ifdef CRYP_HEADERWIDTHUNIT_BYTE
8013
    /* V2 with CRYP_HEADERWIDTHUNIT_BYTE uses byte size for header */
8014
    hcryp.Init.HeaderSize = authInSz;
8015
    #else
8016
    hcryp.Init.HeaderSize = authPadSz/sizeof(word32);
8017
    #endif
8018
    #ifdef CRYP_KEYIVCONFIG_ONCE
8019
    /* allows repeated calls to HAL_CRYP_Encrypt */
8020
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
8021
    #endif
8022
    ByteReverseWords(ctr, ctr, AES_BLOCK_SIZE);
8023
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8024
    HAL_CRYP_Init(&hcryp);
8025
8026
    #ifndef CRYP_KEYIVCONFIG_ONCE
8027
    /* GCM payload phase - can handle partial blocks */
8028
    status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
8029
        (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
8030
    #else
8031
    /* GCM payload phase - blocks */
8032
    if (blocks) {
8033
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in,
8034
            (blocks * AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
8035
    }
8036
    /* GCM payload phase - partial remainder */
8037
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8038
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8039
        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
8040
        status = HAL_CRYP_Encrypt(&hcryp, (uint32_t*)partialBlock, partial,
8041
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
8042
        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
8043
    }
8044
    #endif
8045
    if (status == HAL_OK && !useSwGhash) {
8046
        /* Compute the authTag */
8047
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
8048
            STM32_HAL_TIMEOUT);
8049
    }
8050
#elif defined(STM32_CRYPTO_AES_ONLY)
8051
    /* Set the CRYP parameters */
8052
    hcryp.Init.HeaderSize = authPadSz;
8053
    if (authPadSz == 0)
8054
        hcryp.Init.Header = NULL; /* cannot pass pointer here when authIn == 0 */
8055
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
8056
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_ENCRYPT;
8057
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
8058
    HAL_CRYP_Init(&hcryp);
8059
8060
    /* GCM init phase */
8061
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
8062
    if (status == HAL_OK) {
8063
        /* GCM header phase */
8064
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
8065
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
8066
    }
8067
    if (status == HAL_OK) {
8068
        /* GCM payload phase - blocks */
8069
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
8070
        if (blocks) {
8071
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
8072
                (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
8073
        }
8074
    }
8075
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
8076
        /* GCM payload phase - partial remainder */
8077
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8078
        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
8079
        status = HAL_CRYPEx_AES_Auth(&hcryp, (uint8_t*)partialBlock, partial,
8080
                (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
8081
        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
8082
    }
8083
    if (status == HAL_OK && !useSwGhash) {
8084
        /* GCM final phase */
8085
        hcryp.Init.GCMCMACPhase  = CRYP_FINAL_PHASE;
8086
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
8087
    }
8088
#else
8089
    hcryp.Init.HeaderSize = authPadSz;
8090
    HAL_CRYP_Init(&hcryp);
8091
    if (blocks) {
8092
        /* GCM payload phase - blocks */
8093
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (byte*)in,
8094
            (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
8095
    }
8096
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8097
        /* GCM payload phase - partial remainder */
8098
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8099
        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
8100
        status = HAL_CRYPEx_AESGCM_Encrypt(&hcryp, (uint8_t*)partialBlock, partial,
8101
            (uint8_t*)partialBlock, STM32_HAL_TIMEOUT);
8102
        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
8103
    }
8104
    if (status == HAL_OK && !useSwGhash) {
8105
        /* Compute the authTag */
8106
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (uint8_t*)tag, STM32_HAL_TIMEOUT);
8107
    }
8108
#endif
8109
8110
    if (status != HAL_OK)
8111
        ret = AES_GCM_AUTH_E;
8112
    HAL_CRYP_DeInit(&hcryp);
8113
8114
#else /* Standard Peripheral Library */
8115
    ByteReverseWords(keyCopy, (word32*)aes->key, keySize);
8116
    status = CRYP_AES_GCM(MODE_ENCRYPT, (uint8_t*)ctr,
8117
                         (uint8_t*)keyCopy,      keySize * 8,
8118
                         (uint8_t*)in,           sz,
8119
                         (uint8_t*)authInPadded, authInSz,
8120
                         (uint8_t*)out,          (uint8_t*)tag);
8121
    if (status != SUCCESS)
8122
        ret = AES_GCM_AUTH_E;
8123
#endif /* WOLFSSL_STM32_CUBEMX */
8124
    wolfSSL_CryptHwMutexUnLock();
8125
    wc_Stm32_Aes_Cleanup();
8126
8127
    if (ret == 0) {
8128
        /* return authTag */
8129
        if (authTag) {
8130
            if (useSwGhash) {
8131
                GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
8132
                ret = wc_AesEncrypt(aes, (byte*)ctrInit, (byte*)tag);
8133
                if (ret == 0) {
8134
                    xorbuf(authTag, tag, authTagSz);
8135
                }
8136
            }
8137
            else {
8138
                /* use hardware calculated tag */
8139
                XMEMCPY(authTag, tag, authTagSz);
8140
            }
8141
        }
8142
    }
8143
8144
    /* Free memory */
8145
    if (wasAlloc) {
8146
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
8147
    }
8148
8149
    return ret;
8150
}
8151
8152
#endif /* STM32_CRYPTO_AES_GCM */
8153
8154
#ifdef WOLFSSL_AESNI
8155
/* For performance reasons, this code needs to be not inlined. */
8156
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
8157
                      Aes* aes, byte* out, const byte* in, word32 sz,
8158
                      const byte* iv, word32 ivSz,
8159
                      byte* authTag, word32 authTagSz,
8160
                      const byte* authIn, word32 authInSz);
8161
#else
8162
static
8163
#endif
8164
WARN_UNUSED_RESULT int AES_GCM_encrypt_C(
8165
                      Aes* aes, byte* out, const byte* in, word32 sz,
8166
                      const byte* iv, word32 ivSz,
8167
                      byte* authTag, word32 authTagSz,
8168
                      const byte* authIn, word32 authInSz)
8169
0
{
8170
0
    int ret = 0;
8171
0
    word32 blocks = sz / AES_BLOCK_SIZE;
8172
0
    word32 partial = sz % AES_BLOCK_SIZE;
8173
0
    const byte* p = in;
8174
0
    byte* c = out;
8175
0
    ALIGN16 byte counter[AES_BLOCK_SIZE];
8176
0
    ALIGN16 byte initialCounter[AES_BLOCK_SIZE];
8177
0
    ALIGN16 byte scratch[AES_BLOCK_SIZE];
8178
8179
0
    if (ivSz == GCM_NONCE_MID_SZ) {
8180
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
8181
0
        XMEMCPY(counter, iv, ivSz);
8182
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
8183
0
                                         AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
8184
0
        counter[AES_BLOCK_SIZE - 1] = 1;
8185
0
    }
8186
0
    else {
8187
        /* Counter is GHASH of IV. */
8188
#ifdef OPENSSL_EXTRA
8189
        word32 aadTemp = aes->gcm.aadLen;
8190
        aes->gcm.aadLen = 0;
8191
#endif
8192
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE);
8193
#ifdef OPENSSL_EXTRA
8194
        aes->gcm.aadLen = aadTemp;
8195
#endif
8196
0
    }
8197
0
    XMEMCPY(initialCounter, counter, AES_BLOCK_SIZE);
8198
8199
#ifdef WOLFSSL_PIC32MZ_CRYPT
8200
    if (blocks) {
8201
        /* use initial IV for HW, but don't use it below */
8202
        XMEMCPY(aes->reg, counter, AES_BLOCK_SIZE);
8203
8204
        ret = wc_Pic32AesCrypt(
8205
            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
8206
            out, in, (blocks * AES_BLOCK_SIZE),
8207
            PIC32_ENCRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
8208
        if (ret != 0)
8209
            return ret;
8210
    }
8211
    /* process remainder using partial handling */
8212
#endif
8213
8214
0
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
8215
    /* some hardware acceleration can gain performance from doing AES encryption
8216
     * of the whole buffer at once */
8217
0
    if (c != p && blocks > 0) { /* can not handle inline encryption */
8218
0
        while (blocks--) {
8219
0
            IncrementGcmCounter(counter);
8220
0
            XMEMCPY(c, counter, AES_BLOCK_SIZE);
8221
0
            c += AES_BLOCK_SIZE;
8222
0
        }
8223
8224
        /* reset number of blocks and then do encryption */
8225
0
        blocks = sz / AES_BLOCK_SIZE;
8226
0
        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
8227
0
        xorbuf(out, p, AES_BLOCK_SIZE * blocks);
8228
0
        p += AES_BLOCK_SIZE * blocks;
8229
0
    }
8230
0
    else
8231
0
#endif /* HAVE_AES_ECB && !WOLFSSL_PIC32MZ_CRYPT */
8232
0
    {
8233
0
        while (blocks--) {
8234
0
            IncrementGcmCounter(counter);
8235
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
8236
0
            ret = wc_AesEncrypt(aes, counter, scratch);
8237
0
            if (ret != 0)
8238
0
                return ret;
8239
0
            xorbufout(c, scratch, p, AES_BLOCK_SIZE);
8240
0
        #endif
8241
0
            p += AES_BLOCK_SIZE;
8242
0
            c += AES_BLOCK_SIZE;
8243
0
        }
8244
0
    }
8245
8246
0
    if (partial != 0) {
8247
0
        IncrementGcmCounter(counter);
8248
0
        ret = wc_AesEncrypt(aes, counter, scratch);
8249
0
        if (ret != 0)
8250
0
            return ret;
8251
0
        xorbufout(c, scratch, p, partial);
8252
0
    }
8253
0
    if (authTag) {
8254
0
        GHASH(&aes->gcm, authIn, authInSz, out, sz, authTag, authTagSz);
8255
0
        ret = wc_AesEncrypt(aes, initialCounter, scratch);
8256
0
        if (ret != 0)
8257
0
            return ret;
8258
0
        xorbuf(authTag, scratch, authTagSz);
8259
#ifdef OPENSSL_EXTRA
8260
        if (!in && !sz)
8261
            /* store AAD size for next call */
8262
            aes->gcm.aadLen = authInSz;
8263
#endif
8264
0
    }
8265
8266
0
    return ret;
8267
0
}
8268
8269
/* Software AES - GCM Encrypt */
8270
int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8271
                   const byte* iv, word32 ivSz,
8272
                   byte* authTag, word32 authTagSz,
8273
                   const byte* authIn, word32 authInSz)
8274
0
{
8275
0
    int ret;
8276
8277
    /* argument checks */
8278
0
    if (aes == NULL || authTagSz > AES_BLOCK_SIZE || ivSz == 0) {
8279
0
        return BAD_FUNC_ARG;
8280
0
    }
8281
8282
0
    if (authTagSz < WOLFSSL_MIN_AUTH_TAG_SZ) {
8283
0
        WOLFSSL_MSG("GcmEncrypt authTagSz too small error");
8284
0
        return BAD_FUNC_ARG;
8285
0
    }
8286
8287
0
#ifdef WOLF_CRYPTO_CB
8288
0
    #ifndef WOLF_CRYPTO_CB_FIND
8289
0
    if (aes->devId != INVALID_DEVID)
8290
0
    #endif
8291
0
    {
8292
0
        int crypto_cb_ret =
8293
0
            wc_CryptoCb_AesGcmEncrypt(aes, out, in, sz, iv, ivSz, authTag,
8294
0
                                      authTagSz, authIn, authInSz);
8295
0
        if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
8296
0
            return crypto_cb_ret;
8297
        /* fall-through when unavailable */
8298
0
    }
8299
0
#endif
8300
8301
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
8302
    /* if async and byte count above threshold */
8303
    /* only 12-byte IV is supported in HW */
8304
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
8305
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
8306
    #if defined(HAVE_CAVIUM)
8307
        #ifdef HAVE_CAVIUM_V
8308
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
8309
            return NitroxAesGcmEncrypt(aes, out, in, sz,
8310
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
8311
                authTag, authTagSz, authIn, authInSz);
8312
        }
8313
        #endif
8314
    #elif defined(HAVE_INTEL_QA)
8315
        return IntelQaSymAesGcmEncrypt(&aes->asyncDev, out, in, sz,
8316
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
8317
            authTag, authTagSz, authIn, authInSz);
8318
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
8319
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_ENCRYPT)) {
8320
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
8321
            sw->aes.aes = aes;
8322
            sw->aes.out = out;
8323
            sw->aes.in = in;
8324
            sw->aes.sz = sz;
8325
            sw->aes.iv = iv;
8326
            sw->aes.ivSz = ivSz;
8327
            sw->aes.authTag = authTag;
8328
            sw->aes.authTagSz = authTagSz;
8329
            sw->aes.authIn = authIn;
8330
            sw->aes.authInSz = authInSz;
8331
            return WC_PENDING_E;
8332
        }
8333
    #endif
8334
    }
8335
#endif /* WOLFSSL_ASYNC_CRYPT */
8336
8337
#ifdef WOLFSSL_SILABS_SE_ACCEL
8338
    return wc_AesGcmEncrypt_silabs(
8339
        aes, out, in, sz,
8340
        iv, ivSz,
8341
        authTag, authTagSz,
8342
        authIn, authInSz);
8343
#endif
8344
8345
#ifdef STM32_CRYPTO_AES_GCM
8346
    return wc_AesGcmEncrypt_STM32(
8347
        aes, out, in, sz, iv, ivSz,
8348
        authTag, authTagSz, authIn, authInSz);
8349
#endif /* STM32_CRYPTO_AES_GCM */
8350
8351
0
    VECTOR_REGISTERS_PUSH;
8352
8353
#ifdef WOLFSSL_AESNI
8354
    if (aes->use_aesni) {
8355
#ifdef HAVE_INTEL_AVX2
8356
        if (IS_INTEL_AVX2(intel_flags)) {
8357
            AES_GCM_encrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8358
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
8359
            ret = 0;
8360
        }
8361
        else
8362
#endif
8363
#if defined(HAVE_INTEL_AVX1)
8364
        if (IS_INTEL_AVX1(intel_flags)) {
8365
            AES_GCM_encrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8366
                                 authTagSz, (const byte*)aes->key, (int)aes->rounds);
8367
            ret = 0;
8368
        } else
8369
#endif
8370
        {
8371
            AES_GCM_encrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8372
                            authTagSz, (const byte*)aes->key, (int)aes->rounds);
8373
            ret = 0;
8374
        }
8375
    }
8376
    else
8377
#endif /* WOLFSSL_AESNI */
8378
0
    {
8379
0
        ret = AES_GCM_encrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
8380
0
                                authIn, authInSz);
8381
0
    }
8382
8383
0
    VECTOR_REGISTERS_POP;
8384
8385
0
    return ret;
8386
0
}
8387
#endif
8388
8389
8390
/* AES GCM Decrypt */
8391
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
8392
#ifdef FREESCALE_LTC_AES_GCM
8393
int  wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8394
                   const byte* iv, word32 ivSz,
8395
                   const byte* authTag, word32 authTagSz,
8396
                   const byte* authIn, word32 authInSz)
8397
{
8398
    int ret;
8399
    word32 keySize;
8400
    status_t status;
8401
8402
    /* argument checks */
8403
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
8404
     * in and out are don't cares, as this is is the GMAC case. */
8405
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
8406
        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 ||
8407
        ivSz == 0) {
8408
8409
        return BAD_FUNC_ARG;
8410
    }
8411
8412
    ret = wc_AesGetKeySize(aes, &keySize);
8413
    if (ret != 0) {
8414
        return ret;
8415
    }
8416
8417
    status = wolfSSL_CryptHwMutexLock();
8418
    if (status != 0)
8419
        return status;
8420
8421
    status = LTC_AES_DecryptTagGcm(LTC_BASE, in, out, sz, iv, ivSz,
8422
        authIn, authInSz, (byte*)aes->key, keySize, authTag, authTagSz);
8423
    wolfSSL_CryptHwMutexUnLock();
8424
8425
    return (status == kStatus_Success) ? 0 : AES_GCM_AUTH_E;
8426
}
8427
8428
#else
8429
8430
#ifdef STM32_CRYPTO_AES_GCM
8431
/* this function supports inline decrypt */
8432
static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32(
8433
                                  Aes* aes, byte* out,
8434
                                  const byte* in, word32 sz,
8435
                                  const byte* iv, word32 ivSz,
8436
                                  const byte* authTag, word32 authTagSz,
8437
                                  const byte* authIn, word32 authInSz)
8438
{
8439
    int ret;
8440
#ifdef WOLFSSL_STM32_CUBEMX
8441
    int status = HAL_OK;
8442
    CRYP_HandleTypeDef hcryp;
8443
    word32 blocks = sz / AES_BLOCK_SIZE;
8444
#else
8445
    int status = SUCCESS;
8446
    word32 keyCopy[AES_256_KEY_SIZE/sizeof(word32)];
8447
#endif
8448
    word32 keySize;
8449
    word32 partial = sz % AES_BLOCK_SIZE;
8450
    word32 tag[AES_BLOCK_SIZE/sizeof(word32)];
8451
    word32 tagExpected[AES_BLOCK_SIZE/sizeof(word32)];
8452
    word32 partialBlock[AES_BLOCK_SIZE/sizeof(word32)];
8453
    word32 ctr[AES_BLOCK_SIZE/sizeof(word32)];
8454
    word32 authhdr[AES_BLOCK_SIZE/sizeof(word32)];
8455
    byte* authInPadded = NULL;
8456
    int authPadSz, wasAlloc = 0, tagComputed = 0;
8457
8458
    ret = wc_AesGetKeySize(aes, &keySize);
8459
    if (ret != 0)
8460
        return ret;
8461
8462
#ifdef WOLFSSL_STM32_CUBEMX
8463
    ret = wc_Stm32_Aes_Init(aes, &hcryp);
8464
    if (ret != 0)
8465
        return ret;
8466
#endif
8467
8468
    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
8469
    if (ivSz == GCM_NONCE_MID_SZ) {
8470
        byte* pCtr = (byte*)ctr;
8471
        XMEMCPY(ctr, iv, ivSz);
8472
        pCtr[AES_BLOCK_SIZE - 1] = 1;
8473
    }
8474
    else {
8475
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, (byte*)ctr, AES_BLOCK_SIZE);
8476
    }
8477
8478
    /* Make copy of expected authTag, which could get corrupted in some
8479
     * Cube HAL versions without proper partial block support.
8480
     * For TLS blocks the authTag is after the output buffer, so save it */
8481
    XMEMCPY(tagExpected, authTag, authTagSz);
8482
8483
    /* Authentication buffer - must be 4-byte multiple zero padded */
8484
    authPadSz = authInSz % sizeof(word32);
8485
    if (authPadSz != 0) {
8486
        authPadSz = authInSz + sizeof(word32) - authPadSz;
8487
    }
8488
    else {
8489
        authPadSz = authInSz;
8490
    }
8491
8492
    /* for cases where hardware cannot be used for authTag calculate it */
8493
    /* if IV is not 12 calculate GHASH using software */
8494
    if (ivSz != GCM_NONCE_MID_SZ
8495
    #ifndef CRYP_HEADERWIDTHUNIT_BYTE
8496
        /* or hardware that does not support partial block */
8497
        || sz == 0 || partial != 0
8498
    #endif
8499
    #if !defined(CRYP_HEADERWIDTHUNIT_BYTE) && !defined(STM32_AESGCM_PARTIAL)
8500
        /* or authIn is not a multiple of 4  */
8501
        || authPadSz != authInSz
8502
    #endif
8503
    ) {
8504
        GHASH(&aes->gcm, authIn, authInSz, in, sz, (byte*)tag, sizeof(tag));
8505
        ret = wc_AesEncrypt(aes, (byte*)ctr, (byte*)partialBlock);
8506
        if (ret != 0)
8507
            return ret;
8508
        xorbuf(tag, partialBlock, sizeof(tag));
8509
        tagComputed = 1;
8510
    }
8511
8512
    /* if using hardware for authentication tag make sure its aligned and zero padded */
8513
    if (authPadSz != authInSz && !tagComputed) {
8514
        if (authPadSz <= sizeof(authhdr)) {
8515
            authInPadded = (byte*)authhdr;
8516
        }
8517
        else {
8518
            authInPadded = (byte*)XMALLOC(authPadSz, aes->heap,
8519
                DYNAMIC_TYPE_TMP_BUFFER);
8520
            if (authInPadded == NULL) {
8521
                wolfSSL_CryptHwMutexUnLock();
8522
                return MEMORY_E;
8523
            }
8524
            wasAlloc = 1;
8525
        }
8526
        XMEMSET(authInPadded, 0, authPadSz);
8527
        XMEMCPY(authInPadded, authIn, authInSz);
8528
    } else {
8529
        authInPadded = (byte*)authIn;
8530
    }
8531
8532
    /* Hardware requires counter + 1 */
8533
    IncrementGcmCounter((byte*)ctr);
8534
8535
    ret = wolfSSL_CryptHwMutexLock();
8536
    if (ret != 0) {
8537
        return ret;
8538
    }
8539
#ifdef WOLFSSL_STM32_CUBEMX
8540
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8541
    hcryp.Init.Header = (STM_CRYPT_TYPE*)authInPadded;
8542
8543
#if defined(STM32_HAL_V2)
8544
    hcryp.Init.Algorithm = CRYP_AES_GCM;
8545
    #ifdef CRYP_HEADERWIDTHUNIT_BYTE
8546
    /* V2 with CRYP_HEADERWIDTHUNIT_BYTE uses byte size for header */
8547
    hcryp.Init.HeaderSize = authInSz;
8548
    #else
8549
    hcryp.Init.HeaderSize = authPadSz/sizeof(word32);
8550
    #endif
8551
    #ifdef CRYP_KEYIVCONFIG_ONCE
8552
    /* allows repeated calls to HAL_CRYP_Decrypt */
8553
    hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
8554
    #endif
8555
    ByteReverseWords(ctr, ctr, AES_BLOCK_SIZE);
8556
    hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)ctr;
8557
    HAL_CRYP_Init(&hcryp);
8558
8559
    #ifndef CRYP_KEYIVCONFIG_ONCE
8560
    status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
8561
        (blocks * AES_BLOCK_SIZE) + partial, (uint32_t*)out, STM32_HAL_TIMEOUT);
8562
    #else
8563
    /* GCM payload phase - blocks */
8564
    if (blocks) {
8565
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in,
8566
            (blocks * AES_BLOCK_SIZE), (uint32_t*)out, STM32_HAL_TIMEOUT);
8567
    }
8568
    /* GCM payload phase - partial remainder */
8569
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8570
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8571
        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
8572
        status = HAL_CRYP_Decrypt(&hcryp, (uint32_t*)partialBlock, partial,
8573
            (uint32_t*)partialBlock, STM32_HAL_TIMEOUT);
8574
        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
8575
    }
8576
    #endif
8577
    if (status == HAL_OK && !tagComputed) {
8578
        /* Compute the authTag */
8579
        status = HAL_CRYPEx_AESGCM_GenerateAuthTAG(&hcryp, (uint32_t*)tag,
8580
            STM32_HAL_TIMEOUT);
8581
    }
8582
#elif defined(STM32_CRYPTO_AES_ONLY)
8583
    /* Set the CRYP parameters */
8584
    hcryp.Init.HeaderSize = authPadSz;
8585
    if (authPadSz == 0)
8586
        hcryp.Init.Header = NULL; /* cannot pass pointer when authIn == 0 */
8587
    hcryp.Init.ChainingMode  = CRYP_CHAINMODE_AES_GCM_GMAC;
8588
    hcryp.Init.OperatingMode = CRYP_ALGOMODE_DECRYPT;
8589
    hcryp.Init.GCMCMACPhase  = CRYP_INIT_PHASE;
8590
    HAL_CRYP_Init(&hcryp);
8591
8592
    /* GCM init phase */
8593
    status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
8594
    if (status == HAL_OK) {
8595
        /* GCM header phase */
8596
        hcryp.Init.GCMCMACPhase = CRYP_HEADER_PHASE;
8597
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, 0, NULL, STM32_HAL_TIMEOUT);
8598
    }
8599
    if (status == HAL_OK) {
8600
        /* GCM payload phase - blocks */
8601
        hcryp.Init.GCMCMACPhase = CRYP_PAYLOAD_PHASE;
8602
        if (blocks) {
8603
            status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)in,
8604
                (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
8605
        }
8606
    }
8607
    if (status == HAL_OK && (partial != 0 || (sz > 0 && blocks == 0))) {
8608
        /* GCM payload phase - partial remainder */
8609
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8610
        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
8611
        status = HAL_CRYPEx_AES_Auth(&hcryp, (byte*)partialBlock, partial,
8612
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
8613
        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
8614
    }
8615
    if (status == HAL_OK && tagComputed == 0) {
8616
        /* GCM final phase */
8617
        hcryp.Init.GCMCMACPhase = CRYP_FINAL_PHASE;
8618
        status = HAL_CRYPEx_AES_Auth(&hcryp, NULL, sz, (byte*)tag, STM32_HAL_TIMEOUT);
8619
    }
8620
#else
8621
    hcryp.Init.HeaderSize = authPadSz;
8622
    HAL_CRYP_Init(&hcryp);
8623
    if (blocks) {
8624
        /* GCM payload phase - blocks */
8625
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)in,
8626
            (blocks * AES_BLOCK_SIZE), out, STM32_HAL_TIMEOUT);
8627
    }
8628
    if (status == HAL_OK && (partial != 0 || blocks == 0)) {
8629
        /* GCM payload phase - partial remainder */
8630
        XMEMSET(partialBlock, 0, sizeof(partialBlock));
8631
        XMEMCPY(partialBlock, in + (blocks * AES_BLOCK_SIZE), partial);
8632
        status = HAL_CRYPEx_AESGCM_Decrypt(&hcryp, (byte*)partialBlock, partial,
8633
            (byte*)partialBlock, STM32_HAL_TIMEOUT);
8634
        XMEMCPY(out + (blocks * AES_BLOCK_SIZE), partialBlock, partial);
8635
    }
8636
    if (status == HAL_OK && tagComputed == 0) {
8637
        /* Compute the authTag */
8638
        status = HAL_CRYPEx_AESGCM_Finish(&hcryp, sz, (byte*)tag, STM32_HAL_TIMEOUT);
8639
    }
8640
#endif
8641
8642
    if (status != HAL_OK)
8643
        ret = AES_GCM_AUTH_E;
8644
8645
    HAL_CRYP_DeInit(&hcryp);
8646
8647
#else /* Standard Peripheral Library */
8648
    ByteReverseWords(keyCopy, (word32*)aes->key, aes->keylen);
8649
8650
    /* Input size and auth size need to be the actual sizes, even though
8651
     * they are not block aligned, because this length (in bits) is used
8652
     * in the final GHASH. */
8653
    XMEMSET(partialBlock, 0, sizeof(partialBlock)); /* use this to get tag */
8654
    status = CRYP_AES_GCM(MODE_DECRYPT, (uint8_t*)ctr,
8655
                         (uint8_t*)keyCopy,      keySize * 8,
8656
                         (uint8_t*)in,           sz,
8657
                         (uint8_t*)authInPadded, authInSz,
8658
                         (uint8_t*)out,          (uint8_t*)partialBlock);
8659
    if (status != SUCCESS)
8660
        ret = AES_GCM_AUTH_E;
8661
    if (tagComputed == 0)
8662
        XMEMCPY(tag, partialBlock, authTagSz);
8663
#endif /* WOLFSSL_STM32_CUBEMX */
8664
    wolfSSL_CryptHwMutexUnLock();
8665
    wc_Stm32_Aes_Cleanup();
8666
8667
    /* Check authentication tag */
8668
    if (ConstantCompare((const byte*)tagExpected, (byte*)tag, authTagSz) != 0) {
8669
        ret = AES_GCM_AUTH_E;
8670
    }
8671
8672
    /* Free memory */
8673
    if (wasAlloc) {
8674
        XFREE(authInPadded, aes->heap, DYNAMIC_TYPE_TMP_BUFFER);
8675
    }
8676
8677
    return ret;
8678
}
8679
8680
#endif /* STM32_CRYPTO_AES_GCM */
8681
8682
#ifdef WOLFSSL_AESNI
8683
/* For performance reasons, this code needs to be not inlined. */
8684
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
8685
                      Aes* aes, byte* out, const byte* in, word32 sz,
8686
                      const byte* iv, word32 ivSz,
8687
                      const byte* authTag, word32 authTagSz,
8688
                      const byte* authIn, word32 authInSz);
8689
#else
8690
static
8691
#endif
8692
int WARN_UNUSED_RESULT AES_GCM_decrypt_C(
8693
                      Aes* aes, byte* out, const byte* in, word32 sz,
8694
                      const byte* iv, word32 ivSz,
8695
                      const byte* authTag, word32 authTagSz,
8696
                      const byte* authIn, word32 authInSz)
8697
0
{
8698
0
    int ret;
8699
0
    word32 blocks = sz / AES_BLOCK_SIZE;
8700
0
    word32 partial = sz % AES_BLOCK_SIZE;
8701
0
    const byte* c = in;
8702
0
    byte* p = out;
8703
0
    ALIGN16 byte counter[AES_BLOCK_SIZE];
8704
0
    ALIGN16 byte scratch[AES_BLOCK_SIZE];
8705
0
    ALIGN16 byte Tprime[AES_BLOCK_SIZE];
8706
0
    ALIGN16 byte EKY0[AES_BLOCK_SIZE];
8707
0
    sword32 res;
8708
8709
0
    if (ivSz == GCM_NONCE_MID_SZ) {
8710
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
8711
0
        XMEMCPY(counter, iv, ivSz);
8712
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
8713
0
                                         AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
8714
0
        counter[AES_BLOCK_SIZE - 1] = 1;
8715
0
    }
8716
0
    else {
8717
        /* Counter is GHASH of IV. */
8718
#ifdef OPENSSL_EXTRA
8719
        word32 aadTemp = aes->gcm.aadLen;
8720
        aes->gcm.aadLen = 0;
8721
#endif
8722
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE);
8723
#ifdef OPENSSL_EXTRA
8724
        aes->gcm.aadLen = aadTemp;
8725
#endif
8726
0
    }
8727
8728
    /* Calc the authTag again using received auth data and the cipher text */
8729
0
    GHASH(&aes->gcm, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
8730
0
    ret = wc_AesEncrypt(aes, counter, EKY0);
8731
0
    if (ret != 0)
8732
0
        return ret;
8733
0
    xorbuf(Tprime, EKY0, sizeof(Tprime));
8734
#ifdef WC_AES_GCM_DEC_AUTH_EARLY
8735
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
8736
     * the pairwise bytes in the strings.
8737
     */
8738
    res = ConstantCompare(authTag, Tprime, authTagSz);
8739
    /* convert positive retval from ConstantCompare() to all-1s word, in
8740
     * constant time.
8741
     */
8742
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
8743
    ret = res & AES_GCM_AUTH_E;
8744
    if (ret != 0)
8745
        return ret;
8746
#endif
8747
8748
#ifdef OPENSSL_EXTRA
8749
    if (!out) {
8750
        /* authenticated, non-confidential data */
8751
        /* store AAD size for next call */
8752
        aes->gcm.aadLen = authInSz;
8753
    }
8754
#endif
8755
8756
#if defined(WOLFSSL_PIC32MZ_CRYPT)
8757
    if (blocks) {
8758
        /* use initial IV for HW, but don't use it below */
8759
        XMEMCPY(aes->reg, counter, AES_BLOCK_SIZE);
8760
8761
        ret = wc_Pic32AesCrypt(
8762
            aes->key, aes->keylen, aes->reg, AES_BLOCK_SIZE,
8763
            out, in, (blocks * AES_BLOCK_SIZE),
8764
            PIC32_DECRYPTION, PIC32_ALGO_AES, PIC32_CRYPTOALGO_AES_GCM);
8765
        if (ret != 0)
8766
            return ret;
8767
    }
8768
    /* process remainder using partial handling */
8769
#endif
8770
8771
0
#if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT)
8772
    /* some hardware acceleration can gain performance from doing AES encryption
8773
     * of the whole buffer at once */
8774
0
    if (c != p && blocks > 0) { /* can not handle inline decryption */
8775
0
        while (blocks--) {
8776
0
            IncrementGcmCounter(counter);
8777
0
            XMEMCPY(p, counter, AES_BLOCK_SIZE);
8778
0
            p += AES_BLOCK_SIZE;
8779
0
        }
8780
8781
        /* reset number of blocks and then do encryption */
8782
0
        blocks = sz / AES_BLOCK_SIZE;
8783
8784
0
        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
8785
0
        xorbuf(out, c, AES_BLOCK_SIZE * blocks);
8786
0
        c += AES_BLOCK_SIZE * blocks;
8787
0
    }
8788
0
    else
8789
0
#endif /* HAVE_AES_ECB && !PIC32MZ */
8790
0
    {
8791
0
        while (blocks--) {
8792
0
            IncrementGcmCounter(counter);
8793
0
        #if !defined(WOLFSSL_PIC32MZ_CRYPT)
8794
0
            ret = wc_AesEncrypt(aes, counter, scratch);
8795
0
            if (ret != 0)
8796
0
                return ret;
8797
0
            xorbufout(p, scratch, c, AES_BLOCK_SIZE);
8798
0
        #endif
8799
0
            p += AES_BLOCK_SIZE;
8800
0
            c += AES_BLOCK_SIZE;
8801
0
        }
8802
0
    }
8803
8804
0
    if (partial != 0) {
8805
0
        IncrementGcmCounter(counter);
8806
0
        ret = wc_AesEncrypt(aes, counter, scratch);
8807
0
        if (ret != 0)
8808
0
            return ret;
8809
0
        xorbuf(scratch, c, partial);
8810
0
        XMEMCPY(p, scratch, partial);
8811
0
    }
8812
8813
0
#ifndef WC_AES_GCM_DEC_AUTH_EARLY
8814
    /* ConstantCompare returns the cumulative bitwise or of the bitwise xor of
8815
     * the pairwise bytes in the strings.
8816
     */
8817
0
    res = ConstantCompare(authTag, Tprime, (int)authTagSz);
8818
    /* convert positive retval from ConstantCompare() to all-1s word, in
8819
     * constant time.
8820
     */
8821
0
    res = 0 - (sword32)(((word32)(0 - res)) >> 31U);
8822
    /* now use res as a mask for constant time return of ret, unless tag
8823
     * mismatch, whereupon AES_GCM_AUTH_E is returned.
8824
     */
8825
0
    ret = (ret & ~res) | (res & AES_GCM_AUTH_E);
8826
0
#endif
8827
0
    return ret;
8828
0
}
8829
8830
/* Software AES - GCM Decrypt */
8831
int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
8832
                     const byte* iv, word32 ivSz,
8833
                     const byte* authTag, word32 authTagSz,
8834
                     const byte* authIn, word32 authInSz)
8835
0
{
8836
0
    int ret;
8837
#ifdef WOLFSSL_AESNI
8838
    int res = AES_GCM_AUTH_E;
8839
#endif
8840
8841
    /* argument checks */
8842
    /* If the sz is non-zero, both in and out must be set. If sz is 0,
8843
     * in and out are don't cares, as this is is the GMAC case. */
8844
0
    if (aes == NULL || iv == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
8845
0
        authTag == NULL || authTagSz > AES_BLOCK_SIZE || authTagSz == 0 ||
8846
0
        ivSz == 0) {
8847
8848
0
        return BAD_FUNC_ARG;
8849
0
    }
8850
8851
0
#ifdef WOLF_CRYPTO_CB
8852
0
    #ifndef WOLF_CRYPTO_CB_FIND
8853
0
    if (aes->devId != INVALID_DEVID)
8854
0
    #endif
8855
0
    {
8856
0
        int crypto_cb_ret =
8857
0
            wc_CryptoCb_AesGcmDecrypt(aes, out, in, sz, iv, ivSz,
8858
0
                                      authTag, authTagSz, authIn, authInSz);
8859
0
        if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
8860
0
            return crypto_cb_ret;
8861
        /* fall-through when unavailable */
8862
0
    }
8863
0
#endif
8864
8865
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
8866
    /* if async and byte count above threshold */
8867
    /* only 12-byte IV is supported in HW */
8868
    if (aes->asyncDev.marker == WOLFSSL_ASYNC_MARKER_AES &&
8869
                    sz >= WC_ASYNC_THRESH_AES_GCM && ivSz == GCM_NONCE_MID_SZ) {
8870
    #if defined(HAVE_CAVIUM)
8871
        #ifdef HAVE_CAVIUM_V
8872
        if (authInSz == 20) { /* Nitrox V GCM is only working with 20 byte AAD */
8873
            return NitroxAesGcmDecrypt(aes, out, in, sz,
8874
                (const byte*)aes->devKey, aes->keylen, iv, ivSz,
8875
                authTag, authTagSz, authIn, authInSz);
8876
        }
8877
        #endif
8878
    #elif defined(HAVE_INTEL_QA)
8879
        return IntelQaSymAesGcmDecrypt(&aes->asyncDev, out, in, sz,
8880
            (const byte*)aes->devKey, aes->keylen, iv, ivSz,
8881
            authTag, authTagSz, authIn, authInSz);
8882
    #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
8883
        if (wc_AsyncSwInit(&aes->asyncDev, ASYNC_SW_AES_GCM_DECRYPT)) {
8884
            WC_ASYNC_SW* sw = &aes->asyncDev.sw;
8885
            sw->aes.aes = aes;
8886
            sw->aes.out = out;
8887
            sw->aes.in = in;
8888
            sw->aes.sz = sz;
8889
            sw->aes.iv = iv;
8890
            sw->aes.ivSz = ivSz;
8891
            sw->aes.authTag = (byte*)authTag;
8892
            sw->aes.authTagSz = authTagSz;
8893
            sw->aes.authIn = authIn;
8894
            sw->aes.authInSz = authInSz;
8895
            return WC_PENDING_E;
8896
        }
8897
    #endif
8898
    }
8899
#endif /* WOLFSSL_ASYNC_CRYPT */
8900
8901
#ifdef WOLFSSL_SILABS_SE_ACCEL
8902
    return wc_AesGcmDecrypt_silabs(
8903
        aes, out, in, sz, iv, ivSz,
8904
        authTag, authTagSz, authIn, authInSz);
8905
8906
#endif
8907
8908
#ifdef STM32_CRYPTO_AES_GCM
8909
    /* The STM standard peripheral library API's doesn't support partial blocks */
8910
    return wc_AesGcmDecrypt_STM32(
8911
        aes, out, in, sz, iv, ivSz,
8912
        authTag, authTagSz, authIn, authInSz);
8913
#endif /* STM32_CRYPTO_AES_GCM */
8914
8915
0
    VECTOR_REGISTERS_PUSH;
8916
8917
#ifdef WOLFSSL_AESNI
8918
    if (aes->use_aesni) {
8919
#ifdef HAVE_INTEL_AVX2
8920
        if (IS_INTEL_AVX2(intel_flags)) {
8921
            AES_GCM_decrypt_avx2(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8922
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
8923
            if (res == 0)
8924
                ret = AES_GCM_AUTH_E;
8925
            else
8926
                ret = 0;
8927
        }
8928
        else
8929
#endif
8930
#if defined(HAVE_INTEL_AVX1)
8931
        if (IS_INTEL_AVX1(intel_flags)) {
8932
            AES_GCM_decrypt_avx1(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8933
                                 authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
8934
            if (res == 0)
8935
                ret = AES_GCM_AUTH_E;
8936
            else
8937
                ret = 0;
8938
        }
8939
        else
8940
#endif
8941
        {
8942
            AES_GCM_decrypt_aesni(in, out, authIn, iv, authTag, sz, authInSz, ivSz,
8943
                            authTagSz, (byte*)aes->key, (int)aes->rounds, &res);
8944
            if (res == 0)
8945
                ret = AES_GCM_AUTH_E;
8946
            else
8947
                ret = 0;
8948
        }
8949
    }
8950
    else
8951
#endif /* WOLFSSL_AESNI */
8952
0
    {
8953
0
        ret = AES_GCM_decrypt_C(aes, out, in, sz, iv, ivSz, authTag, authTagSz,
8954
0
                                                             authIn, authInSz);
8955
0
    }
8956
8957
0
    VECTOR_REGISTERS_POP;
8958
8959
0
    return ret;
8960
0
}
8961
#endif
8962
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
8963
8964
#ifdef WOLFSSL_AESGCM_STREAM
8965
8966
#if defined(WC_AES_C_DYNAMIC_FALLBACK) && defined(WOLFSSL_AESNI)
8967
    #error "AES-GCM streaming with AESNI is incompatible with WC_AES_C_DYNAMIC_FALLBACK."
8968
#endif
8969
8970
/* Initialize the AES GCM cipher with an IV. C implementation.
8971
 *
8972
 * @param [in, out] aes   AES object.
8973
 * @param [in]      iv    IV/nonce buffer.
8974
 * @param [in]      ivSz  Length of IV/nonce data.
8975
 */
8976
static WARN_UNUSED_RESULT int AesGcmInit_C(Aes* aes, const byte* iv, word32 ivSz)
8977
0
{
8978
0
    ALIGN32 byte counter[AES_BLOCK_SIZE];
8979
0
    int ret;
8980
8981
#ifdef WOLFSSL_AESNI
8982
    aes->use_aesni = 0;
8983
#endif
8984
8985
0
    if (ivSz == GCM_NONCE_MID_SZ) {
8986
        /* Counter is IV with bottom 4 bytes set to: 0x00,0x00,0x00,0x01. */
8987
0
        XMEMCPY(counter, iv, ivSz);
8988
0
        XMEMSET(counter + GCM_NONCE_MID_SZ, 0,
8989
0
                                         AES_BLOCK_SIZE - GCM_NONCE_MID_SZ - 1);
8990
0
        counter[AES_BLOCK_SIZE - 1] = 1;
8991
0
    }
8992
0
    else {
8993
        /* Counter is GHASH of IV. */
8994
    #ifdef OPENSSL_EXTRA
8995
        word32 aadTemp = aes->gcm.aadLen;
8996
        aes->gcm.aadLen = 0;
8997
    #endif
8998
0
        GHASH(&aes->gcm, NULL, 0, iv, ivSz, counter, AES_BLOCK_SIZE);
8999
    #ifdef OPENSSL_EXTRA
9000
        aes->gcm.aadLen = aadTemp;
9001
    #endif
9002
0
    }
9003
9004
    /* Copy in the counter for use with cipher. */
9005
0
    XMEMCPY(AES_COUNTER(aes), counter, AES_BLOCK_SIZE);
9006
    /* Encrypt initial counter into a buffer for GCM. */
9007
0
    ret = wc_AesEncrypt(aes, counter, AES_INITCTR(aes));
9008
0
    if (ret != 0)
9009
0
        return ret;
9010
    /* Reset state fields. */
9011
0
    aes->over = 0;
9012
0
    aes->aSz = 0;
9013
0
    aes->cSz = 0;
9014
    /* Initialization for GHASH. */
9015
0
    GHASH_INIT(aes);
9016
9017
0
    return 0;
9018
0
}
9019
9020
/* Update the AES GCM cipher with data. C implementation.
9021
 *
9022
 * Only enciphers data.
9023
 *
9024
 * @param [in, out] aes  AES object.
9025
 * @param [in]      out  Cipher text or plaintext buffer.
9026
 * @param [in]      in   Plaintext or cipher text buffer.
9027
 * @param [in]      sz   Length of data.
9028
 */
9029
static WARN_UNUSED_RESULT int AesGcmCryptUpdate_C(
9030
    Aes* aes, byte* out, const byte* in, word32 sz)
9031
0
{
9032
0
    word32 blocks;
9033
0
    word32 partial;
9034
0
    int ret;
9035
9036
    /* Check if previous encrypted block was not used up. */
9037
0
    if (aes->over > 0) {
9038
0
        byte pSz = AES_BLOCK_SIZE - aes->over;
9039
0
        if (pSz > sz) pSz = (byte)sz;
9040
9041
        /* Use some/all of last encrypted block. */
9042
0
        xorbufout(out, AES_LASTBLOCK(aes) + aes->over, in, pSz);
9043
0
        aes->over = (aes->over + pSz) & (AES_BLOCK_SIZE - 1);
9044
9045
        /* Some data used. */
9046
0
        sz  -= pSz;
9047
0
        in  += pSz;
9048
0
        out += pSz;
9049
0
    }
9050
9051
    /* Calculate the number of blocks needing to be encrypted and any leftover.
9052
     */
9053
0
    blocks  = sz / AES_BLOCK_SIZE;
9054
0
    partial = sz & (AES_BLOCK_SIZE - 1);
9055
9056
0
#if defined(HAVE_AES_ECB)
9057
    /* Some hardware acceleration can gain performance from doing AES encryption
9058
     * of the whole buffer at once.
9059
     * Overwrites the cipher text before using plaintext - no inline encryption.
9060
     */
9061
0
    if ((out != in) && blocks > 0) {
9062
0
        word32 b;
9063
        /* Place incrementing counter blocks into cipher text. */
9064
0
        for (b = 0; b < blocks; b++) {
9065
0
            IncrementGcmCounter(AES_COUNTER(aes));
9066
0
            XMEMCPY(out + b * AES_BLOCK_SIZE, AES_COUNTER(aes), AES_BLOCK_SIZE);
9067
0
        }
9068
9069
        /* Encrypt counter blocks. */
9070
0
        wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks);
9071
        /* XOR in plaintext. */
9072
0
        xorbuf(out, in, AES_BLOCK_SIZE * blocks);
9073
        /* Skip over processed data. */
9074
0
        in += AES_BLOCK_SIZE * blocks;
9075
0
        out += AES_BLOCK_SIZE * blocks;
9076
0
    }
9077
0
    else
9078
0
#endif /* HAVE_AES_ECB */
9079
0
    {
9080
        /* Encrypt block by block. */
9081
0
        while (blocks--) {
9082
0
            ALIGN32 byte scratch[AES_BLOCK_SIZE];
9083
0
            IncrementGcmCounter(AES_COUNTER(aes));
9084
            /* Encrypt counter into a buffer. */
9085
0
            ret = wc_AesEncrypt(aes, AES_COUNTER(aes), scratch);
9086
0
            if (ret != 0)
9087
0
                return ret;
9088
            /* XOR plain text into encrypted counter into cipher text buffer. */
9089
0
            xorbufout(out, scratch, in, AES_BLOCK_SIZE);
9090
            /* Data complete. */
9091
0
            in  += AES_BLOCK_SIZE;
9092
0
            out += AES_BLOCK_SIZE;
9093
0
        }
9094
0
    }
9095
9096
0
    if (partial != 0) {
9097
        /* Generate an extra block and use up as much as needed. */
9098
0
        IncrementGcmCounter(AES_COUNTER(aes));
9099
        /* Encrypt counter into cache. */
9100
0
        ret = wc_AesEncrypt(aes, AES_COUNTER(aes), AES_LASTBLOCK(aes));
9101
0
        if (ret != 0)
9102
0
            return ret;
9103
        /* XOR plain text into encrypted counter into cipher text buffer. */
9104
0
        xorbufout(out, AES_LASTBLOCK(aes), in, partial);
9105
        /* Keep amount of encrypted block used. */
9106
0
        aes->over = (byte)partial;
9107
0
    }
9108
9109
0
    return 0;
9110
0
}
9111
9112
/* Calculates authentication tag for AES GCM. C implementation.
9113
 *
9114
 * @param [in, out] aes        AES object.
9115
 * @param [out]     authTag    Buffer to store authentication tag in.
9116
 * @param [in]      authTagSz  Length of tag to create.
9117
 */
9118
static WARN_UNUSED_RESULT int AesGcmFinal_C(
9119
    Aes* aes, byte* authTag, word32 authTagSz)
9120
0
{
9121
    /* Calculate authentication tag. */
9122
0
    GHASH_FINAL(aes, authTag, authTagSz);
9123
    /* XOR in as much of encrypted counter as is required. */
9124
0
    xorbuf(authTag, AES_INITCTR(aes), authTagSz);
9125
#ifdef OPENSSL_EXTRA
9126
    /* store AAD size for next call */
9127
    aes->gcm.aadLen = aes->aSz;
9128
#endif
9129
    /* Zeroize last block to protect sensitive data. */
9130
0
    ForceZero(AES_LASTBLOCK(aes), AES_BLOCK_SIZE);
9131
9132
0
    return 0;
9133
0
}
9134
9135
#ifdef WOLFSSL_AESNI
9136
9137
#ifdef __cplusplus
9138
    extern "C" {
9139
#endif
9140
9141
/* Assembly code implementations in: aes_gcm_asm.S */
9142
#ifdef HAVE_INTEL_AVX2
9143
extern void AES_GCM_init_avx2(const unsigned char* key, int nr,
9144
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
9145
    unsigned char* counter, unsigned char* initCtr);
9146
extern void AES_GCM_aad_update_avx2(const unsigned char* addt,
9147
    unsigned int abytes, unsigned char* tag, unsigned char* h);
9148
extern void AES_GCM_encrypt_block_avx2(const unsigned char* key, int nr,
9149
    unsigned char* out, const unsigned char* in, unsigned char* counter);
9150
extern void AES_GCM_ghash_block_avx2(const unsigned char* data,
9151
    unsigned char* tag, unsigned char* h);
9152
9153
extern void AES_GCM_encrypt_update_avx2(const unsigned char* key, int nr,
9154
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9155
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9156
extern void AES_GCM_encrypt_final_avx2(unsigned char* tag,
9157
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9158
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
9159
#endif
9160
#ifdef HAVE_INTEL_AVX1
9161
extern void AES_GCM_init_avx1(const unsigned char* key, int nr,
9162
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
9163
    unsigned char* counter, unsigned char* initCtr);
9164
extern void AES_GCM_aad_update_avx1(const unsigned char* addt,
9165
    unsigned int abytes, unsigned char* tag, unsigned char* h);
9166
extern void AES_GCM_encrypt_block_avx1(const unsigned char* key, int nr,
9167
    unsigned char* out, const unsigned char* in, unsigned char* counter);
9168
extern void AES_GCM_ghash_block_avx1(const unsigned char* data,
9169
    unsigned char* tag, unsigned char* h);
9170
9171
extern void AES_GCM_encrypt_update_avx1(const unsigned char* key, int nr,
9172
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9173
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9174
extern void AES_GCM_encrypt_final_avx1(unsigned char* tag,
9175
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9176
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
9177
#endif
9178
extern void AES_GCM_init_aesni(const unsigned char* key, int nr,
9179
    const unsigned char* ivec, unsigned int ibytes, unsigned char* h,
9180
    unsigned char* counter, unsigned char* initCtr);
9181
extern void AES_GCM_aad_update_aesni(const unsigned char* addt,
9182
    unsigned int abytes, unsigned char* tag, unsigned char* h);
9183
extern void AES_GCM_encrypt_block_aesni(const unsigned char* key, int nr,
9184
    unsigned char* out, const unsigned char* in, unsigned char* counter);
9185
extern void AES_GCM_ghash_block_aesni(const unsigned char* data,
9186
    unsigned char* tag, unsigned char* h);
9187
9188
extern void AES_GCM_encrypt_update_aesni(const unsigned char* key, int nr,
9189
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9190
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9191
extern void AES_GCM_encrypt_final_aesni(unsigned char* tag,
9192
    unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9193
    unsigned int abytes, unsigned char* h, unsigned char* initCtr);
9194
9195
#ifdef __cplusplus
9196
    } /* extern "C" */
9197
#endif
9198
9199
/* Initialize the AES GCM cipher with an IV. AES-NI implementations.
9200
 *
9201
 * @param [in, out] aes   AES object.
9202
 * @param [in]      iv    IV/nonce buffer.
9203
 * @param [in]      ivSz  Length of IV/nonce data.
9204
 */
9205
static WARN_UNUSED_RESULT int AesGcmInit_aesni(
9206
    Aes* aes, const byte* iv, word32 ivSz)
9207
{
9208
    ASSERT_SAVED_VECTOR_REGISTERS();
9209
9210
    /* Reset state fields. */
9211
    aes->aSz = 0;
9212
    aes->cSz = 0;
9213
    /* Set tag to all zeros as initial value. */
9214
    XMEMSET(AES_TAG(aes), 0, AES_BLOCK_SIZE);
9215
    /* Reset counts of AAD and cipher text. */
9216
    aes->aOver = 0;
9217
    aes->cOver = 0;
9218
9219
#ifdef HAVE_INTEL_AVX2
9220
    if (IS_INTEL_AVX2(intel_flags)) {
9221
        AES_GCM_init_avx2((byte*)aes->key, (int)aes->rounds, iv, ivSz,
9222
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
9223
    }
9224
    else
9225
#endif
9226
#ifdef HAVE_INTEL_AVX1
9227
    if (IS_INTEL_AVX1(intel_flags)) {
9228
        AES_GCM_init_avx1((byte*)aes->key, (int)aes->rounds, iv, ivSz,
9229
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
9230
    }
9231
    else
9232
#endif
9233
    {
9234
        AES_GCM_init_aesni((byte*)aes->key, (int)aes->rounds, iv, ivSz,
9235
            aes->gcm.H, AES_COUNTER(aes), AES_INITCTR(aes));
9236
    }
9237
9238
    aes->use_aesni = 1;
9239
9240
    return 0;
9241
}
9242
9243
/* Update the AES GCM for encryption with authentication data.
9244
 *
9245
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
9246
 *
9247
 * @param [in, out] aes   AES object.
9248
 * @param [in]      a     Buffer holding authentication data.
9249
 * @param [in]      aSz   Length of authentication data in bytes.
9250
 * @param [in]      endA  Whether no more authentication data is expected.
9251
 */
9252
static WARN_UNUSED_RESULT int AesGcmAadUpdate_aesni(
9253
    Aes* aes, const byte* a, word32 aSz, int endA)
9254
{
9255
    word32 blocks;
9256
    int partial;
9257
9258
    ASSERT_SAVED_VECTOR_REGISTERS();
9259
9260
    if (aSz != 0 && a != NULL) {
9261
        /* Total count of AAD updated. */
9262
        aes->aSz += aSz;
9263
        /* Check if we have unprocessed data. */
9264
        if (aes->aOver > 0) {
9265
            /* Calculate amount we can use - fill up the block. */
9266
            byte sz = AES_BLOCK_SIZE - aes->aOver;
9267
            if (sz > aSz) {
9268
                sz = (byte)aSz;
9269
            }
9270
            /* Copy extra into last GHASH block array and update count. */
9271
            XMEMCPY(AES_LASTGBLOCK(aes) + aes->aOver, a, sz);
9272
            aes->aOver += sz;
9273
            if (aes->aOver == AES_BLOCK_SIZE) {
9274
                /* We have filled up the block and can process. */
9275
            #ifdef HAVE_INTEL_AVX2
9276
                if (IS_INTEL_AVX2(intel_flags)) {
9277
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9278
                                             aes->gcm.H);
9279
                }
9280
                else
9281
            #endif
9282
            #ifdef HAVE_INTEL_AVX1
9283
                if (IS_INTEL_AVX1(intel_flags)) {
9284
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9285
                                             aes->gcm.H);
9286
                }
9287
                else
9288
            #endif
9289
                {
9290
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9291
                                              aes->gcm.H);
9292
                }
9293
                /* Reset count. */
9294
                aes->aOver = 0;
9295
            }
9296
            /* Used up some data. */
9297
            aSz -= sz;
9298
            a += sz;
9299
        }
9300
9301
        /* Calculate number of blocks of AAD and the leftover. */
9302
        blocks = aSz / AES_BLOCK_SIZE;
9303
        partial = aSz % AES_BLOCK_SIZE;
9304
        if (blocks > 0) {
9305
            /* GHASH full blocks now. */
9306
        #ifdef HAVE_INTEL_AVX2
9307
            if (IS_INTEL_AVX2(intel_flags)) {
9308
                AES_GCM_aad_update_avx2(a, blocks * AES_BLOCK_SIZE,
9309
                                        AES_TAG(aes), aes->gcm.H);
9310
            }
9311
            else
9312
        #endif
9313
        #ifdef HAVE_INTEL_AVX1
9314
            if (IS_INTEL_AVX1(intel_flags)) {
9315
                AES_GCM_aad_update_avx1(a, blocks * AES_BLOCK_SIZE,
9316
                                        AES_TAG(aes), aes->gcm.H);
9317
            }
9318
            else
9319
        #endif
9320
            {
9321
                AES_GCM_aad_update_aesni(a, blocks * AES_BLOCK_SIZE,
9322
                                         AES_TAG(aes), aes->gcm.H);
9323
            }
9324
            /* Skip over to end of AAD blocks. */
9325
            a += blocks * AES_BLOCK_SIZE;
9326
        }
9327
        if (partial != 0) {
9328
            /* Cache the partial block. */
9329
            XMEMCPY(AES_LASTGBLOCK(aes), a, (size_t)partial);
9330
            aes->aOver = (byte)partial;
9331
        }
9332
    }
9333
    if (endA && (aes->aOver > 0)) {
9334
        /* No more AAD coming and we have a partial block. */
9335
        /* Fill the rest of the block with zeros. */
9336
        XMEMSET(AES_LASTGBLOCK(aes) + aes->aOver, 0,
9337
                AES_BLOCK_SIZE - aes->aOver);
9338
        /* GHASH last AAD block. */
9339
    #ifdef HAVE_INTEL_AVX2
9340
        if (IS_INTEL_AVX2(intel_flags)) {
9341
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9342
                                     aes->gcm.H);
9343
        }
9344
        else
9345
    #endif
9346
    #ifdef HAVE_INTEL_AVX1
9347
        if (IS_INTEL_AVX1(intel_flags)) {
9348
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9349
                                     aes->gcm.H);
9350
        }
9351
        else
9352
    #endif
9353
        {
9354
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9355
                                      aes->gcm.H);
9356
        }
9357
        /* Clear partial count for next time through. */
9358
        aes->aOver = 0;
9359
    }
9360
9361
    return 0;
9362
}
9363
9364
/* Update the AES GCM for encryption with data and/or authentication data.
9365
 *
9366
 * Implementation uses AVX2, AVX1 or straight AES-NI optimized assembly code.
9367
 *
9368
 * @param [in, out] aes  AES object.
9369
 * @param [out]     c    Buffer to hold cipher text.
9370
 * @param [in]      p    Buffer holding plaintext.
9371
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
9372
 * @param [in]      a    Buffer holding authentication data.
9373
 * @param [in]      aSz  Length of authentication data in bytes.
9374
 */
9375
static WARN_UNUSED_RESULT int AesGcmEncryptUpdate_aesni(
9376
    Aes* aes, byte* c, const byte* p, word32 cSz, const byte* a, word32 aSz)
9377
{
9378
    word32 blocks;
9379
    int partial;
9380
    int ret;
9381
9382
    ASSERT_SAVED_VECTOR_REGISTERS();
9383
9384
    /* Hash in A, the Authentication Data */
9385
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
9386
    if (ret != 0)
9387
        return ret;
9388
9389
    /* Encrypt plaintext and Hash in C, the Cipher text */
9390
    if (cSz != 0 && c != NULL) {
9391
        /* Update count of cipher text we have hashed. */
9392
        aes->cSz += cSz;
9393
        if (aes->cOver > 0) {
9394
            /* Calculate amount we can use - fill up the block. */
9395
            byte sz = AES_BLOCK_SIZE - aes->cOver;
9396
            if (sz > cSz) {
9397
                sz = (byte)cSz;
9398
            }
9399
            /* Encrypt some of the plaintext. */
9400
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, p, sz);
9401
            XMEMCPY(c, AES_LASTGBLOCK(aes) + aes->cOver, sz);
9402
            /* Update count of unused encrypted counter. */
9403
            aes->cOver += sz;
9404
            if (aes->cOver == AES_BLOCK_SIZE) {
9405
                /* We have filled up the block and can process. */
9406
            #ifdef HAVE_INTEL_AVX2
9407
                if (IS_INTEL_AVX2(intel_flags)) {
9408
                    AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9409
                                             aes->gcm.H);
9410
                }
9411
                else
9412
            #endif
9413
            #ifdef HAVE_INTEL_AVX1
9414
                if (IS_INTEL_AVX1(intel_flags)) {
9415
                    AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9416
                                             aes->gcm.H);
9417
                }
9418
                else
9419
            #endif
9420
                {
9421
                    AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9422
                                              aes->gcm.H);
9423
                }
9424
                /* Reset count. */
9425
                aes->cOver = 0;
9426
            }
9427
            /* Used up some data. */
9428
            cSz -= sz;
9429
            p += sz;
9430
            c += sz;
9431
        }
9432
9433
        /* Calculate number of blocks of plaintext and the leftover. */
9434
        blocks = cSz / AES_BLOCK_SIZE;
9435
        partial = cSz % AES_BLOCK_SIZE;
9436
        if (blocks > 0) {
9437
            /* Encrypt and GHASH full blocks now. */
9438
        #ifdef HAVE_INTEL_AVX2
9439
            if (IS_INTEL_AVX2(intel_flags)) {
9440
                AES_GCM_encrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
9441
                    c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9442
                    AES_COUNTER(aes));
9443
            }
9444
            else
9445
        #endif
9446
        #ifdef HAVE_INTEL_AVX1
9447
            if (IS_INTEL_AVX1(intel_flags)) {
9448
                AES_GCM_encrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
9449
                    c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9450
                    AES_COUNTER(aes));
9451
            }
9452
            else
9453
        #endif
9454
            {
9455
                AES_GCM_encrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
9456
                    c, p, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9457
                    AES_COUNTER(aes));
9458
            }
9459
            /* Skip over to end of blocks. */
9460
            p += blocks * AES_BLOCK_SIZE;
9461
            c += blocks * AES_BLOCK_SIZE;
9462
        }
9463
        if (partial != 0) {
9464
            /* Encrypt the counter - XOR in zeros as proxy for plaintext. */
9465
            XMEMSET(AES_LASTGBLOCK(aes), 0, AES_BLOCK_SIZE);
9466
        #ifdef HAVE_INTEL_AVX2
9467
            if (IS_INTEL_AVX2(intel_flags)) {
9468
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
9469
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9470
            }
9471
            else
9472
        #endif
9473
        #ifdef HAVE_INTEL_AVX1
9474
            if (IS_INTEL_AVX1(intel_flags)) {
9475
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
9476
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9477
            }
9478
            else
9479
        #endif
9480
            {
9481
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
9482
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9483
            }
9484
            /* XOR the remaining plaintext to calculate cipher text.
9485
             * Keep cipher text for GHASH of last partial block.
9486
             */
9487
            xorbuf(AES_LASTGBLOCK(aes), p, (word32)partial);
9488
            XMEMCPY(c, AES_LASTGBLOCK(aes), (size_t)partial);
9489
            /* Update count of the block used. */
9490
            aes->cOver = (byte)partial;
9491
        }
9492
    }
9493
    return 0;
9494
}
9495
9496
/* Finalize the AES GCM for encryption and calculate the authentication tag.
9497
 *
9498
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
9499
 *
9500
 * @param [in, out] aes        AES object.
9501
 * @param [in]      authTag    Buffer to hold authentication tag.
9502
 * @param [in]      authTagSz  Length of authentication tag in bytes.
9503
 * @return  0 on success.
9504
 */
9505
static WARN_UNUSED_RESULT int AesGcmEncryptFinal_aesni(
9506
    Aes* aes, byte* authTag, word32 authTagSz)
9507
{
9508
    /* AAD block incomplete when > 0 */
9509
    byte over = aes->aOver;
9510
9511
    ASSERT_SAVED_VECTOR_REGISTERS();
9512
9513
    if (aes->cOver > 0) {
9514
        /* Cipher text block incomplete. */
9515
        over = aes->cOver;
9516
    }
9517
    if (over > 0) {
9518
        /* Fill the rest of the block with zeros. */
9519
        XMEMSET(AES_LASTGBLOCK(aes) + over, 0, AES_BLOCK_SIZE - over);
9520
        /* GHASH last cipher block. */
9521
    #ifdef HAVE_INTEL_AVX2
9522
        if (IS_INTEL_AVX2(intel_flags)) {
9523
            AES_GCM_ghash_block_avx2(AES_LASTGBLOCK(aes), AES_TAG(aes),
9524
                                     aes->gcm.H);
9525
        }
9526
        else
9527
    #endif
9528
    #ifdef HAVE_INTEL_AVX1
9529
        if (IS_INTEL_AVX1(intel_flags)) {
9530
            AES_GCM_ghash_block_avx1(AES_LASTGBLOCK(aes), AES_TAG(aes),
9531
                                     aes->gcm.H);
9532
        }
9533
        else
9534
    #endif
9535
        {
9536
            AES_GCM_ghash_block_aesni(AES_LASTGBLOCK(aes), AES_TAG(aes),
9537
                                      aes->gcm.H);
9538
        }
9539
    }
9540
    /* Calculate the authentication tag. */
9541
#ifdef HAVE_INTEL_AVX2
9542
    if (IS_INTEL_AVX2(intel_flags)) {
9543
        AES_GCM_encrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9544
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
9545
    }
9546
    else
9547
#endif
9548
#ifdef HAVE_INTEL_AVX1
9549
    if (IS_INTEL_AVX1(intel_flags)) {
9550
        AES_GCM_encrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9551
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
9552
    }
9553
    else
9554
#endif
9555
    {
9556
        AES_GCM_encrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9557
            aes->aSz, aes->gcm.H, AES_INITCTR(aes));
9558
    }
9559
9560
    return 0;
9561
}
9562
9563
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
9564
9565
#ifdef __cplusplus
9566
    extern "C" {
9567
#endif
9568
9569
/* Assembly code implementations in: aes_gcm_asm.S and aes_gcm_x86_asm.S */
9570
#ifdef HAVE_INTEL_AVX2
9571
extern void AES_GCM_decrypt_update_avx2(const unsigned char* key, int nr,
9572
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9573
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9574
extern void AES_GCM_decrypt_final_avx2(unsigned char* tag,
9575
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9576
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
9577
#endif
9578
#ifdef HAVE_INTEL_AVX1
9579
extern void AES_GCM_decrypt_update_avx1(const unsigned char* key, int nr,
9580
    unsigned char* out, const unsigned char* in, unsigned int nbytes,
9581
    unsigned char* tag, unsigned char* h, unsigned char* counter);
9582
extern void AES_GCM_decrypt_final_avx1(unsigned char* tag,
9583
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9584
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
9585
#endif
9586
extern void AES_GCM_decrypt_update_aesni(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_decrypt_final_aesni(unsigned char* tag,
9590
    const unsigned char* authTag, unsigned int tbytes, unsigned int nbytes,
9591
    unsigned int abytes, unsigned char* h, unsigned char* initCtr, int* res);
9592
9593
#ifdef __cplusplus
9594
    } /* extern "C" */
9595
#endif
9596
9597
/* Update the AES GCM for decryption with data and/or authentication data.
9598
 *
9599
 * @param [in, out] aes  AES object.
9600
 * @param [out]     p    Buffer to hold plaintext.
9601
 * @param [in]      c    Buffer holding cipher text.
9602
 * @param [in]      cSz  Length of cipher text/plaintext in bytes.
9603
 * @param [in]      a    Buffer holding authentication data.
9604
 * @param [in]      aSz  Length of authentication data in bytes.
9605
 */
9606
static WARN_UNUSED_RESULT int AesGcmDecryptUpdate_aesni(
9607
    Aes* aes, byte* p, const byte* c, word32 cSz, const byte* a, word32 aSz)
9608
{
9609
    word32 blocks;
9610
    int partial;
9611
    int ret;
9612
9613
    ASSERT_SAVED_VECTOR_REGISTERS();
9614
9615
    /* Hash in A, the Authentication Data */
9616
    ret = AesGcmAadUpdate_aesni(aes, a, aSz, (cSz > 0) && (c != NULL));
9617
    if (ret != 0)
9618
        return ret;
9619
9620
    /* Hash in C, the Cipher text, and decrypt. */
9621
    if (cSz != 0 && p != NULL) {
9622
        /* Update count of cipher text we have hashed. */
9623
        aes->cSz += cSz;
9624
        if (aes->cOver > 0) {
9625
            /* Calculate amount we can use - fill up the block. */
9626
            byte sz = AES_BLOCK_SIZE - aes->cOver;
9627
            if (sz > cSz) {
9628
                sz = (byte)cSz;
9629
            }
9630
            /* Keep a copy of the cipher text for GHASH. */
9631
            XMEMCPY(AES_LASTBLOCK(aes) + aes->cOver, c, sz);
9632
            /* Decrypt some of the cipher text. */
9633
            xorbuf(AES_LASTGBLOCK(aes) + aes->cOver, c, sz);
9634
            XMEMCPY(p, AES_LASTGBLOCK(aes) + aes->cOver, sz);
9635
            /* Update count of unused encrypted counter. */
9636
            aes->cOver += sz;
9637
            if (aes->cOver == AES_BLOCK_SIZE) {
9638
                /* We have filled up the block and can process. */
9639
            #ifdef HAVE_INTEL_AVX2
9640
                if (IS_INTEL_AVX2(intel_flags)) {
9641
                    AES_GCM_ghash_block_avx2(AES_LASTBLOCK(aes), AES_TAG(aes),
9642
                                             aes->gcm.H);
9643
                }
9644
                else
9645
            #endif
9646
            #ifdef HAVE_INTEL_AVX1
9647
                if (IS_INTEL_AVX1(intel_flags)) {
9648
                    AES_GCM_ghash_block_avx1(AES_LASTBLOCK(aes), AES_TAG(aes),
9649
                                             aes->gcm.H);
9650
                }
9651
                else
9652
            #endif
9653
                {
9654
                    AES_GCM_ghash_block_aesni(AES_LASTBLOCK(aes), AES_TAG(aes),
9655
                                              aes->gcm.H);
9656
                }
9657
                /* Reset count. */
9658
                aes->cOver = 0;
9659
            }
9660
            /* Used up some data. */
9661
            cSz -= sz;
9662
            c += sz;
9663
            p += sz;
9664
        }
9665
9666
        /* Calculate number of blocks of plaintext and the leftover. */
9667
        blocks = cSz / AES_BLOCK_SIZE;
9668
        partial = cSz % AES_BLOCK_SIZE;
9669
        if (blocks > 0) {
9670
            /* Decrypt and GHASH full blocks now. */
9671
        #ifdef HAVE_INTEL_AVX2
9672
            if (IS_INTEL_AVX2(intel_flags)) {
9673
                AES_GCM_decrypt_update_avx2((byte*)aes->key, (int)aes->rounds,
9674
                    p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9675
                    AES_COUNTER(aes));
9676
            }
9677
            else
9678
        #endif
9679
        #ifdef HAVE_INTEL_AVX1
9680
            if (IS_INTEL_AVX1(intel_flags)) {
9681
                AES_GCM_decrypt_update_avx1((byte*)aes->key, (int)aes->rounds,
9682
                    p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9683
                    AES_COUNTER(aes));
9684
            }
9685
            else
9686
        #endif
9687
            {
9688
                AES_GCM_decrypt_update_aesni((byte*)aes->key, (int)aes->rounds,
9689
                    p, c, blocks * AES_BLOCK_SIZE, AES_TAG(aes), aes->gcm.H,
9690
                    AES_COUNTER(aes));
9691
            }
9692
            /* Skip over to end of blocks. */
9693
            c += blocks * AES_BLOCK_SIZE;
9694
            p += blocks * AES_BLOCK_SIZE;
9695
        }
9696
        if (partial != 0) {
9697
            /* Encrypt the counter - XOR in zeros as proxy for cipher text. */
9698
            XMEMSET(AES_LASTGBLOCK(aes), 0, AES_BLOCK_SIZE);
9699
        #ifdef HAVE_INTEL_AVX2
9700
            if (IS_INTEL_AVX2(intel_flags)) {
9701
                AES_GCM_encrypt_block_avx2((byte*)aes->key, (int)aes->rounds,
9702
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9703
            }
9704
            else
9705
        #endif
9706
        #ifdef HAVE_INTEL_AVX1
9707
            if (IS_INTEL_AVX1(intel_flags)) {
9708
                AES_GCM_encrypt_block_avx1((byte*)aes->key, (int)aes->rounds,
9709
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9710
            }
9711
            else
9712
        #endif
9713
            {
9714
                AES_GCM_encrypt_block_aesni((byte*)aes->key, (int)aes->rounds,
9715
                    AES_LASTGBLOCK(aes), AES_LASTGBLOCK(aes), AES_COUNTER(aes));
9716
            }
9717
            /* Keep cipher text for GHASH of last partial block. */
9718
            XMEMCPY(AES_LASTBLOCK(aes), c, (size_t)partial);
9719
            /* XOR the remaining cipher text to calculate plaintext. */
9720
            xorbuf(AES_LASTGBLOCK(aes), c, (word32)partial);
9721
            XMEMCPY(p, AES_LASTGBLOCK(aes), (size_t)partial);
9722
            /* Update count of the block used. */
9723
            aes->cOver = (byte)partial;
9724
        }
9725
    }
9726
9727
    return 0;
9728
}
9729
9730
/* Finalize the AES GCM for decryption and check the authentication tag.
9731
 *
9732
 * Calls AVX2, AVX1 or straight AES-NI optimized assembly code.
9733
 *
9734
 * @param [in, out] aes        AES object.
9735
 * @param [in]      authTag    Buffer holding authentication tag.
9736
 * @param [in]      authTagSz  Length of authentication tag in bytes.
9737
 * @return  0 on success.
9738
 * @return  AES_GCM_AUTH_E when authentication tag doesn't match calculated
9739
 *          value.
9740
 */
9741
static WARN_UNUSED_RESULT int AesGcmDecryptFinal_aesni(
9742
    Aes* aes, const byte* authTag, word32 authTagSz)
9743
{
9744
    int ret = 0;
9745
    int res;
9746
    /* AAD block incomplete when > 0 */
9747
    byte over = aes->aOver;
9748
    byte *lastBlock = AES_LASTGBLOCK(aes);
9749
9750
    ASSERT_SAVED_VECTOR_REGISTERS();
9751
9752
    if (aes->cOver > 0) {
9753
        /* Cipher text block incomplete. */
9754
        over = aes->cOver;
9755
        lastBlock = AES_LASTBLOCK(aes);
9756
    }
9757
    if (over > 0) {
9758
        /* Zeroize the unused part of the block. */
9759
        XMEMSET(lastBlock + over, 0, AES_BLOCK_SIZE - over);
9760
        /* Hash the last block of cipher text. */
9761
    #ifdef HAVE_INTEL_AVX2
9762
        if (IS_INTEL_AVX2(intel_flags)) {
9763
            AES_GCM_ghash_block_avx2(lastBlock, AES_TAG(aes), aes->gcm.H);
9764
        }
9765
        else
9766
    #endif
9767
    #ifdef HAVE_INTEL_AVX1
9768
        if (IS_INTEL_AVX1(intel_flags)) {
9769
            AES_GCM_ghash_block_avx1(lastBlock, AES_TAG(aes), aes->gcm.H);
9770
        }
9771
        else
9772
    #endif
9773
        {
9774
            AES_GCM_ghash_block_aesni(lastBlock, AES_TAG(aes), aes->gcm.H);
9775
        }
9776
    }
9777
    /* Calculate and compare the authentication tag. */
9778
#ifdef HAVE_INTEL_AVX2
9779
    if (IS_INTEL_AVX2(intel_flags)) {
9780
        AES_GCM_decrypt_final_avx2(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9781
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
9782
    }
9783
    else
9784
#endif
9785
#ifdef HAVE_INTEL_AVX1
9786
    if (IS_INTEL_AVX1(intel_flags)) {
9787
        AES_GCM_decrypt_final_avx1(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9788
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
9789
    }
9790
    else
9791
#endif
9792
    {
9793
        AES_GCM_decrypt_final_aesni(AES_TAG(aes), authTag, authTagSz, aes->cSz,
9794
            aes->aSz, aes->gcm.H, AES_INITCTR(aes), &res);
9795
    }
9796
9797
    /* Return error code when calculated doesn't match input. */
9798
    if (res == 0) {
9799
        ret = AES_GCM_AUTH_E;
9800
    }
9801
    return ret;
9802
}
9803
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
9804
#endif /* WOLFSSL_AESNI */
9805
9806
/* Initialize an AES GCM cipher for encryption or decryption.
9807
 *
9808
 * Must call wc_AesInit() before calling this function.
9809
 * Call wc_AesGcmSetIV() before calling this function to generate part of IV.
9810
 * Call wc_AesGcmSetExtIV() before calling this function to cache IV.
9811
 *
9812
 * @param [in, out] aes   AES object.
9813
 * @param [in]      key   Buffer holding key.
9814
 * @param [in]      len   Length of key in bytes.
9815
 * @param [in]      iv    Buffer holding IV/nonce.
9816
 * @param [in]      ivSz  Length of IV/nonce in bytes.
9817
 * @return  0 on success.
9818
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
9819
 *          is NULL, or the IV is NULL and no previous IV has been set.
9820
 * @return  MEMORY_E when dynamic memory allocation fails. (WOLFSSL_SMALL_STACK)
9821
 */
9822
int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv,
9823
    word32 ivSz)
9824
0
{
9825
0
    int ret = 0;
9826
9827
    /* Check validity of parameters. */
9828
0
    if ((aes == NULL) || ((len > 0) && (key == NULL)) ||
9829
0
            ((ivSz == 0) && (iv != NULL)) ||
9830
0
            ((ivSz > 0) && (iv == NULL))) {
9831
0
        ret = BAD_FUNC_ARG;
9832
0
    }
9833
9834
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
9835
0
    if ((ret == 0) && (aes->streamData == NULL)) {
9836
        /* Allocate buffers for streaming. */
9837
0
        aes->streamData = (byte*)XMALLOC(5 * AES_BLOCK_SIZE, aes->heap,
9838
0
                                                              DYNAMIC_TYPE_AES);
9839
0
        if (aes->streamData == NULL) {
9840
0
            ret = MEMORY_E;
9841
0
        }
9842
0
    }
9843
0
#endif
9844
9845
    /* Set the key if passed in. */
9846
0
    if ((ret == 0) && (key != NULL)) {
9847
0
        ret = wc_AesGcmSetKey(aes, key, len);
9848
0
    }
9849
9850
0
    if (ret == 0) {
9851
        /* Set the IV passed in if it is smaller than a block. */
9852
0
        if ((iv != NULL) && (ivSz <= AES_BLOCK_SIZE)) {
9853
0
            XMEMMOVE((byte*)aes->reg, iv, ivSz);
9854
0
            aes->nonceSz = ivSz;
9855
0
        }
9856
        /* No IV passed in, check for cached IV. */
9857
0
        if ((iv == NULL) && (aes->nonceSz != 0)) {
9858
            /* Use the cached copy. */
9859
0
            iv = (byte*)aes->reg;
9860
0
            ivSz = aes->nonceSz;
9861
0
        }
9862
9863
0
        if (iv != NULL) {
9864
            /* Initialize with the IV. */
9865
0
            VECTOR_REGISTERS_PUSH;
9866
9867
        #ifdef WOLFSSL_AESNI
9868
            if (aes->use_aesni) {
9869
                ret = AesGcmInit_aesni(aes, iv, ivSz);
9870
            }
9871
            else
9872
        #endif
9873
0
            {
9874
0
                ret = AesGcmInit_C(aes, iv, ivSz);
9875
0
            }
9876
9877
0
            VECTOR_REGISTERS_POP;
9878
9879
0
            if (ret == 0)
9880
0
                aes->nonceSet = 1;
9881
0
        }
9882
0
    }
9883
9884
0
    return ret;
9885
0
}
9886
9887
/* Initialize an AES GCM cipher for encryption.
9888
 *
9889
 * Must call wc_AesInit() before calling this function.
9890
 *
9891
 * @param [in, out] aes   AES object.
9892
 * @param [in]      key   Buffer holding key.
9893
 * @param [in]      len   Length of key in bytes.
9894
 * @param [in]      iv    Buffer holding IV/nonce.
9895
 * @param [in]      ivSz  Length of IV/nonce in bytes.
9896
 * @return  0 on success.
9897
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
9898
 *          is NULL, or the IV is NULL and no previous IV has been set.
9899
 */
9900
int wc_AesGcmEncryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
9901
    word32 ivSz)
9902
0
{
9903
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
9904
0
}
9905
9906
/* Initialize an AES GCM cipher for encryption. Get IV.
9907
 *
9908
 * Must call wc_AesGcmSetIV() to generate part of IV before calling this
9909
 * function.
9910
 * Must call wc_AesInit() before calling this function.
9911
 *
9912
 * See wc_AesGcmEncrypt_ex() for non-streaming version of getting IV out.
9913
 *
9914
 * @param [in, out] aes   AES object.
9915
 * @param [in]      key   Buffer holding key.
9916
 * @param [in]      len   Length of key in bytes.
9917
 * @param [in]      iv    Buffer holding IV/nonce.
9918
 * @param [in]      ivSz  Length of IV/nonce in bytes.
9919
 * @return  0 on success.
9920
 * @return  BAD_FUNC_ARG when aes is NULL, key length is non-zero but key
9921
 *          is NULL, or the IV is NULL or ivOutSz is not the same as cached
9922
 *          nonce size.
9923
 */
9924
int wc_AesGcmEncryptInit_ex(Aes* aes, const byte* key, word32 len, byte* ivOut,
9925
    word32 ivOutSz)
9926
0
{
9927
0
    int ret;
9928
9929
    /* Check validity of parameters. */
9930
0
    if ((aes == NULL) || (ivOut == NULL) || (ivOutSz != aes->nonceSz)) {
9931
0
        ret = BAD_FUNC_ARG;
9932
0
    }
9933
0
    else {
9934
        /* Copy out the IV including generated part for decryption. */
9935
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
9936
        /* Initialize AES GCM cipher with key and cached Iv. */
9937
0
        ret = wc_AesGcmInit(aes, key, len, NULL, 0);
9938
0
    }
9939
9940
0
    return ret;
9941
0
}
9942
9943
/* Update the AES GCM for encryption with data and/or authentication data.
9944
 *
9945
 * All the AAD must be passed to update before the plaintext.
9946
 * Last part of AAD can be passed with first part of plaintext.
9947
 *
9948
 * Must set key and IV before calling this function.
9949
 * Must call wc_AesGcmInit() before calling this function.
9950
 *
9951
 * @param [in, out] aes       AES object.
9952
 * @param [out]     out       Buffer to hold cipher text.
9953
 * @param [in]      in        Buffer holding plaintext.
9954
 * @param [in]      sz        Length of plaintext in bytes.
9955
 * @param [in]      authIn    Buffer holding authentication data.
9956
 * @param [in]      authInSz  Length of authentication data in bytes.
9957
 * @return  0 on success.
9958
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
9959
 *          is NULL.
9960
 */
9961
int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
9962
    const byte* authIn, word32 authInSz)
9963
0
{
9964
0
    int ret = 0;
9965
9966
    /* Check validity of parameters. */
9967
0
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
9968
0
            ((out == NULL) || (in == NULL)))) {
9969
0
        ret = BAD_FUNC_ARG;
9970
0
    }
9971
9972
    /* Check key has been set. */
9973
0
    if ((ret == 0) && (!aes->gcmKeySet)) {
9974
0
        ret = MISSING_KEY;
9975
0
    }
9976
    /* Check IV has been set. */
9977
0
    if ((ret == 0) && (!aes->nonceSet)) {
9978
0
        ret = MISSING_IV;
9979
0
    }
9980
9981
0
    if ((ret == 0) && aes->ctrSet && (aes->aSz == 0) && (aes->cSz == 0)) {
9982
0
        aes->invokeCtr[0]++;
9983
0
        if (aes->invokeCtr[0] == 0) {
9984
0
            aes->invokeCtr[1]++;
9985
0
            if (aes->invokeCtr[1] == 0)
9986
0
                ret = AES_GCM_OVERFLOW_E;
9987
0
        }
9988
0
    }
9989
9990
0
    if (ret == 0) {
9991
        /* Encrypt with AAD and/or plaintext. */
9992
0
        VECTOR_REGISTERS_PUSH;
9993
9994
    #ifdef WOLFSSL_AESNI
9995
        if (aes->use_aesni) {
9996
            ret = AesGcmEncryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
9997
        }
9998
        else
9999
    #endif
10000
0
        {
10001
            /* Encrypt the plaintext. */
10002
0
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
10003
0
            if (ret == 0) {
10004
                /* Update the authentication tag with any authentication data and the
10005
                 * new cipher text. */
10006
0
                GHASH_UPDATE(aes, authIn, authInSz, out, sz);
10007
0
            }
10008
0
        }
10009
10010
0
        VECTOR_REGISTERS_POP;
10011
0
    }
10012
10013
0
    return ret;
10014
0
}
10015
10016
/* Finalize the AES GCM for encryption and return the authentication tag.
10017
 *
10018
 * Must set key and IV before calling this function.
10019
 * Must call wc_AesGcmInit() before calling this function.
10020
 *
10021
 * @param [in, out] aes        AES object.
10022
 * @param [out]     authTag    Buffer to hold authentication tag.
10023
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10024
 * @return  0 on success.
10025
 */
10026
int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz)
10027
0
{
10028
0
    int ret = 0;
10029
10030
    /* Check validity of parameters. */
10031
0
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > AES_BLOCK_SIZE) ||
10032
0
            (authTagSz == 0)) {
10033
0
        ret = BAD_FUNC_ARG;
10034
0
    }
10035
10036
    /* Check key has been set. */
10037
0
    if ((ret == 0) && (!aes->gcmKeySet)) {
10038
0
        ret = MISSING_KEY;
10039
0
    }
10040
    /* Check IV has been set. */
10041
0
    if ((ret == 0) && (!aes->nonceSet)) {
10042
0
        ret = MISSING_IV;
10043
0
    }
10044
10045
0
    if (ret == 0) {
10046
        /* Calculate authentication tag. */
10047
0
        VECTOR_REGISTERS_PUSH;
10048
    #ifdef WOLFSSL_AESNI
10049
        if (aes->use_aesni) {
10050
            ret = AesGcmEncryptFinal_aesni(aes, authTag, authTagSz);
10051
        }
10052
        else
10053
    #endif
10054
0
        {
10055
0
            ret = AesGcmFinal_C(aes, authTag, authTagSz);
10056
0
        }
10057
0
        VECTOR_REGISTERS_POP;
10058
0
    }
10059
10060
0
    if ((ret == 0) && aes->ctrSet) {
10061
0
        IncCtr((byte*)aes->reg, aes->nonceSz);
10062
0
    }
10063
10064
0
    return ret;
10065
0
}
10066
10067
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
10068
/* Initialize an AES GCM cipher for decryption.
10069
 *
10070
 * Must call wc_AesInit() before calling this function.
10071
 *
10072
 * Call wc_AesGcmSetExtIV() before calling this function to use FIPS external IV
10073
 * instead.
10074
 *
10075
 * @param [in, out] aes   AES object.
10076
 * @param [in]      key   Buffer holding key.
10077
 * @param [in]      len   Length of key in bytes.
10078
 * @param [in]      iv    Buffer holding IV/nonce.
10079
 * @param [in]      ivSz  Length of IV/nonce in bytes.
10080
 * @return  0 on success.
10081
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10082
 *          is NULL, or the IV is NULL and no previous IV has been set.
10083
 */
10084
int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv,
10085
    word32 ivSz)
10086
0
{
10087
0
    return wc_AesGcmInit(aes, key, len, iv, ivSz);
10088
0
}
10089
10090
/* Update the AES GCM for decryption with data and/or authentication data.
10091
 *
10092
 * All the AAD must be passed to update before the cipher text.
10093
 * Last part of AAD can be passed with first part of cipher text.
10094
 *
10095
 * Must set key and IV before calling this function.
10096
 * Must call wc_AesGcmInit() before calling this function.
10097
 *
10098
 * @param [in, out] aes       AES object.
10099
 * @param [out]     out       Buffer to hold plaintext.
10100
 * @param [in]      in        Buffer holding cipher text.
10101
 * @param [in]      sz        Length of cipher text in bytes.
10102
 * @param [in]      authIn    Buffer holding authentication data.
10103
 * @param [in]      authInSz  Length of authentication data in bytes.
10104
 * @return  0 on success.
10105
 * @return  BAD_FUNC_ARG when aes is NULL, or a length is non-zero but buffer
10106
 *          is NULL.
10107
 */
10108
int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz,
10109
    const byte* authIn, word32 authInSz)
10110
0
{
10111
0
    int ret = 0;
10112
10113
    /* Check validity of parameters. */
10114
0
    if ((aes == NULL) || ((authInSz > 0) && (authIn == NULL)) || ((sz > 0) &&
10115
0
            ((out == NULL) || (in == NULL)))) {
10116
0
        ret = BAD_FUNC_ARG;
10117
0
    }
10118
10119
    /* Check key has been set. */
10120
0
    if ((ret == 0) && (!aes->gcmKeySet)) {
10121
0
        ret = MISSING_KEY;
10122
0
    }
10123
    /* Check IV has been set. */
10124
0
    if ((ret == 0) && (!aes->nonceSet)) {
10125
0
        ret = MISSING_IV;
10126
0
    }
10127
10128
0
    if (ret == 0) {
10129
        /* Decrypt with AAD and/or cipher text. */
10130
0
        VECTOR_REGISTERS_PUSH;
10131
    #ifdef WOLFSSL_AESNI
10132
        if (aes->use_aesni) {
10133
            ret = AesGcmDecryptUpdate_aesni(aes, out, in, sz, authIn, authInSz);
10134
        }
10135
        else
10136
    #endif
10137
0
        {
10138
            /* Update the authentication tag with any authentication data and
10139
             * cipher text. */
10140
0
            GHASH_UPDATE(aes, authIn, authInSz, in, sz);
10141
            /* Decrypt the cipher text. */
10142
0
            ret = AesGcmCryptUpdate_C(aes, out, in, sz);
10143
0
        }
10144
0
        VECTOR_REGISTERS_POP;
10145
0
    }
10146
10147
0
    return ret;
10148
0
}
10149
10150
/* Finalize the AES GCM for decryption and check the authentication tag.
10151
 *
10152
 * Must set key and IV before calling this function.
10153
 * Must call wc_AesGcmInit() before calling this function.
10154
 *
10155
 * @param [in, out] aes        AES object.
10156
 * @param [in]      authTag    Buffer holding authentication tag.
10157
 * @param [in]      authTagSz  Length of authentication tag in bytes.
10158
 * @return  0 on success.
10159
 */
10160
int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz)
10161
0
{
10162
0
    int ret = 0;
10163
10164
    /* Check validity of parameters. */
10165
0
    if ((aes == NULL) || (authTag == NULL) || (authTagSz > AES_BLOCK_SIZE) ||
10166
0
            (authTagSz == 0)) {
10167
0
        ret = BAD_FUNC_ARG;
10168
0
    }
10169
10170
    /* Check key has been set. */
10171
0
    if ((ret == 0) && (!aes->gcmKeySet)) {
10172
0
        ret = MISSING_KEY;
10173
0
    }
10174
    /* Check IV has been set. */
10175
0
    if ((ret == 0) && (!aes->nonceSet)) {
10176
0
        ret = MISSING_IV;
10177
0
    }
10178
10179
0
    if (ret == 0) {
10180
        /* Calculate authentication tag and compare with one passed in.. */
10181
0
        VECTOR_REGISTERS_PUSH;
10182
    #ifdef WOLFSSL_AESNI
10183
        if (aes->use_aesni) {
10184
            ret = AesGcmDecryptFinal_aesni(aes, authTag, authTagSz);
10185
        }
10186
        else
10187
    #endif
10188
0
        {
10189
0
            ALIGN32 byte calcTag[AES_BLOCK_SIZE];
10190
            /* Calculate authentication tag. */
10191
0
            ret = AesGcmFinal_C(aes, calcTag, authTagSz);
10192
0
            if (ret == 0) {
10193
                /* Check calculated tag matches the one passed in. */
10194
0
                if (ConstantCompare(authTag, calcTag, (int)authTagSz) != 0) {
10195
0
                    ret = AES_GCM_AUTH_E;
10196
0
                }
10197
0
            }
10198
0
        }
10199
0
        VECTOR_REGISTERS_POP;
10200
0
    }
10201
10202
0
    return ret;
10203
0
}
10204
#endif /* HAVE_AES_DECRYPT || HAVE_AESGCM_DECRYPT */
10205
#endif /* WOLFSSL_AESGCM_STREAM */
10206
#endif /* WOLFSSL_XILINX_CRYPT */
10207
#endif /* end of block for AESGCM implementation selection */
10208
10209
10210
/* Common to all, abstract functions that build off of lower level AESGCM
10211
 * functions */
10212
#ifndef WC_NO_RNG
10213
10214
0
static WARN_UNUSED_RESULT WC_INLINE int CheckAesGcmIvSize(int ivSz) {
10215
0
    return (ivSz == GCM_NONCE_MIN_SZ ||
10216
0
            ivSz == GCM_NONCE_MID_SZ ||
10217
0
            ivSz == GCM_NONCE_MAX_SZ);
10218
0
}
10219
10220
10221
int wc_AesGcmSetExtIV(Aes* aes, const byte* iv, word32 ivSz)
10222
0
{
10223
0
    int ret = 0;
10224
10225
0
    if (aes == NULL || iv == NULL || !CheckAesGcmIvSize((int)ivSz)) {
10226
0
        ret = BAD_FUNC_ARG;
10227
0
    }
10228
10229
0
    if (ret == 0) {
10230
0
        XMEMCPY((byte*)aes->reg, iv, ivSz);
10231
10232
        /* If the IV is 96, allow for a 2^64 invocation counter.
10233
         * For any other size for the nonce, limit the invocation
10234
         * counter to 32-bits. (SP 800-38D 8.3) */
10235
0
        aes->invokeCtr[0] = 0;
10236
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
10237
0
    #ifdef WOLFSSL_AESGCM_STREAM
10238
0
        aes->ctrSet = 1;
10239
0
    #endif
10240
0
        aes->nonceSz = ivSz;
10241
0
    }
10242
10243
0
    return ret;
10244
0
}
10245
10246
10247
int wc_AesGcmSetIV(Aes* aes, word32 ivSz,
10248
                   const byte* ivFixed, word32 ivFixedSz,
10249
                   WC_RNG* rng)
10250
0
{
10251
0
    int ret = 0;
10252
10253
0
    if (aes == NULL || rng == NULL || !CheckAesGcmIvSize((int)ivSz) ||
10254
0
        (ivFixed == NULL && ivFixedSz != 0) ||
10255
0
        (ivFixed != NULL && ivFixedSz != AES_IV_FIXED_SZ)) {
10256
10257
0
        ret = BAD_FUNC_ARG;
10258
0
    }
10259
10260
0
    if (ret == 0) {
10261
0
        byte* iv = (byte*)aes->reg;
10262
10263
0
        if (ivFixedSz)
10264
0
            XMEMCPY(iv, ivFixed, ivFixedSz);
10265
10266
0
        ret = wc_RNG_GenerateBlock(rng, iv + ivFixedSz, ivSz - ivFixedSz);
10267
0
    }
10268
10269
0
    if (ret == 0) {
10270
        /* If the IV is 96, allow for a 2^64 invocation counter.
10271
         * For any other size for the nonce, limit the invocation
10272
         * counter to 32-bits. (SP 800-38D 8.3) */
10273
0
        aes->invokeCtr[0] = 0;
10274
0
        aes->invokeCtr[1] = (ivSz == GCM_NONCE_MID_SZ) ? 0 : 0xFFFFFFFF;
10275
0
    #ifdef WOLFSSL_AESGCM_STREAM
10276
0
        aes->ctrSet = 1;
10277
0
    #endif
10278
0
        aes->nonceSz = ivSz;
10279
0
    }
10280
10281
0
    return ret;
10282
0
}
10283
10284
10285
int wc_AesGcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
10286
                        byte* ivOut, word32 ivOutSz,
10287
                        byte* authTag, word32 authTagSz,
10288
                        const byte* authIn, word32 authInSz)
10289
0
{
10290
0
    int ret = 0;
10291
10292
0
    if (aes == NULL || (sz != 0 && (in == NULL || out == NULL)) ||
10293
0
        ivOut == NULL || ivOutSz != aes->nonceSz ||
10294
0
        (authIn == NULL && authInSz != 0)) {
10295
10296
0
        ret = BAD_FUNC_ARG;
10297
0
    }
10298
10299
0
    if (ret == 0) {
10300
0
        aes->invokeCtr[0]++;
10301
0
        if (aes->invokeCtr[0] == 0) {
10302
0
            aes->invokeCtr[1]++;
10303
0
            if (aes->invokeCtr[1] == 0)
10304
0
                ret = AES_GCM_OVERFLOW_E;
10305
0
        }
10306
0
    }
10307
10308
0
    if (ret == 0) {
10309
0
        XMEMCPY(ivOut, aes->reg, ivOutSz);
10310
0
        ret = wc_AesGcmEncrypt(aes, out, in, sz,
10311
0
                               (byte*)aes->reg, ivOutSz,
10312
0
                               authTag, authTagSz,
10313
0
                               authIn, authInSz);
10314
0
        if (ret == 0)
10315
0
            IncCtr((byte*)aes->reg, ivOutSz);
10316
0
    }
10317
10318
0
    return ret;
10319
0
}
10320
10321
int wc_Gmac(const byte* key, word32 keySz, byte* iv, word32 ivSz,
10322
            const byte* authIn, word32 authInSz,
10323
            byte* authTag, word32 authTagSz, WC_RNG* rng)
10324
0
{
10325
0
#ifdef WOLFSSL_SMALL_STACK
10326
0
    Aes *aes = NULL;
10327
#else
10328
    Aes aes[1];
10329
#endif
10330
0
    int ret;
10331
10332
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
10333
0
        authTag == NULL || authTagSz == 0 || rng == NULL) {
10334
10335
0
        return BAD_FUNC_ARG;
10336
0
    }
10337
10338
0
#ifdef WOLFSSL_SMALL_STACK
10339
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
10340
0
                              DYNAMIC_TYPE_AES)) == NULL)
10341
0
        return MEMORY_E;
10342
0
#endif
10343
10344
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
10345
0
    if (ret == 0) {
10346
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
10347
0
        if (ret == 0)
10348
0
            ret = wc_AesGcmSetIV(aes, ivSz, NULL, 0, rng);
10349
0
        if (ret == 0)
10350
0
            ret = wc_AesGcmEncrypt_ex(aes, NULL, NULL, 0, iv, ivSz,
10351
0
                                  authTag, authTagSz, authIn, authInSz);
10352
0
        wc_AesFree(aes);
10353
0
    }
10354
0
    ForceZero(aes, sizeof *aes);
10355
0
#ifdef WOLFSSL_SMALL_STACK
10356
0
    XFREE(aes, NULL, DYNAMIC_TYPE_AES);
10357
0
#endif
10358
10359
0
    return ret;
10360
0
}
10361
10362
int wc_GmacVerify(const byte* key, word32 keySz,
10363
                  const byte* iv, word32 ivSz,
10364
                  const byte* authIn, word32 authInSz,
10365
                  const byte* authTag, word32 authTagSz)
10366
0
{
10367
0
    int ret;
10368
0
#ifdef HAVE_AES_DECRYPT
10369
0
#ifdef WOLFSSL_SMALL_STACK
10370
0
    Aes *aes = NULL;
10371
#else
10372
    Aes aes[1];
10373
#endif
10374
10375
0
    if (key == NULL || iv == NULL || (authIn == NULL && authInSz != 0) ||
10376
0
        authTag == NULL || authTagSz == 0 || authTagSz > AES_BLOCK_SIZE) {
10377
10378
0
        return BAD_FUNC_ARG;
10379
0
    }
10380
10381
0
#ifdef WOLFSSL_SMALL_STACK
10382
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
10383
0
                              DYNAMIC_TYPE_AES)) == NULL)
10384
0
        return MEMORY_E;
10385
0
#endif
10386
10387
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
10388
0
    if (ret == 0) {
10389
0
        ret = wc_AesGcmSetKey(aes, key, keySz);
10390
0
        if (ret == 0)
10391
0
            ret = wc_AesGcmDecrypt(aes, NULL, NULL, 0, iv, ivSz,
10392
0
                                  authTag, authTagSz, authIn, authInSz);
10393
0
        wc_AesFree(aes);
10394
0
    }
10395
0
    ForceZero(aes, sizeof *aes);
10396
0
#ifdef WOLFSSL_SMALL_STACK
10397
0
    XFREE(aes, NULL, DYNAMIC_TYPE_AES);
10398
0
#endif
10399
#else
10400
    (void)key;
10401
    (void)keySz;
10402
    (void)iv;
10403
    (void)ivSz;
10404
    (void)authIn;
10405
    (void)authInSz;
10406
    (void)authTag;
10407
    (void)authTagSz;
10408
    ret = NOT_COMPILED_IN;
10409
#endif
10410
0
    return ret;
10411
0
}
10412
10413
#endif /* WC_NO_RNG */
10414
10415
10416
WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len)
10417
0
{
10418
0
    if (gmac == NULL || key == NULL) {
10419
0
        return BAD_FUNC_ARG;
10420
0
    }
10421
0
    return wc_AesGcmSetKey(&gmac->aes, key, len);
10422
0
}
10423
10424
10425
WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz,
10426
                              const byte* authIn, word32 authInSz,
10427
                              byte* authTag, word32 authTagSz)
10428
0
{
10429
0
    if (gmac == NULL) {
10430
0
        return BAD_FUNC_ARG;
10431
0
    }
10432
10433
0
    return wc_AesGcmEncrypt(&gmac->aes, NULL, NULL, 0, iv, ivSz,
10434
0
                                         authTag, authTagSz, authIn, authInSz);
10435
0
}
10436
10437
#endif /* HAVE_AESGCM */
10438
10439
10440
#ifdef HAVE_AESCCM
10441
10442
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
10443
0
{
10444
0
    if (!((keySz == 16) || (keySz == 24) || (keySz == 32)))
10445
0
        return BAD_FUNC_ARG;
10446
10447
0
    return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
10448
0
}
10449
10450
10451
/* Checks if the tag size is an accepted value based on RFC 3610 section 2
10452
 * returns 0 if tag size is ok
10453
 */
10454
int wc_AesCcmCheckTagSize(int sz)
10455
0
{
10456
    /* values here are from RFC 3610 section 2 */
10457
0
    if (sz != 4 && sz != 6 && sz != 8 && sz != 10 && sz != 12 && sz != 14
10458
0
            && sz != 16) {
10459
0
        WOLFSSL_MSG("Bad auth tag size AES-CCM");
10460
0
        return BAD_FUNC_ARG;
10461
0
    }
10462
0
    return 0;
10463
0
}
10464
10465
#ifdef WOLFSSL_ARMASM
10466
    /* implementation located in wolfcrypt/src/port/arm/armv8-aes.c */
10467
10468
#elif defined(HAVE_COLDFIRE_SEC)
10469
    #error "Coldfire SEC doesn't currently support AES-CCM mode"
10470
10471
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
10472
        !defined(WOLFSSL_QNX_CAAM)
10473
    /* implemented in wolfcrypt/src/port/caam_aes.c */
10474
10475
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
10476
    /* implemented in wolfcrypt/src/port/silabs/silabs_aes.c */
10477
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10478
                   const byte* nonce, word32 nonceSz,
10479
                   byte* authTag, word32 authTagSz,
10480
                   const byte* authIn, word32 authInSz)
10481
{
10482
    return wc_AesCcmEncrypt_silabs(
10483
        aes, out, in, inSz,
10484
        nonce, nonceSz,
10485
        authTag, authTagSz,
10486
        authIn, authInSz);
10487
}
10488
10489
#ifdef HAVE_AES_DECRYPT
10490
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10491
                   const byte* nonce, word32 nonceSz,
10492
                   const byte* authTag, word32 authTagSz,
10493
                   const byte* authIn, word32 authInSz)
10494
{
10495
    return wc_AesCcmDecrypt_silabs(
10496
        aes, out, in, inSz,
10497
        nonce, nonceSz,
10498
        authTag, authTagSz,
10499
        authIn, authInSz);
10500
}
10501
#endif
10502
#elif defined(FREESCALE_LTC)
10503
10504
/* return 0 on success */
10505
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10506
                   const byte* nonce, word32 nonceSz,
10507
                   byte* authTag, word32 authTagSz,
10508
                   const byte* authIn, word32 authInSz)
10509
{
10510
    byte *key;
10511
    word32 keySize;
10512
    status_t status;
10513
10514
    /* sanity check on arguments */
10515
    /* note, LTC_AES_EncryptTagCcm() doesn't allow null src or dst
10516
     * ptrs even if inSz is zero (ltc_aes_ccm_check_input_args()), so
10517
     * don't allow it here either.
10518
     */
10519
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
10520
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
10521
        return BAD_FUNC_ARG;
10522
    }
10523
10524
    if (wc_AesCcmCheckTagSize(authTagSz) != 0) {
10525
        return BAD_FUNC_ARG;
10526
    }
10527
10528
    key = (byte*)aes->key;
10529
10530
    status = wc_AesGetKeySize(aes, &keySize);
10531
    if (status != 0) {
10532
        return status;
10533
    }
10534
10535
    status = wolfSSL_CryptHwMutexLock();
10536
    if (status != 0)
10537
        return status;
10538
10539
    status = LTC_AES_EncryptTagCcm(LTC_BASE, in, out, inSz,
10540
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
10541
    wolfSSL_CryptHwMutexUnLock();
10542
10543
    return (kStatus_Success == status) ? 0 : BAD_FUNC_ARG;
10544
}
10545
10546
#ifdef HAVE_AES_DECRYPT
10547
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10548
                   const byte* nonce, word32 nonceSz,
10549
                   const byte* authTag, word32 authTagSz,
10550
                   const byte* authIn, word32 authInSz)
10551
{
10552
    byte *key;
10553
    word32 keySize;
10554
    status_t status;
10555
10556
    /* sanity check on arguments */
10557
    if (aes == NULL || out == NULL || in == NULL || nonce == NULL
10558
            || authTag == NULL || nonceSz < 7 || nonceSz > 13) {
10559
        return BAD_FUNC_ARG;
10560
    }
10561
10562
    key = (byte*)aes->key;
10563
10564
    status = wc_AesGetKeySize(aes, &keySize);
10565
    if (status != 0) {
10566
        return status;
10567
    }
10568
10569
    status = wolfSSL_CryptHwMutexLock();
10570
    if (status != 0)
10571
        return status;
10572
    status = LTC_AES_DecryptTagCcm(LTC_BASE, in, out, inSz,
10573
        nonce, nonceSz, authIn, authInSz, key, keySize, authTag, authTagSz);
10574
    wolfSSL_CryptHwMutexUnLock();
10575
10576
    if (status != kStatus_Success) {
10577
        XMEMSET(out, 0, inSz);
10578
        return AES_CCM_AUTH_E;
10579
    }
10580
    return 0;
10581
}
10582
#endif /* HAVE_AES_DECRYPT */
10583
10584
#else
10585
10586
/* Software CCM */
10587
static WARN_UNUSED_RESULT int roll_x(
10588
    Aes* aes, const byte* in, word32 inSz, byte* out)
10589
0
{
10590
0
    int ret;
10591
10592
    /* process the bulk of the data */
10593
0
    while (inSz >= AES_BLOCK_SIZE) {
10594
0
        xorbuf(out, in, AES_BLOCK_SIZE);
10595
0
        in += AES_BLOCK_SIZE;
10596
0
        inSz -= AES_BLOCK_SIZE;
10597
10598
0
        ret = wc_AesEncrypt(aes, out, out);
10599
0
        if (ret != 0)
10600
0
            return ret;
10601
0
    }
10602
10603
    /* process remainder of the data */
10604
0
    if (inSz > 0) {
10605
0
        xorbuf(out, in, inSz);
10606
0
        ret = wc_AesEncrypt(aes, out, out);
10607
0
        if (ret != 0)
10608
0
            return ret;
10609
0
    }
10610
10611
0
    return 0;
10612
0
}
10613
10614
static WARN_UNUSED_RESULT int roll_auth(
10615
    Aes* aes, const byte* in, word32 inSz, byte* out)
10616
0
{
10617
0
    word32 authLenSz;
10618
0
    word32 remainder;
10619
0
    int ret;
10620
10621
    /* encode the length in */
10622
0
    if (inSz <= 0xFEFF) {
10623
0
        authLenSz = 2;
10624
0
        out[0] ^= (byte)(inSz >> 8);
10625
0
        out[1] ^= (byte)inSz;
10626
0
    }
10627
0
    else {
10628
0
        authLenSz = 6;
10629
0
        out[0] ^= 0xFF;
10630
0
        out[1] ^= 0xFE;
10631
0
        out[2] ^= (byte)(inSz >> 24);
10632
0
        out[3] ^= (byte)(inSz >> 16);
10633
0
        out[4] ^= (byte)(inSz >>  8);
10634
0
        out[5] ^= (byte)inSz;
10635
0
    }
10636
    /* Note, the protocol handles auth data up to 2^64, but we are
10637
     * using 32-bit sizes right now, so the bigger data isn't handled
10638
     * else {}
10639
     */
10640
10641
    /* start fill out the rest of the first block */
10642
0
    remainder = AES_BLOCK_SIZE - authLenSz;
10643
0
    if (inSz >= remainder) {
10644
        /* plenty of bulk data to fill the remainder of this block */
10645
0
        xorbuf(out + authLenSz, in, remainder);
10646
0
        inSz -= remainder;
10647
0
        in += remainder;
10648
0
    }
10649
0
    else {
10650
        /* not enough bulk data, copy what is available, and pad zero */
10651
0
        xorbuf(out + authLenSz, in, inSz);
10652
0
        inSz = 0;
10653
0
    }
10654
0
    ret = wc_AesEncrypt(aes, out, out);
10655
10656
0
    if ((ret == 0) && (inSz > 0)) {
10657
0
        ret = roll_x(aes, in, inSz, out);
10658
0
    }
10659
10660
0
    return ret;
10661
0
}
10662
10663
10664
static WC_INLINE void AesCcmCtrInc(byte* B, word32 lenSz)
10665
0
{
10666
0
    word32 i;
10667
10668
0
    for (i = 0; i < lenSz; i++) {
10669
0
        if (++B[AES_BLOCK_SIZE - 1 - i] != 0) return;
10670
0
    }
10671
0
}
10672
10673
#ifdef WOLFSSL_AESNI
10674
static WC_INLINE void AesCcmCtrIncSet4(byte* B, word32 lenSz)
10675
{
10676
    word32 i;
10677
10678
    /* B+1 = B */
10679
    XMEMCPY(B + AES_BLOCK_SIZE * 1, B, AES_BLOCK_SIZE);
10680
    /* B+2,B+3 = B,B+1 */
10681
    XMEMCPY(B + AES_BLOCK_SIZE * 2, B, AES_BLOCK_SIZE * 2);
10682
10683
    for (i = 0; i < lenSz; i++) {
10684
        if (++B[AES_BLOCK_SIZE * 2 - 1 - i] != 0) break;
10685
    }
10686
    B[AES_BLOCK_SIZE * 3 - 1] += 2;
10687
    if (B[AES_BLOCK_SIZE * 3 - 1] < 2) {
10688
        for (i = 1; i < lenSz; i++) {
10689
            if (++B[AES_BLOCK_SIZE * 3 - 1 - i] != 0) break;
10690
        }
10691
    }
10692
    B[AES_BLOCK_SIZE * 4 - 1] += 3;
10693
    if (B[AES_BLOCK_SIZE * 4 - 1] < 3) {
10694
        for (i = 1; i < lenSz; i++) {
10695
            if (++B[AES_BLOCK_SIZE * 4 - 1 - i] != 0) break;
10696
        }
10697
    }
10698
}
10699
10700
static WC_INLINE void AesCcmCtrInc4(byte* B, word32 lenSz)
10701
{
10702
    word32 i;
10703
10704
    B[AES_BLOCK_SIZE - 1] += 4;
10705
    if (B[AES_BLOCK_SIZE - 1] < 4) {
10706
        for (i = 1; i < lenSz; i++) {
10707
            if (++B[AES_BLOCK_SIZE - 1 - i] != 0) break;
10708
        }
10709
    }
10710
}
10711
#endif
10712
10713
/* Software AES - CCM Encrypt */
10714
/* return 0 on success */
10715
int wc_AesCcmEncrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10716
                   const byte* nonce, word32 nonceSz,
10717
                   byte* authTag, word32 authTagSz,
10718
                   const byte* authIn, word32 authInSz)
10719
0
{
10720
#ifdef WOLFSSL_AESNI
10721
    ALIGN128 byte A[AES_BLOCK_SIZE * 4];
10722
    ALIGN128 byte B[AES_BLOCK_SIZE * 4];
10723
#else
10724
0
    byte A[AES_BLOCK_SIZE];
10725
0
    byte B[AES_BLOCK_SIZE];
10726
0
#endif
10727
0
    byte lenSz;
10728
0
    word32 i;
10729
0
    byte mask = 0xFF;
10730
0
    const word32 wordSz = (word32)sizeof(word32);
10731
0
    int ret;
10732
10733
    /* sanity check on arguments */
10734
0
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
10735
0
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
10736
0
            authTagSz > AES_BLOCK_SIZE)
10737
0
        return BAD_FUNC_ARG;
10738
10739
    /* sanity check on tag size */
10740
0
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
10741
0
        return BAD_FUNC_ARG;
10742
0
    }
10743
10744
0
#ifdef WOLF_CRYPTO_CB
10745
0
    #ifndef WOLF_CRYPTO_CB_FIND
10746
0
    if (aes->devId != INVALID_DEVID)
10747
0
    #endif
10748
0
    {
10749
0
        int crypto_cb_ret =
10750
0
            wc_CryptoCb_AesCcmEncrypt(aes, out, in, inSz, nonce, nonceSz,
10751
0
                                      authTag, authTagSz, authIn, authInSz);
10752
0
        if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
10753
0
            return crypto_cb_ret;
10754
        /* fall-through when unavailable */
10755
0
    }
10756
0
#endif
10757
10758
0
    XMEMSET(A, 0, sizeof(A));
10759
0
    XMEMCPY(B+1, nonce, nonceSz);
10760
0
    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
10761
0
    B[0] = (byte)((authInSz > 0 ? 64 : 0)
10762
0
                  + (8 * (((byte)authTagSz - 2) / 2))
10763
0
                  + (lenSz - 1));
10764
0
    for (i = 0; i < lenSz; i++) {
10765
0
        if (mask && i >= wordSz)
10766
0
            mask = 0x00;
10767
0
        B[AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
10768
0
    }
10769
10770
#ifdef WOLFSSL_CHECK_MEM_ZERO
10771
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
10772
#endif
10773
10774
0
    VECTOR_REGISTERS_PUSH;
10775
0
    ret = wc_AesEncrypt(aes, B, A);
10776
#ifdef WOLFSSL_CHECK_MEM_ZERO
10777
    if (ret == 0)
10778
        wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
10779
#endif
10780
10781
0
    if ((ret == 0) && (authInSz > 0))
10782
0
        ret = roll_auth(aes, authIn, authInSz, A);
10783
10784
0
    if ((ret == 0) && (inSz > 0))
10785
0
        ret = roll_x(aes, in, inSz, A);
10786
10787
0
    if (ret == 0) {
10788
0
        XMEMCPY(authTag, A, authTagSz);
10789
10790
0
        B[0] = lenSz - 1;
10791
0
        for (i = 0; i < lenSz; i++)
10792
0
            B[AES_BLOCK_SIZE - 1 - i] = 0;
10793
0
        ret = wc_AesEncrypt(aes, B, A);
10794
0
    }
10795
10796
0
    if (ret == 0) {
10797
0
        xorbuf(authTag, A, authTagSz);
10798
0
        B[15] = 1;
10799
0
    }
10800
#ifdef WOLFSSL_AESNI
10801
    if ((ret == 0) && aes->use_aesni) {
10802
        while (inSz >= AES_BLOCK_SIZE * 4) {
10803
            AesCcmCtrIncSet4(B, lenSz);
10804
10805
            AES_ECB_encrypt_AESNI(B, A, AES_BLOCK_SIZE * 4, (byte*)aes->key,
10806
                            (int)aes->rounds);
10807
10808
            xorbuf(A, in, AES_BLOCK_SIZE * 4);
10809
            XMEMCPY(out, A, AES_BLOCK_SIZE * 4);
10810
10811
            inSz -= AES_BLOCK_SIZE * 4;
10812
            in += AES_BLOCK_SIZE * 4;
10813
            out += AES_BLOCK_SIZE * 4;
10814
10815
            AesCcmCtrInc4(B, lenSz);
10816
        }
10817
    }
10818
#endif
10819
0
    if (ret == 0) {
10820
0
        while (inSz >= AES_BLOCK_SIZE) {
10821
0
            ret = wc_AesEncrypt(aes, B, A);
10822
0
            if (ret != 0)
10823
0
                break;
10824
0
            xorbuf(A, in, AES_BLOCK_SIZE);
10825
0
            XMEMCPY(out, A, AES_BLOCK_SIZE);
10826
10827
0
            AesCcmCtrInc(B, lenSz);
10828
0
            inSz -= AES_BLOCK_SIZE;
10829
0
            in += AES_BLOCK_SIZE;
10830
0
            out += AES_BLOCK_SIZE;
10831
0
        }
10832
0
    }
10833
0
    if ((ret == 0) && (inSz > 0)) {
10834
0
        ret = wc_AesEncrypt(aes, B, A);
10835
0
    }
10836
0
    if ((ret == 0) && (inSz > 0)) {
10837
0
        xorbuf(A, in, inSz);
10838
0
        XMEMCPY(out, A, inSz);
10839
0
    }
10840
10841
0
    ForceZero(A, sizeof(A));
10842
0
    ForceZero(B, sizeof(B));
10843
10844
#ifdef WOLFSSL_CHECK_MEM_ZERO
10845
    wc_MemZero_Check(A, sizeof(A));
10846
    wc_MemZero_Check(B, sizeof(B));
10847
#endif
10848
10849
0
    VECTOR_REGISTERS_POP;
10850
10851
0
    return ret;
10852
0
}
10853
10854
#ifdef HAVE_AES_DECRYPT
10855
/* Software AES - CCM Decrypt */
10856
int  wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
10857
                   const byte* nonce, word32 nonceSz,
10858
                   const byte* authTag, word32 authTagSz,
10859
                   const byte* authIn, word32 authInSz)
10860
0
{
10861
#ifdef WOLFSSL_AESNI
10862
    ALIGN128 byte B[AES_BLOCK_SIZE * 4];
10863
    ALIGN128 byte A[AES_BLOCK_SIZE * 4];
10864
#else
10865
0
    byte A[AES_BLOCK_SIZE];
10866
0
    byte B[AES_BLOCK_SIZE];
10867
0
#endif
10868
0
    byte* o;
10869
0
    byte lenSz;
10870
0
    word32 i, oSz;
10871
0
    byte mask = 0xFF;
10872
0
    const word32 wordSz = (word32)sizeof(word32);
10873
0
    int ret = 0;
10874
10875
    /* sanity check on arguments */
10876
0
    if (aes == NULL || (inSz != 0 && (in == NULL || out == NULL)) ||
10877
0
        nonce == NULL || authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
10878
0
        authTagSz > AES_BLOCK_SIZE)
10879
0
        return BAD_FUNC_ARG;
10880
10881
    /* sanity check on tag size */
10882
0
    if (wc_AesCcmCheckTagSize((int)authTagSz) != 0) {
10883
0
        return BAD_FUNC_ARG;
10884
0
    }
10885
10886
0
#ifdef WOLF_CRYPTO_CB
10887
0
    #ifndef WOLF_CRYPTO_CB_FIND
10888
0
    if (aes->devId != INVALID_DEVID)
10889
0
    #endif
10890
0
    {
10891
0
        int crypto_cb_ret =
10892
0
            wc_CryptoCb_AesCcmDecrypt(aes, out, in, inSz, nonce, nonceSz,
10893
0
            authTag, authTagSz, authIn, authInSz);
10894
0
        if (crypto_cb_ret != CRYPTOCB_UNAVAILABLE)
10895
0
            return crypto_cb_ret;
10896
        /* fall-through when unavailable */
10897
0
    }
10898
0
#endif
10899
10900
0
    o = out;
10901
0
    oSz = inSz;
10902
0
    XMEMSET(A, 0, sizeof A);
10903
0
    XMEMCPY(B+1, nonce, nonceSz);
10904
0
    lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
10905
10906
0
    B[0] = lenSz - 1;
10907
0
    for (i = 0; i < lenSz; i++)
10908
0
        B[AES_BLOCK_SIZE - 1 - i] = 0;
10909
0
    B[15] = 1;
10910
10911
#ifdef WOLFSSL_CHECK_MEM_ZERO
10912
    wc_MemZero_Add("wc_AesCcmEncrypt A", A, sizeof(A));
10913
    wc_MemZero_Add("wc_AesCcmEncrypt B", B, sizeof(B));
10914
#endif
10915
10916
0
    VECTOR_REGISTERS_PUSH;
10917
10918
#ifdef WOLFSSL_AESNI
10919
    if (aes->use_aesni) {
10920
        while (oSz >= AES_BLOCK_SIZE * 4) {
10921
            AesCcmCtrIncSet4(B, lenSz);
10922
10923
            AES_ECB_encrypt_AESNI(B, A, AES_BLOCK_SIZE * 4, (byte*)aes->key,
10924
                            (int)aes->rounds);
10925
10926
            xorbuf(A, in, AES_BLOCK_SIZE * 4);
10927
            XMEMCPY(o, A, AES_BLOCK_SIZE * 4);
10928
10929
            oSz -= AES_BLOCK_SIZE * 4;
10930
            in += AES_BLOCK_SIZE * 4;
10931
            o += AES_BLOCK_SIZE * 4;
10932
10933
            AesCcmCtrInc4(B, lenSz);
10934
        }
10935
    }
10936
#endif
10937
10938
0
    while (oSz >= AES_BLOCK_SIZE) {
10939
0
        ret = wc_AesEncrypt(aes, B, A);
10940
0
        if (ret != 0)
10941
0
            break;
10942
0
        xorbuf(A, in, AES_BLOCK_SIZE);
10943
0
        XMEMCPY(o, A, AES_BLOCK_SIZE);
10944
0
        AesCcmCtrInc(B, lenSz);
10945
0
        oSz -= AES_BLOCK_SIZE;
10946
0
        in += AES_BLOCK_SIZE;
10947
0
        o += AES_BLOCK_SIZE;
10948
0
    }
10949
10950
0
    if ((ret == 0) && (inSz > 0))
10951
0
        ret = wc_AesEncrypt(aes, B, A);
10952
10953
0
    if ((ret == 0) && (inSz > 0)) {
10954
0
        xorbuf(A, in, oSz);
10955
0
        XMEMCPY(o, A, oSz);
10956
0
        for (i = 0; i < lenSz; i++)
10957
0
            B[AES_BLOCK_SIZE - 1 - i] = 0;
10958
0
        ret = wc_AesEncrypt(aes, B, A);
10959
0
    }
10960
10961
0
    if (ret == 0) {
10962
0
        o = out;
10963
0
        oSz = inSz;
10964
10965
0
        B[0] = (byte)((authInSz > 0 ? 64 : 0)
10966
0
                      + (8 * (((byte)authTagSz - 2) / 2))
10967
0
                      + (lenSz - 1));
10968
0
        for (i = 0; i < lenSz; i++) {
10969
0
            if (mask && i >= wordSz)
10970
0
                mask = 0x00;
10971
0
            B[AES_BLOCK_SIZE - 1 - i] = (byte)((inSz >> ((8 * i) & mask)) & mask);
10972
0
        }
10973
10974
0
        ret = wc_AesEncrypt(aes, B, A);
10975
0
    }
10976
10977
0
    if (ret == 0) {
10978
0
        if (authInSz > 0)
10979
0
            ret = roll_auth(aes, authIn, authInSz, A);
10980
0
    }
10981
0
    if ((ret == 0) && (inSz > 0))
10982
0
        ret = roll_x(aes, o, oSz, A);
10983
10984
0
    if (ret == 0) {
10985
0
        B[0] = lenSz - 1;
10986
0
        for (i = 0; i < lenSz; i++)
10987
0
            B[AES_BLOCK_SIZE - 1 - i] = 0;
10988
0
        ret = wc_AesEncrypt(aes, B, B);
10989
0
    }
10990
10991
0
    if (ret == 0)
10992
0
        xorbuf(A, B, authTagSz);
10993
10994
0
    if (ret == 0) {
10995
0
        if (ConstantCompare(A, authTag, (int)authTagSz) != 0) {
10996
            /* If the authTag check fails, don't keep the decrypted data.
10997
             * Unfortunately, you need the decrypted data to calculate the
10998
             * check value. */
10999
            #if defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) &&   \
11000
                        defined(ACVP_VECTOR_TESTING)
11001
            WOLFSSL_MSG("Preserve output for vector responses");
11002
            #else
11003
0
            if (inSz > 0)
11004
0
                XMEMSET(out, 0, inSz);
11005
0
            #endif
11006
0
            ret = AES_CCM_AUTH_E;
11007
0
        }
11008
0
    }
11009
11010
0
    ForceZero(A, sizeof(A));
11011
0
    ForceZero(B, sizeof(B));
11012
0
    o = NULL;
11013
11014
#ifdef WOLFSSL_CHECK_MEM_ZERO
11015
    wc_MemZero_Check(A, sizeof(A));
11016
    wc_MemZero_Check(B, sizeof(B));
11017
#endif
11018
11019
0
    VECTOR_REGISTERS_POP;
11020
11021
0
    return ret;
11022
0
}
11023
11024
#endif /* HAVE_AES_DECRYPT */
11025
#endif /* software CCM */
11026
11027
/* abstract functions that call lower level AESCCM functions */
11028
#ifndef WC_NO_RNG
11029
11030
int wc_AesCcmSetNonce(Aes* aes, const byte* nonce, word32 nonceSz)
11031
0
{
11032
0
    int ret = 0;
11033
11034
0
    if (aes == NULL || nonce == NULL ||
11035
0
        nonceSz < CCM_NONCE_MIN_SZ || nonceSz > CCM_NONCE_MAX_SZ) {
11036
11037
0
        ret = BAD_FUNC_ARG;
11038
0
    }
11039
11040
0
    if (ret == 0) {
11041
0
        XMEMCPY(aes->reg, nonce, nonceSz);
11042
0
        aes->nonceSz = nonceSz;
11043
11044
        /* Invocation counter should be 2^61 */
11045
0
        aes->invokeCtr[0] = 0;
11046
0
        aes->invokeCtr[1] = 0xE0000000;
11047
0
    }
11048
11049
0
    return ret;
11050
0
}
11051
11052
11053
int wc_AesCcmEncrypt_ex(Aes* aes, byte* out, const byte* in, word32 sz,
11054
                        byte* ivOut, word32 ivOutSz,
11055
                        byte* authTag, word32 authTagSz,
11056
                        const byte* authIn, word32 authInSz)
11057
0
{
11058
0
    int ret = 0;
11059
11060
0
    if (aes == NULL || out == NULL ||
11061
0
        (in == NULL && sz != 0) ||
11062
0
        ivOut == NULL ||
11063
0
        (authIn == NULL && authInSz != 0) ||
11064
0
        (ivOutSz != aes->nonceSz)) {
11065
11066
0
        ret = BAD_FUNC_ARG;
11067
0
    }
11068
11069
0
    if (ret == 0) {
11070
0
        aes->invokeCtr[0]++;
11071
0
        if (aes->invokeCtr[0] == 0) {
11072
0
            aes->invokeCtr[1]++;
11073
0
            if (aes->invokeCtr[1] == 0)
11074
0
                ret = AES_CCM_OVERFLOW_E;
11075
0
        }
11076
0
    }
11077
11078
0
    if (ret == 0) {
11079
0
        ret = wc_AesCcmEncrypt(aes, out, in, sz,
11080
0
                               (byte*)aes->reg, aes->nonceSz,
11081
0
                               authTag, authTagSz,
11082
0
                               authIn, authInSz);
11083
0
        if (ret == 0) {
11084
0
            XMEMCPY(ivOut, aes->reg, aes->nonceSz);
11085
0
            IncCtr((byte*)aes->reg, aes->nonceSz);
11086
0
        }
11087
0
    }
11088
11089
0
    return ret;
11090
0
}
11091
11092
#endif /* WC_NO_RNG */
11093
11094
#endif /* HAVE_AESCCM */
11095
11096
11097
/* Initialize Aes for use with async hardware */
11098
int wc_AesInit(Aes* aes, void* heap, int devId)
11099
0
{
11100
0
    int ret = 0;
11101
11102
0
    if (aes == NULL)
11103
0
        return BAD_FUNC_ARG;
11104
11105
0
    aes->heap = heap;
11106
11107
0
#ifdef WOLF_CRYPTO_CB
11108
0
    aes->devId = devId;
11109
0
    aes->devCtx = NULL;
11110
#else
11111
    (void)devId;
11112
#endif
11113
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11114
    ret = wolfAsync_DevCtxInit(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES,
11115
                                                        aes->heap, devId);
11116
#endif /* WOLFSSL_ASYNC_CRYPT */
11117
11118
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
11119
    aes->alFd = WC_SOCK_NOTSET;
11120
    aes->rdFd = WC_SOCK_NOTSET;
11121
#endif
11122
#ifdef WOLFSSL_KCAPI_AES
11123
    aes->handle = NULL;
11124
    aes->init   = 0;
11125
#endif
11126
#if defined(WOLFSSL_DEVCRYPTO) && \
11127
   (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
11128
    aes->ctx.cfd = -1;
11129
#endif
11130
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
11131
    XMEMSET(&aes->ctx, 0, sizeof(aes->ctx));
11132
#endif
11133
#if defined(WOLFSSL_IMXRT_DCP)
11134
    DCPAesInit(aes);
11135
#endif
11136
11137
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11138
    XMEMSET(&aes->maxq_ctx, 0, sizeof(aes->maxq_ctx));
11139
#endif
11140
11141
0
#ifdef HAVE_AESGCM
11142
#ifdef OPENSSL_EXTRA
11143
    XMEMSET(aes->gcm.aadH, 0, sizeof(aes->gcm.aadH));
11144
    aes->gcm.aadLen = 0;
11145
#endif
11146
0
#endif
11147
11148
0
#ifdef WOLFSSL_AESGCM_STREAM
11149
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_AESNI)
11150
0
    aes->streamData = NULL;
11151
0
#endif
11152
0
    aes->keylen = 0;
11153
0
    aes->nonceSz = 0;
11154
0
    aes->gcmKeySet = 0;
11155
0
    aes->nonceSet = 0;
11156
0
    aes->ctrSet = 0;
11157
0
#endif
11158
11159
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
11160
    ret = wc_psa_aes_init(aes);
11161
#endif
11162
11163
#if defined(WOLFSSL_RENESAS_FSPSM)
11164
    XMEMSET(&aes->ctx, 0, sizeof(aes->ctx));
11165
#endif
11166
11167
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
11168
    if (ret == 0)
11169
        ret = wc_debug_CipherLifecycleInit(&aes->CipherLifecycleTag, aes->heap);
11170
#endif
11171
11172
0
    return ret;
11173
0
}
11174
11175
#ifdef WOLF_PRIVATE_KEY_ID
11176
int  wc_AesInit_Id(Aes* aes, unsigned char* id, int len, void* heap, int devId)
11177
0
{
11178
0
    int ret = 0;
11179
11180
0
    if (aes == NULL)
11181
0
        ret = BAD_FUNC_ARG;
11182
0
    if (ret == 0 && (len < 0 || len > AES_MAX_ID_LEN))
11183
0
        ret = BUFFER_E;
11184
11185
0
    if (ret == 0)
11186
0
        ret = wc_AesInit(aes, heap, devId);
11187
0
    if (ret == 0) {
11188
0
        XMEMCPY(aes->id, id, (size_t)len);
11189
0
        aes->idLen = len;
11190
0
        aes->labelLen = 0;
11191
0
    }
11192
11193
0
    return ret;
11194
0
}
11195
11196
int wc_AesInit_Label(Aes* aes, const char* label, void* heap, int devId)
11197
0
{
11198
0
    int ret = 0;
11199
0
    size_t labelLen = 0;
11200
11201
0
    if (aes == NULL || label == NULL)
11202
0
        ret = BAD_FUNC_ARG;
11203
0
    if (ret == 0) {
11204
0
        labelLen = XSTRLEN(label);
11205
0
        if (labelLen == 0 || labelLen > AES_MAX_LABEL_LEN)
11206
0
            ret = BUFFER_E;
11207
0
    }
11208
11209
0
    if (ret == 0)
11210
0
        ret = wc_AesInit(aes, heap, devId);
11211
0
    if (ret == 0) {
11212
0
        XMEMCPY(aes->label, label, labelLen);
11213
0
        aes->labelLen = (int)labelLen;
11214
0
        aes->idLen = 0;
11215
0
    }
11216
11217
0
    return ret;
11218
0
}
11219
#endif
11220
11221
/* Free Aes from use with async hardware */
11222
void wc_AesFree(Aes* aes)
11223
0
{
11224
0
    if (aes == NULL)
11225
0
        return;
11226
11227
#ifdef WC_DEBUG_CIPHER_LIFECYCLE
11228
    (void)wc_debug_CipherLifecycleFree(&aes->CipherLifecycleTag, aes->heap, 1);
11229
#endif
11230
11231
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES)
11232
    wolfAsync_DevCtxFree(&aes->asyncDev, WOLFSSL_ASYNC_MARKER_AES);
11233
#endif /* WOLFSSL_ASYNC_CRYPT */
11234
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
11235
    if (aes->rdFd > 0) { /* negative is error case */
11236
        close(aes->rdFd);
11237
        aes->rdFd = WC_SOCK_NOTSET;
11238
    }
11239
    if (aes->alFd > 0) {
11240
        close(aes->alFd);
11241
        aes->alFd = WC_SOCK_NOTSET;
11242
    }
11243
#endif /* WOLFSSL_AFALG */
11244
#ifdef WOLFSSL_KCAPI_AES
11245
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
11246
    if (aes->init == 1) {
11247
        kcapi_cipher_destroy(aes->handle);
11248
    }
11249
    aes->init = 0;
11250
    aes->handle = NULL;
11251
#endif
11252
#if defined(WOLFSSL_DEVCRYPTO) && \
11253
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))
11254
    wc_DevCryptoFree(&aes->ctx);
11255
#endif
11256
0
#if defined(WOLF_CRYPTO_CB) || (defined(WOLFSSL_DEVCRYPTO) && \
11257
0
    (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC))) || \
11258
0
    (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_AES))
11259
0
    ForceZero((byte*)aes->devKey, AES_MAX_KEY_SIZE/WOLFSSL_BIT_SIZE);
11260
0
#endif
11261
#if defined(WOLFSSL_IMXRT_DCP)
11262
    DCPAesFree(aes);
11263
#endif
11264
0
#if defined(WOLFSSL_AESGCM_STREAM) && defined(WOLFSSL_SMALL_STACK) && \
11265
0
    !defined(WOLFSSL_AESNI)
11266
0
    if (aes->streamData != NULL) {
11267
0
        XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
11268
0
        aes->streamData = NULL;
11269
0
    }
11270
0
#endif
11271
11272
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_CRYPT)
11273
    if (aes->useSWCrypt == 0) {
11274
        se050_aes_free(aes);
11275
    }
11276
#endif
11277
11278
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
11279
    wc_psa_aes_free(aes);
11280
#endif
11281
11282
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
11283
    wc_MAXQ10XX_AesFree(aes);
11284
#endif
11285
11286
#if ((defined(WOLFSSL_RENESAS_FSPSM_TLS) || \
11287
    defined(WOLFSSL_RENESAS_FSPSM_CRYPTONLY)) && \
11288
    !defined(NO_WOLFSSL_RENESAS_FSPSM_AES))
11289
    wc_fspsm_Aesfree(aes);
11290
#endif
11291
11292
#ifdef WOLFSSL_CHECK_MEM_ZERO
11293
    wc_MemZero_Check(aes, sizeof(Aes));
11294
#endif
11295
0
}
11296
11297
int wc_AesGetKeySize(Aes* aes, word32* keySize)
11298
0
{
11299
0
    int ret = 0;
11300
11301
0
    if (aes == NULL || keySize == NULL) {
11302
0
        return BAD_FUNC_ARG;
11303
0
    }
11304
11305
#if defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_AES)
11306
    return wc_psa_aes_get_key_size(aes, keySize);
11307
#endif
11308
#if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES)
11309
    *keySize = aes->ctx.key.keySize;
11310
    return ret;
11311
#endif
11312
0
    switch (aes->rounds) {
11313
0
#ifdef WOLFSSL_AES_128
11314
0
    case 10:
11315
0
        *keySize = 16;
11316
0
        break;
11317
0
#endif
11318
0
#ifdef WOLFSSL_AES_192
11319
0
    case 12:
11320
0
        *keySize = 24;
11321
0
        break;
11322
0
#endif
11323
0
#ifdef WOLFSSL_AES_256
11324
0
    case 14:
11325
0
        *keySize = 32;
11326
0
        break;
11327
0
#endif
11328
0
    default:
11329
0
        *keySize = 0;
11330
0
        ret = BAD_FUNC_ARG;
11331
0
    }
11332
11333
0
    return ret;
11334
0
}
11335
11336
#endif /* !WOLFSSL_TI_CRYPT */
11337
11338
/* the earlier do-nothing default definitions for VECTOR_REGISTERS_{PUSH,POP}
11339
 * are missed when WOLFSSL_TI_CRYPT or WOLFSSL_ARMASM.
11340
 */
11341
#ifndef VECTOR_REGISTERS_PUSH
11342
    #define VECTOR_REGISTERS_PUSH { WC_DO_NOTHING
11343
#endif
11344
#ifndef VECTOR_REGISTERS_POP
11345
    #define VECTOR_REGISTERS_POP } WC_DO_NOTHING
11346
#endif
11347
11348
#ifdef HAVE_AES_ECB
11349
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_AES) && \
11350
        !defined(WOLFSSL_QNX_CAAM)
11351
    /* implemented in wolfcrypt/src/port/caam/caam_aes.c */
11352
11353
#elif defined(WOLFSSL_AFALG)
11354
    /* implemented in wolfcrypt/src/port/af_alg/afalg_aes.c */
11355
11356
#elif defined(WOLFSSL_DEVCRYPTO_AES)
11357
    /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
11358
11359
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
11360
11361
/* Software AES - ECB */
11362
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11363
{
11364
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11365
        return BAD_FUNC_ARG;
11366
11367
    return AES_ECB_encrypt(aes, in, out, sz);
11368
}
11369
11370
11371
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11372
{
11373
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11374
        return BAD_FUNC_ARG;
11375
11376
    return AES_ECB_decrypt(aes, in, out, sz);
11377
}
11378
11379
#else
11380
11381
/* Software AES - ECB */
11382
static WARN_UNUSED_RESULT int _AesEcbEncrypt(
11383
    Aes* aes, byte* out, const byte* in, word32 sz)
11384
0
{
11385
0
    int ret = 0;
11386
11387
0
#ifdef WOLF_CRYPTO_CB
11388
0
    #ifndef WOLF_CRYPTO_CB_FIND
11389
0
    if (aes->devId != INVALID_DEVID)
11390
0
    #endif
11391
0
    {
11392
0
        ret = wc_CryptoCb_AesEcbEncrypt(aes, out, in, sz);
11393
0
        if (ret != CRYPTOCB_UNAVAILABLE)
11394
0
            return ret;
11395
0
        ret = 0;
11396
        /* fall-through when unavailable */
11397
0
    }
11398
0
#endif
11399
#ifdef WOLFSSL_IMXRT_DCP
11400
    if (aes->keylen == 16)
11401
        return DCPAesEcbEncrypt(aes, out, in, sz);
11402
#endif
11403
11404
0
    VECTOR_REGISTERS_PUSH;
11405
11406
#ifdef WOLFSSL_AESNI
11407
    if (aes->use_aesni) {
11408
        AES_ECB_encrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
11409
    }
11410
    else
11411
#endif
11412
0
    {
11413
0
#ifndef WOLFSSL_ARMASM
11414
0
        AesEncryptBlocks_C(aes, in, out, sz);
11415
#else
11416
        word32 i;
11417
11418
        for (i = 0; i < sz; i += AES_BLOCK_SIZE) {
11419
            ret = wc_AesEncryptDirect(aes, out, in);
11420
            if (ret != 0)
11421
                break;
11422
            in += AES_BLOCK_SIZE;
11423
            out += AES_BLOCK_SIZE;
11424
        }
11425
#endif
11426
0
    }
11427
11428
0
    VECTOR_REGISTERS_POP;
11429
11430
0
    return ret;
11431
0
}
11432
11433
static WARN_UNUSED_RESULT int _AesEcbDecrypt(
11434
    Aes* aes, byte* out, const byte* in, word32 sz)
11435
0
{
11436
0
    int ret = 0;
11437
11438
0
#ifdef WOLF_CRYPTO_CB
11439
0
    #ifndef WOLF_CRYPTO_CB_FIND
11440
0
    if (aes->devId != INVALID_DEVID)
11441
0
    #endif
11442
0
    {
11443
0
        ret = wc_CryptoCb_AesEcbDecrypt(aes, out, in, sz);
11444
0
        if (ret != CRYPTOCB_UNAVAILABLE)
11445
0
            return ret;
11446
0
        ret = 0;
11447
        /* fall-through when unavailable */
11448
0
    }
11449
0
#endif
11450
#ifdef WOLFSSL_IMXRT_DCP
11451
    if (aes->keylen == 16)
11452
        return DCPAesEcbDecrypt(aes, out, in, sz);
11453
#endif
11454
11455
0
    VECTOR_REGISTERS_PUSH;
11456
11457
#ifdef WOLFSSL_AESNI
11458
    if (aes->use_aesni) {
11459
        AES_ECB_decrypt_AESNI(in, out, sz, (byte*)aes->key, (int)aes->rounds);
11460
    }
11461
    else
11462
#endif
11463
0
    {
11464
0
#ifndef WOLFSSL_ARMASM
11465
0
        AesDecryptBlocks_C(aes, in, out, sz);
11466
#else
11467
        word32 i;
11468
11469
        for (i = 0; i < sz; i += AES_BLOCK_SIZE) {
11470
            ret = wc_AesDecryptDirect(aes, out, in);
11471
            if (ret != 0)
11472
                break;
11473
            in += AES_BLOCK_SIZE;
11474
            out += AES_BLOCK_SIZE;
11475
        }
11476
#endif
11477
0
    }
11478
11479
0
    VECTOR_REGISTERS_POP;
11480
11481
0
    return ret;
11482
0
}
11483
11484
int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11485
0
{
11486
0
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11487
0
      return BAD_FUNC_ARG;
11488
0
    if ((sz % AES_BLOCK_SIZE) != 0) {
11489
0
        return BAD_LENGTH_E;
11490
0
    }
11491
11492
0
    return _AesEcbEncrypt(aes, out, in, sz);
11493
0
}
11494
11495
int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11496
0
{
11497
0
    if ((in == NULL) || (out == NULL) || (aes == NULL))
11498
0
      return BAD_FUNC_ARG;
11499
0
    if ((sz % AES_BLOCK_SIZE) != 0) {
11500
0
        return BAD_LENGTH_E;
11501
0
    }
11502
11503
0
    return _AesEcbDecrypt(aes, out, in, sz);
11504
0
}
11505
#endif
11506
#endif /* HAVE_AES_ECB */
11507
11508
#if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_OFB)
11509
/* Feedback AES mode
11510
 *
11511
 * aes structure holding key to use for encryption
11512
 * out buffer to hold result of encryption (must be at least as large as input
11513
 *     buffer)
11514
 * in  buffer to encrypt
11515
 * sz  size of input buffer
11516
 * mode flag to specify AES mode
11517
 *
11518
 * returns 0 on success and negative error values on failure
11519
 */
11520
/* Software AES - CFB Encrypt */
11521
static WARN_UNUSED_RESULT int wc_AesFeedbackEncrypt(
11522
    Aes* aes, byte* out, const byte* in, word32 sz, byte mode)
11523
0
{
11524
0
    byte*  tmp = NULL;
11525
0
    int ret = 0;
11526
0
    word32 processed;
11527
11528
0
    if (aes == NULL || out == NULL || in == NULL) {
11529
0
        return BAD_FUNC_ARG;
11530
0
    }
11531
11532
    /* consume any unused bytes left in aes->tmp */
11533
0
    processed = min(aes->left, sz);
11534
0
    xorbufout(out, in, (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left, processed);
11535
0
#ifdef WOLFSSL_AES_CFB
11536
0
    if (mode == AES_CFB_MODE) {
11537
0
        XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, out, processed);
11538
0
    }
11539
0
#endif
11540
0
    aes->left -= processed;
11541
0
    out += processed;
11542
0
    in += processed;
11543
0
    sz -= processed;
11544
11545
0
    VECTOR_REGISTERS_PUSH;
11546
11547
0
    while (sz >= AES_BLOCK_SIZE) {
11548
        /* Using aes->tmp here for inline case i.e. in=out */
11549
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
11550
0
        if (ret != 0)
11551
0
            break;
11552
0
    #ifdef WOLFSSL_AES_OFB
11553
0
        if (mode == AES_OFB_MODE) {
11554
0
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
11555
0
        }
11556
0
    #endif
11557
0
        xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE);
11558
0
    #ifdef WOLFSSL_AES_CFB
11559
0
        if (mode == AES_CFB_MODE) {
11560
0
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
11561
0
        }
11562
0
    #endif
11563
0
        XMEMCPY(out, aes->tmp, AES_BLOCK_SIZE);
11564
0
        out += AES_BLOCK_SIZE;
11565
0
        in  += AES_BLOCK_SIZE;
11566
0
        sz  -= AES_BLOCK_SIZE;
11567
0
        aes->left = 0;
11568
0
    }
11569
11570
    /* encrypt left over data */
11571
0
    if ((ret == 0) && sz) {
11572
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
11573
0
    }
11574
0
    if ((ret == 0) && sz) {
11575
0
        aes->left = AES_BLOCK_SIZE;
11576
0
        tmp = (byte*)aes->tmp;
11577
0
    #ifdef WOLFSSL_AES_OFB
11578
0
        if (mode == AES_OFB_MODE) {
11579
0
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
11580
0
        }
11581
0
    #endif
11582
11583
0
        xorbufout(out, in, tmp, sz);
11584
0
    #ifdef WOLFSSL_AES_CFB
11585
0
        if (mode == AES_CFB_MODE) {
11586
0
            XMEMCPY(aes->reg, out, sz);
11587
0
        }
11588
0
    #endif
11589
0
        aes->left -= sz;
11590
0
    }
11591
11592
0
    VECTOR_REGISTERS_POP;
11593
11594
0
    return ret;
11595
0
}
11596
11597
11598
#ifdef HAVE_AES_DECRYPT
11599
/* CFB 128
11600
 *
11601
 * aes structure holding key to use for decryption
11602
 * out buffer to hold result of decryption (must be at least as large as input
11603
 *     buffer)
11604
 * in  buffer to decrypt
11605
 * sz  size of input buffer
11606
 *
11607
 * returns 0 on success and negative error values on failure
11608
 */
11609
/* Software AES - CFB Decrypt */
11610
static WARN_UNUSED_RESULT int wc_AesFeedbackDecrypt(
11611
    Aes* aes, byte* out, const byte* in, word32 sz, byte mode)
11612
0
{
11613
0
    int ret = 0;
11614
0
    word32 processed;
11615
11616
0
    if (aes == NULL || out == NULL || in == NULL) {
11617
0
        return BAD_FUNC_ARG;
11618
0
    }
11619
11620
0
    #ifdef WOLFSSL_AES_CFB
11621
    /* check if more input needs copied over to aes->reg */
11622
0
    if (aes->left && sz && mode == AES_CFB_MODE) {
11623
0
        word32 size = min(aes->left, sz);
11624
0
        XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size);
11625
0
    }
11626
0
    #endif
11627
11628
    /* consume any unused bytes left in aes->tmp */
11629
0
    processed = min(aes->left, sz);
11630
0
    xorbufout(out, in, (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left, processed);
11631
0
    aes->left -= processed;
11632
0
    out += processed;
11633
0
    in += processed;
11634
0
    sz -= processed;
11635
11636
0
    VECTOR_REGISTERS_PUSH;
11637
11638
0
    while (sz > AES_BLOCK_SIZE) {
11639
        /* Using aes->tmp here for inline case i.e. in=out */
11640
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
11641
0
        if (ret != 0)
11642
0
            break;
11643
0
    #ifdef WOLFSSL_AES_OFB
11644
0
        if (mode == AES_OFB_MODE) {
11645
0
            XMEMCPY((byte*)aes->reg, (byte*)aes->tmp, AES_BLOCK_SIZE);
11646
0
        }
11647
0
    #endif
11648
0
        xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE);
11649
0
    #ifdef WOLFSSL_AES_CFB
11650
0
        if (mode == AES_CFB_MODE) {
11651
0
            XMEMCPY(aes->reg, in, AES_BLOCK_SIZE);
11652
0
        }
11653
0
    #endif
11654
0
        XMEMCPY(out, (byte*)aes->tmp, AES_BLOCK_SIZE);
11655
0
        out += AES_BLOCK_SIZE;
11656
0
        in  += AES_BLOCK_SIZE;
11657
0
        sz  -= AES_BLOCK_SIZE;
11658
0
        aes->left = 0;
11659
0
    }
11660
11661
    /* decrypt left over data */
11662
0
    if ((ret == 0) && sz) {
11663
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
11664
0
    }
11665
0
    if ((ret == 0) && sz) {
11666
0
    #ifdef WOLFSSL_AES_CFB
11667
0
        if (mode == AES_CFB_MODE) {
11668
0
            XMEMCPY(aes->reg, in, sz);
11669
0
        }
11670
0
    #endif
11671
0
    #ifdef WOLFSSL_AES_OFB
11672
0
        if (mode == AES_OFB_MODE) {
11673
0
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
11674
0
        }
11675
0
    #endif
11676
11677
0
        aes->left = AES_BLOCK_SIZE - sz;
11678
0
        xorbufout(out, in, aes->tmp, sz);
11679
0
    }
11680
11681
0
    VECTOR_REGISTERS_POP;
11682
11683
0
    return ret;
11684
0
}
11685
#endif /* HAVE_AES_DECRYPT */
11686
#endif /* WOLFSSL_AES_CFB */
11687
11688
#ifdef WOLFSSL_AES_CFB
11689
/* CFB 128
11690
 *
11691
 * aes structure holding key to use for encryption
11692
 * out buffer to hold result of encryption (must be at least as large as input
11693
 *     buffer)
11694
 * in  buffer to encrypt
11695
 * sz  size of input buffer
11696
 *
11697
 * returns 0 on success and negative error values on failure
11698
 */
11699
/* Software AES - CFB Encrypt */
11700
int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11701
0
{
11702
0
    return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_CFB_MODE);
11703
0
}
11704
11705
11706
#ifdef HAVE_AES_DECRYPT
11707
/* CFB 128
11708
 *
11709
 * aes structure holding key to use for decryption
11710
 * out buffer to hold result of decryption (must be at least as large as input
11711
 *     buffer)
11712
 * in  buffer to decrypt
11713
 * sz  size of input buffer
11714
 *
11715
 * returns 0 on success and negative error values on failure
11716
 */
11717
/* Software AES - CFB Decrypt */
11718
int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11719
0
{
11720
0
    return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE);
11721
0
}
11722
#endif /* HAVE_AES_DECRYPT */
11723
11724
11725
/* shift the whole AES_BLOCK_SIZE array left by 8 or 1 bits */
11726
static void shiftLeftArray(byte* ary, byte shift)
11727
0
{
11728
0
    int i;
11729
11730
0
    if (shift == WOLFSSL_BIT_SIZE) {
11731
        /* shifting over by 8 bits */
11732
0
        for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
11733
0
            ary[i] = ary[i+1];
11734
0
        }
11735
0
        ary[i] = 0;
11736
0
    }
11737
0
    else {
11738
        /* shifting over by 7 or less bits */
11739
0
        for (i = 0; i < AES_BLOCK_SIZE - 1; i++) {
11740
0
            byte carry = ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift));
11741
0
            carry >>= (WOLFSSL_BIT_SIZE - shift);
11742
0
            ary[i] = (byte)((ary[i] << shift) + carry);
11743
0
        }
11744
0
        ary[i] = ary[i] << shift;
11745
0
    }
11746
0
}
11747
11748
11749
/* returns 0 on success and negative values on failure */
11750
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB8(
11751
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
11752
0
{
11753
0
    byte *pt;
11754
0
    int ret = 0;
11755
11756
0
    if (aes == NULL || out == NULL || in == NULL) {
11757
0
        return BAD_FUNC_ARG;
11758
0
    }
11759
11760
0
    if (sz == 0) {
11761
0
        return 0;
11762
0
    }
11763
11764
0
    VECTOR_REGISTERS_PUSH;
11765
11766
0
    while (sz > 0) {
11767
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
11768
0
        if (ret != 0)
11769
0
            break;
11770
0
        if (dir == AES_DECRYPTION) {
11771
0
            pt = (byte*)aes->reg;
11772
11773
            /* LSB + CAT */
11774
0
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
11775
0
            pt[AES_BLOCK_SIZE - 1] = in[0];
11776
0
        }
11777
11778
        /* MSB + XOR */
11779
    #ifdef BIG_ENDIAN_ORDER
11780
        ByteReverseWords(aes->tmp, aes->tmp, AES_BLOCK_SIZE);
11781
    #endif
11782
0
        out[0] = (byte)(aes->tmp[0] ^ in[0]);
11783
0
        if (dir == AES_ENCRYPTION) {
11784
0
            pt = (byte*)aes->reg;
11785
11786
            /* LSB + CAT */
11787
0
            shiftLeftArray(pt, WOLFSSL_BIT_SIZE);
11788
0
            pt[AES_BLOCK_SIZE - 1] = out[0];
11789
0
        }
11790
11791
0
        out += 1;
11792
0
        in  += 1;
11793
0
        sz  -= 1;
11794
0
    }
11795
11796
0
    VECTOR_REGISTERS_POP;
11797
11798
0
    return ret;
11799
0
}
11800
11801
11802
/* returns 0 on success and negative values on failure */
11803
static WARN_UNUSED_RESULT int wc_AesFeedbackCFB1(
11804
    Aes* aes, byte* out, const byte* in, word32 sz, byte dir)
11805
0
{
11806
0
    byte tmp;
11807
0
    byte cur = 0; /* hold current work in order to handle inline in=out */
11808
0
    byte* pt;
11809
0
    int bit = 7;
11810
0
    int ret = 0;
11811
11812
0
    if (aes == NULL || out == NULL || in == NULL) {
11813
0
        return BAD_FUNC_ARG;
11814
0
    }
11815
11816
0
    if (sz == 0) {
11817
0
        return 0;
11818
0
    }
11819
11820
0
    VECTOR_REGISTERS_PUSH;
11821
11822
0
    while (sz > 0) {
11823
0
        ret = wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg);
11824
0
        if (ret != 0)
11825
0
            break;
11826
0
        if (dir == AES_DECRYPTION) {
11827
0
            pt = (byte*)aes->reg;
11828
11829
            /* LSB + CAT */
11830
0
            tmp = (0X01 << bit) & in[0];
11831
0
            tmp = tmp >> bit;
11832
0
            tmp &= 0x01;
11833
0
            shiftLeftArray((byte*)aes->reg, 1);
11834
0
            pt[AES_BLOCK_SIZE - 1] |= tmp;
11835
0
        }
11836
11837
        /* MSB  + XOR */
11838
0
        tmp = (0X01 << bit) & in[0];
11839
0
        pt = (byte*)aes->tmp;
11840
0
        tmp = (pt[0] >> 7) ^ (tmp >> bit);
11841
0
        tmp &= 0x01;
11842
0
        cur |= (tmp << bit);
11843
11844
11845
0
        if (dir == AES_ENCRYPTION) {
11846
0
            pt = (byte*)aes->reg;
11847
11848
            /* LSB + CAT */
11849
0
            shiftLeftArray((byte*)aes->reg, 1);
11850
0
            pt[AES_BLOCK_SIZE - 1] |= tmp;
11851
0
        }
11852
11853
0
        bit--;
11854
0
        if (bit < 0) {
11855
0
            out[0] = cur;
11856
0
            out += 1;
11857
0
            in  += 1;
11858
0
            sz  -= 1;
11859
0
            bit = 7;
11860
0
            cur = 0;
11861
0
        }
11862
0
        else {
11863
0
            sz -= 1;
11864
0
        }
11865
0
    }
11866
11867
0
    if (ret == 0) {
11868
0
        if (bit > 0 && bit < 7) {
11869
0
            out[0] = cur;
11870
0
        }
11871
0
    }
11872
11873
0
    VECTOR_REGISTERS_POP;
11874
11875
0
    return ret;
11876
0
}
11877
11878
11879
/* CFB 1
11880
 *
11881
 * aes structure holding key to use for encryption
11882
 * out buffer to hold result of encryption (must be at least as large as input
11883
 *     buffer)
11884
 * in  buffer to encrypt (packed to left, i.e. 101 is 0x90)
11885
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
11886
 *
11887
 * returns 0 on success and negative values on failure
11888
 */
11889
int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11890
0
{
11891
0
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION);
11892
0
}
11893
11894
11895
/* CFB 8
11896
 *
11897
 * aes structure holding key to use for encryption
11898
 * out buffer to hold result of encryption (must be at least as large as input
11899
 *     buffer)
11900
 * in  buffer to encrypt
11901
 * sz  size of input buffer
11902
 *
11903
 * returns 0 on success and negative values on failure
11904
 */
11905
int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11906
0
{
11907
0
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION);
11908
0
}
11909
#ifdef HAVE_AES_DECRYPT
11910
11911
/* CFB 1
11912
 *
11913
 * aes structure holding key to use for encryption
11914
 * out buffer to hold result of encryption (must be at least as large as input
11915
 *     buffer)
11916
 * in  buffer to encrypt
11917
 * sz  size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8)
11918
 *
11919
 * returns 0 on success and negative values on failure
11920
 */
11921
int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11922
0
{
11923
0
    return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION);
11924
0
}
11925
11926
11927
/* CFB 8
11928
 *
11929
 * aes structure holding key to use for encryption
11930
 * out buffer to hold result of encryption (must be at least as large as input
11931
 *     buffer)
11932
 * in  buffer to encrypt
11933
 * sz  size of input buffer
11934
 *
11935
 * returns 0 on success and negative values on failure
11936
 */
11937
int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11938
0
{
11939
0
    return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION);
11940
0
}
11941
#endif /* HAVE_AES_DECRYPT */
11942
#endif /* WOLFSSL_AES_CFB */
11943
11944
#ifdef WOLFSSL_AES_OFB
11945
/* OFB
11946
 *
11947
 * aes structure holding key to use for encryption
11948
 * out buffer to hold result of encryption (must be at least as large as input
11949
 *     buffer)
11950
 * in  buffer to encrypt
11951
 * sz  size of input buffer
11952
 *
11953
 * returns 0 on success and negative error values on failure
11954
 */
11955
/* Software AES - CFB Encrypt */
11956
int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11957
0
{
11958
0
    return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_OFB_MODE);
11959
0
}
11960
11961
11962
#ifdef HAVE_AES_DECRYPT
11963
/* OFB
11964
 *
11965
 * aes structure holding key to use for decryption
11966
 * out buffer to hold result of decryption (must be at least as large as input
11967
 *     buffer)
11968
 * in  buffer to decrypt
11969
 * sz  size of input buffer
11970
 *
11971
 * returns 0 on success and negative error values on failure
11972
 */
11973
/* Software AES - OFB Decrypt */
11974
int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
11975
0
{
11976
0
    return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE);
11977
0
}
11978
#endif /* HAVE_AES_DECRYPT */
11979
#endif /* WOLFSSL_AES_OFB */
11980
11981
11982
#ifdef HAVE_AES_KEYWRAP
11983
11984
/* Initialize key wrap counter with value */
11985
static WC_INLINE void InitKeyWrapCounter(byte* inOutCtr, word32 value)
11986
0
{
11987
0
    word32 i;
11988
0
    word32 bytes;
11989
11990
0
    bytes = sizeof(word32);
11991
0
    for (i = 0; i < sizeof(word32); i++) {
11992
0
        inOutCtr[i+sizeof(word32)] = (byte)(value >> ((bytes - 1) * 8));
11993
0
        bytes--;
11994
0
    }
11995
0
}
11996
11997
/* Increment key wrap counter */
11998
static WC_INLINE void IncrementKeyWrapCounter(byte* inOutCtr)
11999
0
{
12000
0
    int i;
12001
12002
    /* in network byte order so start at end and work back */
12003
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
12004
0
        if (++inOutCtr[i])  /* we're done unless we overflow */
12005
0
            return;
12006
0
    }
12007
0
}
12008
12009
/* Decrement key wrap counter */
12010
static WC_INLINE void DecrementKeyWrapCounter(byte* inOutCtr)
12011
0
{
12012
0
    int i;
12013
12014
0
    for (i = KEYWRAP_BLOCK_SIZE - 1; i >= 0; i--) {
12015
0
        if (--inOutCtr[i] != 0xFF)  /* we're done unless we underflow */
12016
0
            return;
12017
0
    }
12018
0
}
12019
12020
int wc_AesKeyWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
12021
        word32 outSz, const byte* iv)
12022
0
{
12023
0
    word32 i;
12024
0
    byte* r;
12025
0
    int j;
12026
0
    int ret = 0;
12027
12028
0
    byte t[KEYWRAP_BLOCK_SIZE];
12029
0
    byte tmp[AES_BLOCK_SIZE];
12030
12031
    /* n must be at least 2 64-bit blocks, output size is (n + 1) 8 bytes (64-bit) */
12032
0
    if (aes == NULL || in  == NULL || inSz < 2*KEYWRAP_BLOCK_SIZE ||
12033
0
        out == NULL || outSz < (inSz + KEYWRAP_BLOCK_SIZE))
12034
0
        return BAD_FUNC_ARG;
12035
12036
    /* input must be multiple of 64-bits */
12037
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
12038
0
        return BAD_FUNC_ARG;
12039
12040
0
    r = out + 8;
12041
0
    XMEMCPY(r, in, inSz);
12042
0
    XMEMSET(t, 0, sizeof(t));
12043
12044
    /* user IV is optional */
12045
0
    if (iv == NULL) {
12046
0
        XMEMSET(tmp, 0xA6, KEYWRAP_BLOCK_SIZE);
12047
0
    } else {
12048
0
        XMEMCPY(tmp, iv, KEYWRAP_BLOCK_SIZE);
12049
0
    }
12050
12051
0
    VECTOR_REGISTERS_PUSH;
12052
12053
0
    for (j = 0; j <= 5; j++) {
12054
0
        for (i = 1; i <= inSz / KEYWRAP_BLOCK_SIZE; i++) {
12055
            /* load R[i] */
12056
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
12057
12058
0
            ret = wc_AesEncryptDirect(aes, tmp, tmp);
12059
0
            if (ret != 0)
12060
0
                break;
12061
12062
            /* calculate new A */
12063
0
            IncrementKeyWrapCounter(t);
12064
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
12065
12066
            /* save R[i] */
12067
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
12068
0
            r += KEYWRAP_BLOCK_SIZE;
12069
0
        }
12070
0
        if (ret != 0)
12071
0
            break;
12072
0
        r = out + KEYWRAP_BLOCK_SIZE;
12073
0
    }
12074
12075
0
    VECTOR_REGISTERS_POP;
12076
12077
0
    if (ret != 0)
12078
0
        return ret;
12079
12080
    /* C[0] = A */
12081
0
    XMEMCPY(out, tmp, KEYWRAP_BLOCK_SIZE);
12082
12083
0
    return (int)(inSz + KEYWRAP_BLOCK_SIZE);
12084
0
}
12085
12086
/* perform AES key wrap (RFC3394), return out sz on success, negative on err */
12087
int wc_AesKeyWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
12088
                  byte* out, word32 outSz, const byte* iv)
12089
0
{
12090
0
#ifdef WOLFSSL_SMALL_STACK
12091
0
    Aes *aes = NULL;
12092
#else
12093
    Aes aes[1];
12094
#endif
12095
0
    int ret;
12096
12097
0
    if (key == NULL)
12098
0
        return BAD_FUNC_ARG;
12099
12100
0
#ifdef WOLFSSL_SMALL_STACK
12101
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
12102
0
                              DYNAMIC_TYPE_AES)) == NULL)
12103
0
        return MEMORY_E;
12104
0
#endif
12105
12106
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12107
0
    if (ret != 0)
12108
0
        goto out;
12109
12110
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
12111
0
    if (ret != 0) {
12112
0
        wc_AesFree(aes);
12113
0
        goto out;
12114
0
    }
12115
12116
0
    ret = wc_AesKeyWrap_ex(aes, in, inSz, out, outSz, iv);
12117
12118
0
    wc_AesFree(aes);
12119
12120
0
  out:
12121
0
#ifdef WOLFSSL_SMALL_STACK
12122
0
    if (aes != NULL)
12123
0
        XFREE(aes, NULL, DYNAMIC_TYPE_AES);
12124
0
#endif
12125
12126
0
    return ret;
12127
0
}
12128
12129
int wc_AesKeyUnWrap_ex(Aes *aes, const byte* in, word32 inSz, byte* out,
12130
        word32 outSz, const byte* iv)
12131
0
{
12132
0
    byte* r;
12133
0
    word32 i, n;
12134
0
    int j;
12135
0
    int ret = 0;
12136
12137
0
    byte t[KEYWRAP_BLOCK_SIZE];
12138
0
    byte tmp[AES_BLOCK_SIZE];
12139
12140
0
    const byte* expIv;
12141
0
    const byte defaultIV[] = {
12142
0
        0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6
12143
0
    };
12144
12145
0
    if (aes == NULL || in == NULL || inSz < 3 * KEYWRAP_BLOCK_SIZE ||
12146
0
        out == NULL || outSz < (inSz - KEYWRAP_BLOCK_SIZE))
12147
0
        return BAD_FUNC_ARG;
12148
12149
    /* input must be multiple of 64-bits */
12150
0
    if (inSz % KEYWRAP_BLOCK_SIZE != 0)
12151
0
        return BAD_FUNC_ARG;
12152
12153
    /* user IV optional */
12154
0
    if (iv != NULL)
12155
0
        expIv = iv;
12156
0
    else
12157
0
        expIv = defaultIV;
12158
12159
    /* A = C[0], R[i] = C[i] */
12160
0
    XMEMCPY(tmp, in, KEYWRAP_BLOCK_SIZE);
12161
0
    XMEMCPY(out, in + KEYWRAP_BLOCK_SIZE, inSz - KEYWRAP_BLOCK_SIZE);
12162
0
    XMEMSET(t, 0, sizeof(t));
12163
12164
0
    VECTOR_REGISTERS_PUSH;
12165
12166
    /* initialize counter to 6n */
12167
0
    n = (inSz - 1) / KEYWRAP_BLOCK_SIZE;
12168
0
    InitKeyWrapCounter(t, 6 * n);
12169
12170
0
    for (j = 5; j >= 0; j--) {
12171
0
        for (i = n; i >= 1; i--) {
12172
12173
            /* calculate A */
12174
0
            xorbuf(tmp, t, KEYWRAP_BLOCK_SIZE);
12175
0
            DecrementKeyWrapCounter(t);
12176
12177
            /* load R[i], starting at end of R */
12178
0
            r = out + ((i - 1) * KEYWRAP_BLOCK_SIZE);
12179
0
            XMEMCPY(tmp + KEYWRAP_BLOCK_SIZE, r, KEYWRAP_BLOCK_SIZE);
12180
0
            ret = wc_AesDecryptDirect(aes, tmp, tmp);
12181
0
            if (ret != 0)
12182
0
                break;
12183
12184
            /* save R[i] */
12185
0
            XMEMCPY(r, tmp + KEYWRAP_BLOCK_SIZE, KEYWRAP_BLOCK_SIZE);
12186
0
        }
12187
0
        if (ret != 0)
12188
0
            break;
12189
0
    }
12190
12191
0
    VECTOR_REGISTERS_POP;
12192
12193
0
    if (ret != 0)
12194
0
        return ret;
12195
12196
    /* verify IV */
12197
0
    if (XMEMCMP(tmp, expIv, KEYWRAP_BLOCK_SIZE) != 0)
12198
0
        return BAD_KEYWRAP_IV_E;
12199
12200
0
    return (int)(inSz - KEYWRAP_BLOCK_SIZE);
12201
0
}
12202
12203
int wc_AesKeyUnWrap(const byte* key, word32 keySz, const byte* in, word32 inSz,
12204
                    byte* out, word32 outSz, const byte* iv)
12205
0
{
12206
0
#ifdef WOLFSSL_SMALL_STACK
12207
0
    Aes *aes = NULL;
12208
#else
12209
    Aes aes[1];
12210
#endif
12211
0
    int ret;
12212
12213
0
    (void)iv;
12214
12215
0
    if (key == NULL)
12216
0
        return BAD_FUNC_ARG;
12217
12218
0
#ifdef WOLFSSL_SMALL_STACK
12219
0
    if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL,
12220
0
                              DYNAMIC_TYPE_AES)) == NULL)
12221
0
        return MEMORY_E;
12222
0
#endif
12223
12224
12225
0
    ret = wc_AesInit(aes, NULL, INVALID_DEVID);
12226
0
    if (ret != 0)
12227
0
        goto out;
12228
12229
0
    ret = wc_AesSetKey(aes, key, keySz, NULL, AES_DECRYPTION);
12230
0
    if (ret != 0) {
12231
0
        wc_AesFree(aes);
12232
0
        goto out;
12233
0
    }
12234
12235
0
    ret = wc_AesKeyUnWrap_ex(aes, in, inSz, out, outSz, iv);
12236
12237
0
    wc_AesFree(aes);
12238
12239
0
  out:
12240
0
#ifdef WOLFSSL_SMALL_STACK
12241
0
    if (aes)
12242
0
        XFREE(aes, NULL, DYNAMIC_TYPE_AES);
12243
0
#endif
12244
12245
0
    return ret;
12246
0
}
12247
12248
#endif /* HAVE_AES_KEYWRAP */
12249
12250
#ifdef WOLFSSL_AES_XTS
12251
12252
/* Galios Field to use */
12253
0
#define GF_XTS 0x87
12254
12255
int wc_AesXtsInit(XtsAes* aes, void* heap, int devId)
12256
0
{
12257
0
    int    ret = 0;
12258
12259
0
    if (aes == NULL) {
12260
0
        return BAD_FUNC_ARG;
12261
0
    }
12262
12263
0
    if ((ret = wc_AesInit(&aes->tweak, heap, devId)) != 0) {
12264
0
        return ret;
12265
0
    }
12266
0
    if ((ret = wc_AesInit(&aes->aes, heap, devId)) != 0) {
12267
0
        return ret;
12268
0
    }
12269
12270
0
    return 0;
12271
0
}
12272
12273
/* This is to help with setting keys to correct encrypt or decrypt type.
12274
 *
12275
 * tweak AES key for tweak in XTS
12276
 * aes   AES key for encrypt/decrypt process
12277
 * key   buffer holding aes key | tweak key
12278
 * len   length of key buffer in bytes. Should be twice that of key size. i.e.
12279
 *       32 for a 16 byte key.
12280
 * dir   direction, either AES_ENCRYPTION or AES_DECRYPTION
12281
 * heap  heap hint to use for memory. Can be NULL
12282
 * devId id to use with async crypto. Can be 0
12283
 *
12284
 * return 0 on success
12285
 */
12286
int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir)
12287
0
{
12288
0
    word32 keySz;
12289
0
    int    ret = 0;
12290
12291
0
    if (aes == NULL || key == NULL) {
12292
0
        return BAD_FUNC_ARG;
12293
0
    }
12294
12295
0
    keySz = len/2;
12296
0
    if (keySz != 16 && keySz != 32) {
12297
0
        WOLFSSL_MSG("Unsupported key size");
12298
0
        return WC_KEY_SIZE_E;
12299
0
    }
12300
12301
0
    if ((ret = wc_AesSetKey(&aes->aes, key, keySz, NULL, dir)) == 0) {
12302
0
        ret = wc_AesSetKey(&aes->tweak, key + keySz, keySz, NULL,
12303
0
                AES_ENCRYPTION);
12304
0
        if (ret != 0) {
12305
0
            wc_AesFree(&aes->aes);
12306
0
        }
12307
#ifdef WOLFSSL_AESNI
12308
        if (aes->aes.use_aesni != aes->tweak.use_aesni) {
12309
            if (aes->aes.use_aesni)
12310
                aes->aes.use_aesni = 0;
12311
            else
12312
                aes->tweak.use_aesni = 0;
12313
        }
12314
#endif
12315
0
    }
12316
12317
0
    return ret;
12318
0
}
12319
12320
/* Combined call to wc_AesXtsInit() and wc_AesXtsSetKeyNoInit().
12321
 *
12322
 * Note: is up to user to call wc_AesXtsFree when done.
12323
 *
12324
 * return 0 on success
12325
 */
12326
int wc_AesXtsSetKey(XtsAes* aes, const byte* key, word32 len, int dir,
12327
        void* heap, int devId)
12328
0
{
12329
0
    int    ret = 0;
12330
12331
0
    if (aes == NULL || key == NULL) {
12332
0
        return BAD_FUNC_ARG;
12333
0
    }
12334
12335
0
    ret = wc_AesXtsInit(aes, heap, devId);
12336
0
    if (ret != 0)
12337
0
        return ret;
12338
12339
0
    ret = wc_AesXtsSetKeyNoInit(aes, key, len, dir);
12340
12341
0
    if (ret != 0)
12342
0
        wc_AesXtsFree(aes);
12343
12344
0
    return ret;
12345
0
}
12346
12347
12348
/* This is used to free up resources used by Aes structs
12349
 *
12350
 * aes AES keys to free
12351
 *
12352
 * return 0 on success
12353
 */
12354
int wc_AesXtsFree(XtsAes* aes)
12355
0
{
12356
0
    if (aes != NULL) {
12357
0
        wc_AesFree(&aes->aes);
12358
0
        wc_AesFree(&aes->tweak);
12359
0
    }
12360
12361
0
    return 0;
12362
0
}
12363
12364
12365
/* Same process as wc_AesXtsEncrypt but uses a word64 type as the tweak value
12366
 * instead of a byte array. This just converts the word64 to a byte array and
12367
 * calls wc_AesXtsEncrypt.
12368
 *
12369
 * aes    AES keys to use for block encrypt/decrypt
12370
 * out    output buffer to hold cipher text
12371
 * in     input plain text buffer to encrypt
12372
 * sz     size of both out and in buffers
12373
 * sector value to use for tweak
12374
 *
12375
 * returns 0 on success
12376
 */
12377
int wc_AesXtsEncryptSector(XtsAes* aes, byte* out, const byte* in,
12378
        word32 sz, word64 sector)
12379
0
{
12380
0
    byte* pt;
12381
0
    byte  i[AES_BLOCK_SIZE];
12382
12383
0
    XMEMSET(i, 0, AES_BLOCK_SIZE);
12384
#ifdef BIG_ENDIAN_ORDER
12385
    sector = ByteReverseWord64(sector);
12386
#endif
12387
0
    pt = (byte*)&sector;
12388
0
    XMEMCPY(i, pt, sizeof(word64));
12389
12390
0
    return wc_AesXtsEncrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
12391
0
}
12392
12393
12394
/* Same process as wc_AesXtsDecrypt but uses a word64 type as the tweak value
12395
 * instead of a byte array. This just converts the word64 to a byte array.
12396
 *
12397
 * aes    AES keys to use for block encrypt/decrypt
12398
 * out    output buffer to hold plain text
12399
 * in     input cipher text buffer to encrypt
12400
 * sz     size of both out and in buffers
12401
 * sector value to use for tweak
12402
 *
12403
 * returns 0 on success
12404
 */
12405
int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz,
12406
        word64 sector)
12407
0
{
12408
0
    byte* pt;
12409
0
    byte  i[AES_BLOCK_SIZE];
12410
12411
0
    XMEMSET(i, 0, AES_BLOCK_SIZE);
12412
#ifdef BIG_ENDIAN_ORDER
12413
    sector = ByteReverseWord64(sector);
12414
#endif
12415
0
    pt = (byte*)&sector;
12416
0
    XMEMCPY(i, pt, sizeof(word64));
12417
12418
0
    return wc_AesXtsDecrypt(aes, out, in, sz, (const byte*)i, AES_BLOCK_SIZE);
12419
0
}
12420
12421
#ifdef WOLFSSL_AESNI
12422
12423
#if defined(USE_INTEL_SPEEDUP)
12424
    #define HAVE_INTEL_AVX1
12425
    #define HAVE_INTEL_AVX2
12426
#endif /* USE_INTEL_SPEEDUP */
12427
12428
void AES_XTS_encrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
12429
                     const unsigned char* i, const unsigned char* key,
12430
                     const unsigned char* key2, int nr)
12431
                     XASM_LINK("AES_XTS_encrypt_aesni");
12432
#ifdef HAVE_INTEL_AVX1
12433
void AES_XTS_encrypt_avx1(const unsigned char *in, unsigned char *out,
12434
                          word32 sz, const unsigned char* i,
12435
                          const unsigned char* key, const unsigned char* key2,
12436
                          int nr)
12437
                          XASM_LINK("AES_XTS_encrypt_avx1");
12438
#endif /* HAVE_INTEL_AVX1 */
12439
12440
#ifdef HAVE_AES_DECRYPT
12441
void AES_XTS_decrypt_aesni(const unsigned char *in, unsigned char *out, word32 sz,
12442
                     const unsigned char* i, const unsigned char* key,
12443
                     const unsigned char* key2, int nr)
12444
                     XASM_LINK("AES_XTS_decrypt_aesni");
12445
#ifdef HAVE_INTEL_AVX1
12446
void AES_XTS_decrypt_avx1(const unsigned char *in, unsigned char *out,
12447
                          word32 sz, const unsigned char* i,
12448
                          const unsigned char* key, const unsigned char* key2,
12449
                          int nr)
12450
                          XASM_LINK("AES_XTS_decrypt_avx1");
12451
#endif /* HAVE_INTEL_AVX1 */
12452
#endif /* HAVE_AES_DECRYPT */
12453
12454
#endif /* WOLFSSL_AESNI */
12455
12456
#if !defined(WOLFSSL_ARMASM) || defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
12457
#ifdef HAVE_AES_ECB
12458
/* helper function for encrypting / decrypting full buffer at once */
12459
static WARN_UNUSED_RESULT int _AesXtsHelper(
12460
    Aes* aes, byte* out, const byte* in, word32 sz, int dir)
12461
0
{
12462
0
    word32 outSz   = sz;
12463
0
    word32 totalSz = (sz / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; /* total bytes */
12464
0
    byte*  pt      = out;
12465
12466
0
    outSz -= AES_BLOCK_SIZE;
12467
12468
0
    while (outSz > 0) {
12469
0
        word32 j;
12470
0
        byte carry = 0;
12471
12472
        /* multiply by shift left and propagate carry */
12473
0
        for (j = 0; j < AES_BLOCK_SIZE && outSz > 0; j++, outSz--) {
12474
0
            byte tmpC;
12475
12476
0
            tmpC   = (pt[j] >> 7) & 0x01;
12477
0
            pt[j+AES_BLOCK_SIZE] = (byte)((pt[j] << 1) + carry);
12478
0
            carry  = tmpC;
12479
0
        }
12480
0
        if (carry) {
12481
0
            pt[AES_BLOCK_SIZE] ^= GF_XTS;
12482
0
        }
12483
12484
0
        pt += AES_BLOCK_SIZE;
12485
0
    }
12486
12487
0
    xorbuf(out, in, totalSz);
12488
0
    if (dir == AES_ENCRYPTION) {
12489
0
        return _AesEcbEncrypt(aes, out, out, totalSz);
12490
0
    }
12491
0
    else {
12492
0
        return _AesEcbDecrypt(aes, out, out, totalSz);
12493
0
    }
12494
0
}
12495
#endif /* HAVE_AES_ECB */
12496
12497
12498
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
12499
 *
12500
 * xaes  AES keys to use for block encrypt/decrypt
12501
 * out   output buffer to hold cipher text
12502
 * in    input plain text buffer to encrypt
12503
 * sz    size of both out and in buffers
12504
 * i     value to use for tweak
12505
 *
12506
 * returns 0 on success
12507
 */
12508
/* Software AES - XTS Encrypt  */
12509
static int AesXtsEncrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
12510
        const byte* i)
12511
0
{
12512
0
    int ret = 0;
12513
0
    word32 blocks = (sz / AES_BLOCK_SIZE);
12514
0
    Aes *aes = &xaes->aes;
12515
0
    Aes *tweak = &xaes->tweak;
12516
0
    byte tmp[AES_BLOCK_SIZE];
12517
12518
0
    XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
12519
                                      * key setup passed to encrypt direct*/
12520
12521
0
    ret = wc_AesEncryptDirect(tweak, tmp, i);
12522
12523
0
    if (ret != 0)
12524
0
        return ret;
12525
12526
0
#ifdef HAVE_AES_ECB
12527
    /* encrypt all of buffer at once when possible */
12528
0
    if (in != out) { /* can not handle inline */
12529
0
        XMEMCPY(out, tmp, AES_BLOCK_SIZE);
12530
0
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_ENCRYPTION)) != 0)
12531
0
            return ret;
12532
0
    }
12533
0
#endif
12534
12535
0
    while (blocks > 0) {
12536
0
        word32 j;
12537
0
        byte carry = 0;
12538
12539
0
#ifdef HAVE_AES_ECB
12540
0
        if (in == out)
12541
0
#endif
12542
0
        { /* check for if inline */
12543
0
            byte buf[AES_BLOCK_SIZE];
12544
12545
0
            XMEMCPY(buf, in, AES_BLOCK_SIZE);
12546
0
            xorbuf(buf, tmp, AES_BLOCK_SIZE);
12547
0
            ret = wc_AesEncryptDirect(aes, out, buf);
12548
0
            if (ret != 0)
12549
0
                return ret;
12550
0
        }
12551
0
        xorbuf(out, tmp, AES_BLOCK_SIZE);
12552
12553
        /* multiply by shift left and propagate carry */
12554
0
        for (j = 0; j < AES_BLOCK_SIZE; j++) {
12555
0
            byte tmpC;
12556
12557
0
            tmpC   = (tmp[j] >> 7) & 0x01;
12558
0
            tmp[j] = (byte)((tmp[j] << 1) + carry);
12559
0
            carry  = tmpC;
12560
0
        }
12561
0
        if (carry) {
12562
0
            tmp[0] ^= GF_XTS;
12563
0
        }
12564
12565
0
        in  += AES_BLOCK_SIZE;
12566
0
        out += AES_BLOCK_SIZE;
12567
0
        sz  -= AES_BLOCK_SIZE;
12568
0
        blocks--;
12569
0
    }
12570
12571
    /* stealing operation of XTS to handle left overs */
12572
0
    if (sz > 0) {
12573
0
        byte buf[AES_BLOCK_SIZE];
12574
12575
0
        XMEMCPY(buf, out - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
12576
0
        if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
12577
0
            return BUFFER_E;
12578
0
        }
12579
0
        if (in != out) {
12580
0
            XMEMCPY(out, buf, sz);
12581
0
            XMEMCPY(buf, in, sz);
12582
0
        }
12583
0
        else {
12584
0
            byte buf2[AES_BLOCK_SIZE];
12585
12586
0
            XMEMCPY(buf2, buf, sz);
12587
0
            XMEMCPY(buf, in, sz);
12588
0
            XMEMCPY(out, buf2, sz);
12589
0
        }
12590
12591
0
        xorbuf(buf, tmp, AES_BLOCK_SIZE);
12592
0
        ret = wc_AesEncryptDirect(aes, out - AES_BLOCK_SIZE, buf);
12593
0
        if (ret == 0)
12594
0
            xorbuf(out - AES_BLOCK_SIZE, tmp, AES_BLOCK_SIZE);
12595
0
    }
12596
12597
0
    return ret;
12598
0
}
12599
12600
/* AES with XTS mode. (XTS) XEX encryption with Tweak and cipher text Stealing.
12601
 *
12602
 * xaes  AES keys to use for block encrypt/decrypt
12603
 * out   output buffer to hold cipher text
12604
 * in    input plain text buffer to encrypt
12605
 * sz    size of both out and in buffers
12606
 * i     value to use for tweak
12607
 * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input
12608
 *       adds a sanity check on how the user calls the function.
12609
 *
12610
 * returns 0 on success
12611
 */
12612
int wc_AesXtsEncrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
12613
        const byte* i, word32 iSz)
12614
0
{
12615
0
    int ret;
12616
12617
0
    if (xaes == NULL || out == NULL || in == NULL) {
12618
0
        return BAD_FUNC_ARG;
12619
0
    }
12620
12621
0
    if (iSz < AES_BLOCK_SIZE) {
12622
0
        return BAD_FUNC_ARG;
12623
0
    }
12624
12625
0
    if (sz < AES_BLOCK_SIZE) {
12626
0
        WOLFSSL_MSG("Plain text input too small for encryption");
12627
0
        return BAD_FUNC_ARG;
12628
0
    }
12629
12630
0
    {
12631
#ifdef WOLFSSL_AESNI
12632
#ifdef WC_AES_C_DYNAMIC_FALLBACK
12633
        int orig_use_aesni = xaes->aes.use_aesni;
12634
#endif
12635
        if (xaes->aes.use_aesni && ((ret = SAVE_VECTOR_REGISTERS2()) != 0)) {
12636
#ifdef WC_AES_C_DYNAMIC_FALLBACK
12637
            xaes->aes.use_aesni = 0;
12638
            xaes->tweak.use_aesni = 0;
12639
#else
12640
            return ret;
12641
#endif
12642
        }
12643
        if (xaes->aes.use_aesni) {
12644
#if defined(HAVE_INTEL_AVX1)
12645
            if (IS_INTEL_AVX1(intel_flags)) {
12646
                AES_XTS_encrypt_avx1(in, out, sz, i, (const byte*)xaes->aes.key,
12647
                                     (const byte*)xaes->tweak.key, (int)xaes->aes.rounds);
12648
                ret = 0;
12649
            }
12650
            else
12651
#endif
12652
            {
12653
                AES_XTS_encrypt_aesni(in, out, sz, i, (const byte*)xaes->aes.key,
12654
                                      (const byte*)xaes->tweak.key, (int)xaes->aes.rounds);
12655
                ret = 0;
12656
            }
12657
        }
12658
        else
12659
#endif
12660
0
        {
12661
0
            ret = AesXtsEncrypt_sw(xaes, out, in, sz, i);
12662
0
        }
12663
12664
#ifdef WOLFSSL_AESNI
12665
        if (xaes->aes.use_aesni)
12666
            RESTORE_VECTOR_REGISTERS();
12667
#ifdef WC_AES_C_DYNAMIC_FALLBACK
12668
        else if (orig_use_aesni) {
12669
            xaes->aes.use_aesni = orig_use_aesni;
12670
            xaes->tweak.use_aesni = orig_use_aesni;
12671
        }
12672
#endif
12673
#endif
12674
0
    }
12675
12676
0
    return ret;
12677
0
}
12678
12679
/* Same process as encryption but Aes key is AES_DECRYPTION type.
12680
 *
12681
 * xaes  AES keys to use for block encrypt/decrypt
12682
 * out   output buffer to hold plain text
12683
 * in    input cipher text buffer to decrypt
12684
 * sz    size of both out and in buffers
12685
 * i     value to use for tweak
12686
 *
12687
 * returns 0 on success
12688
 */
12689
/* Software AES - XTS Decrypt */
12690
static int AesXtsDecrypt_sw(XtsAes* xaes, byte* out, const byte* in, word32 sz,
12691
        const byte* i)
12692
0
{
12693
0
    int ret = 0;
12694
0
    word32 blocks = (sz / AES_BLOCK_SIZE);
12695
0
    Aes *aes = &xaes->aes;
12696
0
    Aes *tweak = &xaes->tweak;
12697
0
    word32 j;
12698
0
    byte carry = 0;
12699
0
    byte tmp[AES_BLOCK_SIZE];
12700
0
    byte stl = (sz % AES_BLOCK_SIZE);
12701
12702
0
    XMEMSET(tmp, 0, AES_BLOCK_SIZE); /* set to 0's in case of improper AES
12703
                                      * key setup passed to decrypt direct*/
12704
12705
0
    ret = wc_AesEncryptDirect(tweak, tmp, i);
12706
0
    if (ret != 0)
12707
0
        return ret;
12708
12709
    /* if Stealing then break out of loop one block early to handle special
12710
     * case */
12711
0
    if (stl > 0) {
12712
0
        blocks--;
12713
0
    }
12714
12715
0
#ifdef HAVE_AES_ECB
12716
    /* decrypt all of buffer at once when possible */
12717
0
    if (in != out) { /* can not handle inline */
12718
0
        XMEMCPY(out, tmp, AES_BLOCK_SIZE);
12719
0
        if ((ret = _AesXtsHelper(aes, out, in, sz, AES_DECRYPTION)) != 0)
12720
0
            return ret;
12721
0
    }
12722
0
#endif
12723
12724
0
    while (blocks > 0) {
12725
0
#ifdef HAVE_AES_ECB
12726
0
        if (in == out)
12727
0
#endif
12728
0
        { /* check for if inline */
12729
0
            byte buf[AES_BLOCK_SIZE];
12730
12731
0
            XMEMCPY(buf, in, AES_BLOCK_SIZE);
12732
0
            xorbuf(buf, tmp, AES_BLOCK_SIZE);
12733
0
            ret = wc_AesDecryptDirect(aes, out, buf);
12734
0
            if (ret != 0)
12735
0
                return ret;
12736
0
        }
12737
0
        xorbuf(out, tmp, AES_BLOCK_SIZE);
12738
12739
        /* multiply by shift left and propagate carry */
12740
0
        for (j = 0; j < AES_BLOCK_SIZE; j++) {
12741
0
            byte tmpC;
12742
12743
0
            tmpC   = (tmp[j] >> 7) & 0x01;
12744
0
            tmp[j] = (byte)((tmp[j] << 1) + carry);
12745
0
            carry  = tmpC;
12746
0
        }
12747
0
        if (carry) {
12748
0
            tmp[0] ^= GF_XTS;
12749
0
        }
12750
0
        carry = 0;
12751
12752
0
        in  += AES_BLOCK_SIZE;
12753
0
        out += AES_BLOCK_SIZE;
12754
0
        sz  -= AES_BLOCK_SIZE;
12755
0
        blocks--;
12756
0
    }
12757
12758
    /* stealing operation of XTS to handle left overs */
12759
0
    if (sz >= AES_BLOCK_SIZE) {
12760
0
        byte buf[AES_BLOCK_SIZE];
12761
0
        byte tmp2[AES_BLOCK_SIZE];
12762
12763
        /* multiply by shift left and propagate carry */
12764
0
        for (j = 0; j < AES_BLOCK_SIZE; j++) {
12765
0
            byte tmpC;
12766
12767
0
            tmpC   = (tmp[j] >> 7) & 0x01;
12768
0
            tmp2[j] = (byte)((tmp[j] << 1) + carry);
12769
0
            carry  = tmpC;
12770
0
        }
12771
0
        if (carry) {
12772
0
            tmp2[0] ^= GF_XTS;
12773
0
        }
12774
12775
0
        XMEMCPY(buf, in, AES_BLOCK_SIZE);
12776
0
        xorbuf(buf, tmp2, AES_BLOCK_SIZE);
12777
0
        ret = wc_AesDecryptDirect(aes, out, buf);
12778
0
        if (ret != 0)
12779
0
            return ret;
12780
0
        xorbuf(out, tmp2, AES_BLOCK_SIZE);
12781
12782
        /* tmp2 holds partial | last */
12783
0
        XMEMCPY(tmp2, out, AES_BLOCK_SIZE);
12784
0
        in  += AES_BLOCK_SIZE;
12785
0
        out += AES_BLOCK_SIZE;
12786
0
        sz  -= AES_BLOCK_SIZE;
12787
12788
        /* Make buffer with end of cipher text | last */
12789
0
        XMEMCPY(buf, tmp2, AES_BLOCK_SIZE);
12790
0
        if (sz >= AES_BLOCK_SIZE) { /* extra sanity check before copy */
12791
0
            return BUFFER_E;
12792
0
        }
12793
0
        XMEMCPY(buf, in,   sz);
12794
0
        XMEMCPY(out, tmp2, sz);
12795
12796
0
        xorbuf(buf, tmp, AES_BLOCK_SIZE);
12797
0
        ret = wc_AesDecryptDirect(aes, tmp2, buf);
12798
0
        if (ret != 0)
12799
0
            return ret;
12800
0
        xorbuf(tmp2, tmp, AES_BLOCK_SIZE);
12801
0
        XMEMCPY(out - AES_BLOCK_SIZE, tmp2, AES_BLOCK_SIZE);
12802
0
    }
12803
12804
0
    return ret;
12805
0
}
12806
12807
/* Same process as encryption but Aes key is AES_DECRYPTION type.
12808
 *
12809
 * xaes  AES keys to use for block encrypt/decrypt
12810
 * out   output buffer to hold plain text
12811
 * in    input cipher text buffer to decrypt
12812
 * sz    size of both out and in buffers
12813
 * i     value to use for tweak
12814
 * iSz   size of i buffer, should always be AES_BLOCK_SIZE but having this input
12815
 *       adds a sanity check on how the user calls the function.
12816
 *
12817
 * returns 0 on success
12818
 */
12819
int wc_AesXtsDecrypt(XtsAes* xaes, byte* out, const byte* in, word32 sz,
12820
        const byte* i, word32 iSz)
12821
0
{
12822
0
    int ret;
12823
12824
0
    if (xaes == NULL || out == NULL || in == NULL) {
12825
0
        return BAD_FUNC_ARG;
12826
0
    }
12827
12828
0
    if (iSz < AES_BLOCK_SIZE) {
12829
0
        return BAD_FUNC_ARG;
12830
0
    }
12831
12832
0
    if (sz < AES_BLOCK_SIZE) {
12833
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
12834
0
        return BAD_FUNC_ARG;
12835
0
    }
12836
12837
0
    {
12838
#ifdef WOLFSSL_AESNI
12839
#ifdef WC_AES_C_DYNAMIC_FALLBACK
12840
        int orig_use_aesni = xaes->aes.use_aesni;
12841
#endif
12842
12843
        if (xaes->aes.use_aesni && (SAVE_VECTOR_REGISTERS2() != 0)) {
12844
            xaes->aes.use_aesni = 0;
12845
            xaes->tweak.use_aesni = 0;
12846
        }
12847
        if (xaes->aes.use_aesni) {
12848
#if defined(HAVE_INTEL_AVX1)
12849
            if (IS_INTEL_AVX1(intel_flags)) {
12850
                AES_XTS_decrypt_avx1(in, out, sz, i, (const byte*)xaes->aes.key,
12851
                                     (const byte*)xaes->tweak.key, (int)xaes->aes.rounds);
12852
                ret = 0;
12853
            }
12854
            else
12855
#endif
12856
            {
12857
                AES_XTS_decrypt_aesni(in, out, sz, i, (const byte*)xaes->aes.key,
12858
                                      (const byte*)xaes->tweak.key, (int)xaes->aes.rounds);
12859
                ret = 0;
12860
            }
12861
        }
12862
        else
12863
#endif
12864
0
        {
12865
0
            ret = AesXtsDecrypt_sw(xaes, out, in, sz, i);
12866
0
        }
12867
12868
#ifdef WOLFSSL_AESNI
12869
        if (xaes->aes.use_aesni)
12870
            RESTORE_VECTOR_REGISTERS();
12871
#ifdef WC_AES_C_DYNAMIC_FALLBACK
12872
        else if (orig_use_aesni) {
12873
            xaes->aes.use_aesni = orig_use_aesni;
12874
            xaes->tweak.use_aesni = orig_use_aesni;
12875
        }
12876
#endif
12877
#endif
12878
12879
0
        return ret;
12880
0
    }
12881
0
}
12882
#endif /* !WOLFSSL_ARMASM || WOLFSSL_ARMASM_NO_HW_CRYPTO */
12883
12884
/* Same as wc_AesXtsEncryptSector but the sector gets incremented by one every
12885
 * sectorSz bytes
12886
 *
12887
 * xaes     AES keys to use for block encrypt
12888
 * out      output buffer to hold cipher text
12889
 * in       input plain text buffer to encrypt
12890
 * sz       size of both out and in buffers
12891
 * sector   value to use for tweak
12892
 * sectorSz size of the sector
12893
 *
12894
 * returns 0 on success
12895
 */
12896
int wc_AesXtsEncryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
12897
        word32 sz, word64 sector, word32 sectorSz)
12898
0
{
12899
0
    int ret  = 0;
12900
0
    word32 iter = 0;
12901
0
    word32 sectorCount;
12902
0
    word32 remainder;
12903
12904
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
12905
0
        return BAD_FUNC_ARG;
12906
0
    }
12907
12908
0
    if (sz < AES_BLOCK_SIZE) {
12909
0
        WOLFSSL_MSG("Cipher text input too small for encryption");
12910
0
        return BAD_FUNC_ARG;
12911
0
    }
12912
12913
0
    sectorCount  = sz / sectorSz;
12914
0
    remainder = sz % sectorSz;
12915
12916
0
    while (sectorCount) {
12917
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
12918
0
                in + (iter * sectorSz), sectorSz, sector);
12919
0
        if (ret != 0)
12920
0
            break;
12921
12922
0
        sectorCount--;
12923
0
        iter++;
12924
0
        sector++;
12925
0
    }
12926
12927
0
    if (remainder && ret == 0)
12928
0
        ret = wc_AesXtsEncryptSector(aes, out + (iter * sectorSz),
12929
0
                in + (iter * sectorSz), remainder, sector);
12930
12931
0
    return ret;
12932
0
}
12933
12934
/* Same as wc_AesXtsEncryptConsecutiveSectors but Aes key is AES_DECRYPTION type
12935
 *
12936
 * xaes     AES keys to use for block decrypt
12937
 * out      output buffer to hold cipher text
12938
 * in       input plain text buffer to encrypt
12939
 * sz       size of both out and in buffers
12940
 * sector   value to use for tweak
12941
 * sectorSz size of the sector
12942
 *
12943
 * returns 0 on success
12944
 */
12945
int wc_AesXtsDecryptConsecutiveSectors(XtsAes* aes, byte* out, const byte* in,
12946
        word32 sz, word64 sector, word32 sectorSz)
12947
0
{
12948
0
    int ret  = 0;
12949
0
    word32 iter = 0;
12950
0
    word32 sectorCount;
12951
0
    word32 remainder;
12952
12953
0
    if (aes == NULL || out == NULL || in == NULL || sectorSz == 0) {
12954
0
        return BAD_FUNC_ARG;
12955
0
    }
12956
12957
0
    if (sz < AES_BLOCK_SIZE) {
12958
0
        WOLFSSL_MSG("Cipher text input too small for decryption");
12959
0
        return BAD_FUNC_ARG;
12960
0
    }
12961
12962
0
    sectorCount  = sz / sectorSz;
12963
0
    remainder = sz % sectorSz;
12964
12965
0
    while (sectorCount) {
12966
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
12967
0
                in + (iter * sectorSz), sectorSz, sector);
12968
0
        if (ret != 0)
12969
0
            break;
12970
12971
0
        sectorCount--;
12972
0
        iter++;
12973
0
        sector++;
12974
0
    }
12975
12976
0
    if (remainder && ret == 0)
12977
0
        ret = wc_AesXtsDecryptSector(aes, out + (iter * sectorSz),
12978
0
                in + (iter * sectorSz), remainder, sector);
12979
12980
0
    return ret;
12981
0
}
12982
#endif /* WOLFSSL_AES_XTS */
12983
12984
#ifdef WOLFSSL_AES_SIV
12985
12986
/*
12987
 * See RFC 5297 Section 2.4.
12988
 */
12989
static WARN_UNUSED_RESULT int S2V(
12990
    const byte* key, word32 keySz, const byte* assoc, word32 assocSz,
12991
    const byte* nonce, word32 nonceSz, const byte* data,
12992
    word32 dataSz, byte* out)
12993
0
{
12994
0
#ifdef WOLFSSL_SMALL_STACK
12995
0
    byte* tmp[3] = {NULL, NULL, NULL};
12996
0
    int i;
12997
0
    Cmac* cmac;
12998
#else
12999
    byte tmp[3][AES_BLOCK_SIZE];
13000
    Cmac cmac[1];
13001
#endif
13002
0
    word32 macSz = AES_BLOCK_SIZE;
13003
0
    int ret = 0;
13004
0
    word32 zeroBytes;
13005
13006
0
#ifdef WOLFSSL_SMALL_STACK
13007
0
    for (i = 0; i < 3; ++i) {
13008
0
        tmp[i] = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13009
0
        if (tmp[i] == NULL) {
13010
0
            ret = MEMORY_E;
13011
0
            break;
13012
0
        }
13013
0
    }
13014
0
    if (ret == 0)
13015
0
#endif
13016
0
    {
13017
0
        XMEMSET(tmp[1], 0, AES_BLOCK_SIZE);
13018
0
        XMEMSET(tmp[2], 0, AES_BLOCK_SIZE);
13019
13020
0
        ret = wc_AesCmacGenerate(tmp[0], &macSz, tmp[1], AES_BLOCK_SIZE,
13021
0
                                 key, keySz);
13022
0
        if (ret == 0) {
13023
0
            ShiftAndXorRb(tmp[1], tmp[0]);
13024
0
            ret = wc_AesCmacGenerate(tmp[0], &macSz, assoc, assocSz, key,
13025
0
                                     keySz);
13026
0
            if (ret == 0) {
13027
0
                xorbuf(tmp[1], tmp[0], AES_BLOCK_SIZE);
13028
0
            }
13029
0
        }
13030
0
    }
13031
13032
0
    if (ret == 0) {
13033
0
        if (nonceSz > 0) {
13034
0
            ShiftAndXorRb(tmp[0], tmp[1]);
13035
0
            ret = wc_AesCmacGenerate(tmp[1], &macSz, nonce, nonceSz, key,
13036
0
                                     keySz);
13037
0
            if (ret == 0) {
13038
0
                xorbuf(tmp[0], tmp[1], AES_BLOCK_SIZE);
13039
0
            }
13040
0
        }
13041
0
        else {
13042
0
            XMEMCPY(tmp[0], tmp[1], AES_BLOCK_SIZE);
13043
0
        }
13044
0
    }
13045
13046
0
    if (ret == 0) {
13047
0
        if (dataSz >= AES_BLOCK_SIZE) {
13048
13049
0
        #ifdef WOLFSSL_SMALL_STACK
13050
0
            cmac = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC);
13051
0
            if (cmac == NULL) {
13052
0
                ret = MEMORY_E;
13053
0
            }
13054
0
            if (ret == 0)
13055
0
        #endif
13056
0
            {
13057
            #ifdef WOLFSSL_CHECK_MEM_ZERO
13058
                /* Aes part is checked by wc_AesFree. */
13059
                wc_MemZero_Add("wc_AesCmacGenerate cmac",
13060
                    ((unsigned char *)cmac) + sizeof(Aes),
13061
                    sizeof(Cmac) - sizeof(Aes));
13062
            #endif
13063
0
                xorbuf(tmp[0], data + (dataSz - AES_BLOCK_SIZE),
13064
0
                       AES_BLOCK_SIZE);
13065
0
                ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
13066
0
                if (ret == 0) {
13067
0
                    ret = wc_CmacUpdate(cmac, data, dataSz - AES_BLOCK_SIZE);
13068
0
                }
13069
0
                if (ret == 0) {
13070
0
                    ret = wc_CmacUpdate(cmac, tmp[0], AES_BLOCK_SIZE);
13071
0
                }
13072
0
                if (ret == 0) {
13073
0
                    ret = wc_CmacFinal(cmac, out, &macSz);
13074
0
                }
13075
0
            }
13076
0
        #ifdef WOLFSSL_SMALL_STACK
13077
0
            if (cmac != NULL) {
13078
0
                XFREE(cmac, NULL, DYNAMIC_TYPE_CMAC);
13079
0
            }
13080
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
13081
            wc_MemZero_Check(cmac, sizeof(Cmac));
13082
        #endif
13083
0
        }
13084
0
        else {
13085
0
            XMEMCPY(tmp[2], data, dataSz);
13086
0
            tmp[2][dataSz] |= 0x80;
13087
0
            zeroBytes = AES_BLOCK_SIZE - (dataSz + 1);
13088
0
            if (zeroBytes != 0) {
13089
0
                XMEMSET(tmp[2] + dataSz + 1, 0, zeroBytes);
13090
0
            }
13091
0
            ShiftAndXorRb(tmp[1], tmp[0]);
13092
0
            xorbuf(tmp[1], tmp[2], AES_BLOCK_SIZE);
13093
0
            ret = wc_AesCmacGenerate(out, &macSz, tmp[1], AES_BLOCK_SIZE, key,
13094
0
                                     keySz);
13095
0
        }
13096
0
    }
13097
13098
0
#ifdef WOLFSSL_SMALL_STACK
13099
0
    for (i = 0; i < 3; ++i) {
13100
0
        if (tmp[i] != NULL) {
13101
0
            XFREE(tmp[i], NULL, DYNAMIC_TYPE_TMP_BUFFER);
13102
0
        }
13103
0
    }
13104
0
#endif
13105
13106
0
    return ret;
13107
0
}
13108
13109
static WARN_UNUSED_RESULT int AesSivCipher(
13110
    const byte* key, word32 keySz, const byte* assoc,
13111
    word32 assocSz, const byte* nonce, word32 nonceSz,
13112
    const byte* data, word32 dataSz, byte* siv, byte* out,
13113
    int enc)
13114
0
{
13115
0
    int ret = 0;
13116
0
#ifdef WOLFSSL_SMALL_STACK
13117
0
    Aes* aes = NULL;
13118
#else
13119
    Aes aes[1];
13120
#endif
13121
0
    byte sivTmp[AES_BLOCK_SIZE];
13122
13123
0
    if (key == NULL || siv == NULL || out == NULL) {
13124
0
        WOLFSSL_MSG("Bad parameter");
13125
0
        ret = BAD_FUNC_ARG;
13126
0
    }
13127
13128
0
    if (ret == 0 && keySz != 32 && keySz != 48 && keySz != 64) {
13129
0
        WOLFSSL_MSG("Bad key size. Must be 256, 384, or 512 bits.");
13130
0
        ret = BAD_FUNC_ARG;
13131
0
    }
13132
13133
0
    if (ret == 0) {
13134
0
        if (enc == 1) {
13135
0
            ret = S2V(key, keySz / 2, assoc, assocSz, nonce, nonceSz, data,
13136
0
                      dataSz, sivTmp);
13137
0
            if (ret != 0) {
13138
0
                WOLFSSL_MSG("S2V failed.");
13139
0
            }
13140
0
            else {
13141
0
                XMEMCPY(siv, sivTmp, AES_BLOCK_SIZE);
13142
0
            }
13143
0
        }
13144
0
        else {
13145
0
            XMEMCPY(sivTmp, siv, AES_BLOCK_SIZE);
13146
0
        }
13147
0
    }
13148
13149
0
#ifdef WOLFSSL_SMALL_STACK
13150
0
    if (ret == 0) {
13151
0
        aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_AES);
13152
0
        if (aes == NULL) {
13153
0
            ret = MEMORY_E;
13154
0
        }
13155
0
    }
13156
0
#endif
13157
13158
0
    if (ret == 0) {
13159
0
        ret = wc_AesInit(aes, NULL, INVALID_DEVID);
13160
0
        if (ret != 0) {
13161
0
            WOLFSSL_MSG("Failed to initialized AES object.");
13162
0
        }
13163
0
    }
13164
13165
0
    if (ret == 0 && dataSz > 0) {
13166
0
        sivTmp[12] &= 0x7f;
13167
0
        sivTmp[8] &= 0x7f;
13168
0
        ret = wc_AesSetKey(aes, key + keySz / 2, keySz / 2, sivTmp,
13169
0
                           AES_ENCRYPTION);
13170
0
        if (ret != 0) {
13171
0
            WOLFSSL_MSG("Failed to set key for AES-CTR.");
13172
0
        }
13173
0
        else {
13174
0
            ret = wc_AesCtrEncrypt(aes, out, data, dataSz);
13175
0
            if (ret != 0) {
13176
0
                WOLFSSL_MSG("AES-CTR encryption failed.");
13177
0
            }
13178
0
        }
13179
0
    }
13180
13181
0
    if (ret == 0 && enc == 0) {
13182
0
        ret = S2V(key, keySz / 2, assoc, assocSz, nonce, nonceSz, out, dataSz,
13183
0
                  sivTmp);
13184
0
        if (ret != 0) {
13185
0
            WOLFSSL_MSG("S2V failed.");
13186
0
        }
13187
13188
0
        if (XMEMCMP(siv, sivTmp, AES_BLOCK_SIZE) != 0) {
13189
0
            WOLFSSL_MSG("Computed SIV doesn't match received SIV.");
13190
0
            ret = AES_SIV_AUTH_E;
13191
0
        }
13192
0
    }
13193
13194
0
    wc_AesFree(aes);
13195
0
#ifdef WOLFSSL_SMALL_STACK
13196
0
    XFREE(aes, NULL, DYNAMIC_TYPE_AES);
13197
0
#endif
13198
13199
0
    return ret;
13200
0
}
13201
13202
/*
13203
 * See RFC 5297 Section 2.6.
13204
 */
13205
int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc,
13206
                     word32 assocSz, const byte* nonce, word32 nonceSz,
13207
                     const byte* in, word32 inSz, byte* siv, byte* out)
13208
0
{
13209
0
    return AesSivCipher(key, keySz, assoc, assocSz, nonce, nonceSz, in, inSz,
13210
0
                        siv, out, 1);
13211
0
}
13212
13213
/*
13214
 * See RFC 5297 Section 2.7.
13215
 */
13216
int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc,
13217
                     word32 assocSz, const byte* nonce, word32 nonceSz,
13218
                     const byte* in, word32 inSz, byte* siv, byte* out)
13219
0
{
13220
0
    return AesSivCipher(key, keySz, assoc, assocSz, nonce, nonceSz, in, inSz,
13221
0
                        siv, out, 0);
13222
0
}
13223
13224
#endif /* WOLFSSL_AES_SIV */
13225
13226
#if defined(WOLFSSL_AES_EAX)
13227
13228
/*
13229
 * AES EAX one-shot API
13230
 * Encrypts input data and computes an auth tag over the input
13231
 * auth data and ciphertext
13232
 *
13233
 * Returns 0 on success
13234
 * Returns error code on failure
13235
 */
13236
int  wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out,
13237
                          const byte* in, word32 inSz,
13238
                          const byte* nonce, word32 nonceSz,
13239
                          /* output computed auth tag */
13240
                          byte* authTag, word32 authTagSz,
13241
                          /* input data to authenticate */
13242
                          const byte* authIn, word32 authInSz)
13243
{
13244
#if defined(WOLFSSL_SMALL_STACK)
13245
    AesEax *eax;
13246
#else
13247
    AesEax eax_mem;
13248
    AesEax *eax = &eax_mem;
13249
#endif
13250
    int ret;
13251
    int eaxInited = 0;
13252
13253
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
13254
                              || authTag == NULL || authIn == NULL) {
13255
        return BAD_FUNC_ARG;
13256
    }
13257
13258
#if defined(WOLFSSL_SMALL_STACK)
13259
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
13260
                                 NULL,
13261
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
13262
        return MEMORY_E;
13263
    }
13264
#endif
13265
13266
    if ((ret = wc_AesEaxInit(eax,
13267
                             key, keySz,
13268
                             nonce, nonceSz,
13269
                             authIn, authInSz)) != 0) {
13270
        goto cleanup;
13271
    }
13272
    eaxInited = 1;
13273
13274
    if ((ret = wc_AesEaxEncryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
13275
        goto cleanup;
13276
    }
13277
13278
    if ((ret = wc_AesEaxEncryptFinal(eax, authTag, authTagSz)) != 0) {
13279
        goto cleanup;
13280
    }
13281
13282
cleanup:
13283
    if (eaxInited)
13284
        wc_AesEaxFree(eax);
13285
#if defined(WOLFSSL_SMALL_STACK)
13286
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
13287
#endif
13288
    return ret;
13289
}
13290
13291
13292
/*
13293
 * AES EAX one-shot API
13294
 * Decrypts and authenticates data against a supplied auth tag
13295
 *
13296
 * Returns 0 on success
13297
 * Returns error code on failure
13298
 */
13299
int  wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out,
13300
                          const byte* in, word32 inSz,
13301
                          const byte* nonce, word32 nonceSz,
13302
                          /* auth tag to verify against */
13303
                          const byte* authTag, word32 authTagSz,
13304
                          /* input data to authenticate */
13305
                          const byte* authIn, word32 authInSz)
13306
{
13307
#if defined(WOLFSSL_SMALL_STACK)
13308
    AesEax *eax;
13309
#else
13310
    AesEax eax_mem;
13311
    AesEax *eax = &eax_mem;
13312
#endif
13313
    int ret;
13314
    int eaxInited = 0;
13315
13316
    if (key == NULL || out == NULL || in == NULL || nonce == NULL
13317
                              || authTag == NULL || authIn == NULL) {
13318
        return BAD_FUNC_ARG;
13319
    }
13320
13321
#if defined(WOLFSSL_SMALL_STACK)
13322
    if ((eax = (AesEax *)XMALLOC(sizeof(AesEax),
13323
                                 NULL,
13324
                                 DYNAMIC_TYPE_AES_EAX)) == NULL) {
13325
        return MEMORY_E;
13326
    }
13327
#endif
13328
13329
    if ((ret = wc_AesEaxInit(eax,
13330
                             key, keySz,
13331
                             nonce, nonceSz,
13332
                             authIn, authInSz)) != 0) {
13333
13334
        goto cleanup;
13335
    }
13336
    eaxInited = 1;
13337
13338
    if ((ret = wc_AesEaxDecryptUpdate(eax, out, in, inSz, NULL, 0)) != 0) {
13339
        goto cleanup;
13340
    }
13341
13342
    if ((ret = wc_AesEaxDecryptFinal(eax, authTag, authTagSz)) != 0) {
13343
        goto cleanup;
13344
    }
13345
13346
cleanup:
13347
    if (eaxInited)
13348
        wc_AesEaxFree(eax);
13349
#if defined(WOLFSSL_SMALL_STACK)
13350
    XFREE(eax, NULL, DYNAMIC_TYPE_AES_EAX);
13351
#endif
13352
    return ret;
13353
}
13354
13355
13356
/*
13357
 * AES EAX Incremental API:
13358
 * Initializes an AES EAX encryption or decryption operation. This must be
13359
 * called before any other EAX APIs are used on the AesEax struct
13360
 *
13361
 * Returns 0 on success
13362
 * Returns error code on failure
13363
 */
13364
int  wc_AesEaxInit(AesEax* eax,
13365
                   const byte* key, word32 keySz,
13366
                   const byte* nonce, word32 nonceSz,
13367
                   const byte* authIn, word32 authInSz)
13368
{
13369
    int ret = 0;
13370
    word32 cmacSize;
13371
    int aesInited = 0;
13372
    int nonceCmacInited = 0;
13373
    int aadCmacInited = 0;
13374
13375
    if (eax == NULL || key == NULL ||  nonce == NULL) {
13376
        return BAD_FUNC_ARG;
13377
    }
13378
13379
    XMEMSET(eax->prefixBuf, 0, sizeof(eax->prefixBuf));
13380
13381
    if ((ret = wc_AesInit(&eax->aes, NULL, INVALID_DEVID)) != 0) {
13382
        goto out;
13383
    }
13384
    aesInited = 1;
13385
13386
    if ((ret = wc_AesSetKey(&eax->aes,
13387
                            key,
13388
                            keySz,
13389
                            NULL,
13390
                            AES_ENCRYPTION)) != 0) {
13391
        goto out;
13392
    }
13393
13394
    /*
13395
    * OMAC the nonce to use as the IV for CTR encryption and auth tag chunk
13396
    *   N' = OMAC^0_K(N)
13397
    */
13398
    if ((ret = wc_InitCmac(&eax->nonceCmac,
13399
                           key,
13400
                           keySz,
13401
                           WC_CMAC_AES,
13402
                           NULL)) != 0) {
13403
        return ret;
13404
    }
13405
    nonceCmacInited = 1;
13406
13407
    if ((ret = wc_CmacUpdate(&eax->nonceCmac,
13408
                             eax->prefixBuf,
13409
                             sizeof(eax->prefixBuf))) != 0) {
13410
        goto out;
13411
    }
13412
13413
    if ((ret = wc_CmacUpdate(&eax->nonceCmac, nonce, nonceSz)) != 0) {
13414
        goto out;
13415
    }
13416
13417
    cmacSize = AES_BLOCK_SIZE;
13418
    if ((ret = wc_CmacFinal(&eax->nonceCmac,
13419
                            eax->nonceCmacFinal,
13420
                            &cmacSize)) != 0) {
13421
        goto out;
13422
    }
13423
13424
    if ((ret = wc_AesSetIV(&eax->aes, eax->nonceCmacFinal)) != 0) {
13425
        goto out;
13426
    }
13427
13428
    /*
13429
     * start the OMAC used to build the auth tag chunk for the AD .
13430
     * This CMAC is continued in subsequent update calls when more auth data is
13431
     * provided
13432
     *   H' = OMAC^1_K(H)
13433
     */
13434
    eax->prefixBuf[AES_BLOCK_SIZE-1] = 1;
13435
    if ((ret = wc_InitCmac(&eax->aadCmac,
13436
                           key,
13437
                           keySz,
13438
                           WC_CMAC_AES,
13439
                           NULL)) != 0) {
13440
        goto out;
13441
    }
13442
    aadCmacInited = 1;
13443
13444
    if ((ret = wc_CmacUpdate(&eax->aadCmac,
13445
                             eax->prefixBuf,
13446
                             sizeof(eax->prefixBuf))) != 0) {
13447
        goto out;
13448
    }
13449
13450
    if (authIn != NULL) {
13451
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
13452
            goto out;
13453
        }
13454
    }
13455
13456
    /*
13457
     * start the OMAC to create auth tag chunk for ciphertext. This MAC will be
13458
     * updated in subsequent calls to encrypt/decrypt
13459
     *  C' = OMAC^2_K(C)
13460
     */
13461
    eax->prefixBuf[AES_BLOCK_SIZE-1] = 2;
13462
    if ((ret = wc_InitCmac(&eax->ciphertextCmac,
13463
                           key,
13464
                           keySz,
13465
                           WC_CMAC_AES,
13466
                           NULL)) != 0) {
13467
        goto out;
13468
    }
13469
13470
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac,
13471
                             eax->prefixBuf,
13472
                             sizeof(eax->prefixBuf))) != 0) {
13473
        goto out;
13474
    }
13475
13476
out:
13477
13478
    if (ret != 0) {
13479
        if (aesInited)
13480
            wc_AesFree(&eax->aes);
13481
        if (nonceCmacInited)
13482
            wc_CmacFree(&eax->nonceCmac);
13483
        if (aadCmacInited)
13484
            wc_CmacFree(&eax->aadCmac);
13485
    }
13486
13487
    return ret;
13488
}
13489
13490
13491
/*
13492
 * AES EAX Incremental API:
13493
 * Encrypts input plaintext using AES EAX mode, adding optional auth data to
13494
 * the authentication stream
13495
 *
13496
 * Returns 0 on success
13497
 * Returns error code on failure
13498
 */
13499
int  wc_AesEaxEncryptUpdate(AesEax* eax, byte* out,
13500
                            const byte* in, word32 inSz,
13501
                            const byte* authIn, word32 authInSz)
13502
{
13503
    int ret;
13504
13505
    if (eax == NULL || out == NULL ||  in == NULL) {
13506
        return BAD_FUNC_ARG;
13507
    }
13508
13509
    /*
13510
     * Encrypt the plaintext using AES CTR
13511
     *  C = CTR(M)
13512
     */
13513
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
13514
        return ret;
13515
    }
13516
13517
    /*
13518
     * update OMAC with new ciphertext
13519
     *  C' = OMAC^2_K(C)
13520
     */
13521
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, out, inSz)) != 0) {
13522
        return ret;
13523
    }
13524
13525
    /* If there exists new auth data, update the OMAC for that as well */
13526
    if (authIn != NULL) {
13527
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
13528
            return ret;
13529
        }
13530
    }
13531
13532
    return 0;
13533
}
13534
13535
13536
/*
13537
 * AES EAX Incremental API:
13538
 * Decrypts input ciphertext using AES EAX mode, adding optional auth data to
13539
 * the authentication stream
13540
 *
13541
 * Returns 0 on success
13542
 * Returns error code on failure
13543
 */
13544
int  wc_AesEaxDecryptUpdate(AesEax* eax, byte* out,
13545
                            const byte* in, word32 inSz,
13546
                            const byte* authIn, word32 authInSz)
13547
{
13548
    int ret;
13549
13550
    if (eax == NULL || out == NULL ||  in == NULL) {
13551
        return BAD_FUNC_ARG;
13552
    }
13553
13554
    /*
13555
     * Decrypt the plaintext using AES CTR
13556
     *  C = CTR(M)
13557
     */
13558
    if ((ret = wc_AesCtrEncrypt(&eax->aes, out, in, inSz)) != 0) {
13559
        return ret;
13560
    }
13561
13562
    /*
13563
     * update OMAC with new ciphertext
13564
     *  C' = OMAC^2_K(C)
13565
     */
13566
    if ((ret = wc_CmacUpdate(&eax->ciphertextCmac, in, inSz)) != 0) {
13567
        return ret;
13568
    }
13569
13570
    /* If there exists new auth data, update the OMAC for that as well */
13571
    if (authIn != NULL) {
13572
        if ((ret = wc_CmacUpdate(&eax->aadCmac, authIn, authInSz)) != 0) {
13573
            return ret;
13574
        }
13575
    }
13576
13577
    return 0;
13578
}
13579
13580
13581
/*
13582
 * AES EAX Incremental API:
13583
 * Provides additional auth data information to the authentication
13584
 * stream for an authenticated encryption or decryption operation
13585
 *
13586
 * Returns 0 on success
13587
 * Returns error code on failure
13588
 */
13589
int  wc_AesEaxAuthDataUpdate(AesEax* eax, const byte* authIn, word32 authInSz)
13590
{
13591
    return wc_CmacUpdate(&eax->aadCmac, authIn, authInSz);
13592
}
13593
13594
13595
/*
13596
 * AES EAX Incremental API:
13597
 * Finalizes the authenticated encryption operation, computing the auth tag
13598
 * over previously supplied auth data and computed ciphertext
13599
 *
13600
 * Returns 0 on success
13601
 * Returns error code on failure
13602
 */
13603
int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz)
13604
{
13605
    word32 cmacSize;
13606
    int ret;
13607
    word32 i;
13608
13609
    if (eax == NULL || authTag == NULL || authTagSz > AES_BLOCK_SIZE) {
13610
        return BAD_FUNC_ARG;
13611
    }
13612
13613
    /* Complete the OMAC for the ciphertext */
13614
    cmacSize = AES_BLOCK_SIZE;
13615
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
13616
                                  eax->ciphertextCmacFinal,
13617
                                  &cmacSize)) != 0) {
13618
        return ret;
13619
    }
13620
13621
    /* Complete the OMAC for auth data */
13622
    cmacSize = AES_BLOCK_SIZE;
13623
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
13624
                                  eax->aadCmacFinal,
13625
                                  &cmacSize)) != 0) {
13626
        return ret;
13627
    }
13628
13629
    /*
13630
     * Concatenate all three auth tag chunks into the final tag, truncating
13631
     * at the specified tag length
13632
     *   T = Tag [first authTagSz bytes]
13633
     */
13634
    for (i = 0; i < authTagSz; i++) {
13635
        authTag[i] = eax->nonceCmacFinal[i]
13636
                    ^ eax->aadCmacFinal[i]
13637
                    ^ eax->ciphertextCmacFinal[i];
13638
    }
13639
13640
    return 0;
13641
}
13642
13643
13644
/*
13645
 * AES EAX Incremental API:
13646
 * Finalizes the authenticated decryption operation, computing the auth tag
13647
 * for the previously supplied auth data and cipher text and validating it
13648
 * against a provided auth tag
13649
 *
13650
 * Returns 0 on success
13651
 * Return error code for failure
13652
 */
13653
int wc_AesEaxDecryptFinal(AesEax* eax,
13654
                          const byte* authIn, word32 authInSz)
13655
{
13656
    int ret;
13657
    word32 i;
13658
    word32 cmacSize;
13659
13660
#if defined(WOLFSSL_SMALL_STACK)
13661
    byte *authTag;
13662
#else
13663
    byte authTag[AES_BLOCK_SIZE];
13664
#endif
13665
13666
    if (eax == NULL || authIn == NULL || authInSz > AES_BLOCK_SIZE) {
13667
        return BAD_FUNC_ARG;
13668
    }
13669
13670
    /* Complete the OMAC for the ciphertext */
13671
    cmacSize = AES_BLOCK_SIZE;
13672
    if ((ret = wc_CmacFinalNoFree(&eax->ciphertextCmac,
13673
                                  eax->ciphertextCmacFinal,
13674
                                  &cmacSize)) != 0) {
13675
        return ret;
13676
    }
13677
13678
    /* Complete the OMAC for auth data */
13679
    cmacSize = AES_BLOCK_SIZE;
13680
    if ((ret = wc_CmacFinalNoFree(&eax->aadCmac,
13681
                                  eax->aadCmacFinal,
13682
                                  &cmacSize)) != 0) {
13683
        return ret;
13684
    }
13685
13686
#if defined(WOLFSSL_SMALL_STACK)
13687
    authTag = (byte*)XMALLOC(AES_BLOCK_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13688
    if (authTag == NULL) {
13689
        return MEMORY_E;
13690
    }
13691
#endif
13692
13693
    /*
13694
     * Concatenate all three auth tag chunks into the final tag, truncating
13695
     * at the specified tag length
13696
     *   T = Tag [first authInSz bytes]
13697
     */
13698
    for (i = 0; i < authInSz; i++) {
13699
        authTag[i] = eax->nonceCmacFinal[i]
13700
                    ^ eax->aadCmacFinal[i]
13701
                    ^ eax->ciphertextCmacFinal[i];
13702
    }
13703
13704
    if (ConstantCompare((const byte*)authTag, authIn, (int)authInSz) != 0) {
13705
        ret = AES_EAX_AUTH_E;
13706
    }
13707
    else {
13708
        ret = 0;
13709
    }
13710
13711
#if defined(WOLFSSL_SMALL_STACK)
13712
    XFREE(authTag, NULL, DYNAMIC_TYPE_TMP_BUFFER);
13713
#endif
13714
13715
    return ret;
13716
}
13717
13718
/*
13719
 * Frees the underlying CMAC and AES contexts. Must be called when done using
13720
 * the AES EAX context structure.
13721
 *
13722
 * Returns 0 on success
13723
 * Returns error code on failure
13724
 */
13725
int wc_AesEaxFree(AesEax* eax)
13726
{
13727
    if (eax == NULL) {
13728
        return BAD_FUNC_ARG;
13729
    }
13730
13731
    (void)wc_CmacFree(&eax->ciphertextCmac);
13732
    (void)wc_CmacFree(&eax->aadCmac);
13733
    wc_AesFree(&eax->aes);
13734
13735
    return 0;
13736
}
13737
13738
#endif /* WOLFSSL_AES_EAX */
13739
13740
#endif /* !NO_AES */