Coverage Report

Created: 2026-08-15 06:21

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