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