Coverage Report

Created: 2025-11-16 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-fastmath/wolfcrypt/src/des3.c
Line
Count
Source
1
/* des3.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifndef NO_DES3
25
26
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
27
    (HAVE_FIPS_VERSION == 2 || HAVE_FIPS_VERSION == 3)
28
29
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
30
    #define FIPS_NO_WRAPPERS
31
32
    #ifdef USE_WINDOWS_API
33
        #pragma code_seg(".fipsA$d")
34
        #pragma const_seg(".fipsB$d")
35
    #endif
36
#endif
37
38
#include <wolfssl/wolfcrypt/des3.h>
39
40
#ifdef WOLF_CRYPTO_CB
41
    #include <wolfssl/wolfcrypt/cryptocb.h>
42
#endif
43
44
#if defined(WOLFSSL_TI_CRYPT)
45
    #include <wolfcrypt/src/port/ti/ti-des3.c>
46
#else
47
48
49
#ifdef NO_INLINE
50
    #include <wolfssl/wolfcrypt/misc.h>
51
#else
52
    #define WOLFSSL_MISC_INCLUDED
53
    #include <wolfcrypt/src/misc.c>
54
#endif
55
56
57
/* Hardware Acceleration */
58
#if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY)
59
60
    /*
61
     * STM32F2/F4 hardware DES/3DES support through the standard
62
     * peripheral library. (See note in README).
63
     */
64
65
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
66
    {
67
        word32 *dkey = des->key;
68
69
        (void)dir;
70
71
        XMEMCPY(dkey, key, 8);
72
    #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2)
73
        ByteReverseWords(dkey, dkey, 8);
74
    #endif
75
76
        wc_Des_SetIV(des, iv);
77
78
        return 0;
79
    }
80
81
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
82
    {
83
        if (des == NULL || key == NULL)
84
            return BAD_FUNC_ARG;
85
86
        (void)dir;
87
88
    #ifndef WOLFSSL_STM32_CUBEMX
89
        {
90
            word32 *dkey1 = des->key[0];
91
            word32 *dkey2 = des->key[1];
92
            word32 *dkey3 = des->key[2];
93
94
            XMEMCPY(dkey1, key, 8);         /* set key 1 */
95
            XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
96
            XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
97
98
            ByteReverseWords(dkey1, dkey1, 8);
99
            ByteReverseWords(dkey2, dkey2, 8);
100
            ByteReverseWords(dkey3, dkey3, 8);
101
        }
102
    #else
103
        /* CUBEMX wants keys in sequential memory */
104
        XMEMCPY(des->key[0], key, DES3_KEYLEN);
105
        #ifdef STM32_HAL_V2
106
        ByteReverseWords((word32*)des->key, (word32*)des->key, DES3_KEYLEN);
107
        #endif
108
    #endif
109
110
        return wc_Des3_SetIV(des, iv);
111
    }
112
113
    static void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
114
                  int dir, int mode)
115
    {
116
        int ret;
117
    #ifdef WOLFSSL_STM32_CUBEMX
118
        CRYP_HandleTypeDef hcryp;
119
    #else
120
        word32 *dkey, *iv;
121
        CRYP_InitTypeDef DES_CRYP_InitStructure;
122
        CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
123
        CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
124
    #endif
125
126
        ret = wolfSSL_CryptHwMutexLock();
127
        if (ret != 0) {
128
            return;
129
        }
130
131
    #ifdef WOLFSSL_STM32_CUBEMX
132
        XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
133
        hcryp.Instance = CRYP;
134
        hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;
135
        hcryp.Init.DataType = CRYP_DATATYPE_8B;
136
        hcryp.Init.pKey = (STM_CRYPT_TYPE*)des->key;
137
        hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)des->reg;
138
    #ifdef STM32_HAL_V2
139
        hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
140
        if (mode == DES_CBC)
141
            hcryp.Init.Algorithm = CRYP_DES_CBC;
142
        else
143
            hcryp.Init.Algorithm = CRYP_DES_ECB;
144
    #endif
145
146
        HAL_CRYP_Init(&hcryp);
147
148
    #ifdef STM32_HAL_V2
149
        if (dir == DES_ENCRYPTION) {
150
            HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
151
                STM32_HAL_TIMEOUT);
152
        }
153
        else {
154
            HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
155
                STM32_HAL_TIMEOUT);
156
        }
157
        /* save off IV */
158
        #ifdef WOLFSSL_STM32MP13
159
            des->reg[0] = ((CRYP_TypeDef *)(hcryp.Instance))->IV0LR;
160
            des->reg[1] = ((CRYP_TypeDef *)(hcryp.Instance))->IV0RR;
161
        #else
162
            des->reg[0] = hcryp.Instance->IV0LR;
163
            des->reg[1] = hcryp.Instance->IV0RR;
164
        #endif
165
    #else
