Coverage Report

Created: 2024-06-28 06:19

/src/wolfssl/wolfcrypt/src/des3.c
Line
Count
Source (jump to first uncovered line)
1
/* des3.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
#ifdef HAVE_CONFIG_H
24
    #include <config.h>
25
#endif
26
27
#include <wolfssl/wolfcrypt/settings.h>
28
#include <wolfssl/wolfcrypt/error-crypt.h>
29
#include <wolfssl/wolfcrypt/logging.h>
30
31
32
#ifndef NO_DES3
33
34
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
35
    (HAVE_FIPS_VERSION == 2 || HAVE_FIPS_VERSION == 3)
36
37
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
38
    #define FIPS_NO_WRAPPERS
39
40
    #ifdef USE_WINDOWS_API
41
        #pragma code_seg(".fipsA$i")
42
        #pragma const_seg(".fipsB$i")
43
    #endif
44
#endif
45
46
#include <wolfssl/wolfcrypt/des3.h>
47
48
#ifdef WOLF_CRYPTO_CB
49
    #include <wolfssl/wolfcrypt/cryptocb.h>
50
#endif
51
52
#if defined(WOLFSSL_TI_CRYPT)
53
    #include <wolfcrypt/src/port/ti/ti-des3.c>
54
#else
55
56
57
#ifdef NO_INLINE
58
    #include <wolfssl/wolfcrypt/misc.h>
59
#else
60
    #define WOLFSSL_MISC_INCLUDED
61
    #include <wolfcrypt/src/misc.c>
62
#endif
63
64
65
/* Hardware Acceleration */
66
#if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY)
67
68
    /*
69
     * STM32F2/F4 hardware DES/3DES support through the standard
70
     * peripheral library. (See note in README).
71
     */
72
73
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
74
    {
75
        word32 *dkey = des->key;
76
77
        (void)dir;
78
79
        XMEMCPY(dkey, key, 8);
80
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
81
        ByteReverseWords(dkey, dkey, 8);
82
    #endif
83
84
        wc_Des_SetIV(des, iv);
85
86
        return 0;
87
    }
88
89
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
90
    {
91
        if (des == NULL || key == NULL)
92
            return BAD_FUNC_ARG;
93
94
        (void)dir;
95
96
    #ifndef WOLFSSL_STM32_CUBEMX
97
        {
98
            word32 *dkey1 = des->key[0];
99
            word32 *dkey2 = des->key[1];
100
            word32 *dkey3 = des->key[2];
101
102
            XMEMCPY(dkey1, key, 8);         /* set key 1 */
103
            XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
104
            XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
105
106
            ByteReverseWords(dkey1, dkey1, 8);
107
            ByteReverseWords(dkey2, dkey2, 8);
108
            ByteReverseWords(dkey3, dkey3, 8);
109
        }
110
    #else
111
        /* CUBEMX wants keys in sequential memory */
112
        XMEMCPY(des->key[0], key, DES3_KEYLEN);
113
        #ifdef STM32_HAL_V2
114
        ByteReverseWords((word32*)des->key, (word32*)des->key, DES3_KEYLEN);
115
        #endif
116
    #endif
117
118
        return wc_Des3_SetIV(des, iv);
119
    }
120
121
    static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
122
                  int dir, int mode)
123
    {
124
        int ret;
125
    #ifdef WOLFSSL_STM32_CUBEMX
126
        CRYP_HandleTypeDef hcryp;
127
    #else
128
        word32 *dkey, *iv;
129
        CRYP_InitTypeDef DES_CRYP_InitStructure;
130
        CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
131
        CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
132
    #endif
133
134
        ret = wolfSSL_CryptHwMutexLock();
135
        if (ret != 0) {
136
            return;
137
        }
138
139
    #ifdef WOLFSSL_STM32_CUBEMX
140
        XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
141
        hcryp.Instance = CRYP;
142
        hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;
143
        hcryp.Init.DataType = CRYP_DATATYPE_8B;
144
        hcryp.Init.pKey = (STM_CRYPT_TYPE*)des->key;
145
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)des->reg;
146
    #ifdef STM32_HAL_V2
147
        hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
148
        if (mode == DES_CBC)
149
            hcryp.Init.Algorithm = CRYP_DES_CBC;
150
        else
151
            hcryp.Init.Algorithm = CRYP_DES_ECB;
152
    #endif
153
154
        HAL_CRYP_Init(&hcryp);
155
156
    #ifdef STM32_HAL_V2
157
        if (dir == DES_ENCRYPTION) {
158
            HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
159
                STM32_HAL_TIMEOUT);
160
        }
161
        else {
162
            HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
163
                STM32_HAL_TIMEOUT);
164
        }
165
        /* save off IV */
166
        des->reg[0] = hcryp.Instance->IV0LR;
167
        des->reg[1] = hcryp.Instance->IV0RR;
168
    #else
169
        while (sz > 0) {
170
            /* if input and output same will overwrite input iv */
171
            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
172
173
            if (mode == DES_CBC) {
174
                if (dir == DES_ENCRYPTION) {
175
                    HAL_CRYP_DESCBC_Encrypt(&hcryp, (uint8_t*)in,
176
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
177
                }
178
                else {
179
                    HAL_CRYP_DESCBC_Decrypt(&hcryp, (uint8_t*)in,
180
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
181
                }
182
            }
183
            else {
184
                if (dir == DES_ENCRYPTION) {
185
                    HAL_CRYP_DESECB_Encrypt(&hcryp, (uint8_t*)in,
186
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
187
                }
188
                else {
189
                    HAL_CRYP_DESECB_Decrypt(&hcryp, (uint8_t*)in,
190
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
191
                }
192
            }
193
194
            /* store iv for next call */
195
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
196
197
            sz  -= DES_BLOCK_SIZE;
198
            in  += DES_BLOCK_SIZE;
199
            out += DES_BLOCK_SIZE;
200
        }
201
    #endif /* STM32_HAL_V2 */
202
203
        HAL_CRYP_DeInit(&hcryp);
204
    #else
205
        dkey = des->key;
206
        iv = des->reg;
207
208
        /* crypto structure initialization */
209
        CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
210
        CRYP_StructInit(&DES_CRYP_InitStructure);
211
        CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
212
213
        /* reset registers to their default values */
214
        CRYP_DeInit();
215
216
        /* set direction, mode, and datatype */
217
        if (dir == DES_ENCRYPTION) {
218
            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
219
        } else { /* DES_DECRYPTION */
220
            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
221
        }
222
223
        if (mode == DES_CBC) {
224
            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
225
        } else { /* DES_ECB */
226
            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
227
        }
228
229
        DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
230
        CRYP_Init(&DES_CRYP_InitStructure);
231
232
        /* load key into correct registers */
233
        DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];
234
        DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
235
        CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
236
237
        /* set iv */
238
        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
239
        DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
240
        DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
241
        CRYP_IVInit(&DES_CRYP_IVInitStructure);
242
243
        /* enable crypto processor */
244
        CRYP_Cmd(ENABLE);
245
246
        while (sz > 0) {
247
            /* flush IN/OUT FIFOs */
248
            CRYP_FIFOFlush();
249
250
            /* if input and output same will overwrite input iv */
251
            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
252
253
            CRYP_DataIn(*(uint32_t*)&in[0]);
254
            CRYP_DataIn(*(uint32_t*)&in[4]);
255
256
            /* wait until the complete message has been processed */
257
            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
258
259
            *(uint32_t*)&out[0]  = CRYP_DataOut();
260
            *(uint32_t*)&out[4]  = CRYP_DataOut();
261
262
            /* store iv for next call */
263
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
264
265
            sz  -= DES_BLOCK_SIZE;
266
            in  += DES_BLOCK_SIZE;
267
            out += DES_BLOCK_SIZE;
268
        }
269
270
        /* disable crypto processor */
271
        CRYP_Cmd(DISABLE);
272
    #endif /* WOLFSSL_STM32_CUBEMX */
273
        wolfSSL_CryptHwMutexUnLock();
274
    }
275
276
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
277
    {
278
        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
279
        return 0;
280
    }
281
282
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
283
    {
284
        DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
285
        return 0;
286
    }
287
288
    int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
289
    {
290
        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
291
        return 0;
292
    }
293
294
    static int Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
295
                   int dir)
296
    {
297
        if (des == NULL || out == NULL || in == NULL)
298
            return BAD_FUNC_ARG;
299
300
    #ifdef WOLFSSL_STM32_CUBEMX
301
        {
302
            CRYP_HandleTypeDef hcryp;
303
304
            XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
305
            hcryp.Instance = CRYP;
306
            hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;
307
            hcryp.Init.DataType = CRYP_DATATYPE_8B;
308
            hcryp.Init.pKey = (STM_CRYPT_TYPE*)des->key;
309
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)des->reg;
310
        #ifdef STM32_HAL_V2
311
            hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
312
            hcryp.Init.Algorithm = CRYP_TDES_CBC;
313
        #endif
314
315
            HAL_CRYP_Init(&hcryp);
316
317
        #ifdef STM32_HAL_V2
318
            if (dir == DES_ENCRYPTION) {
319
                HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
320
                    STM32_HAL_TIMEOUT);
321
            }
322
            else {
323
                HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
324
                    STM32_HAL_TIMEOUT);
325
            }
