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