166
        while (sz > 0) {
167
            /* if input and output same will overwrite input iv */
168
            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
169
170
            if (mode == DES_CBC) {
171
                if (dir == DES_ENCRYPTION) {
172
                    HAL_CRYP_DESCBC_Encrypt(&hcryp, (uint8_t*)in,
173
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
174
                }
175
                else {
176
                    HAL_CRYP_DESCBC_Decrypt(&hcryp, (uint8_t*)in,
177
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
178
                }
179
            }
180
            else {
181
                if (dir == DES_ENCRYPTION) {
182
                    HAL_CRYP_DESECB_Encrypt(&hcryp, (uint8_t*)in,
183
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
184
                }
185
                else {
186
                    HAL_CRYP_DESECB_Decrypt(&hcryp, (uint8_t*)in,
187
                                    DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
188
                }
189
            }
190
191
            /* store iv for next call */
192
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
193
194
            sz  -= DES_BLOCK_SIZE;
195
            in  += DES_BLOCK_SIZE;
196
            out += DES_BLOCK_SIZE;
197
        }
198
    #endif /* STM32_HAL_V2 */
199
200
        HAL_CRYP_DeInit(&hcryp);
201
    #else
202
        dkey = des->key;
203
        iv = des->reg;
204
205
        /* crypto structure initialization */
206
        CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
207
        CRYP_StructInit(&DES_CRYP_InitStructure);
208
        CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
209
210
        /* reset registers to their default values */
211
        CRYP_DeInit();
212
213
        /* set direction, mode, and datatype */
214
        if (dir == DES_ENCRYPTION) {
215
            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
216
        } else { /* DES_DECRYPTION */
217
            DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
218
        }
219
220
        if (mode == DES_CBC) {
221
            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
222
        } else { /* DES_ECB */
223
            DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
224
        }
225
226
        DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
227
        CRYP_Init(&DES_CRYP_InitStructure);
228
229
        /* load key into correct registers */
230
        DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];
231
        DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
232
        CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
233
234
        /* set iv */
235
        ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
236
        DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
237
        DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
238
        CRYP_IVInit(&DES_CRYP_IVInitStructure);
239
240
        /* enable crypto processor */
241
        CRYP_Cmd(ENABLE);
242
243
        while (sz > 0) {
244
            /* flush IN/OUT FIFOs */
245
            CRYP_FIFOFlush();
246
247
            /* if input and output same will overwrite input iv */
248
            XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
249
250
            CRYP_DataIn(*(uint32_t*)&in[0]);
251
            CRYP_DataIn(*(uint32_t*)&in[4]);
252
253
            /* wait until the complete message has been processed */
254
            while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
255
256
            *(uint32_t*)&out[0]  = CRYP_DataOut();
257
            *(uint32_t*)&out[4]  = CRYP_DataOut();
258
259
            /* store iv for next call */
260
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
261
262
            sz  -= DES_BLOCK_SIZE;
263
            in  += DES_BLOCK_SIZE;
264
            out += DES_BLOCK_SIZE;
265
        }
266
267
        /* disable crypto processor */
268
        CRYP_Cmd(DISABLE);
269
    #endif /* WOLFSSL_STM32_CUBEMX */
270
        wolfSSL_CryptHwMutexUnLock();
271
    }
272
273
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
274
    {
275
        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
276
        return 0;
277
    }
278
279
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
280
    {
281
        DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
282
        return 0;
283
    }
284
285
    int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
286
    {
287
        DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
288
        return 0;
289
    }
290
291
    static int Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
292
                   int dir)
293
    {
294
        if (des == NULL || out == NULL || in == NULL)
295
            return BAD_FUNC_ARG;
296
297
    #ifdef WOLFSSL_STM32_CUBEMX
298
        {
299
            CRYP_HandleTypeDef hcryp;
300
301
            XMEMSET(&hcryp, 0, sizeof(CRYP_HandleTypeDef));
302
            hcryp.Instance = CRYP;
303
            hcryp.Init.KeySize  = CRYP_KEYSIZE_128B;
304
            hcryp.Init.DataType = CRYP_DATATYPE_8B;
305
            hcryp.Init.pKey = (STM_CRYPT_TYPE*)des->key;
306
            hcryp.Init.pInitVect = (STM_CRYPT_TYPE*)des->reg;
307
        #ifdef STM32_HAL_V2
308
            hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
309
            hcryp.Init.Algorithm = CRYP_TDES_CBC;
310
        #endif
311
312
            HAL_CRYP_Init(&hcryp);
313
314
        #ifdef STM32_HAL_V2
315
            if (dir == DES_ENCRYPTION) {
316
                HAL_CRYP_Encrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
317
                    STM32_HAL_TIMEOUT);
318
            }
319
            else {
320
                HAL_CRYP_Decrypt(&hcryp, (uint32_t*)in, sz, (uint32_t*)out,
321
                    STM32_HAL_TIMEOUT);
322
            }
323
            /* save off IV */
324
            #ifdef WOLFSSL_STM32MP13
325
                des->reg[0] = ((CRYP_TypeDef *)(hcryp.Instance))->IV0LR;
326
                des->reg[1] = ((CRYP_TypeDef *)(hcryp.Instance))->IV0RR;
327
            #else
328
                des->reg[0] = hcryp.Instance->IV0LR;
329
                des->reg[1] = hcryp.Instance->IV0RR;
330
            #endif
331
        #else
332
            while (sz > 0) {
333
                if (dir == DES_ENCRYPTION) {
334
                    HAL_CRYP_TDESCBC_Encrypt(&hcryp, (byte*)in,
335
                                       DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
336
                }
337
                else {
338
                    HAL_CRYP_TDESCBC_Decrypt(&hcryp, (byte*)in,
339
                                       DES_BLOCK_SIZE, out, STM32_HAL_TIMEOUT);
340
                }
341
342
                /* store iv for next call */
343
                XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
344
345
                sz  -= DES_BLOCK_SIZE;
346
                in  += DES_BLOCK_SIZE;
347
                out += DES_BLOCK_SIZE;
348
            }
349
        #endif /* STM32_HAL_V2 */
350
351
            HAL_CRYP_DeInit(&hcryp);
352
        }
353
    #else
354
        {
355
            word32 *dkey1, *dkey2, *dkey3, *iv;
356
            CRYP_InitTypeDef DES3_CRYP_InitStructure;
357
            CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
358
            CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
359
360
            dkey1 = des->key[0];
361
            dkey2 = des->key[1];
362
            dkey3 = des->key[2];
363
            iv = des->reg;
364
365
            /* crypto structure initialization */
366
            CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
367
            CRYP_StructInit(&DES3_CRYP_InitStructure);
368
            CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
369
370
            /* reset registers to their default values */
371
            CRYP_DeInit();
372
373
            /* set direction, mode, and datatype */
374
            if (dir == DES_ENCRYPTION) {
375
                DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
376
            } else {
377
                DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
378
            }
379
380
            DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
381
            DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
382
            CRYP_Init(&DES3_CRYP_InitStructure);
383
384
            /* load key into correct registers */
385
            DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];
386
            DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
387
            DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];
388
            DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
389
            DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];
390
            DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
391
            CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
392
393
            /* set iv */
394
            ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
395
            DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
396
            DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
397
            CRYP_IVInit(&DES3_CRYP_IVInitStructure);
398
399
            /* enable crypto processor */
400
            CRYP_Cmd(ENABLE);
401
402
            while (sz > 0)
403
            {
404
                /* flush IN/OUT FIFOs */
405
                CRYP_FIFOFlush();
406
407
                CRYP_DataIn(*(uint32_t*)&in[0]);
408
                CRYP_DataIn(*(uint32_t*)&in[4]);
409
410
                /* wait until the complete message has been processed */
411
                while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
412
413
                *(uint32_t*)&out[0]  = CRYP_DataOut();
414
                *(uint32_t*)&out[4]  = CRYP_DataOut();
415
416
                /* store iv for next call */
417
                XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
418
419
                sz  -= DES_BLOCK_SIZE;
420
                in  += DES_BLOCK_SIZE;
421
                out += DES_BLOCK_SIZE;
422
            }
423
424
            /* disable crypto processor */
425
            CRYP_Cmd(DISABLE);
426
        }
427
    #endif /* WOLFSSL_STM32_CUBEMX */
428
        return 0;
429
    }
430
431
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
432
    {
433
        return Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
434
    }
435
436
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
437
    {
438
        return Des3Crypt(des, out, in, sz, DES_DECRYPTION);
439
    }
440
441
#elif defined(HAVE_COLDFIRE_SEC)
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
#ifdef WOLFSSL_DES_ECB
1035
    /* One block, compatibility only */
1036
    int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1037
    {
1038
        int offset = 0;
1039
        int len = sz;
1040
        int ret = 0;
1041
        byte temp_block[DES_BLOCK_SIZE];
1042
1043
1044
    #ifdef FREESCALE_MMCAU_CLASSIC
1045
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
1046
            WOLFSSL_MSG("Bad cau_des_encrypt alignment");
1047
            return BAD_ALIGN_E;
1048
        }