326
            /* save off IV */
327
            des->reg[0] = hcryp.Instance->IV0LR;
328
            des->reg[1] = hcryp.Instance->IV0RR;
329
        #else
330
            while (sz > 0) {
331
                if (dir == DES_ENCRYPTION) {
332
                    HAL_CRYP_TDESCBC_Encrypt(&hcryp, (byte*)in,
333
                                       DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
334
                }
335
                else {
336
                    HAL_CRYP_TDESCBC_Decrypt(&hcryp, (byte*)in,
337
                                       DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
338
                }
339
340
                /* store iv for next call */
341
                XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
342
343
                sz  -= DES_BLOCK_SIZE;
344
                in  += DES_BLOCK_SIZE;
345
                out += DES_BLOCK_SIZE;
346
            }
347
        #endif /* STM32_HAL_V2 */
348
349
            HAL_CRYP_DeInit(&hcryp);
350
        }
351
    #else
352
        {
353
            word32 *dkey1, *dkey2, *dkey3, *iv;
354
            CRYP_InitTypeDef DES3_CRYP_InitStructure;
355
            CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
356
            CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
357
358
            dkey1 = des->key[0];
359
            dkey2 = des->key[1];
360
            dkey3 = des->key[2];
361
            iv = des->reg;
362
363
            /* crypto structure initialization */
364
            CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
365
            CRYP_StructInit(&DES3_CRYP_InitStructure);
366
            CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
367
368
            /* reset registers to their default values */
369
            CRYP_DeInit();
370
371
            /* set direction, mode, and datatype */
372
            if (dir == DES_ENCRYPTION) {
373
                DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
374
            } else {
375
                DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
376
            }
377
378
            DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
379
            DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
380
            CRYP_Init(&DES3_CRYP_InitStructure);
381
382
            /* load key into correct registers */
383
            DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];
384
            DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
385
            DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];
386
            DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
387
            DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];
388
            DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
389
            CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
390
391
            /* set iv */
392
            ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
393
            DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
394
            DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
395
            CRYP_IVInit(&DES3_CRYP_IVInitStructure);
396
397
            /* enable crypto processor */
398
            CRYP_Cmd(ENABLE);
399
400
            while (sz > 0)
401
            {
402
                /* flush IN/OUT FIFOs */
403
                CRYP_FIFOFlush();
404
405
                CRYP_DataIn(*(uint32_t*)&in[0]);
406
                CRYP_DataIn(*(uint32_t*)&in[4]);
407
408
                /* wait until the complete message has been processed */
409
                while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
410
411
                *(uint32_t*)&out[0]  = CRYP_DataOut();
412
                *(uint32_t*)&out[4]  = CRYP_DataOut();
413
414
                /* store iv for next call */
415
                XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
416
417
                sz  -= DES_BLOCK_SIZE;
418
                in  += DES_BLOCK_SIZE;
419
                out += DES_BLOCK_SIZE;
420
            }
421
422
            /* disable crypto processor */
423
            CRYP_Cmd(DISABLE);
424
        }
425
    #endif /* WOLFSSL_STM32_CUBEMX */
426
        return 0;
427
    }
428
429
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
430
    {
431
        return Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
432
    }
433
434
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
435
    {
436
        return Des3Crypt(des, out, in, sz, DES_DECRYPTION);
437
    }
438
439
#elif defined(HAVE_COLDFIRE_SEC)
440
441
    #include <wolfssl/wolfcrypt/types.h>
442
443
    #include "sec.h"
444
    #include "mcf5475_sec.h"
445
    #include "mcf5475_siu.h"
446
447
    #if defined (HAVE_THREADX)
448
    #include "memory_pools.h"
449
    extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
450
    #endif
451
452
    #define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64)
453
    static unsigned char *desBuffIn = NULL;
454
    static unsigned char *desBuffOut = NULL;
455
    static byte *secIV;
456
    static byte *secKey;
457
    static volatile SECdescriptorType *secDesc;
458
459
    static wolfSSL_Mutex Mutex_DesSEC;
460
461
    #define SEC_DESC_DES_CBC_ENCRYPT  0x20500010
462
    #define SEC_DESC_DES_CBC_DECRYPT  0x20400010
463
    #define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010
464
    #define SEC_DESC_DES3_CBC_DECRYPT 0x20600010
465
466
    #define DES_IVLEN 8
467
    #define DES_KEYLEN 8
468
    #define DES3_IVLEN 8
469
    #define DES3_KEYLEN 24
470
471
    extern volatile unsigned char __MBAR[];
472
473
    static void wc_Des_Cbc(byte* out, const byte* in, word32 sz,
474
                        byte *key, byte *iv, word32 desc)
475
    {
476
        #ifdef DEBUG_WOLFSSL
477
        int ret;  int stat1,stat2;
478
        #endif
479
        int size;
480
        volatile int v;
481
482
        wc_LockMutex(&Mutex_DesSEC) ;
483
484
        secDesc->length1 = 0x0;
485
        secDesc->pointer1 = NULL;
486
        if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){
487
            secDesc->length2 = DES_IVLEN;
488
            secDesc->length3 = DES_KEYLEN;
489
        } else {
490
            secDesc->length2 = DES3_IVLEN;
491
            secDesc->length3 = DES3_KEYLEN;
492
        }
493
        secDesc->pointer2 = secIV;
494
        secDesc->pointer3 = secKey;
495
        secDesc->pointer4 = desBuffIn;
496
        secDesc->pointer5 = desBuffOut;
497
        secDesc->length6 = 0;
498
        secDesc->pointer6 = NULL;
499
        secDesc->length7 = 0x0;
500
        secDesc->pointer7 = NULL;
501
        secDesc->nextDescriptorPtr = NULL;
502
503
        while(sz) {
504
            XMEMCPY(secIV, iv, secDesc->length2);
505
            if((sz%DES_BUFFER_SIZE) == sz) {
506
                size = sz;
507
                sz = 0;
508
            } else {
509
                size = DES_BUFFER_SIZE;
510
                sz -= DES_BUFFER_SIZE;
511
            }
512
513
            XMEMCPY(desBuffIn, in, size);
514
            XMEMCPY(secKey, key, secDesc->length3);
515
516
            secDesc->header = desc;
517
            secDesc->length4 = size;
518
            secDesc->length5 = size;
519
            /* Point SEC to the location of the descriptor */
520
            MCF_SEC_FR0 = (uint32)secDesc;
521
            /* Initialize SEC and wait for encryption to complete */
522
            MCF_SEC_CCCR0 = 0x0000001a;
523
            /* poll SISR to determine when channel is complete */
524
            v=0;
525
            while((secDesc->header>> 24) != 0xff) {
526
                if(v++ > 1000)break;
527
            }
528
529
        #ifdef DEBUG_WOLFSSL
530
            ret = MCF_SEC_SISRH;
531
            stat1 = MCF_SEC_DSR;
532
            stat2 = MCF_SEC_DISR;
533
            if(ret & 0xe0000000) {
534
                /* db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2); */
535
            }
536
        #endif
537
538
            XMEMCPY(out, desBuffOut, size);
539
540
            if ((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) {
541
                XMEMCPY((void*)iv, (void*)&(out[size-secDesc->length2]), secDesc->length2);
542
            } else {
543
                XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2);
544
            }
545
546
            in  += size;
547
            out += size;
548
549
        }
