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