1049
    #endif
1050
1051
        while (len > 0)
1052
        {
1053
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
1054
1055
            ret = wolfSSL_CryptHwMutexLock();
1056
            if (ret != 0) {
1057
                return ret;
1058
            }
1059
        #ifdef FREESCALE_MMCAU_CLASSIC
1060
            cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
1061
        #else
1062
            MMCAU_DES_EncryptEcb(temp_block, (byte*)des->key, out + offset);
1063
        #endif
1064
            wolfSSL_CryptHwMutexUnLock();
1065
1066
            len    -= DES_BLOCK_SIZE;
1067
            offset += DES_BLOCK_SIZE;
1068
1069
        }
1070
       return ret;
1071
1072
    }
1073
1074
    int wc_Des_EcbDecrypt(Des* des, byte* out, const byte* in, word32 sz)
1075
    {
1076
        int offset = 0;
1077
        int len = sz;
1078
        int ret = 0;
1079
        byte temp_block[DES_BLOCK_SIZE];
1080
1081
    #ifdef FREESCALE_MMCAU_CLASSIC
1082
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
1083
            WOLFSSL_MSG("Bad cau_des_decrypt alignment");
1084
            return BAD_ALIGN_E;
1085
        }
1086
    #endif
1087
1088
        while (len > 0)
1089
        {
1090
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
1091
1092
            ret = wolfSSL_CryptHwMutexLock();
1093
            if (ret != 0) {
1094
                return ret;
1095
            }
1096
1097
        #ifdef FREESCALE_MMCAU_CLASSIC
1098
            cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
1099
        #else
1100
            MMCAU_DES_DecryptEcb(in + offset, (byte*)des->key, out + offset);
1101
        #endif
1102
            wolfSSL_CryptHwMutexUnLock();
1103
1104
            len    -= DES_BLOCK_SIZE;
1105
            offset += DES_BLOCK_SIZE;
1106
        }
1107
1108
        return ret;
1109
    }
1110
1111
    int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1112
    {
1113
        int offset = 0;
1114
        int len = sz;
1115
        int ret = 0;
1116
1117
        byte temp_block[DES_BLOCK_SIZE];
1118
1119
1120
    #ifdef FREESCALE_MMCAU_CLASSIC
1121
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
1122
            WOLFSSL_MSG("Bad 3ede cau_des_encrypt alignment");
1123
            return BAD_ALIGN_E;
1124
        }
1125
    #endif
1126
1127
        while (len > 0)
1128
        {
1129
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
1130
1131
            ret = wolfSSL_CryptHwMutexLock();
1132
            if (ret != 0) {
1133
                return ret;
1134
            }
1135
    #ifdef FREESCALE_MMCAU_CLASSIC
1136
            cau_des_encrypt(temp_block,   (byte*)des->key[0], out + offset);
1137
            cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
1138
            cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
1139
    #else
1140
            MMCAU_DES_EncryptEcb(temp_block  , (byte*)des->key[0], out + offset);
1141
            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[1], out + offset);
1142
            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[2], out + offset);
1143
    #endif
1144
            wolfSSL_CryptHwMutexUnLock();
1145
1146
            len    -= DES_BLOCK_SIZE;
1147
            offset += DES_BLOCK_SIZE;
1148
1149
        }
1150
1151
        return ret;
1152
    }
1153
1154
    int wc_Des3_EcbDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
1155
    {
1156
        int offset = 0;
1157
        int len = sz;
1158
        int ret = 0;
1159
1160
        byte temp_block[DES_BLOCK_SIZE];
1161
1162
    #ifdef FREESCALE_MMCAU_CLASSIC
1163
        if ((wc_ptr_t)out % WOLFSSL_MMCAU_ALIGNMENT) {
1164
            WOLFSSL_MSG("Bad 3ede cau_des_decrypt alignment");
1165
            return BAD_ALIGN_E;
1166
        }
1167
    #endif
1168
1169
        while (len > 0)
1170
        {
1171
            XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
1172
1173
            ret = wolfSSL_CryptHwMutexLock();
1174
            if (ret != 0) {
1175
                return ret;
1176
            }
1177
        #ifdef FREESCALE_MMCAU_CLASSIC
1178
            cau_des_decrypt(in + offset,  (byte*)des->key[2], out + offset);
1179
            cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
1180
            cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
1181
        #else
1182
            MMCAU_DES_DecryptEcb(in + offset , (byte*)des->key[2], out + offset);
1183
            MMCAU_DES_EncryptEcb(out + offset, (byte*)des->key[1], out + offset);
1184
            MMCAU_DES_DecryptEcb(out + offset, (byte*)des->key[0], out + offset);
1185
        #endif
1186
            wolfSSL_CryptHwMutexUnLock();
1187
1188
            len    -= DES_BLOCK_SIZE;
1189
            offset += DES_BLOCK_SIZE;
1190
        }
1191
1192
        return ret;
1193
    }
1194
#endif /* WOLFSSL_DES_ECB */
1195
1196
1197
#elif defined(WOLFSSL_PIC32MZ_CRYPT)
1198
1199
    /* PIC32MZ DES hardware requires size multiple of block size */
1200
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
1201
1202
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
1203
    {
1204
        if (des == NULL || key == NULL || iv == NULL)
1205
            return BAD_FUNC_ARG;
1206
1207
        XMEMCPY(des->key, key, DES_KEYLEN);
1208
        XMEMCPY(des->reg, iv, DES_IVLEN);
1209
1210
        return 0;
1211
    }
1212
1213
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
1214
    {
1215
        if (des == NULL || key == NULL || iv == NULL)
1216
            return BAD_FUNC_ARG;
1217
1218
        XMEMCPY(des->key[0], key, DES3_KEYLEN);
1219
        XMEMCPY(des->reg, iv, DES3_IVLEN);
1220
1221
        return 0;
1222
    }
1223
1224
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1225
    {
1226
        word32 blocks = sz / DES_BLOCK_SIZE;
1227
1228
        if (des == NULL || out == NULL || in == NULL)
1229
            return BAD_FUNC_ARG;
1230
1231
        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
1232
            out, in, (blocks * DES_BLOCK_SIZE),
1233
            PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
1234
    }
1235
1236
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
1237
    {
1238
        word32 blocks = sz / DES_BLOCK_SIZE;
1239
1240
        if (des == NULL || out == NULL || in == NULL)
1241
            return BAD_FUNC_ARG;
1242
1243
        return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
1244
            out, in, (blocks * DES_BLOCK_SIZE),
1245
            PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
1246
    }