550
        wc_UnLockMutex(&Mutex_DesSEC) ;
551
552
    }
553
554
555
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
556
    {
557
        wc_Des_Cbc(out, in, sz,  (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_ENCRYPT);
558
        return 0;
559
    }
560
561
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
562
    {
563
        wc_Des_Cbc(out, in, sz,   (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_DECRYPT);
564
        return 0;
565
    }
566
567
    int wc_Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)
568
    {
569
        wc_Des_Cbc(out, in, sz,  (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_ENCRYPT);
570
        return 0;
571
    }
572
573
574
    int wc_Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)
575
    {
576
        wc_Des_Cbc(out, in, sz,   (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_DECRYPT);
577
        return 0;
578
    }
579
580
    static void setParity(byte *buf, int len)
581
    {
582
        int i, j;
583
        byte v;
584
        int bits;
585
586
        for (i=0; i<len; i++) {
587
            v = buf[i] >> 1;
588
            buf[i] = v << 1;
589
            bits = 0;
590
            for (j=0; j<7; j++) {
591
                bits += (v&0x1);
592
                v = v >> 1;
593
            }
594
            buf[i] |= (1 - (bits&0x1));
595
        }
596
597
    }
598
599
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
600
    {
601
        if(desBuffIn == NULL) {
602
        #if defined (HAVE_THREADX)
603
            int s1, s2, s3, s4, s5;
604
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
605
                                                         sizeof(SECdescriptorType), TX_NO_WAIT);
606
            s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
607
            s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
608
            /* Don't know des or des3 to be used. Allocate larger buffers */
609
            s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
610
            s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);
611
        #else
612
            #warning "Allocate non-Cache buffers"
613
        #endif
614
615
            InitMutex(&Mutex_DesSEC);
616
        }
617
618
        XMEMCPY(des->key, key, DES_KEYLEN);
619
        setParity((byte *)des->key, DES_KEYLEN);
620
621
        if (iv) {
622
            XMEMCPY(des->reg, iv, DES_IVLEN);
623
        }   else {
624
            XMEMSET(des->reg, 0x0, DES_IVLEN);
625
        }
626
        return 0;
627
    }
628
629
    int wc_Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
630
    {
631
        if (des3 == NULL || key == NULL) {
632
            return BAD_FUNC_ARG;
633
        }
634
635
        if (desBuffIn == NULL) {
636
        #if defined (HAVE_THREADX)
637
            int s1, s2, s3, s4, s5;
638
            s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc,
639
                                                         sizeof(SECdescriptorType), TX_NO_WAIT);
640
            s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
641
            s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
642
            s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
643
            s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);
644
        #else
645
            #warning "Allocate non-Cache buffers"
646
        #endif
647
648
            InitMutex(&Mutex_DesSEC);
649
        }
650
651
        XMEMCPY(des3->key[0], key, DES3_KEYLEN);
652
        setParity((byte *)des3->key[0], DES3_KEYLEN);
653
654
        if (iv) {
655
            XMEMCPY(des3->reg, iv, DES3_IVLEN);
656
        }   else {
657
            XMEMSET(des3->reg, 0x0, DES3_IVLEN);
658
        }
659
        return 0;
660
661
    }
662
#elif defined(FREESCALE_LTC_DES)
663
664
    #include "fsl_ltc.h"
665
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
666
    {
667
        byte* dkey;
668
669
        if (des == NULL || key == NULL) {
670
            return BAD_FUNC_ARG;
671
        }
672
673
        dkey = (byte*)des->key;
674
675
        XMEMCPY(dkey, key, 8);
676
677
        wc_Des_SetIV(des, iv);
678
679
        return 0;
680
    }
681
682
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
683
    {
684
        int ret = 0;
685
        byte* dkey1;
686
        byte* dkey2;
687
        byte* dkey3;
688
689
        if (des == NULL || key == NULL) {
690
            return BAD_FUNC_ARG;
691
        }
692
693
        dkey1 = (byte*)des->key[0];
694
        dkey2 = (byte*)des->key[1];
695
        dkey3 = (byte*)des->key[2];
696
697
        XMEMCPY(dkey1, key, 8);         /* set key 1 */
698
        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
699
        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
700
701
        ret = wc_Des3_SetIV(des, iv);
702
        if (ret != 0)
703
            return ret;
704
705
        return ret;
706
    }
707
708
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
709
    {
710
        status_t status;
711
        status = LTC_DES_EncryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);
712
        if (status == kStatus_Success)
713
            return 0;
714
        else
715
            return -1;
716
    }
717
718
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
719
    {
720
        status_t status;
721
        status = LTC_DES_DecryptCbc(LTC_BASE, in, out, sz, (byte*)des->reg, (byte*)des->key);
722
        if (status == kStatus_Success)
723
            return 0;
724
        else
725
            return -1;
726
    }
727
728
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
729
    {
730
        status_t status;
731
        status = LTC_DES3_EncryptCbc(LTC_BASE,
732
                                 in,
733
                                 out,
734
                                 sz,
735
                                 (byte*)des->reg,
736
                                 (byte*)des->key[0],
737
                                 (byte*)des->key[1],
738
                                 (byte*)des->key[2]);
739
        if (status == kStatus_Success)
740
            return 0;
741
        else
742
            return -1;
743
    }
744
745
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
746
    {
747
        status_t status;
748
        status = LTC_DES3_DecryptCbc(LTC_BASE,
749
                                 in,
750
                                 out,
751
                                 sz,
752
                                 (byte*)des->reg,
753
                                 (byte*)des->key[0],
754
                                 (byte*)des->key[1],
755
                                 (byte*)des->key[2]);
756
        if (status == kStatus_Success)
757
            return 0;
758
        else
759
            return -1;
760
761
    }
762
763
#elif defined(FREESCALE_MMCAU)
764
    /*
765
     * Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
766
     * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
767
     * Software Library User Guide (See note in README).
768
     */
769
    #ifdef FREESCALE_MMCAU_CLASSIC
770
        #include "cau_api.h"
771
    #else
772
        #include "fsl_mmcau.h"
773
    #endif
774
775
    const unsigned char parityLookup[128] = {
776
        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
777
        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
778
        0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
779
        1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
780
     };
781
782
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
783
    {
784
        int i = 0;
785
        byte* dkey;
786
787
788
        if (des == NULL || key == NULL) {
789
            return BAD_FUNC_ARG;
790
        }
791
792
        dkey = (byte*)des->key;
793
794
        XMEMCPY(dkey, key, 8);
795
796
        wc_Des_SetIV(des, iv);
797
798
        /* fix key parity, if needed */
799
        for (i = 0; i < 8; i++) {
800
            dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);
801
        }
802
803
        return 0;
804
    }
805
806
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
807
    {
808
        int i = 0, ret = 0;
809
        byte* dkey1;
810
        byte* dkey2;
811
        byte* dkey3;
812
813
        if (des == NULL || key == NULL) {
814
            return BAD_FUNC_ARG;
815
        }
816
817
        dkey1 = (byte*)des->key[0];
818
        dkey2 = (byte*)des->key[1];
819
        dkey3 = (byte*)des->key[2];
820
821
        XMEMCPY(dkey1, key, 8);         /* set key 1 */
822
        XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
823
        XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
824
825
        ret = wc_Des3_SetIV(des, iv);
826
        if (ret != 0)
827
            return ret;
828
829
        /* fix key parity if needed */
830
        for (i = 0; i < 8; i++)
831
           dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);
