Coverage Report

Created: 2022-08-24 06:25

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