1247
1248
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1249
    {
1250
        word32 blocks = sz / DES_BLOCK_SIZE;
1251
1252
        if (des == NULL || out == NULL || in == NULL)
1253
            return BAD_FUNC_ARG;
1254
1255
        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
1256
            out, in, (blocks * DES_BLOCK_SIZE),
1257
            PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
1258
    }
1259
1260
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
1261
    {
1262
        word32 blocks = sz / DES_BLOCK_SIZE;
1263
1264
        if (des == NULL || out == NULL || in == NULL)
1265
            return BAD_FUNC_ARG;
1266
1267
        return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
1268
            out, in, (blocks * DES_BLOCK_SIZE),
1269
            PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
1270
    }
1271
1272
    #ifdef WOLFSSL_DES_ECB
1273
        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1274
        {
1275
            word32 blocks = sz / DES_BLOCK_SIZE;
1276
1277
            if (des == NULL || out == NULL || in == NULL)
1278
                return BAD_FUNC_ARG;
1279
1280
            return wc_Pic32DesCrypt(des->key, DES_KEYLEN, des->reg, DES_IVLEN,
1281
                out, in, (blocks * DES_BLOCK_SIZE),
1282
                    PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_ECB);
1283
        }
1284
1285
        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1286
        {
1287
            word32 blocks = sz / DES_BLOCK_SIZE;
1288
1289
            if (des == NULL || out == NULL || in == NULL)
1290
                return BAD_FUNC_ARG;
1291
1292
            return wc_Pic32DesCrypt(des->key[0], DES3_KEYLEN, des->reg, DES3_IVLEN,
1293
                out, in, (blocks * DES_BLOCK_SIZE),
1294
                PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TECB);
1295
        }
1296
    #endif /* WOLFSSL_DES_ECB */
1297
1298
#else
1299
    #define NEED_SOFT_DES
1300
1301
#endif
1302
1303
1304
#ifdef NEED_SOFT_DES
1305
1306
    /* permuted choice table (key) */
1307
    static const FLASH_QUALIFIER byte pc1[] = {
1308
           57, 49, 41, 33, 25, 17,  9,
1309
            1, 58, 50, 42, 34, 26, 18,
1310
           10,  2, 59, 51, 43, 35, 27,
1311
           19, 11,  3, 60, 52, 44, 36,
1312
1313
           63, 55, 47, 39, 31, 23, 15,
1314
            7, 62, 54, 46, 38, 30, 22,
1315
           14,  6, 61, 53, 45, 37, 29,
1316
           21, 13,  5, 28, 20, 12,  4
1317
    };
1318
1319
    /* number left rotations of pc1 */
1320
    static const FLASH_QUALIFIER byte totrot[] = {
1321
           1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
1322
    };
1323
1324
    /* permuted choice key (table) */
1325
    static const FLASH_QUALIFIER byte pc2[] = {
1326
           14, 17, 11, 24,  1,  5,
1327
            3, 28, 15,  6, 21, 10,
1328
           23, 19, 12,  4, 26,  8,
1329
           16,  7, 27, 20, 13,  2,
1330
           41, 52, 31, 37, 47, 55,
1331
           30, 40, 51, 45, 33, 48,
1332
           44, 49, 39, 56, 34, 53,
1333
           46, 42, 50, 36, 29, 32
1334
    };
1335
1336
    /* End of DES-defined tables */
1337
1338
    /* bit 0 is left-most in byte */
1339
    static const FLASH_QUALIFIER int bytebit[] = {
1340
        0200,0100,040,020,010,04,02,01
1341
    };