832
833
        for (i = 0; i < 8; i++)
834
           dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);
835
836
        for (i = 0; i < 8; i++)
837
           dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);
838
839
        return ret;
840
    }
841
842
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
843
    {
844
        int offset = 0;
845
        int len = sz;
846
        int ret = 0;
847
        byte *iv;
848
        byte temp_block[DES_BLOCK_SIZE];
849
850
        iv = (byte*)des->reg;
851
852
    #ifdef FREESCALE_MMCAU_CLASSIC
853
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
854
            WOLFSSL_MSG("Bad cau_des_encrypt alignment");
855
            return BAD_ALIGN_E;
856
        }
857
    #endif
858
859
        while (len > 0)
860
        {
861
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
862
863
            /* XOR block with IV for CBC */
864
            xorbuf(temp_block, iv, DES_BLOCK_SIZE);
865
866
            ret = wolfSSL_CryptHwMutexLock();
867
            if(ret != 0) {
868
                return ret;
869
            }
870
        #ifdef FREESCALE_MMCAU_CLASSIC
871
            cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
872
        #else
873
            MMCAU_DES_EncryptEcb(temp_block, (byte*)des->key, out + offset);
874
        #endif
875
            wolfSSL_CryptHwMutexUnLock();
876
877
            len    -= DES_BLOCK_SIZE;
878
            offset += DES_BLOCK_SIZE;
879
880
            /* store IV for next block */
881
            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
882
        }
883
884
        return ret;
885
    }
886
887
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
888
    {
889
        int offset = 0;
890
        int len = sz;
891
        int ret = 0;
892
        byte* iv;
893
        byte temp_block[DES_BLOCK_SIZE];
894
895
        iv = (byte*)des->reg;
896
897
    #ifdef FREESCALE_MMCAU_CLASSIC
898
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
899
            WOLFSSL_MSG("Bad cau_des_decrypt alignment");
900
            return BAD_ALIGN_E;
901
        }
902
    #endif
903
904
        while (len > 0)
905
        {
906
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
907
908
            ret = wolfSSL_CryptHwMutexLock();
909
            if(ret != 0) {
910
                return ret;
911
            }
912
913
        #ifdef FREESCALE_MMCAU_CLASSIC
914
            cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
915
        #else
916
            MMCAU_DES_DecryptEcb(in + offset, (byte*)des->key, out + offset);
917
        #endif
918
            wolfSSL_CryptHwMutexUnLock();
919
920
            /* XOR block with IV for CBC */
921
            xorbuf(out + offset, iv, DES_BLOCK_SIZE);
922
923
            /* store IV for next block */
924
            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
925
926
            len     -= DES_BLOCK_SIZE;
927
            offset += DES_BLOCK_SIZE;
928
        }
929
930
        return ret;
931
    }
932
933
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
934
    {
935
        int offset = 0;
936
        int len = sz;
937
        int ret = 0;
938
939
        byte *iv;
940
        byte temp_block[DES_BLOCK_SIZE];
941
942
        iv = (byte*)des->reg;
943
944
    #ifdef FREESCALE_MMCAU_CLASSIC
945
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
946
            WOLFSSL_MSG("Bad 3ede cau_des_encrypt alignment");
947
            return BAD_ALIGN_E;
948
        }
949
    #endif
950
951
        while (len > 0)
952
        {
953
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
954
955
            /* XOR block with IV for CBC */
956
            xorbuf(temp_block, iv, DES_BLOCK_SIZE);
957
958
            ret = wolfSSL_CryptHwMutexLock();
959
            if(ret != 0) {
960
                return ret;
961
            }
962
    #ifdef FREESCALE_MMCAU_CLASSIC
963
            cau_des_encrypt(temp_block,   (byte*)des->key[0], out + offset);
964
            cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
965
            cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
966
    #else
967
            MMCAU_DES_EncryptEcb(temp_block  , (byte*)des->key[0], out + offset);
968
            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[1], out + offset);
969
            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[2], out + offset);
970
    #endif
971
            wolfSSL_CryptHwMutexUnLock();
972
973
            len    -= DES_BLOCK_SIZE;
974
            offset += DES_BLOCK_SIZE;
975
976
            /* store IV for next block */
977
            XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
978
        }
979
980
        return ret;
981
    }
982
983
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
984
    {
985
        int offset = 0;
986
        int len = sz;
987
        int ret = 0;
988
989
        byte* iv;
990
        byte temp_block[DES_BLOCK_SIZE];
991
992
        iv = (byte*)des->reg;
993
994
    #ifdef FREESCALE_MMCAU_CLASSIC
995
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
996
            WOLFSSL_MSG("Bad 3ede cau_des_decrypt alignment");
997
            return BAD_ALIGN_E;
998
        }
999
    #endif
1000
1001
        while (len > 0)
1002
        {
1003
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
1004
1005
            ret = wolfSSL_CryptHwMutexLock();
1006
            if(ret != 0) {
1007
                return ret;
1008
            }
1009
        #ifdef FREESCALE_MMCAU_CLASSIC
1010
            cau_des_decrypt(in + offset,  (byte*)des->key[2], out + offset);
1011
            cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
1012
            cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
1013
        #else
1014
            MMCAU_DES_DecryptEcb(in + offset , (byte*)des->key[2], out + offset);
1015
            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[1], out + offset);
1016
            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[0], out + offset);
1017
        #endif
1018
            wolfSSL_CryptHwMutexUnLock();
1019
1020
            /* XOR block with IV for CBC */
1021
            xorbuf(out + offset, iv, DES_BLOCK_SIZE);
1022
1023
            /* store IV for next block */
1024
            XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
1025
1026
            len    -= DES_BLOCK_SIZE;
1027
            offset += DES_BLOCK_SIZE;
1028
        }
1029
1030
        return ret;
1031
    }
1032
1033
1034
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
1035
1036
    /* PIC32MZ DES hardware requires size multiple of block size */
1037
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
1038
1039
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
1040
    {
1041
        if (des == NULL || key == NULL || iv == NULL)
1042
            return BAD_FUNC_ARG;
1043
1044
        XMEMCPY(des->key, key, DES_KEYLEN);
1045
        XMEMCPY(des->reg, iv, DES_IVLEN);
1046
1047
        return 0;
1048
    }
1049
1050
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
1051
    {
1052
        if (des == NULL || key == NULL || iv == NULL)
1053
            return BAD_FUNC_ARG;
1054
1055
        XMEMCPY(des->key[0], key, DES3_KEYLEN);
1056
        XMEMCPY(des->reg, iv, DES3_IVLEN);
1057
1058
        return 0;
1059
    }
1060
1061
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1062
    {
1063
        word32 blocks = sz / DES_BLOCK_SIZE;
1064
1065
        if (des == NULL || out == NULL || in == NULL)
1066
            return BAD_FUNC_ARG;
1067
1068
        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
1069
            out, in, (blocks * DES_BLOCK_SIZE),
1070
            PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
1071
    }
1072
1073
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
1074
    {
1075
        word32 blocks = sz / DES_BLOCK_SIZE;
1076
1077
        if (des == NULL || out == NULL || in == NULL)
1078
            return BAD_FUNC_ARG;
1079
1080
        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
1081
            out, in, (blocks * DES_BLOCK_SIZE),
1082
            PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
1083
    }
1084
1085
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1086
    {
1087
        word32 blocks = sz / DES_BLOCK_SIZE;
1088
1089
        if (des == NULL || out == NULL || in == NULL)
1090
            return BAD_FUNC_ARG;
1091
1092
        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
1093
            out, in, (blocks * DES_BLOCK_SIZE),
1094
            PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
1095
    }
1096
1097
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
1098
    {
1099
        word32 blocks = sz / DES_BLOCK_SIZE;
1100
1101
        if (des == NULL || out == NULL || in == NULL)
1102
            return BAD_FUNC_ARG;
1103
1104
        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
1105
            out, in, (blocks * DES_BLOCK_SIZE),
1106
            PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
1107
    }
