Coverage Report

Created: 2026-09-20 06:33

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