1342
1343
    static const FLASH_QUALIFIER word32 Spbox[8][64] = {
1344
    {   0x01010400,0x00000000,0x00010000,0x01010404,
1345
        0x01010004,0x00010404,0x00000004,0x00010000,
1346
        0x00000400,0x01010400,0x01010404,0x00000400,
1347
        0x01000404,0x01010004,0x01000000,0x00000004,
1348
        0x00000404,0x01000400,0x01000400,0x00010400,
1349
        0x00010400,0x01010000,0x01010000,0x01000404,
1350
        0x00010004,0x01000004,0x01000004,0x00010004,
1351
        0x00000000,0x00000404,0x00010404,0x01000000,
1352
        0x00010000,0x01010404,0x00000004,0x01010000,
1353
        0x01010400,0x01000000,0x01000000,0x00000400,
1354
        0x01010004,0x00010000,0x00010400,0x01000004,
1355
        0x00000400,0x00000004,0x01000404,0x00010404,
1356
        0x01010404,0x00010004,0x01010000,0x01000404,
1357
        0x01000004,0x00000404,0x00010404,0x01010400,
1358
        0x00000404,0x01000400,0x01000400,0x00000000,
1359
        0x00010004,0x00010400,0x00000000,0x01010004},
1360
    {   0x80108020,0x80008000,0x00008000,0x00108020,
1361
        0x00100000,0x00000020,0x80100020,0x80008020,
1362
        0x80000020,0x80108020,0x80108000,0x80000000,
1363
        0x80008000,0x00100000,0x00000020,0x80100020,
1364
        0x00108000,0x00100020,0x80008020,0x00000000,
1365
        0x80000000,0x00008000,0x00108020,0x80100000,
1366
        0x00100020,0x80000020,0x00000000,0x00108000,
1367
        0x00008020,0x80108000,0x80100000,0x00008020,
1368
        0x00000000,0x00108020,0x80100020,0x00100000,
1369
        0x80008020,0x80100000,0x80108000,0x00008000,
1370
        0x80100000,0x80008000,0x00000020,0x80108020,
1371
        0x00108020,0x00000020,0x00008000,0x80000000,
1372
        0x00008020,0x80108000,0x00100000,0x80000020,
1373
        0x00100020,0x80008020,0x80000020,0x00100020,
1374
        0x00108000,0x00000000,0x80008000,0x00008020,
1375
        0x80000000,0x80100020,0x80108020,0x00108000},
1376
    {   0x00000208,0x08020200,0x00000000,0x08020008,
1377
        0x08000200,0x00000000,0x00020208,0x08000200,
1378
        0x00020008,0x08000008,0x08000008,0x00020000,
1379
        0x08020208,0x00020008,0x08020000,0x00000208,
1380
        0x08000000,0x00000008,0x08020200,0x00000200,
1381
        0x00020200,0x08020000,0x08020008,0x00020208,
1382
        0x08000208,0x00020200,0x00020000,0x08000208,
1383
        0x00000008,0x08020208,0x00000200,0x08000000,
1384
        0x08020200,0x08000000,0x00020008,0x00000208,
1385
        0x00020000,0x08020200,0x08000200,0x00000000,
1386
        0x00000200,0x00020008,0x08020208,0x08000200,
1387
        0x08000008,0x00000200,0x00000000,0x08020008,
1388
        0x08000208,0x00020000,0x08000000,0x08020208,
1389
        0x00000008,0x00020208,0x00020200,0x08000008,
1390
        0x08020000,0x08000208,0x00000208,0x08020000,
1391
        0x00020208,0x00000008,0x08020008,0x00020200},
1392
    {   0x00802001,0x00002081,0x00002081,0x00000080,
1393
        0x00802080,0x00800081,0x00800001,0x00002001,
1394
        0x00000000,0x00802000,0x00802000,0x00802081,
1395
        0x00000081,0x00000000,0x00800080,0x00800001,
1396
        0x00000001,0x00002000,0x00800000,0x00802001,
1397
        0x00000080,0x00800000,0x00002001,0x00002080,
1398
        0x00800081,0x00000001,0x00002080,0x00800080,
1399
        0x00002000,0x00802080,0x00802081,0x00000081,
1400
        0x00800080,0x00800001,0x00802000,0x00802081,
1401
        0x00000081,0x00000000,0x00000000,0x00802000,
1402
        0x00002080,0x00800080,0x00800081,0x00000001,
1403
        0x00802001,0x00002081,0x00002081,0x00000080,
1404
        0x00802081,0x00000081,0x00000001,0x00002000,
1405
        0x00800001,0x00002001,0x00802080,0x00800081,
1406
        0x00002001,0x00002080,0x00800000,0x00802001,
1407
        0x00000080,0x00800000,0x00002000,0x00802080},
1408
    {   0x00000100,0x02080100,0x02080000,0x42000100,
1409
        0x00080000,0x00000100,0x40000000,0x02080000,
1410
        0x40080100,0x00080000,0x02000100,0x40080100,
1411
        0x42000100,0x42080000,0x00080100,0x40000000,
1412
        0x02000000,0x40080000,0x40080000,0x00000000,
1413
        0x40000100,0x42080100,0x42080100,0x02000100,
1414
        0x42080000,0x40000100,0x00000000,0x42000000,
1415
        0x02080100,0x02000000,0x42000000,0x00080100,
1416
        0x00080000,0x42000100,0x00000100,0x02000000,
1417
        0x40000000,0x02080000,0x42000100,0x40080100,
1418
        0x02000100,0x40000000,0x42080000,0x02080100,
1419
        0x40080100,0x00000100,0x02000000,0x42080000,
1420
        0x42080100,0x00080100,0x42000000,0x42080100,
1421
        0x02080000,0x00000000,0x40080000,0x42000000,
1422
        0x00080100,0x02000100,0x40000100,0x00080000,
1423
        0x00000000,0x40080000,0x02080100,0x40000100},
1424
    {   0x20000010,0x20400000,0x00004000,0x20404010,
1425
        0x20400000,0x00000010,0x20404010,0x00400000,
1426
        0x20004000,0x00404010,0x00400000,0x20000010,
1427
        0x00400010,0x20004000,0x20000000,0x00004010,
1428
        0x00000000,0x00400010,0x20004010,0x00004000,
1429
        0x00404000,0x20004010,0x00000010,0x20400010,
1430
        0x20400010,0x00000000,0x00404010,0x20404000,
1431
        0x00004010,0x00404000,0x20404000,0x20000000,
1432
        0x20004000,0x00000010,0x20400010,0x00404000,
1433
        0x20404010,0x00400000,0x00004010,0x20000010,
1434
        0x00400000,0x20004000,0x20000000,0x00004010,
1435
        0x20000010,0x20404010,0x00404000,0x20400000,
1436
        0x00404010,0x20404000,0x00000000,0x20400010,
1437
        0x00000010,0x00004000,0x20400000,0x00404010,
1438
        0x00004000,0x00400010,0x20004010,0x00000000,
1439
        0x20404000,0x20000000,0x00400010,0x20004010},
1440
    {   0x00200000,0x04200002,0x04000802,0x00000000,
1441
        0x00000800,0x04000802,0x00200802,0x04200800,
1442
        0x04200802,0x00200000,0x00000000,0x04000002,
1443
        0x00000002,0x04000000,0x04200002,0x00000802,
1444
        0x04000800,0x00200802,0x00200002,0x04000800,
1445
        0x04000002,0x04200000,0x04200800,0x00200002,
1446
        0x04200000,0x00000800,0x00000802,0x04200802,
1447
        0x00200800,0x00000002,0x04000000,0x00200800,
1448
        0x04000000,0x00200800,0x00200000,0x04000802,
1449
        0x04000802,0x04200002,0x04200002,0x00000002,
1450
        0x00200002,0x04000000,0x04000800,0x00200000,
1451
        0x04200800,0x00000802,0x00200802,0x04200800,
1452
        0x00000802,0x04000002,0x04200802,0x04200000,
1453
        0x00200800,0x00000000,0x00000002,0x04200802,
1454
        0x00000000,0x00200802,0x04200000,0x00000800,
1455
        0x04000002,0x04000800,0x00000800,0x00200002},
1456
    {   0x10001040,0x00001000,0x00040000,0x10041040,
1457
        0x10000000,0x10001040,0x00000040,0x10000000,
1458
        0x00040040,0x10040000,0x10041040,0x00041000,
1459
        0x10041000,0x00041040,0x00001000,0x00000040,
1460
        0x10040000,0x10000040,0x10001000,0x00001040,
1461
        0x00041000,0x00040040,0x10040040,0x10041000,
1462
        0x00001040,0x00000000,0x00000000,0x10040040,
1463
        0x10000040,0x10001000,0x00041040,0x00040000,
1464
        0x00041040,0x00040000,0x10041000,0x00001000,
1465
        0x00000040,0x10040040,0x00001000,0x00041040,
1466
        0x10001000,0x00000040,0x10000040,0x10040000,
1467
        0x10040040,0x10000000,0x00040000,0x10001040,
1468
        0x00000000,0x10041040,0x00040040,0x10000040,
1469
        0x10040000,0x10001000,0x10001040,0x00000000,
1470
        0x10041040,0x00041000,0x00041000,0x00001040,
1471
        0x00001040,0x00040040,0x10000000,0x10041000}
1472
    };
1473
1474
    static WC_INLINE void IPERM(word32* left, word32* right)
1475
3.15k
    {
1476
3.15k
        word32 work;
1477
1478
3.15k
        *right = rotlFixed(*right, 4U);
1479
3.15k
        work = (*left ^ *right) & 0xf0f0f0f0;
1480
3.15k
        *left ^= work;
1481
1482
3.15k
        *right = rotrFixed(*right^work, 20U);
1483
3.15k
        work = (*left ^ *right) & 0xffff0000;
1484
3.15k
        *left ^= work;
1485
1486
3.15k
        *right = rotrFixed(*right^work, 18U);
1487
3.15k
        work = (*left ^ *right) & 0x33333333;
1488
3.15k
        *left ^= work;
1489
1490
3.15k
        *right = rotrFixed(*right^work, 6U);
1491
3.15k
        work = (*left ^ *right) & 0x00ff00ff;
1492
3.15k
        *left ^= work;
1493
1494
3.15k
        *right = rotlFixed(*right^work, 9U);
1495
3.15k
        work = (*left ^ *right) & 0xaaaaaaaa;
1496
3.15k
        *left = rotlFixed(*left^work, 1U);
1497
3.15k
        *right ^= work;
1498
3.15k
    }