1108
1109
    #ifdef WOLFSSL_DES_ECB
1110
        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1111
        {
1112
            word32 blocks = sz / DES_BLOCK_SIZE;
1113
1114
            if (des == NULL || out == NULL || in == NULL)
1115
                return BAD_FUNC_ARG;
1116
1117
            return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
1118
                out, in, (blocks * DES_BLOCK_SIZE),
1119
                    PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_ECB);
1120
        }
1121
1122
        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1123
        {
1124
            word32 blocks = sz / DES_BLOCK_SIZE;
1125
1126
            if (des == NULL || out == NULL || in == NULL)
1127
                return BAD_FUNC_ARG;
1128
1129
            return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
1130
                out, in, (blocks * DES_BLOCK_SIZE),
1131
                PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TECB);
1132
        }
1133
    #endif /* WOLFSSL_DES_ECB */
1134
1135
#else
1136
    #define NEED_SOFT_DES
1137
1138
#endif
1139
1140
1141
#ifdef NEED_SOFT_DES
1142
1143
    /* permuted choice table (key) */
1144
    static const FLASH_QUALIFIER byte pc1[] = {
1145
           57, 49, 41, 33, 25, 17,  9,
1146
            1, 58, 50, 42, 34, 26, 18,
1147
           10,  2, 59, 51, 43, 35, 27,
1148
           19, 11,  3, 60, 52, 44, 36,
1149
1150
           63, 55, 47, 39, 31, 23, 15,
1151
            7, 62, 54, 46, 38, 30, 22,
1152
           14,  6, 61, 53, 45, 37, 29,
1153
           21, 13,  5, 28, 20, 12,  4
1154
    };
1155
1156
    /* number left rotations of pc1 */
1157
    static const FLASH_QUALIFIER byte totrot[] = {
1158
           1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
1159
    };
1160
1161
    /* permuted choice key (table) */
1162
    static const FLASH_QUALIFIER byte pc2[] = {
1163
           14, 17, 11, 24,  1,  5,
1164
            3, 28, 15,  6, 21, 10,
1165
           23, 19, 12,  4, 26,  8,
1166
           16,  7, 27, 20, 13,  2,
1167
           41, 52, 31, 37, 47, 55,
1168
           30, 40, 51, 45, 33, 48,
1169
           44, 49, 39, 56, 34, 53,
1170
           46, 42, 50, 36, 29, 32
1171
    };
1172
1173
    /* End of DES-defined tables */
1174
1175
    /* bit 0 is left-most in byte */
1176
    static const FLASH_QUALIFIER int bytebit[] = {
1177
        0200,0100,040,020,010,04,02,01
1178
    };
1179
1180
    static const FLASH_QUALIFIER word32 Spbox[8][64] = {
1181
    {   0x01010400,0x00000000,0x00010000,0x01010404,
1182
        0x01010004,0x00010404,0x00000004,0x00010000,
1183
        0x00000400,0x01010400,0x01010404,0x00000400,
1184
        0x01000404,0x01010004,0x01000000,0x00000004,
1185
        0x00000404,0x01000400,0x01000400,0x00010400,
1186
        0x00010400,0x01010000,0x01010000,0x01000404,
1187
        0x00010004,0x01000004,0x01000004,0x00010004,
1188
        0x00000000,0x00000404,0x00010404,0x01000000,
1189
        0x00010000,0x01010404,0x00000004,0x01010000,
1190
        0x01010400,0x01000000,0x01000000,0x00000400,
1191
        0x01010004,0x00010000,0x00010400,0x01000004,
1192
        0x00000400,0x00000004,0x01000404,0x00010404,
1193
        0x01010404,0x00010004,0x01010000,0x01000404,
1194
        0x01000004,0x00000404,0x00010404,0x01010400,
1195
        0x00000404,0x01000400,0x01000400,0x00000000,
1196
        0x00010004,0x00010400,0x00000000,0x01010004},
1197
    {   0x80108020,0x80008000,0x00008000,0x00108020,
1198
        0x00100000,0x00000020,0x80100020,0x80008020,
1199
        0x80000020,0x80108020,0x80108000,0x80000000,
1200
        0x80008000,0x00100000,0x00000020,0x80100020,
1201
        0x00108000,0x00100020,0x80008020,0x00000000,
1202
        0x80000000,0x00008000,0x00108020,0x80100000,
1203
        0x00100020,0x80000020,0x00000000,0x00108000,
1204
        0x00008020,0x80108000,0x80100000,0x00008020,
1205
        0x00000000,0x00108020,0x80100020,0x00100000,
1206
        0x80008020,0x80100000,0x80108000,0x00008000,
1207
        0x80100000,0x80008000,0x00000020,0x80108020,
1208
        0x00108020,0x00000020,0x00008000,0x80000000,
1209
        0x00008020,0x80108000,0x00100000,0x80000020,
1210
        0x00100020,0x80008020,0x80000020,0x00100020,
1211
        0x00108000,0x00000000,0x80008000,0x00008020,
1212
        0x80000000,0x80100020,0x80108020,0x00108000},
1213
    {   0x00000208,0x08020200,0x00000000,0x08020008,
1214
        0x08000200,0x00000000,0x00020208,0x08000200,
1215
        0x00020008,0x08000008,0x08000008,0x00020000,
1216
        0x08020208,0x00020008,0x08020000,0x00000208,
1217
        0x08000000,0x00000008,0x08020200,0x00000200,
1218
        0x00020200,0x08020000,0x08020008,0x00020208,
1219
        0x08000208,0x00020200,0x00020000,0x08000208,
1220
        0x00000008,0x08020208,0x00000200,0x08000000,
1221
        0x08020200,0x08000000,0x00020008,0x00000208,
1222
        0x00020000,0x08020200,0x08000200,0x00000000,
1223
        0x00000200,0x00020008,0x08020208,0x08000200,
1224
        0x08000008,0x00000200,0x00000000,0x08020008,
1225
        0x08000208,0x00020000,0x08000000,0x08020208,
1226
        0x00000008,0x00020208,0x00020200,0x08000008,
1227
        0x08020000,0x08000208,0x00000208,0x08020000,
1228
        0x00020208,0x00000008,0x08020008,0x00020200},
1229
    {   0x00802001,0x00002081,0x00002081,0x00000080,
1230
        0x00802080,0x00800081,0x00800001,0x00002001,
1231
        0x00000000,0x00802000,0x00802000,0x00802081,
1232
        0x00000081,0x00000000,0x00800080,0x00800001,
1233
        0x00000001,0x00002000,0x00800000,0x00802001,
1234
        0x00000080,0x00800000,0x00002001,0x00002080,
1235
        0x00800081,0x00000001,0x00002080,0x00800080,
1236
        0x00002000,0x00802080,0x00802081,0x00000081,
1237
        0x00800080,0x00800001,0x00802000,0x00802081,
1238
        0x00000081,0x00000000,0x00000000,0x00802000,
1239
        0x00002080,0x00800080,0x00800081,0x00000001,
1240
        0x00802001,0x00002081,0x00002081,0x00000080,
1241
        0x00802081,0x00000081,0x00000001,0x00002000,
1242
        0x00800001,0x00002001,0x00802080,0x00800081,
1243
        0x00002001,0x00002080,0x00800000,0x00802001,
1244
        0x00000080,0x00800000,0x00002000,0x00802080},
1245
    {   0x00000100,0x02080100,0x02080000,0x42000100,
1246
        0x00080000,0x00000100,0x40000000,0x02080000,
1247
        0x40080100,0x00080000,0x02000100,0x40080100,
1248
        0x42000100,0x42080000,0x00080100,0x40000000,
1249
        0x02000000,0x40080000,0x40080000,0x00000000,
1250
        0x40000100,0x42080100,0x42080100,0x02000100,
1251
        0x42080000,0x40000100,0x00000000,0x42000000,
1252
        0x02080100,0x02000000,0x42000000,0x00080100,
1253
        0x00080000,0x42000100,0x00000100,0x02000000,
1254
        0x40000000,0x02080000,0x42000100,0x40080100,
1255
        0x02000100,0x40000000,0x42080000,0x02080100,
1256
        0x40080100,0x00000100,0x02000000,0x42080000,
1257
        0x42080100,0x00080100,0x42000000,0x42080100,
1258
        0x02080000,0x00000000,0x40080000,0x42000000,
1259
        0x00080100,0x02000100,0x40000100,0x00080000,
1260
        0x00000000,0x40080000,0x02080100,0x40000100},
1261
    {   0x20000010,0x20400000,0x00004000,0x20404010,
1262
        0x20400000,0x00000010,0x20404010,0x00400000,
1263
        0x20004000,0x00404010,0x00400000,0x20000010,
1264
        0x00400010,0x20004000,0x20000000,0x00004010,
1265
        0x00000000,0x00400010,0x20004010,0x00004000,
1266
        0x00404000,0x20004010,0x00000010,0x20400010,
1267
        0x20400010,0x00000000,0x00404010,0x20404000,
1268
        0x00004010,0x00404000,0x20404000,0x20000000,
1269
        0x20004000,0x00000010,0x20400010,0x00404000,
1270
        0x20404010,0x00400000,0x00004010,0x20000010,
1271
        0x00400000,0x20004000,0x20000000,0x00004010,
1272
        0x20000010,0x20404010,0x00404000,0x20400000,
1273
        0x00404010,0x20404000,0x00000000,0x20400010,
1274
        0x00000010,0x00004000,0x20400000,0x00404010,
1275
        0x00004000,0x00400010,0x20004010,0x00000000,
1276
        0x20404000,0x20000000,0x00400010,0x20004010},
1277
    {   0x00200000,0x04200002,0x04000802,0x00000000,
1278
        0x00000800,0x04000802,0x00200802,0x04200800,
1279
        0x04200802,0x00200000,0x00000000,0x04000002,
1280
        0x00000002,0x04000000,0x04200002,0x00000802,
1281
        0x04000800,0x00200802,0x00200002,0x04000800,
1282
        0x04000002,0x04200000,0x04200800,0x00200002,
1283
        0x04200000,0x00000800,0x00000802,0x04200802,
1284
        0x00200800,0x00000002,0x04000000,0x00200800,
1285
        0x04000000,0x00200800,0x00200000,0x04000802,
1286
        0x04000802,0x04200002,0x04200002,0x00000002,
1287
        0x00200002,0x04000000,0x04000800,0x00200000,
1288
        0x04200800,0x00000802,0x00200802,0x04200800,
1289
        0x00000802,0x04000002,0x04200802,0x04200000,
1290
        0x00200800,0x00000000,0x00000002,0x04200802,
1291
        0x00000000,0x00200802,0x04200000,0x00000800,
1292
        0x04000002,0x04000800,0x00000800,0x00200002},
1293
    {   0x10001040,0x00001000,0x00040000,0x10041040,
1294
        0x10000000,0x10001040,0x00000040,0x10000000,
1295
        0x00040040,0x10040000,0x10041040,0x00041000,
1296
        0x10041000,0x00041040,0x00001000,0x00000040,
1297
        0x10040000,0x10000040,0x10001000,0x00001040,
1298
        0x00041000,0x00040040,0x10040040,0x10041000,
1299
        0x00001040,0x00000000,0x00000000,0x10040040,
1300
        0x10000040,0x10001000,0x00041040,0x00040000,
1301
        0x00041040,0x00040000,0x10041000,0x00001000,
1302
        0x00000040,0x10040040,0x00001000,0x00041040,
1303
        0x10001000,0x00000040,0x10000040,0x10040000,
1304
        0x10040040,0x10000000,0x00040000,0x10001040,
1305
        0x00000000,0x10041040,0x00040040,0x10000040,
1306
        0x10040000,0x10001000,0x10001040,0x00000000,
1307
        0x10041040,0x00041000,0x00041000,0x00001040,
1308
        0x00001040,0x00040040,0x10000000,0x10041000}
1309
    };
1310
1311
    static WC_INLINE void IPERM(word32* left, word32* right)
1312
0
    {
1313
0
        word32 work;
1314
1315
0
        *right = rotlFixed(*right, 4U);
1316
0
        work = (*left ^ *right) & 0xf0f0f0f0;
1317
0
        *left ^= work;
1318
1319
0
        *right = rotrFixed(*right^work, 20U);
1320
0
        work = (*left ^ *right) & 0xffff0000;
1321
0
        *left ^= work;
1322
1323
0
        *right = rotrFixed(*right^work, 18U);
1324
0
        work = (*left ^ *right) & 0x33333333;
1325
0
        *left ^= work;
1326
1327
0
        *right = rotrFixed(*right^work, 6U);
1328
0
        work = (*left ^ *right) & 0x00ff00ff;
1329
0
        *left ^= work;
1330
1331
0
        *right = rotlFixed(*right^work, 9U);
1332
0
        work = (*left ^ *right) & 0xaaaaaaaa;
1333
0
        *left = rotlFixed(*left^work, 1U);
1334
0
        *right ^= work;
1335
0
    }
1336
1337
    static WC_INLINE void FPERM(word32* left, word32* right)
1338
0
    {
1339
0
        word32 work;
1340
1341
0
        *right = rotrFixed(*right, 1U);
1342
0
        work = (*left ^ *right) & 0xaaaaaaaa;
1343
0
        *right ^= work;
1344
1345
0
        *left = rotrFixed(*left^work, 9U);
1346
0
        work = (*left ^ *right) & 0x00ff00ff;
1347
0
        *right ^= work;
1348
1349
0
        *left = rotlFixed(*left^work, 6U);
1350
0
        work = (*left ^ *right) & 0x33333333;
1351
0
        *right ^= work;
1352
1353
0
        *left = rotlFixed(*left^work, 18U);
1354
0
        work = (*left ^ *right) & 0xffff0000;
1355
0
        *right ^= work;
1356
1357
0
        *left = rotlFixed(*left^work, 20U);
1358
0
        work = (*left ^ *right) & 0xf0f0f0f0;
1359
0
        *right ^= work;
1360
1361
0
        *left = rotrFixed(*left^work, 4U);
1362
0
    }
1363
1364
    static int DesSetKey(const byte* key, int dir, word32* out)
1365
0
    {
1366
0
        #define DES_KEY_BUFFER_SIZE (56+56+8)
1367
0
    #ifdef WOLFSSL_SMALL_STACK
1368
0
        byte* buffer = (byte*)XMALLOC(DES_KEY_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1369
1370
0
        if (buffer == NULL)
1371
0
            return MEMORY_E;
1372
    #else
1373
        byte buffer[DES_KEY_BUFFER_SIZE];
1374
    #endif
1375
1376
0
        {
1377
0
            byte* const  pc1m = buffer;            /* place to modify pc1 into */
1378
0
            byte* const  pcr  = pc1m + 56;         /* place to rotate pc1 into */
1379
0
            byte* const  ks   = pcr  + 56;
1380
0
            int i, j, l;
1381
0
            int          m;
1382
1383
0
            for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */
1384
0
                l = pc1[j] - 1;                    /* integer bit location        */
1385
0
                m = l & 07;                        /* find bit                    */
1386
0
                pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */
1387
0
                    bytebit[m])                    /* and which bit of that byte  */
1388
0
                    ? 1 : 0;                       /* and store 1-bit result      */
1389
0
            }
1390
1391
0
            for (i = 0; i < 16; i++) {            /* key chunk for each iteration */
1392
0
                XMEMSET(ks, 0, 8);                /* Clear key schedule */
1393
1394
0
                for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */
1395
0
                    pcr[j] =
1396
0
                          pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];
1397
1398
                /* rotate left and right halves independently */
1399
0
                for (j = 0; j < 48; j++) {        /* select bits individually     */
1400
0
                    if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */
1401
0
                        l= j % 6;                 /* mask it in if it's there     */
1402
0
                        ks[j/6] |= (byte)(bytebit[l] >> 2);
1403
0
                    }
1404
0
                }