1499
1500
    static WC_INLINE void FPERM(word32* left, word32* right)
1501
3.15k
    {
1502
3.15k
        word32 work;
1503
1504
3.15k
        *right = rotrFixed(*right, 1U);
1505
3.15k
        work = (*left ^ *right) & 0xaaaaaaaa;
1506
3.15k
        *right ^= work;
1507
1508
3.15k
        *left = rotrFixed(*left^work, 9U);
1509
3.15k
        work = (*left ^ *right) & 0x00ff00ff;
1510
3.15k
        *right ^= work;
1511
1512
3.15k
        *left = rotlFixed(*left^work, 6U);
1513
3.15k
        work = (*left ^ *right) & 0x33333333;
1514
3.15k
        *right ^= work;
1515
1516
3.15k
        *left = rotlFixed(*left^work, 18U);
1517
3.15k
        work = (*left ^ *right) & 0xffff0000;
1518
3.15k
        *right ^= work;
1519
1520
3.15k
        *left = rotlFixed(*left^work, 20U);
1521
3.15k
        work = (*left ^ *right) & 0xf0f0f0f0;
1522
3.15k
        *right ^= work;
1523
1524
3.15k
        *left = rotrFixed(*left^work, 4U);
1525
3.15k
    }
1526
1527
    static int DesSetKey(const byte* key, int dir, word32* out)
1528
922
    {
1529
922
        #define DES_KEY_BUFFER_SIZE (56+56+8)
1530
922
    #ifdef WOLFSSL_SMALL_STACK
1531
922
        byte* buffer = (byte*)XMALLOC(DES_KEY_BUFFER_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1532
1533
922
        if (buffer == NULL)
1534
0
            return MEMORY_E;
1535
    #else
1536
        byte buffer[DES_KEY_BUFFER_SIZE];
1537
    #endif
1538
1539
922
        {
1540
922
            byte* const  pc1m = buffer;            /* place to modify pc1 into */
1541
922
            byte* const  pcr  = pc1m + 56;         /* place to rotate pc1 into */
1542
922
            byte* const  ks   = pcr  + 56;
1543
922
            int i, j, l;
1544
922
            int          m;
1545
1546
52.5k
            for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */
1547
51.6k
                l = pc1[j] - 1;                    /* integer bit location        */
1548
51.6k
                m = l & 07;                        /* find bit                    */
1549
51.6k
                pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */
1550
51.6k
                    bytebit[m])                    /* and which bit of that byte  */
1551
51.6k
                    ? 1 : 0;                       /* and store 1-bit result      */
1552
51.6k
            }
1553
1554
15.6k
            for (i = 0; i < 16; i++) {            /* key chunk for each iteration */
1555
14.7k
                XMEMSET(ks, 0, 8);                /* Clear key schedule */
1556
1557
840k
                for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */
1558
826k
                    pcr[j] =
1559
826k
                          pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];
1560
1561
                /* rotate left and right halves independently */
1562
722k
                for (j = 0; j < 48; j++) {        /* select bits individually     */
1563
708k
                    if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */
1564
312k
                        l= j % 6;                 /* mask it in if it's there     */
1565
312k
                        ks[j/6] |= (byte)(bytebit[l] >> 2);
1566
312k
                    }
1567
708k
                }
1568
1569
                /* Now convert to odd/even interleaved form for use in F */
1570
14.7k
                out[2*i] = ((word32) ks[0] << 24)
1571
14.7k
                         | ((word32) ks[2] << 16)
1572
14.7k
                         | ((word32) ks[4] << 8)
1573
14.7k
                         | ((word32) ks[6]);
1574
1575
14.7k
                out[2*i + 1] = ((word32) ks[1] << 24)
1576
14.7k
                             | ((word32) ks[3] << 16)
1577
14.7k
                             | ((word32) ks[5] << 8)
1578
14.7k
                             | ((word32) ks[7]);
1579
14.7k
            }
1580
1581
            /* reverse key schedule order */
1582
922
            if (dir == DES_DECRYPTION) {
1583
4.07k
                for (i = 0; i < 16; i += 2) {
1584
3.62k
                    word32 swap = out[i];
1585
3.62k
                    out[i] = out[DES_KS_SIZE - 2 - i];
1586
3.62k
                    out[DES_KS_SIZE - 2 - i] = swap;
1587
1588
3.62k
                    swap = out[i + 1];
1589
3.62k
                    out[i + 1] = out[DES_KS_SIZE - 1 - i];
1590
3.62k
                    out[DES_KS_SIZE - 1 - i] = swap;
1591
3.62k
                }
1592
453
            }
1593
1594
922
            WC_FREE_VAR_EX(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1595
922
        }
1596
1597
922
        return 0;
1598
922
    }
1599
1600
    int wc_Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
1601
670
    {
1602
670
        wc_Des_SetIV(des, iv);
1603
1604
670
        return DesSetKey(key, dir, des->key);
1605
670
    }
1606
1607
    int wc_Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
1608
84
    {
1609
84
        int ret;
1610
1611
84
        if (des == NULL || key == NULL || dir < 0) {
1612
0
            return BAD_FUNC_ARG;
1613
0
        }
1614
1615
84
        XMEMSET(des->key, 0, sizeof(*(des->key)));
1616
84
        XMEMSET(des->reg, 0, sizeof(*(des->reg)));
1617
84
        XMEMSET(des->tmp, 0, sizeof(*(des->tmp)));
1618
1619
84
    #if defined(WOLF_CRYPTO_CB) || \
1620
84
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))
1621
84
        #ifdef WOLF_CRYPTO_CB
1622
84
        if (des->devId != INVALID_DEVID)
1623
84
        #endif
1624
84
        {
1625
84
            XMEMCPY(des->devKey, key, DES3_KEYLEN);
1626
84
        }
1627
84
    #endif
1628
1629
84
        ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);
1630
84
        if (ret != 0)
1631
0
            return ret;
1632
1633
84
        ret = DesSetKey(key + 8, !dir, des->key[1]);
1634
84
        if (ret != 0)
1635
0
            return ret;
1636
1637
84
        ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);
1638
84
        if (ret != 0)
1639
0
            return ret;
1640
1641
84
        return wc_Des3_SetIV(des, iv);
1642
84
    }
1643
1644
    static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
1645
4.88k
    {
1646
4.88k
        word32 l = *lIn, r = *rIn, i;
1647
1648
43.9k
        for (i=0; i<8; i++)
1649
39.0k
        {
1650
39.0k
            word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
1651
39.0k
            l ^= Spbox[6][(work) & 0x3f]
1652
39.0k
              ^  Spbox[4][(work >> 8) & 0x3f]
1653
39.0k
              ^  Spbox[2][(work >> 16) & 0x3f]
1654
39.0k
              ^  Spbox[0][(work >> 24) & 0x3f];
1655
39.0k
            work = r ^ kptr[4*i+1];
1656
39.0k
            l ^= Spbox[7][(work) & 0x3f]
1657
39.0k
              ^  Spbox[5][(work >> 8) & 0x3f]
1658
39.0k
              ^  Spbox[3][(work >> 16) & 0x3f]
1659
39.0k
              ^  Spbox[1][(work >> 24) & 0x3f];
1660
1661
39.0k
            work = rotrFixed(l, 4U) ^ kptr[4*i+2];
1662
39.0k
            r ^= Spbox[6][(work) & 0x3f]
1663
39.0k
              ^  Spbox[4][(work >> 8) & 0x3f]
1664
39.0k
              ^  Spbox[2][(work >> 16) & 0x3f]
1665
39.0k
              ^  Spbox[0][(work >> 24) & 0x3f];
1666
39.0k
            work = l ^ kptr[4*i+3];
1667
39.0k
            r ^= Spbox[7][(work) & 0x3f]
1668
39.0k
              ^  Spbox[5][(work >> 8) & 0x3f]
1669
39.0k
              ^  Spbox[3][(work >> 16) & 0x3f]
1670
39.0k
              ^  Spbox[1][(work >> 24) & 0x3f];
1671
39.0k
        }
1672
1673
4.88k
        *lIn = l; *rIn = r;
1674
4.88k
    }
1675
1676
    static void DesProcessBlock(Des* des, const byte* in, byte* out)
1677
2.29k
    {
1678
2.29k
        word32 l = 0, r = 0;
1679
1680
2.29k
        XMEMCPY(&l, in, sizeof(l));
1681
2.29k
        XMEMCPY(&r, in + sizeof(l), sizeof(r));
1682
2.29k
        #ifdef LITTLE_ENDIAN_ORDER
1683
2.29k
            l = ByteReverseWord32(l);
1684
2.29k
            r = ByteReverseWord32(r);
1685
2.29k
        #endif
1686
2.29k
        IPERM(&l,&r);
1687
1688
2.29k
        DesRawProcessBlock(&l, &r, des->key);
1689
1690
2.29k
        FPERM(&l,&r);
1691
2.29k
        #ifdef LITTLE_ENDIAN_ORDER
1692
2.29k
            l = ByteReverseWord32(l);
1693
2.29k
            r = ByteReverseWord32(r);
1694
2.29k
        #endif
1695
2.29k
        XMEMCPY(out, &r, sizeof(r));
1696
2.29k
        XMEMCPY(out + sizeof(r), &l, sizeof(l));
1697
2.29k
    }
1698
1699
    static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
1700
865
    {
1701
865
        word32 l = 0, r = 0;
1702
1703
865
        XMEMCPY(&l, in, sizeof(l));
1704
865
        XMEMCPY(&r, in + sizeof(l), sizeof(r));
1705
865
        #ifdef LITTLE_ENDIAN_ORDER
1706
865
            l = ByteReverseWord32(l);
1707
865
            r = ByteReverseWord32(r);
1708
865
        #endif
1709
865
        IPERM(&l,&r);
1710
1711
865
        DesRawProcessBlock(&l, &r, des->key[0]);
1712
865
        DesRawProcessBlock(&r, &l, des->key[1]);
1713
865
        DesRawProcessBlock(&l, &r, des->key[2]);
1714
1715
865
        FPERM(&l,&r);
1716
865
        #ifdef LITTLE_ENDIAN_ORDER
1717
865
            l = ByteReverseWord32(l);
1718
865
            r = ByteReverseWord32(r);
1719
865
        #endif
1720
865
        XMEMCPY(out, &r, sizeof(r));
1721
865
        XMEMCPY(out + sizeof(r), &l, sizeof(l));
1722
865
    }
1723
1724
    int wc_Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1725
276
    {
1726
276
        word32 blocks = sz / DES_BLOCK_SIZE;
1727
1728
276
        if (des == NULL || out == NULL || in == NULL) {
1729
0
            return BAD_FUNC_ARG;
1730
0
        }
1731
1732
829
        while (blocks--) {
1733
553
            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
1734
553
            DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
1735
553
            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
1736
1737
553
            out += DES_BLOCK_SIZE;
1738
553
            in  += DES_BLOCK_SIZE;
1739
553
        }
1740
276
        return 0;
1741
276
    }
1742
1743
    int wc_Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
1744
133
    {
1745
133
        word32 blocks = sz / DES_BLOCK_SIZE;
1746
1747
133
        if (des == NULL || out == NULL || in == NULL) {
1748
0
            return BAD_FUNC_ARG;
1749
0
        }
1750
1751
730
        while (blocks--) {
1752
597
            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
1753
597
            DesProcessBlock(des, (byte*)des->tmp, out);
1754
597
            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
1755
597
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
1756
1757
597
            out += DES_BLOCK_SIZE;
1758
597
            in  += DES_BLOCK_SIZE;
1759
597
        }
1760
133
        return 0;
1761
133
    }
1762
1763
    int wc_Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1764
136
    {
1765
136
        word32 blocks;
1766
1767
136
        if (des == NULL || out == NULL || in == NULL) {
1768
0
            return BAD_FUNC_ARG;
1769
0
        }
1770
1771
136
    #ifdef WOLF_CRYPTO_CB
1772
136
        if (des->devId != INVALID_DEVID) {
1773
136
            int ret = wc_CryptoCb_Des3Encrypt(des, out, in, sz);
1774
136
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1775
0
                return ret;
1776
            /* fall-through when unavailable */
1777
136
        }
1778
136
    #endif
1779
1780
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1781
        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&
1782
                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {
1783
        #if defined(HAVE_CAVIUM)
1784
            return NitroxDes3CbcEncrypt(des, out, in, sz);
1785
        #elif defined(HAVE_INTEL_QA)
1786
            return IntelQaSymDes3CbcEncrypt(&des->asyncDev, out, in, sz,
1787
                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);
1788
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
1789
            if (wc_AsyncSwInit(&des->asyncDev, ASYNC_SW_DES3_CBC_ENCRYPT)) {
1790
                WC_ASYNC_SW* sw = &des->asyncDev.sw;
1791
                sw->des.des = des;
1792
                sw->des.out = out;
1793
                sw->des.in = in;
1794
                sw->des.sz = sz;
1795
                return WC_PENDING_E;
1796
            }
1797
        #endif
1798
        }
1799
    #endif /* WOLFSSL_ASYNC_CRYPT */
1800
1801
136
        blocks = sz / DES_BLOCK_SIZE;
1802
565
        while (blocks--) {
1803
429
            xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
1804
429
            Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
1805
429
            XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
1806
1807
429
            out += DES_BLOCK_SIZE;
1808
429
            in  += DES_BLOCK_SIZE;
1809
429
        }
1810
136
        return 0;
1811
136
    }