1405
1406
                /* Now convert to odd/even interleaved form for use in F */
1407
0
                out[2*i] = ((word32) ks[0] << 24)
1408
0
                         | ((word32) ks[2] << 16)
1409
0
                         | ((word32) ks[4] << 8)
1410
0
                         | ((word32) ks[6]);
1411
1412
0
                out[2*i + 1] = ((word32) ks[1] << 24)
1413
0
                             | ((word32) ks[3] << 16)
1414
0
                             | ((word32) ks[5] << 8)
1415
0
                             | ((word32) ks[7]);
1416
0
            }
1417
1418
            /* reverse key schedule order */
1419
0
            if (dir == DES_DECRYPTION) {
1420
0
                for (i = 0; i < 16; i += 2) {
1421
0
                    word32 swap = out[i];
1422
0
                    out[i] = out[DES_KS_SIZE - 2 - i];
1423
0
                    out[DES_KS_SIZE - 2 - i] = swap;
1424
1425
0
                    swap = out[i + 1];
1426
0
                    out[i + 1] = out[DES_KS_SIZE - 1 - i];
1427
0
                    out[DES_KS_SIZE - 1 - i] = swap;
1428
0
                }
1429
0
            }
1430
1431
0
    #ifdef WOLFSSL_SMALL_STACK
1432
0
            XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1433
0
    #endif
1434
0
        }
1435
1436
0
        return 0;
1437
0
    }
1438
1439
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
1440
0
    {
1441
0
        wc_Des_SetIV(des, iv);
1442
1443
0
        return DesSetKey(key, dir, des->key);
1444
0
    }
1445
1446
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
1447
0
    {
1448
0
        int ret;
1449
1450
0
        if (des == NULL || key == NULL || dir < 0) {
1451
0
            return BAD_FUNC_ARG;
1452
0
        }
1453
1454
0
        XMEMSET(des->key, 0, sizeof(*(des->key)));
1455
0
        XMEMSET(des->reg, 0, sizeof(*(des->reg)));
1456
0
        XMEMSET(des->tmp, 0, sizeof(*(des->tmp)));
1457
1458
0
    #if defined(WOLF_CRYPTO_CB) || \
1459
0
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))
1460
0
        #ifdef WOLF_CRYPTO_CB
1461
0
        if (des->devId != INVALID_DEVID)
1462
0
        #endif
1463
0
        {
1464
0
            XMEMCPY(des->devKey, key, DES3_KEYLEN);
1465
0
        }
1466
0
    #endif
1467
1468
0
        ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);
1469
0
        if (ret != 0)
1470
0
            return ret;
1471
1472
0
        ret = DesSetKey(key + 8, !dir, des->key[1]);
1473
0
        if (ret != 0)
1474
0
            return ret;
1475
1476
0
        ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);
1477
0
        if (ret != 0)
1478
0
            return ret;
1479
1480
0
        return wc_Des3_SetIV(des, iv);
1481
0
    }
1482
1483
    static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
1484
0
    {
1485
0
        word32 l = *lIn, r = *rIn, i;
1486
1487
0
        for (i=0; i<8; i++)
1488
0
        {
1489
0
            word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
1490
0
            l ^= Spbox[6][(work) & 0x3f]
1491
0
              ^  Spbox[4][(work >> 8) & 0x3f]
1492
0
              ^  Spbox[2][(work >> 16) & 0x3f]
1493
0
              ^  Spbox[0][(work >> 24) & 0x3f];
1494
0
            work = r ^ kptr[4*i+1];
1495
0
            l ^= Spbox[7][(work) & 0x3f]
1496
0
              ^  Spbox[5][(work >> 8) & 0x3f]
1497
0
              ^  Spbox[3][(work >> 16) & 0x3f]
1498
0
              ^  Spbox[1][(work >> 24) & 0x3f];
1499
1500
0
            work = rotrFixed(l, 4U) ^ kptr[4*i+2];
1501
0
            r ^= Spbox[6][(work) & 0x3f]
1502
0
              ^  Spbox[4][(work >> 8) & 0x3f]
1503
0
              ^  Spbox[2][(work >> 16) & 0x3f]
1504
0
              ^  Spbox[0][(work >> 24) & 0x3f];
1505
0
            work = l ^ kptr[4*i+3];
1506
0
            r ^= Spbox[7][(work) & 0x3f]
1507
0
              ^  Spbox[5][(work >> 8) & 0x3f]
1508
0
              ^  Spbox[3][(work >> 16) & 0x3f]
1509
0
              ^  Spbox[1][(work >> 24) & 0x3f];
1510
0
        }
1511
1512
0
        *lIn = l; *rIn = r;
1513
0
    }
1514
1515
    static void DesProcessBlock(Des* des, const byte* in, byte* out)
1516
0
    {
1517
0
        word32 l, r;
1518
1519
0
        XMEMCPY(&l, in, sizeof(l));
1520
0
        XMEMCPY(&r, in + sizeof(l), sizeof(r));
1521
0
        #ifdef LITTLE_ENDIAN_ORDER
1522
0
            l = ByteReverseWord32(l);
1523
0
            r = ByteReverseWord32(r);
1524
0
        #endif
1525
0
        IPERM(&l,&r);
1526
1527
0
        DesRawProcessBlock(&l, &r, des->key);
1528
1529
0
        FPERM(&l,&r);
1530
0
        #ifdef LITTLE_ENDIAN_ORDER
1531
0
            l = ByteReverseWord32(l);
1532
0
            r = ByteReverseWord32(r);
1533
0
        #endif
1534
0
        XMEMCPY(out, &r, sizeof(r));
1535
0
        XMEMCPY(out + sizeof(r), &l, sizeof(l));
1536
0
    }
1537
1538
    static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
1539
0
    {
1540
0
        word32 l, r;
1541
1542
0
        XMEMCPY(&l, in, sizeof(l));
1543
0
        XMEMCPY(&r, in + sizeof(l), sizeof(r));
1544
0
        #ifdef LITTLE_ENDIAN_ORDER
1545
0
            l = ByteReverseWord32(l);
1546
0
            r = ByteReverseWord32(r);
1547
0
        #endif
1548
0
        IPERM(&l,&r);
1549
1550
0
        DesRawProcessBlock(&l, &r, des->key[0]);
1551
0
        DesRawProcessBlock(&r, &l, des->key[1]);
1552
0
        DesRawProcessBlock(&l, &r, des->key[2]);
1553
1554
0
        FPERM(&l,&r);
1555
0
        #ifdef LITTLE_ENDIAN_ORDER
1556
0
            l = ByteReverseWord32(l);
1557
0
            r = ByteReverseWord32(r);
1558
0
        #endif
1559
0
        XMEMCPY(out, &r, sizeof(r));
1560
0
        XMEMCPY(out + sizeof(r), &l, sizeof(l));
1561
0
    }
1562
1563
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1564
0
    {
1565
0
        word32 blocks = sz / DES_BLOCK_SIZE;
1566
1567
0
        while (blocks--) {
1568
0
            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
1569
0
            DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
1570
0
            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
1571
1572
0
            out += DES_BLOCK_SIZE;
1573
0
            in  += DES_BLOCK_SIZE;
1574
0
        }
1575
0
        return 0;
1576
0
    }
1577
1578
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
1579
0
    {
1580
0
        word32 blocks = sz / DES_BLOCK_SIZE;
1581
1582
0
        while (blocks--) {
1583
0
            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
1584
0
            DesProcessBlock(des, (byte*)des->tmp, out);
1585
0
            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
1586
0
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
1587
1588
0
            out += DES_BLOCK_SIZE;
1589
0
            in  += DES_BLOCK_SIZE;
1590
0
        }
1591
0
        return 0;
1592
0
    }