1812
1813
1814
    int wc_Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
1815
41
    {
1816
41
        word32 blocks;
1817
1818
41
        if (des == NULL || out == NULL || in == NULL) {
1819
0
            return BAD_FUNC_ARG;
1820
0
        }
1821
1822
41
    #ifdef WOLF_CRYPTO_CB
1823
41
        if (des->devId != INVALID_DEVID) {
1824
41
            int ret = wc_CryptoCb_Des3Decrypt(des, out, in, sz);
1825
41
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1826
0
                return ret;
1827
            /* fall-through when unavailable */
1828
41
        }
1829
41
    #endif
1830
1831
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1832
        if (des->asyncDev.marker == WOLFSSL_ASYNC_MARKER_3DES &&
1833
                                            sz >= WC_ASYNC_THRESH_DES3_CBC) {
1834
        #if defined(HAVE_CAVIUM)
1835
            return NitroxDes3CbcDecrypt(des, out, in, sz);
1836
        #elif defined(HAVE_INTEL_QA)
1837
            return IntelQaSymDes3CbcDecrypt(&des->asyncDev, out, in, sz,
1838
                (const byte*)des->devKey, DES3_KEYLEN, (byte*)des->reg, DES3_IVLEN);
1839
        #elif defined(WOLFSSL_ASYNC_CRYPT_SW)
1840
            if (wc_AsyncSwInit(&des->asyncDev, ASYNC_SW_DES3_CBC_DECRYPT)) {
1841
                WC_ASYNC_SW* sw = &des->asyncDev.sw;
1842
                sw->des.des = des;
1843
                sw->des.out = out;
1844
                sw->des.in = in;
1845
                sw->des.sz = sz;
1846
                return WC_PENDING_E;
1847
            }
1848
        #endif
1849
        }
1850
    #endif /* WOLFSSL_ASYNC_CRYPT */
1851
1852
41
        blocks = sz / DES_BLOCK_SIZE;
1853
477
        while (blocks--) {
1854
436
            XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
1855
436
            Des3ProcessBlock(des, (byte*)des->tmp, out);
1856
436
            xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
1857
436
            XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
1858
1859
436
            out += DES_BLOCK_SIZE;
1860
436
            in  += DES_BLOCK_SIZE;
1861
436
        }
1862
41
        return 0;
1863
41
    }
1864
1865
    #ifdef WOLFSSL_DES_ECB
1866
        /* One block, compatibility only */
1867
        int wc_Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
1868
582
        {
1869
582
            word32 blocks = sz / DES_BLOCK_SIZE;
1870
1871
582
            if (des == NULL || out == NULL || in == NULL) {
1872
0
                return BAD_FUNC_ARG;
1873
0
            }
1874
1875
1.72k
            while (blocks--) {
1876
1.14k
                DesProcessBlock(des, in, out);
1877
1878
1.14k
                out += DES_BLOCK_SIZE;
1879
1.14k
                in  += DES_BLOCK_SIZE;
1880
1.14k
            }
1881
582
            return 0;
1882
582
        }
1883
1884
        int wc_Des3_EcbEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
1885
0
        {
1886
0
            word32 blocks = sz / DES_BLOCK_SIZE;
1887
1888
0
            if (des == NULL || out == NULL || in == NULL) {
1889
0
                return BAD_FUNC_ARG;
1890
0
            }
1891
1892
0
            while (blocks--) {
1893
0
                Des3ProcessBlock(des, in, out);
1894
1895
0
                out += DES_BLOCK_SIZE;
1896
0
                in  += DES_BLOCK_SIZE;
1897
0
            }
1898
0
            return 0;
1899
0
        }
1900
    #endif /* WOLFSSL_DES_ECB */
1901
1902
#endif /* NEED_SOFT_DES */
1903
1904
1905
void wc_Des_SetIV(Des* des, const byte* iv)
1906
889
{
1907
889
    if (des && iv) {
1908
466
        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
1909
    #if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY) && defined(STM32_HAL_V2)
1910
        ByteReverseWords(des->reg, des->reg, DES_BLOCK_SIZE);
1911
    #endif
1912
466
    }
1913
423
    else if (des)
1914
423
        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
1915
889
}
1916
1917
int wc_Des3_SetIV(Des3* des, const byte* iv)
1918
160
{
1919
160
    if (des == NULL) {
1920
0
        return BAD_FUNC_ARG;
1921
0
    }
1922
160
    if (iv) {
1923
160
        XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
1924
    #if defined(STM32_CRYPTO) && !defined(STM32_CRYPTO_AES_ONLY) && defined(STM32_HAL_V2)
1925
        ByteReverseWords(des->reg, des->reg, DES_BLOCK_SIZE);
1926
    #endif
1927
160
    }
1928
0
    else
1929
0
        XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
1930
1931
160
    return 0;
1932
160
}
1933
1934
1935
/* Initialize Des3 for use with async device */
1936
int wc_Des3Init(Des3* des3, void* heap, int devId)
1937
0
{
1938
0
    int ret = 0;
1939
0
    if (des3 == NULL)
1940
0
        return BAD_FUNC_ARG;
1941
1942
0
    des3->heap = heap;
1943
1944
0
#ifdef WOLF_CRYPTO_CB
1945
0
    des3->devId = devId;
1946
0
    des3->devCtx = NULL;
1947
#else
1948
    (void)devId;
1949
#endif
1950
1951
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1952
    ret = wolfAsync_DevCtxInit(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES,
1953
                                                        des3->heap, devId);
1954
#endif
1955
#if defined(WOLFSSL_CHECK_MEM_ZERO) && (defined(WOLF_CRYPTO_CB) || \
1956
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)))
1957
    wc_MemZero_Add("DES3 devKey", &des3->devKey, sizeof(des3->devKey));
1958
#endif
1959
1960
0
    return ret;
1961
0
}
1962
1963
/* Free Des3 from use with async device */
1964
void wc_Des3Free(Des3* des3)
1965
163k
{
1966
163k
    if (des3 == NULL)
1967
163k
        return;
1968
1969
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES)
1970
    wolfAsync_DevCtxFree(&des3->asyncDev, WOLFSSL_ASYNC_MARKER_3DES);
1971
#endif /* WOLFSSL_ASYNC_CRYPT */
1972
0
#if defined(WOLF_CRYPTO_CB) || \
1973
0
        (defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_3DES))
1974
0
    ForceZero(des3->devKey, sizeof(des3->devKey));
1975
0
#endif
1976
#ifdef WOLFSSL_CHECK_MEM_ZERO
1977
    wc_MemZero_Check(des3, sizeof(Des3));
1978
#endif
1979
0
}
1980
1981
#endif /* WOLFSSL_TI_CRYPT */
1982
#endif /* NO_DES3 */