1593
1594
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1595
0
    {
1596
0
        word32 blocks;
1597
1598
0
        if (des == NULL || out == NULL || in == NULL) {
1599
0
            return BAD_FUNC_ARG;
1600
0
        }
1601
1602
0
    #ifdef WOLF_CRYPTO_CB
1603
0
        if (des->devId != INVALID_DEVID) {
1604
0
            int ret = wc_CryptoCb_Des3Encrypt(des, out, in, sz);
1605
0
            if (ret != CRYPTOCB_UNAVAILABLE)
1606
0
                return ret;
1607
            /* fall-through when unavailable */
1608
0
        }
1609
0
    #endif
1610
1611
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1612
        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&
1613
                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {
1614
        #if defined(HAVE_CAVIUM)
1615
            return NitroxDes3CbcEncrypt(des, out, in, sz);
1616
        #elif defined(HAVE_INTEL_QA)
1617
            return IntelQaSymDes3CbcEncrypt(&des->asyncDev, out, in, sz,
1618
                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);
1619
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
1620
            if (wc_AsyncSwInit(&des->asyncDev, ASYNC_SW_DES3_CBC_ENCRYPT)) {
1621
                WC_ASYNC_SW* sw = &des->asyncDev.sw;
1622
                sw->des.des = des;
1623
                sw->des.out = out;
1624
                sw->des.in = in;
1625
                sw->des.sz = sz;
1626
                return WC_PENDING_E;
1627
            }
1628
        #endif
1629
        }
1630
    #endif /* WOLFSSL_ASYNC_CRYPT */
1631
1632
0
        blocks = sz / DES_BLOCK_SIZE;
1633
0
        while (blocks--) {
1634
0
            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
1635
0
            Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
1636
0
            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
1637
1638
0
            out += DES_BLOCK_SIZE;
1639
0
            in  += DES_BLOCK_SIZE;
1640
0
        }
1641
0
        return 0;
1642
0
    }
1643
1644
1645
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
1646
0
    {
1647
0
        word32 blocks;
1648
1649
0
        if (des == NULL || out == NULL || in == NULL) {
1650
0
            return BAD_FUNC_ARG;
1651
0
        }
1652
1653
0
    #ifdef WOLF_CRYPTO_CB
1654
0
        if (des->devId != INVALID_DEVID) {
1655
0
            int ret = wc_CryptoCb_Des3Decrypt(des, out, in, sz);
1656
0
            if (ret != CRYPTOCB_UNAVAILABLE)
1657
0
                return ret;
1658
            /* fall-through when unavailable */
1659
0
        }
1660
0
    #endif
1661
1662
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1663
        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&
1664
                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {
1665
        #if defined(HAVE_CAVIUM)
1666
            return NitroxDes3CbcDecrypt(des, out, in, sz);
1667
        #elif defined(HAVE_INTEL_QA)
1668
            return IntelQaSymDes3CbcDecrypt(&des->asyncDev, out, in, sz,
1669
                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);
1670
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
1671
            if (wc_AsyncSwInit(&des->asyncDev, ASYNC_SW_DES3_CBC_DECRYPT)) {
1672
                WC_ASYNC_SW* sw = &des->asyncDev.sw;
1673
                sw->des.des = des;
1674
                sw->des.out = out;
1675
                sw->des.in = in;
1676
                sw->des.sz = sz;
1677
                return WC_PENDING_E;
1678
            }
1679
        #endif
1680
        }
1681
    #endif /* WOLFSSL_ASYNC_CRYPT */
1682
1683
0
        blocks = sz / DES_BLOCK_SIZE;
1684
0
        while (blocks--) {
1685
0
            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
1686
0
            Des3ProcessBlock(des, (byte*)des->tmp, out);
1687
0
            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
1688
0
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
1689
1690
0
            out += DES_BLOCK_SIZE;
1691
0
            in  += DES_BLOCK_SIZE;
1692
0
        }
1693
0
        return 0;
1694
0
    }
1695
1696
    #ifdef WOLFSSL_DES_ECB
1697
        /* One block, compatibility only */
1698
        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1699
0
        {
1700
0
            word32 blocks = sz / DES_BLOCK_SIZE;
1701
1702
0
            if (des == NULL || out == NULL || in == NULL) {
1703
0
                return BAD_FUNC_ARG;
1704
0
            }
1705
1706
0
            while (blocks--) {
1707
0
                DesProcessBlock(des, in, out);
1708
1709
0
                out += DES_BLOCK_SIZE;
1710
0
                in  += DES_BLOCK_SIZE;
1711
0
            }
1712
0
            return 0;
1713
0
        }
1714
1715
        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1716
0
        {
1717
0
            word32 blocks = sz / DES_BLOCK_SIZE;
1718
1719
0
            if (des == NULL || out == NULL || in == NULL) {
1720
0
                return BAD_FUNC_ARG;
1721
0
            }
1722
1723
0
            while (blocks--) {
1724
0
                Des3ProcessBlock(des, in, out);
1725
1726
0
                out += DES_BLOCK_SIZE;
1727
0
                in  += DES_BLOCK_SIZE;
1728
0
            }
1729
0
            return 0;
1730
0
        }
1731
    #endif /* WOLFSSL_DES_ECB */
1732
1733
#endif /* NEED_SOFT_DES */
1734
1735
1736
void wc_Des_SetIV(Des* des, const byte* iv)
1737
0
{
1738
0
    if (des && iv) {
1739
0
        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
1740
    #if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY) && defined(STM32_HAL_V2)
1741
        ByteReverseWords(des->reg, des->reg, DES_BLOCK_SIZE);
1742
    #endif
1743
0
    }
1744
0
    else if (des)
1745
0
        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
1746
0
}
1747
1748
int wc_Des3_SetIV(Des3* des, const byte* iv)
1749
0
{
1750
0
    if (des == NULL) {
1751
0
        return BAD_FUNC_ARG;
1752
0
    }
1753
0
    if (iv) {
1754
0
        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
1755
    #if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY) && defined(STM32_HAL_V2)
1756
        ByteReverseWords(des->reg, des->reg, DES_BLOCK_SIZE);
1757
    #endif
1758
0
    }
1759
0
    else
1760
0
        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
1761
1762
0
    return 0;
1763
0
}
1764
1765
1766
/* Initialize Des3 for use with async device */
1767
int wc_Des3Init(Des3* des3, void* heap, int devId)
1768
0
{
1769
0
    int ret = 0;
1770
0
    if (des3 == NULL)
1771
0
        return BAD_FUNC_ARG;
1772
1773
0
    des3->heap = heap;
1774
1775
0
#ifdef WOLF_CRYPTO_CB
1776
0
    des3->devId = devId;
1777
0
    des3->devCtx = NULL;
1778
#else
1779
    (void)devId;
1780
#endif
1781
1782
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1783
    ret = wolfAsync_DevCtxInit(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES,
1784
                                                        des3->heap, devId);
1785
#endif
1786
#if defined(WOLFSSL_CHECK_MEM_ZERO) && (defined(WOLF_CRYPTO_CB) || \
1787
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)))
1788
    wc_MemZero_Add("DES3 devKey", &des3->devKey, sizeof(des3->devKey));
1789
#endif
1790
1791
0
    return ret;
1792
0
}
1793
1794
/* Free Des3 from use with async device */
1795
void wc_Des3Free(Des3* des3)
1796
0
{
1797
0
    if (des3 == NULL)
1798
0
        return;
1799
1800
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1801
    wolfAsync_DevCtxFree(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES);
1802
#endif /* WOLFSSL_ASYNC_CRYPT */
1803
0
#if defined(WOLF_CRYPTO_CB) || \
1804
0
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))
1805
0
    ForceZero(des3->devKey, sizeof(des3->devKey));
1806
0
#endif
1807
#ifdef WOLFSSL_CHECK_MEM_ZERO
1808
    wc_MemZero_Check(des3, sizeof(Des3));
1809
#endif
1810
0
}
1811
1812
#endif /* WOLFSSL_TI_CRYPT */
1813
#endif /* NO_DES3 */