MultiTech / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers des3.c Source File

des3.c

00001 /* des3.c
00002  *
00003  * Copyright (C) 2006-2014 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <cyassl/ctaocrypt/settings.h>
00027 
00028 #ifndef NO_DES3
00029 
00030 #ifdef HAVE_FIPS
00031     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
00032     #define FIPS_NO_WRAPPERS
00033 #endif
00034 
00035 #include <cyassl/ctaocrypt/des3.h>
00036 #include <cyassl/ctaocrypt/error-crypt.h>
00037 #include <cyassl/ctaocrypt/logging.h>
00038 
00039 #ifdef NO_INLINE
00040     #include <cyassl/ctaocrypt/misc.h>
00041 #else
00042     #include <ctaocrypt/src/misc.c>
00043 #endif
00044 
00045 
00046 #ifdef HAVE_CAVIUM
00047     static int Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv);
00048     static int Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
00049                                       word32 length);
00050     static int Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
00051                                       word32 length);
00052 #endif
00053 
00054 
00055 
00056 
00057 #ifdef STM32F2_CRYPTO
00058     /*
00059      * STM32F2 hardware DES/3DES support through the STM32F2 standard
00060      * peripheral library. Documentation located in STM32F2xx Standard
00061      * Peripheral Library document (See note in README).
00062      */
00063     #include "stm32f2xx.h"
00064         #include "stm32f2xx_cryp.h"
00065 
00066     int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
00067     {
00068         word32 *dkey = des->key;
00069 
00070         XMEMCPY(dkey, key, 8);
00071         ByteReverseWords(dkey, dkey, 8);
00072 
00073         Des_SetIV(des, iv);
00074 
00075         return 0;
00076     }
00077 
00078     int Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
00079     {
00080         word32 *dkey1 = des->key[0];
00081         word32 *dkey2 = des->key[1];
00082         word32 *dkey3 = des->key[2];
00083 
00084         XMEMCPY(dkey1, key, 8);         /* set key 1 */
00085         XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
00086         XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
00087 
00088         ByteReverseWords(dkey1, dkey1, 8);
00089         ByteReverseWords(dkey2, dkey2, 8);
00090         ByteReverseWords(dkey3, dkey3, 8);
00091 
00092         return Des3_SetIV(des, iv);
00093     }
00094 
00095     void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
00096                   int dir, int mode)
00097     {
00098         word32 *dkey, *iv;
00099         CRYP_InitTypeDef DES_CRYP_InitStructure;
00100         CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
00101         CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
00102 
00103         dkey = des->key;
00104         iv = des->reg;
00105 
00106         /* crypto structure initialization */
00107         CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
00108         CRYP_StructInit(&DES_CRYP_InitStructure);
00109         CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
00110 
00111         /* reset registers to their default values */
00112         CRYP_DeInit();
00113 
00114         /* set direction, mode, and datatype */
00115         if (dir == DES_ENCRYPTION) {
00116             DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
00117         } else { /* DES_DECRYPTION */
00118             DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
00119         }
00120 
00121         if (mode == DES_CBC) {
00122             DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
00123         } else { /* DES_ECB */
00124             DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
00125         }
00126 
00127         DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
00128         CRYP_Init(&DES_CRYP_InitStructure);
00129 
00130         /* load key into correct registers */
00131         DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];
00132         DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
00133         CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
00134 
00135         /* set iv */
00136         ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
00137         DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
00138         DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
00139         CRYP_IVInit(&DES_CRYP_IVInitStructure);
00140 
00141         /* enable crypto processor */
00142         CRYP_Cmd(ENABLE);
00143 
00144         while (sz > 0)
00145         {
00146             /* flush IN/OUT FIFOs */
00147             CRYP_FIFOFlush();
00148 
00149             /* if input and output same will overwrite input iv */
00150             XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00151 
00152             CRYP_DataIn(*(uint32_t*)&in[0]);
00153             CRYP_DataIn(*(uint32_t*)&in[4]);
00154 
00155             /* wait until the complete message has been processed */
00156             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00157 
00158             *(uint32_t*)&out[0]  = CRYP_DataOut();
00159             *(uint32_t*)&out[4]  = CRYP_DataOut();
00160 
00161             /* store iv for next call */
00162             XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
00163 
00164             sz  -= DES_BLOCK_SIZE;
00165             in  += DES_BLOCK_SIZE;
00166             out += DES_BLOCK_SIZE;
00167         }
00168 
00169         /* disable crypto processor */
00170         CRYP_Cmd(DISABLE);
00171     }
00172 
00173     int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00174     {
00175         DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
00176         return 0;
00177     }
00178 
00179     int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
00180     {
00181         DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
00182         return 0;
00183     }
00184 
00185     int Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00186     {
00187         DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
00188         return 0;
00189     }
00190 
00191     void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
00192                    int dir)
00193     {
00194         word32 *dkey1, *dkey2, *dkey3, *iv;
00195         CRYP_InitTypeDef DES3_CRYP_InitStructure;
00196         CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
00197         CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
00198 
00199         dkey1 = des->key[0];
00200         dkey2 = des->key[1];
00201         dkey3 = des->key[2];
00202         iv = des->reg;
00203 
00204         /* crypto structure initialization */
00205         CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
00206         CRYP_StructInit(&DES3_CRYP_InitStructure);
00207         CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
00208 
00209         /* reset registers to their default values */
00210         CRYP_DeInit();
00211 
00212         /* set direction, mode, and datatype */
00213         if (dir == DES_ENCRYPTION) {
00214             DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
00215         } else {
00216             DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
00217         }
00218 
00219         DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
00220         DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
00221         CRYP_Init(&DES3_CRYP_InitStructure);
00222 
00223         /* load key into correct registers */
00224         DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];
00225         DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
00226         DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];
00227         DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
00228         DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];
00229         DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
00230         CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
00231 
00232         /* set iv */
00233         ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
00234         DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
00235         DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
00236         CRYP_IVInit(&DES3_CRYP_IVInitStructure);
00237 
00238         /* enable crypto processor */
00239         CRYP_Cmd(ENABLE);
00240 
00241         while (sz > 0)
00242         {
00243             /* flush IN/OUT FIFOs */
00244             CRYP_FIFOFlush();
00245 
00246             CRYP_DataIn(*(uint32_t*)&in[0]);
00247             CRYP_DataIn(*(uint32_t*)&in[4]);
00248 
00249             /* wait until the complete message has been processed */
00250             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00251 
00252             *(uint32_t*)&out[0]  = CRYP_DataOut();
00253             *(uint32_t*)&out[4]  = CRYP_DataOut();
00254 
00255             /* store iv for next call */
00256             XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00257 
00258             sz  -= DES_BLOCK_SIZE;
00259             in  += DES_BLOCK_SIZE;
00260             out += DES_BLOCK_SIZE;
00261         }
00262 
00263         /* disable crypto processor */
00264         CRYP_Cmd(DISABLE);
00265 
00266     }
00267 
00268     int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
00269     {
00270         Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
00271         return 0;
00272     }
00273 
00274     int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
00275     {
00276         Des3Crypt(des, out, in, sz, DES_DECRYPTION);
00277         return 0;
00278     }
00279 
00280 #elif defined(HAVE_COLDFIRE_SEC)
00281 
00282 #include <cyassl/ctaocrypt/types.h>
00283 
00284 #include "sec.h"
00285 #include "mcf5475_sec.h"
00286 #include "mcf5475_siu.h"
00287 
00288 #if defined (HAVE_THREADX)
00289 #include "memory_pools.h"
00290 extern TX_BYTE_POOL mp_ncached;  /* Non Cached memory pool */
00291 #endif
00292 
00293 #define DES_BUFFER_SIZE (DES_BLOCK_SIZE * 64)
00294 static unsigned char *desBuffIn = NULL ;
00295 static unsigned char *desBuffOut = NULL ;
00296 static byte *secIV ; 
00297 static byte *secKey ; 
00298 static volatile SECdescriptorType *secDesc ;
00299 
00300 static CyaSSL_Mutex Mutex_DesSEC ;
00301 
00302 #define SEC_DESC_DES_CBC_ENCRYPT  0x20500010
00303 #define SEC_DESC_DES_CBC_DECRYPT  0x20400010
00304 #define SEC_DESC_DES3_CBC_ENCRYPT 0x20700010
00305 #define SEC_DESC_DES3_CBC_DECRYPT 0x20600010
00306 
00307 #define DES_IVLEN 8
00308 #define DES_KEYLEN 8
00309 #define DES3_IVLEN 8
00310 #define DES3_KEYLEN 24
00311 
00312 extern volatile unsigned char __MBAR[];
00313 
00314 static void Des_Cbc(byte* out, const byte* in, word32 sz, 
00315                     byte *key, byte *iv, word32 desc)
00316 {
00317     #ifdef DEBUG_CYASSL
00318     int ret ;  int stat1,stat2 ; 
00319       #endif
00320     int size ;
00321     volatile int v ;
00322  
00323     LockMutex(&Mutex_DesSEC) ;
00324     
00325     secDesc->length1 = 0x0;
00326     secDesc->pointer1 = NULL;
00327     if((desc==SEC_DESC_DES_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_DECRYPT)){
00328         secDesc->length2 = DES_IVLEN ;  
00329         secDesc->length3 = DES_KEYLEN ;
00330     } else {
00331         secDesc->length2 = DES3_IVLEN ; 
00332         secDesc->length3 = DES3_KEYLEN ;
00333     }
00334     secDesc->pointer2 = secIV ;
00335     secDesc->pointer3 = secKey;
00336     secDesc->pointer4 = desBuffIn ;
00337     secDesc->pointer5 = desBuffOut ;
00338     secDesc->length6 = 0; 
00339     secDesc->pointer6 = NULL; 
00340     secDesc->length7 = 0x0;
00341     secDesc->pointer7 = NULL;
00342     secDesc->nextDescriptorPtr = NULL ; 
00343     
00344     while(sz) {
00345         XMEMCPY(secIV, iv, secDesc->length2) ;
00346         if((sz%DES_BUFFER_SIZE) == sz) {
00347             size = sz ;
00348             sz = 0 ;
00349         } else {
00350             size = DES_BUFFER_SIZE ;
00351             sz -= DES_BUFFER_SIZE ;
00352         }
00353         
00354         XMEMCPY(desBuffIn, in, size) ;
00355         XMEMCPY(secKey, key, secDesc->length3) ;
00356         
00357         secDesc->header = desc ;
00358         secDesc->length4 = size;
00359         secDesc->length5 = size;
00360         /* Point SEC to the location of the descriptor */
00361         MCF_SEC_FR0 = (uint32)secDesc;
00362         /* Initialize SEC and wait for encryption to complete */
00363         MCF_SEC_CCCR0 = 0x0000001a;
00364         /* poll SISR to determine when channel is complete */
00365         v=0 ;
00366         while((secDesc->header>> 24) != 0xff) {
00367             if(v++ > 1000)break ;
00368         }
00369                 
00370 #ifdef DEBUG_CYASSL
00371         ret = MCF_SEC_SISRH;
00372         stat1 = MCF_SEC_DSR ; 
00373         stat2 = MCF_SEC_DISR ; 
00374         if(ret & 0xe0000000) {
00375             /* db_printf("Des_Cbc(%x):ISRH=%08x, DSR=%08x, DISR=%08x\n", desc, ret, stat1, stat2) ; */
00376         }
00377 #endif
00378                 
00379         XMEMCPY(out, desBuffOut, size) ;
00380 
00381         if((desc==SEC_DESC_DES3_CBC_ENCRYPT)||(desc==SEC_DESC_DES_CBC_ENCRYPT)) {
00382             XMEMCPY((void*)iv, (void*)&(out[size-secDesc->length2]), secDesc->length2) ;
00383         } else {
00384             XMEMCPY((void*)iv, (void*)&(in[size-secDesc->length2]), secDesc->length2) ;
00385         }
00386         
00387         in  += size ;   
00388         out += size ;
00389                 
00390     }
00391     UnLockMutex(&Mutex_DesSEC) ;
00392     
00393 }
00394 
00395 
00396 int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00397 {
00398     Des_Cbc(out, in, sz,  (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_ENCRYPT) ;
00399     return 0;
00400 }
00401 
00402 int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
00403 {
00404     Des_Cbc(out, in, sz,   (byte *)des->key,  (byte *)des->reg, SEC_DESC_DES_CBC_DECRYPT) ;
00405     return 0;
00406 }
00407 
00408 int Des3_CbcEncrypt(Des3* des3, byte* out, const byte* in, word32 sz)
00409 {
00410     Des_Cbc(out, in, sz,  (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_ENCRYPT) ;
00411       return 0;
00412 }
00413 
00414 
00415 int Des3_CbcDecrypt(Des3* des3, byte* out, const byte* in, word32 sz)
00416 {
00417     Des_Cbc(out, in, sz,   (byte *)des3->key,  (byte *)des3->reg, SEC_DESC_DES3_CBC_DECRYPT) ;
00418       return 0;
00419 }
00420 
00421 static void setParity(byte *buf, int len) 
00422 {
00423     int i, j ;
00424     byte v ;
00425     int bits ;
00426 
00427     for(i=0; i<len; i++) 
00428     {
00429         v = buf[i] >> 1 ;
00430         buf[i] = v << 1 ;
00431         bits = 0 ;
00432         for(j=0; j<7; j++)
00433         {
00434             bits += (v&0x1) ;
00435             v = v >> 1 ;
00436         }
00437         buf[i] |= (1 - (bits&0x1)) ;
00438     }
00439     
00440 }
00441 
00442 
00443 int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
00444 {
00445     if(desBuffIn == NULL) {
00446         #if defined (HAVE_THREADX)
00447               int s1, s2, s3, s4, s5 ;
00448         s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, 
00449                                                      sizeof(SECdescriptorType), TX_NO_WAIT);
00450         s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
00451         s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
00452         /* Don't know des or des3 to be used. Allocate larger buffers */
00453         s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
00454         s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);              
00455         #else
00456         #warning "Allocate non-Cache buffers"
00457         #endif
00458         
00459         InitMutex(&Mutex_DesSEC) ;
00460     }
00461      
00462     XMEMCPY(des->key, key, DES_KEYLEN);  
00463     setParity((byte *)des->key, DES_KEYLEN) ;  
00464         
00465     if (iv) {
00466         XMEMCPY(des->reg, iv, DES_IVLEN);
00467     }   else {
00468         XMEMSET(des->reg, 0x0, DES_IVLEN) ;
00469     }
00470         return 0;
00471 }
00472 
00473 int Des3_SetKey(Des3* des3, const byte* key, const byte* iv, int dir)
00474 {
00475     
00476     if(desBuffIn == NULL) {
00477         #if defined (HAVE_THREADX)
00478               int s1, s2, s3, s4, s5 ;
00479         s5 = tx_byte_allocate(&mp_ncached,(void *)&secDesc, 
00480                                                      sizeof(SECdescriptorType), TX_NO_WAIT);
00481         s1 = tx_byte_allocate(&mp_ncached,(void *)&desBuffIn,  DES_BUFFER_SIZE, TX_NO_WAIT);
00482         s2 = tx_byte_allocate(&mp_ncached,(void *)&desBuffOut, DES_BUFFER_SIZE, TX_NO_WAIT);
00483         s3 = tx_byte_allocate(&mp_ncached,(void *)&secKey,     DES3_KEYLEN,TX_NO_WAIT);
00484         s4 = tx_byte_allocate(&mp_ncached,(void *)&secIV,      DES3_IVLEN,  TX_NO_WAIT);              
00485         #else
00486         #warning "Allocate non-Cache buffers"
00487         #endif
00488         
00489         InitMutex(&Mutex_DesSEC) ;
00490     }
00491     
00492     XMEMCPY(des3->key[0], key, DES3_KEYLEN); 
00493     setParity((byte *)des3->key[0], DES3_KEYLEN) ;  
00494         
00495     if (iv) {
00496         XMEMCPY(des3->reg, iv, DES3_IVLEN);
00497     }   else {
00498         XMEMSET(des3->reg, 0x0, DES3_IVLEN) ;
00499     }
00500     return 0;
00501 
00502 }
00503 
00504 #elif defined FREESCALE_MMCAU
00505     /*
00506      * Freescale mmCAU hardware DES/3DES support through the CAU/mmCAU library.
00507      * Documentation located in ColdFire/ColdFire+ CAU and Kinetis mmCAU
00508      * Software Library User Guide (See note in README).
00509      */
00510     #include "cau_api.h"
00511 
00512     const unsigned char parityLookup[128] =
00513     {
00514         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,
00515         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,
00516         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,
00517         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
00518      };
00519 
00520     int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
00521     {
00522         int i = 0;
00523         byte* dkey = (byte*)des->key;
00524 
00525         XMEMCPY(dkey, key, 8);
00526 
00527         Des_SetIV(des, iv);
00528 
00529         /* fix key parity, if needed */
00530         for (i = 0; i < 8; i++) {
00531             dkey[i] = ((dkey[i] & 0xFE) | parityLookup[dkey[i] >> 1]);
00532         }
00533 
00534         return 0;
00535     }
00536 
00537     int Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
00538     {
00539         int i = 0, ret = 0;
00540         byte* dkey1 = (byte*)des->key[0];
00541         byte* dkey2 = (byte*)des->key[1];
00542         byte* dkey3 = (byte*)des->key[2];
00543 
00544         XMEMCPY(dkey1, key, 8);         /* set key 1 */
00545         XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
00546         XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
00547 
00548         ret = Des3_SetIV(des, iv);
00549         if (ret != 0)
00550             return ret;
00551 
00552         /* fix key parity if needed */
00553         for (i = 0; i < 8; i++)
00554            dkey1[i] = ((dkey1[i] & 0xFE) | parityLookup[dkey1[i] >> 1]);
00555 
00556         for (i = 0; i < 8; i++)
00557            dkey2[i] = ((dkey2[i] & 0xFE) | parityLookup[dkey2[i] >> 1]);
00558 
00559         for (i = 0; i < 8; i++)
00560            dkey3[i] = ((dkey3[i] & 0xFE) | parityLookup[dkey3[i] >> 1]);
00561 
00562         return ret;
00563     }
00564 
00565     int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00566     {
00567         int i;
00568         int offset = 0;
00569         int len = sz;
00570         byte *iv;
00571         byte temp_block[DES_BLOCK_SIZE];
00572 
00573         iv = (byte*)des->reg;
00574 
00575         if ((cyassl_word)out % CYASSL_MMCAU_ALIGNMENT) {
00576             CYASSL_MSG("Bad cau_des_encrypt alignment"); 
00577             return BAD_ALIGN_E;
00578         }
00579 
00580         while (len > 0)
00581         {
00582             XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
00583 
00584             /* XOR block with IV for CBC */
00585             for (i = 0; i < DES_BLOCK_SIZE; i++)
00586                 temp_block[i] ^= iv[i];
00587 
00588             cau_des_encrypt(temp_block, (byte*)des->key, out + offset);
00589 
00590             len    -= DES_BLOCK_SIZE;
00591             offset += DES_BLOCK_SIZE;
00592 
00593             /* store IV for next block */
00594             XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00595         }
00596 
00597         return 0;
00598     }
00599 
00600     int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
00601     {
00602         int i;
00603         int offset = 0;
00604         int len = sz;
00605         byte* iv;
00606         byte temp_block[DES_BLOCK_SIZE];
00607 
00608         iv = (byte*)des->reg;
00609 
00610         if ((cyassl_word)out % CYASSL_MMCAU_ALIGNMENT) {
00611             CYASSL_MSG("Bad cau_des_decrypt alignment"); 
00612             return BAD_ALIGN_E;
00613         }
00614 
00615         while (len > 0)
00616         {
00617             XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
00618 
00619             cau_des_decrypt(in + offset, (byte*)des->key, out + offset);
00620 
00621             /* XOR block with IV for CBC */
00622             for (i = 0; i < DES_BLOCK_SIZE; i++)
00623                 (out + offset)[i] ^= iv[i];
00624 
00625             /* store IV for next block */
00626             XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
00627 
00628             len     -= DES_BLOCK_SIZE;
00629             offset += DES_BLOCK_SIZE;
00630         }
00631 
00632         return 0;
00633     }
00634 
00635     int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
00636     {
00637         int i;
00638         int offset = 0;
00639         int len = sz;
00640 
00641         byte *iv;
00642         byte temp_block[DES_BLOCK_SIZE];
00643 
00644         iv = (byte*)des->reg;
00645 
00646         if ((cyassl_word)out % CYASSL_MMCAU_ALIGNMENT) {
00647             CYASSL_MSG("Bad 3ede cau_des_encrypt alignment"); 
00648             return BAD_ALIGN_E;
00649         }
00650 
00651         while (len > 0)
00652         {
00653             XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
00654 
00655             /* XOR block with IV for CBC */
00656             for (i = 0; i < DES_BLOCK_SIZE; i++)
00657                 temp_block[i] ^= iv[i];
00658 
00659             cau_des_encrypt(temp_block  , (byte*)des->key[0], out + offset);
00660             cau_des_decrypt(out + offset, (byte*)des->key[1], out + offset);
00661             cau_des_encrypt(out + offset, (byte*)des->key[2], out + offset);
00662 
00663             len    -= DES_BLOCK_SIZE;
00664             offset += DES_BLOCK_SIZE;
00665 
00666             /* store IV for next block */
00667             XMEMCPY(iv, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00668         }
00669 
00670         return 0;
00671     }
00672 
00673     int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
00674     {
00675         int i;
00676         int offset = 0;
00677         int len = sz;
00678 
00679         byte* iv;
00680         byte temp_block[DES_BLOCK_SIZE];
00681 
00682         iv = (byte*)des->reg;
00683 
00684         if ((cyassl_word)out % CYASSL_MMCAU_ALIGNMENT) {
00685             CYASSL_MSG("Bad 3ede cau_des_decrypt alignment"); 
00686             return BAD_ALIGN_E;
00687         }
00688 
00689         while (len > 0)
00690         {
00691             XMEMCPY(temp_block, in + offset, DES_BLOCK_SIZE);
00692 
00693             cau_des_decrypt(in + offset , (byte*)des->key[2], out + offset);
00694             cau_des_encrypt(out + offset, (byte*)des->key[1], out + offset);
00695             cau_des_decrypt(out + offset, (byte*)des->key[0], out + offset);
00696 
00697             /* XOR block with IV for CBC */
00698             for (i = 0; i < DES_BLOCK_SIZE; i++)
00699                 (out + offset)[i] ^= iv[i];
00700 
00701             /* store IV for next block */
00702             XMEMCPY(iv, temp_block, DES_BLOCK_SIZE);
00703 
00704             len    -= DES_BLOCK_SIZE;
00705             offset += DES_BLOCK_SIZE;
00706         }
00707 
00708         return 0;
00709     }
00710 
00711 
00712 #elif defined(CYASSL_PIC32MZ_CRYPT)
00713 
00714     #include "cyassl/ctaocrypt/port/pic32/pic32mz-crypt.h"
00715 
00716 void Des_SetIV(Des* des, const byte* iv);
00717 int  Des3_SetIV(Des3* des, const byte* iv);
00718 
00719     int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
00720     {
00721         word32 *dkey = des->key ;
00722         word32 *dreg = des->reg ;
00723 
00724         XMEMCPY((byte *)dkey, (byte *)key, 8);
00725         ByteReverseWords(dkey, dkey, 8);
00726         XMEMCPY((byte *)dreg, (byte *)iv, 8);
00727         ByteReverseWords(dreg, dreg, 8);
00728 
00729         return 0;
00730     }
00731 
00732     int Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
00733     {
00734         word32 *dkey1 = des->key[0];
00735         word32 *dreg = des->reg ;
00736 
00737         XMEMCPY(dkey1, key, 24);
00738         ByteReverseWords(dkey1, dkey1, 24);
00739         XMEMCPY(dreg, iv, 8);
00740         ByteReverseWords(dreg, dreg, 8) ;
00741 
00742         return 0;
00743     }
00744 
00745     void DesCrypt(word32 *key, word32 *iv, byte* out, const byte* in, word32 sz,
00746                   int dir, int algo, int cryptoalgo)
00747     {
00748         securityAssociation *sa_p ;
00749         bufferDescriptor *bd_p ;
00750         const byte *in_p, *in_l ;
00751         byte *out_p, *out_l ;
00752         volatile securityAssociation sa __attribute__((aligned (8)));
00753         volatile bufferDescriptor bd __attribute__((aligned (8)));
00754         volatile int k ;
00755         
00756         /* get uncached address */
00757 
00758         in_l = in;
00759         out_l = out ;
00760         sa_p = KVA0_TO_KVA1(&sa) ; 
00761         bd_p = KVA0_TO_KVA1(&bd) ;
00762         in_p = KVA0_TO_KVA1(in_l) ;
00763         out_p= KVA0_TO_KVA1(out_l);
00764         
00765         if(PIC32MZ_IF_RAM(in_p))
00766             XMEMCPY((void *)in_p, (void *)in, sz);
00767         XMEMSET((void *)out_p, 0, sz);
00768 
00769         /* Set up the Security Association */
00770         XMEMSET((byte *)KVA0_TO_KVA1(&sa), 0, sizeof(sa));
00771         sa_p->SA_CTRL.ALGO = algo ; 
00772         sa_p->SA_CTRL.LNC = 1;
00773         sa_p->SA_CTRL.LOADIV = 1;
00774         sa_p->SA_CTRL.FB = 1;
00775         sa_p->SA_CTRL.ENCTYPE = dir ; /* Encryption/Decryption */
00776         sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo;
00777         sa_p->SA_CTRL.KEYSIZE = 1 ; /* KEY is 192 bits */
00778         XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCKEY[algo==PIC32_ALGO_TDES ? 2 : 6]),
00779                 (byte *)key, algo==PIC32_ALGO_TDES ? 24 : 8);
00780         XMEMCPY((byte *)KVA0_TO_KVA1(&sa.SA_ENCIV[2]), (byte *)iv, 8);
00781 
00782         XMEMSET((byte *)KVA0_TO_KVA1(&bd), 0, sizeof(bd));
00783         /* Set up the Buffer Descriptor */
00784         bd_p->BD_CTRL.BUFLEN = sz;
00785         bd_p->BD_CTRL.LIFM = 1;
00786         bd_p->BD_CTRL.SA_FETCH_EN = 1;
00787         bd_p->BD_CTRL.LAST_BD = 1;
00788         bd_p->BD_CTRL.DESC_EN = 1;
00789     
00790         bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa) ; /* (unsigned int)sa_p; */
00791         bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in) ; /* (unsigned int)in_p; */
00792         bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out); /* (unsigned int)out_p; */
00793         bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd);
00794         bd_p->MSGLEN = sz ;
00795         
00796         /* Fire in the hole! */
00797         CECON = 1 << 6;
00798         while (CECON);
00799         
00800         /* Run the engine */
00801         CEBDPADDR = (unsigned int)KVA_TO_PA(&bd) ; /* (unsigned int)bd_p ; */
00802         CEINTEN = 0x07;
00803         CECON = 0x27;
00804 
00805         WAIT_ENGINE ;
00806 
00807         if((cryptoalgo == PIC32_CRYPTOALGO_CBC) ||
00808            (cryptoalgo == PIC32_CRYPTOALGO_TCBC)||
00809            (cryptoalgo == PIC32_CRYPTOALGO_RCBC)) {
00810             /* set iv for the next call */
00811             if(dir == PIC32_ENCRYPTION) {
00812             XMEMCPY((void *)iv, (void*)&(out_p[sz-DES_IVLEN]), DES_IVLEN) ;
00813             } else {
00814                 ByteReverseWords((word32*)iv, (word32 *)&(in_p[sz-DES_IVLEN]),
00815                                  DES_IVLEN);
00816             }
00817 
00818         }
00819 
00820         ByteReverseWords((word32*)out, (word32 *)KVA0_TO_KVA1(out), sz);
00821     }
00822 
00823     int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00824     {
00825         DesCrypt(des->key, des->reg, out, in, sz, 
00826                 PIC32_ENCRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC );
00827         return 0;
00828     }
00829 
00830     int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
00831     {
00832         DesCrypt(des->key, des->reg, out, in, sz, 
00833                 PIC32_DECRYPTION, PIC32_ALGO_DES, PIC32_CRYPTOALGO_CBC);
00834         return 0;
00835     }
00836 
00837     int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
00838     {
00839         DesCrypt(des->key[0], des->reg, out, in, sz, 
00840                 PIC32_ENCRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
00841         return 0;
00842     }
00843 
00844     int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
00845     {
00846         DesCrypt(des->key[0], des->reg, out, in, sz, 
00847                 PIC32_DECRYPTION, PIC32_ALGO_TDES, PIC32_CRYPTOALGO_TCBC);
00848         return 0;
00849     }
00850 
00851 #else /* CTaoCrypt software implementation */
00852 
00853 /* permuted choice table (key) */
00854 static const byte pc1[] = {
00855        57, 49, 41, 33, 25, 17,  9,
00856         1, 58, 50, 42, 34, 26, 18,
00857        10,  2, 59, 51, 43, 35, 27,
00858        19, 11,  3, 60, 52, 44, 36,
00859 
00860        63, 55, 47, 39, 31, 23, 15,
00861         7, 62, 54, 46, 38, 30, 22,
00862        14,  6, 61, 53, 45, 37, 29,
00863        21, 13,  5, 28, 20, 12,  4
00864 };
00865 
00866 /* number left rotations of pc1 */
00867 static const byte totrot[] = {
00868        1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
00869 };
00870 
00871 /* permuted choice key (table) */
00872 static const byte pc2[] = {
00873        14, 17, 11, 24,  1,  5,
00874         3, 28, 15,  6, 21, 10,
00875        23, 19, 12,  4, 26,  8,
00876        16,  7, 27, 20, 13,  2,
00877        41, 52, 31, 37, 47, 55,
00878        30, 40, 51, 45, 33, 48,
00879        44, 49, 39, 56, 34, 53,
00880        46, 42, 50, 36, 29, 32
00881 };
00882 
00883 /* End of DES-defined tables */
00884 
00885 /* bit 0 is left-most in byte */
00886 static const int bytebit[] = {
00887        0200,0100,040,020,010,04,02,01
00888 };
00889 
00890 static const word32 Spbox[8][64] = {
00891 {
00892 0x01010400,0x00000000,0x00010000,0x01010404,
00893 0x01010004,0x00010404,0x00000004,0x00010000,
00894 0x00000400,0x01010400,0x01010404,0x00000400,
00895 0x01000404,0x01010004,0x01000000,0x00000004,
00896 0x00000404,0x01000400,0x01000400,0x00010400,
00897 0x00010400,0x01010000,0x01010000,0x01000404,
00898 0x00010004,0x01000004,0x01000004,0x00010004,
00899 0x00000000,0x00000404,0x00010404,0x01000000,
00900 0x00010000,0x01010404,0x00000004,0x01010000,
00901 0x01010400,0x01000000,0x01000000,0x00000400,
00902 0x01010004,0x00010000,0x00010400,0x01000004,
00903 0x00000400,0x00000004,0x01000404,0x00010404,
00904 0x01010404,0x00010004,0x01010000,0x01000404,
00905 0x01000004,0x00000404,0x00010404,0x01010400,
00906 0x00000404,0x01000400,0x01000400,0x00000000,
00907 0x00010004,0x00010400,0x00000000,0x01010004},
00908 {
00909 0x80108020,0x80008000,0x00008000,0x00108020,
00910 0x00100000,0x00000020,0x80100020,0x80008020,
00911 0x80000020,0x80108020,0x80108000,0x80000000,
00912 0x80008000,0x00100000,0x00000020,0x80100020,
00913 0x00108000,0x00100020,0x80008020,0x00000000,
00914 0x80000000,0x00008000,0x00108020,0x80100000,
00915 0x00100020,0x80000020,0x00000000,0x00108000,
00916 0x00008020,0x80108000,0x80100000,0x00008020,
00917 0x00000000,0x00108020,0x80100020,0x00100000,
00918 0x80008020,0x80100000,0x80108000,0x00008000,
00919 0x80100000,0x80008000,0x00000020,0x80108020,
00920 0x00108020,0x00000020,0x00008000,0x80000000,
00921 0x00008020,0x80108000,0x00100000,0x80000020,
00922 0x00100020,0x80008020,0x80000020,0x00100020,
00923 0x00108000,0x00000000,0x80008000,0x00008020,
00924 0x80000000,0x80100020,0x80108020,0x00108000},
00925 {
00926 0x00000208,0x08020200,0x00000000,0x08020008,
00927 0x08000200,0x00000000,0x00020208,0x08000200,
00928 0x00020008,0x08000008,0x08000008,0x00020000,
00929 0x08020208,0x00020008,0x08020000,0x00000208,
00930 0x08000000,0x00000008,0x08020200,0x00000200,
00931 0x00020200,0x08020000,0x08020008,0x00020208,
00932 0x08000208,0x00020200,0x00020000,0x08000208,
00933 0x00000008,0x08020208,0x00000200,0x08000000,
00934 0x08020200,0x08000000,0x00020008,0x00000208,
00935 0x00020000,0x08020200,0x08000200,0x00000000,
00936 0x00000200,0x00020008,0x08020208,0x08000200,
00937 0x08000008,0x00000200,0x00000000,0x08020008,
00938 0x08000208,0x00020000,0x08000000,0x08020208,
00939 0x00000008,0x00020208,0x00020200,0x08000008,
00940 0x08020000,0x08000208,0x00000208,0x08020000,
00941 0x00020208,0x00000008,0x08020008,0x00020200},
00942 {
00943 0x00802001,0x00002081,0x00002081,0x00000080,
00944 0x00802080,0x00800081,0x00800001,0x00002001,
00945 0x00000000,0x00802000,0x00802000,0x00802081,
00946 0x00000081,0x00000000,0x00800080,0x00800001,
00947 0x00000001,0x00002000,0x00800000,0x00802001,
00948 0x00000080,0x00800000,0x00002001,0x00002080,
00949 0x00800081,0x00000001,0x00002080,0x00800080,
00950 0x00002000,0x00802080,0x00802081,0x00000081,
00951 0x00800080,0x00800001,0x00802000,0x00802081,
00952 0x00000081,0x00000000,0x00000000,0x00802000,
00953 0x00002080,0x00800080,0x00800081,0x00000001,
00954 0x00802001,0x00002081,0x00002081,0x00000080,
00955 0x00802081,0x00000081,0x00000001,0x00002000,
00956 0x00800001,0x00002001,0x00802080,0x00800081,
00957 0x00002001,0x00002080,0x00800000,0x00802001,
00958 0x00000080,0x00800000,0x00002000,0x00802080},
00959 {
00960 0x00000100,0x02080100,0x02080000,0x42000100,
00961 0x00080000,0x00000100,0x40000000,0x02080000,
00962 0x40080100,0x00080000,0x02000100,0x40080100,
00963 0x42000100,0x42080000,0x00080100,0x40000000,
00964 0x02000000,0x40080000,0x40080000,0x00000000,
00965 0x40000100,0x42080100,0x42080100,0x02000100,
00966 0x42080000,0x40000100,0x00000000,0x42000000,
00967 0x02080100,0x02000000,0x42000000,0x00080100,
00968 0x00080000,0x42000100,0x00000100,0x02000000,
00969 0x40000000,0x02080000,0x42000100,0x40080100,
00970 0x02000100,0x40000000,0x42080000,0x02080100,
00971 0x40080100,0x00000100,0x02000000,0x42080000,
00972 0x42080100,0x00080100,0x42000000,0x42080100,
00973 0x02080000,0x00000000,0x40080000,0x42000000,
00974 0x00080100,0x02000100,0x40000100,0x00080000,
00975 0x00000000,0x40080000,0x02080100,0x40000100},
00976 {
00977 0x20000010,0x20400000,0x00004000,0x20404010,
00978 0x20400000,0x00000010,0x20404010,0x00400000,
00979 0x20004000,0x00404010,0x00400000,0x20000010,
00980 0x00400010,0x20004000,0x20000000,0x00004010,
00981 0x00000000,0x00400010,0x20004010,0x00004000,
00982 0x00404000,0x20004010,0x00000010,0x20400010,
00983 0x20400010,0x00000000,0x00404010,0x20404000,
00984 0x00004010,0x00404000,0x20404000,0x20000000,
00985 0x20004000,0x00000010,0x20400010,0x00404000,
00986 0x20404010,0x00400000,0x00004010,0x20000010,
00987 0x00400000,0x20004000,0x20000000,0x00004010,
00988 0x20000010,0x20404010,0x00404000,0x20400000,
00989 0x00404010,0x20404000,0x00000000,0x20400010,
00990 0x00000010,0x00004000,0x20400000,0x00404010,
00991 0x00004000,0x00400010,0x20004010,0x00000000,
00992 0x20404000,0x20000000,0x00400010,0x20004010},
00993 {
00994 0x00200000,0x04200002,0x04000802,0x00000000,
00995 0x00000800,0x04000802,0x00200802,0x04200800,
00996 0x04200802,0x00200000,0x00000000,0x04000002,
00997 0x00000002,0x04000000,0x04200002,0x00000802,
00998 0x04000800,0x00200802,0x00200002,0x04000800,
00999 0x04000002,0x04200000,0x04200800,0x00200002,
01000 0x04200000,0x00000800,0x00000802,0x04200802,
01001 0x00200800,0x00000002,0x04000000,0x00200800,
01002 0x04000000,0x00200800,0x00200000,0x04000802,
01003 0x04000802,0x04200002,0x04200002,0x00000002,
01004 0x00200002,0x04000000,0x04000800,0x00200000,
01005 0x04200800,0x00000802,0x00200802,0x04200800,
01006 0x00000802,0x04000002,0x04200802,0x04200000,
01007 0x00200800,0x00000000,0x00000002,0x04200802,
01008 0x00000000,0x00200802,0x04200000,0x00000800,
01009 0x04000002,0x04000800,0x00000800,0x00200002},
01010 {
01011 0x10001040,0x00001000,0x00040000,0x10041040,
01012 0x10000000,0x10001040,0x00000040,0x10000000,
01013 0x00040040,0x10040000,0x10041040,0x00041000,
01014 0x10041000,0x00041040,0x00001000,0x00000040,
01015 0x10040000,0x10000040,0x10001000,0x00001040,
01016 0x00041000,0x00040040,0x10040040,0x10041000,
01017 0x00001040,0x00000000,0x00000000,0x10040040,
01018 0x10000040,0x10001000,0x00041040,0x00040000,
01019 0x00041040,0x00040000,0x10041000,0x00001000,
01020 0x00000040,0x10040040,0x00001000,0x00041040,
01021 0x10001000,0x00000040,0x10000040,0x10040000,
01022 0x10040040,0x10000000,0x00040000,0x10001040,
01023 0x00000000,0x10041040,0x00040040,0x10000040,
01024 0x10040000,0x10001000,0x10001040,0x00000000,
01025 0x10041040,0x00041000,0x00041000,0x00001040,
01026 0x00001040,0x00040040,0x10000000,0x10041000}
01027 };
01028 
01029 
01030 static INLINE void IPERM(word32* left, word32* right)
01031 {
01032     word32 work;
01033 
01034     *right = rotlFixed(*right, 4U);
01035     work = (*left ^ *right) & 0xf0f0f0f0;
01036     *left ^= work;
01037 
01038     *right = rotrFixed(*right^work, 20U);
01039     work = (*left ^ *right) & 0xffff0000;
01040     *left ^= work;
01041 
01042     *right = rotrFixed(*right^work, 18U);
01043     work = (*left ^ *right) & 0x33333333;
01044     *left ^= work;
01045 
01046     *right = rotrFixed(*right^work, 6U);
01047     work = (*left ^ *right) & 0x00ff00ff;
01048     *left ^= work;
01049 
01050     *right = rotlFixed(*right^work, 9U);
01051     work = (*left ^ *right) & 0xaaaaaaaa;
01052     *left = rotlFixed(*left^work, 1U);
01053     *right ^= work;
01054 }
01055 
01056 
01057 static INLINE void FPERM(word32* left, word32* right)
01058 {
01059     word32 work;
01060 
01061     *right = rotrFixed(*right, 1U);
01062     work = (*left ^ *right) & 0xaaaaaaaa;
01063     *right ^= work;
01064 
01065     *left = rotrFixed(*left^work, 9U);
01066     work = (*left ^ *right) & 0x00ff00ff;
01067     *right ^= work;
01068 
01069     *left = rotlFixed(*left^work, 6U);
01070     work = (*left ^ *right) & 0x33333333;
01071     *right ^= work;
01072 
01073     *left = rotlFixed(*left^work, 18U);
01074     work = (*left ^ *right) & 0xffff0000;
01075     *right ^= work;
01076 
01077     *left = rotlFixed(*left^work, 20U);
01078     work = (*left ^ *right) & 0xf0f0f0f0;
01079     *right ^= work;
01080 
01081     *left = rotrFixed(*left^work, 4U);
01082 }
01083 
01084 
01085 static int DesSetKey(const byte* key, int dir, word32* out)
01086 {
01087 #ifdef CYASSL_SMALL_STACK
01088     byte* buffer = (byte*)XMALLOC(56+56+8, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01089 
01090     if (buffer == NULL)
01091         return MEMORY_E;
01092 #else
01093     byte buffer[56+56+8];
01094 #endif
01095 
01096     {
01097         byte* const  pc1m = buffer;               /* place to modify pc1 into */
01098         byte* const  pcr  = pc1m + 56;            /* place to rotate pc1 into */
01099         byte* const  ks   = pcr  + 56;
01100         register int i, j, l;
01101         int          m;
01102 
01103         for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */
01104             l = pc1[j] - 1;                    /* integer bit location        */
01105             m = l & 07;                        /* find bit                    */
01106             pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */
01107                 bytebit[m])                    /* and which bit of that byte  */
01108                 ? 1 : 0;                       /* and store 1-bit result      */
01109         }
01110 
01111         for (i = 0; i < 16; i++) {            /* key chunk for each iteration */
01112             XMEMSET(ks, 0, 8);                /* Clear key schedule */
01113 
01114             for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */
01115                 pcr[j] =
01116                       pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];
01117 
01118             /* rotate left and right halves independently */
01119             for (j = 0; j < 48; j++) {        /* select bits individually     */
01120                 if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */
01121                     l= j % 6;                 /* mask it in if it's there     */
01122                     ks[j/6] |= bytebit[l] >> 2;
01123                 }
01124             }
01125 
01126             /* Now convert to odd/even interleaved form for use in F */
01127             out[2*i] = ((word32) ks[0] << 24)
01128                      | ((word32) ks[2] << 16)
01129                      | ((word32) ks[4] << 8)
01130                      | ((word32) ks[6]);
01131 
01132             out[2*i + 1] = ((word32) ks[1] << 24)
01133                          | ((word32) ks[3] << 16)
01134                          | ((word32) ks[5] << 8)
01135                          | ((word32) ks[7]);
01136         }
01137 
01138         /* reverse key schedule order */
01139         if (dir == DES_DECRYPTION) {
01140             for (i = 0; i < 16; i += 2) {
01141                 word32 swap = out[i];
01142                 out[i] = out[DES_KS_SIZE - 2 - i];
01143                 out[DES_KS_SIZE - 2 - i] = swap;
01144     
01145                 swap = out[i + 1];
01146                 out[i + 1] = out[DES_KS_SIZE - 1 - i];
01147                 out[DES_KS_SIZE - 1 - i] = swap;
01148             }
01149         }
01150 
01151 #ifdef CYASSL_SMALL_STACK
01152         XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01153 #endif
01154     }
01155 
01156     return 0;
01157 }
01158 
01159 
01160 static INLINE int Reverse(int dir)
01161 {
01162     return !dir;
01163 }
01164 
01165 
01166 int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
01167 {
01168     Des_SetIV(des, iv);
01169 
01170     return DesSetKey(key, dir, des->key);
01171 }
01172 
01173 
01174 int Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
01175 {
01176     int ret;
01177 
01178 #ifdef HAVE_CAVIUM
01179     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
01180         return Des3_CaviumSetKey(des, key, iv);
01181 #endif
01182 
01183     ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);
01184     if (ret != 0)
01185         return ret;
01186 
01187     ret = DesSetKey(key + 8, Reverse(dir), des->key[1]);
01188     if (ret != 0)
01189         return ret;
01190 
01191     ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);
01192     if (ret != 0)
01193         return ret;
01194 
01195     return Des3_SetIV(des, iv);
01196 }
01197 
01198 
01199 static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
01200 {
01201     word32 l = *lIn, r = *rIn, i;
01202 
01203     for (i=0; i<8; i++)
01204     {
01205         word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
01206         l ^= Spbox[6][(work) & 0x3f]
01207           ^  Spbox[4][(work >> 8) & 0x3f]
01208           ^  Spbox[2][(work >> 16) & 0x3f]
01209           ^  Spbox[0][(work >> 24) & 0x3f];
01210         work = r ^ kptr[4*i+1];
01211         l ^= Spbox[7][(work) & 0x3f]
01212           ^  Spbox[5][(work >> 8) & 0x3f]
01213           ^  Spbox[3][(work >> 16) & 0x3f]
01214           ^  Spbox[1][(work >> 24) & 0x3f];
01215 
01216         work = rotrFixed(l, 4U) ^ kptr[4*i+2];
01217         r ^= Spbox[6][(work) & 0x3f]
01218           ^  Spbox[4][(work >> 8) & 0x3f]
01219           ^  Spbox[2][(work >> 16) & 0x3f]
01220           ^  Spbox[0][(work >> 24) & 0x3f];
01221         work = l ^ kptr[4*i+3];
01222         r ^= Spbox[7][(work) & 0x3f]
01223           ^  Spbox[5][(work >> 8) & 0x3f]
01224           ^  Spbox[3][(work >> 16) & 0x3f]
01225           ^  Spbox[1][(work >> 24) & 0x3f];
01226     }
01227 
01228     *lIn = l; *rIn = r;
01229 }
01230 
01231 
01232 static void DesProcessBlock(Des* des, const byte* in, byte* out)
01233 {
01234     word32 l, r;
01235 
01236     XMEMCPY(&l, in, sizeof(l));
01237     XMEMCPY(&r, in + sizeof(l), sizeof(r));
01238     #ifdef LITTLE_ENDIAN_ORDER
01239         l = ByteReverseWord32(l);
01240         r = ByteReverseWord32(r);
01241     #endif
01242     IPERM(&l,&r);
01243     
01244     DesRawProcessBlock(&l, &r, des->key);   
01245 
01246     FPERM(&l,&r);
01247     #ifdef LITTLE_ENDIAN_ORDER
01248         l = ByteReverseWord32(l);
01249         r = ByteReverseWord32(r);
01250     #endif
01251     XMEMCPY(out, &r, sizeof(r));
01252     XMEMCPY(out + sizeof(r), &l, sizeof(l));
01253 }
01254 
01255 
01256 static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
01257 {
01258     word32 l, r;
01259 
01260     XMEMCPY(&l, in, sizeof(l));
01261     XMEMCPY(&r, in + sizeof(l), sizeof(r));
01262     #ifdef LITTLE_ENDIAN_ORDER
01263         l = ByteReverseWord32(l);
01264         r = ByteReverseWord32(r);
01265     #endif
01266     IPERM(&l,&r);
01267     
01268     DesRawProcessBlock(&l, &r, des->key[0]);   
01269     DesRawProcessBlock(&r, &l, des->key[1]);   
01270     DesRawProcessBlock(&l, &r, des->key[2]);   
01271 
01272     FPERM(&l,&r);
01273     #ifdef LITTLE_ENDIAN_ORDER
01274         l = ByteReverseWord32(l);
01275         r = ByteReverseWord32(r);
01276     #endif
01277     XMEMCPY(out, &r, sizeof(r));
01278     XMEMCPY(out + sizeof(r), &l, sizeof(l));
01279 }
01280 
01281 
01282 int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
01283 {
01284     word32 blocks = sz / DES_BLOCK_SIZE;
01285 
01286     while (blocks--) {
01287         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
01288         DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
01289         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
01290 
01291         out += DES_BLOCK_SIZE;
01292         in  += DES_BLOCK_SIZE; 
01293     }
01294     return 0;
01295 }
01296 
01297 
01298 int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
01299 {
01300     word32 blocks = sz / DES_BLOCK_SIZE;
01301     byte   hold[DES_BLOCK_SIZE];
01302 
01303     while (blocks--) {
01304         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
01305         DesProcessBlock(des, (byte*)des->tmp, out);
01306         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
01307 
01308         XMEMCPY(hold, des->reg, DES_BLOCK_SIZE);
01309         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
01310         XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE);
01311 
01312         out += DES_BLOCK_SIZE;
01313         in  += DES_BLOCK_SIZE; 
01314     }
01315     return 0;
01316 }
01317 
01318 
01319 int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
01320 {
01321     word32 blocks;
01322 
01323 #ifdef HAVE_CAVIUM
01324     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
01325         return Des3_CaviumCbcEncrypt(des, out, in, sz);
01326 #endif
01327 
01328     blocks = sz / DES_BLOCK_SIZE;
01329     while (blocks--) {
01330         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
01331         Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
01332         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
01333 
01334         out += DES_BLOCK_SIZE;
01335         in  += DES_BLOCK_SIZE; 
01336     }
01337     return 0;
01338 }
01339 
01340 
01341 int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
01342 {
01343     word32 blocks;
01344 
01345 #ifdef HAVE_CAVIUM
01346     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
01347         return Des3_CaviumCbcDecrypt(des, out, in, sz);
01348 #endif
01349 
01350     blocks = sz / DES_BLOCK_SIZE;
01351     while (blocks--) {
01352         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
01353         Des3ProcessBlock(des, (byte*)des->tmp, out);
01354         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
01355         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
01356 
01357         out += DES_BLOCK_SIZE;
01358         in  += DES_BLOCK_SIZE; 
01359     }
01360     return 0;
01361 }
01362 
01363 #ifdef CYASSL_DES_ECB
01364 
01365 /* One block, compatibility only */
01366 int Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
01367 {
01368     word32 blocks = sz / DES_BLOCK_SIZE;
01369 
01370     while (blocks--) {
01371         DesProcessBlock(des, in, out);
01372 
01373         out += DES_BLOCK_SIZE;
01374         in  += DES_BLOCK_SIZE; 
01375     }
01376     return 0;
01377 }
01378 
01379 #endif /* CYASSL_DES_ECB */
01380 
01381 #endif /* STM32F2_CRYPTO */
01382 
01383 void Des_SetIV(Des* des, const byte* iv)
01384 {
01385     if (des && iv)
01386         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
01387     else if (des)
01388         XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
01389 }
01390 
01391 
01392 int Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,
01393                                                 const byte* key, const byte* iv)
01394 {
01395     int ret  = 0;
01396 #ifdef CYASSL_SMALL_STACK
01397     Des* des = NULL;
01398 #else
01399     Des  des[1];
01400 #endif
01401 
01402 #ifdef CYASSL_SMALL_STACK
01403     des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER);
01404     if (des == NULL)
01405         return MEMORY_E;
01406 #endif
01407 
01408     ret = Des_SetKey(des, key, iv, DES_DECRYPTION);
01409     if (ret == 0)
01410         ret = Des_CbcDecrypt(des, out, in, sz); 
01411 
01412 #ifdef CYASSL_SMALL_STACK
01413     XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01414 #endif
01415 
01416     return ret;
01417 }
01418 
01419 
01420 int Des3_SetIV(Des3* des, const byte* iv)
01421 {
01422     if (des && iv)
01423         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
01424     else if (des)
01425         XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
01426 
01427     return 0;
01428 }
01429 
01430 
01431 int Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz,
01432                                                 const byte* key, const byte* iv)
01433 {
01434     int ret    = 0;
01435 #ifdef CYASSL_SMALL_STACK
01436     Des3* des3 = NULL;
01437 #else
01438     Des3  des3[1];
01439 #endif
01440 
01441 #ifdef CYASSL_SMALL_STACK
01442     des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER);
01443     if (des3 == NULL)
01444         return MEMORY_E;
01445 #endif
01446 
01447     ret = Des3_SetKey(des3, key, iv, DES_DECRYPTION);
01448     if (ret == 0)
01449         ret = Des3_CbcDecrypt(des3, out, in, sz); 
01450 
01451 #ifdef CYASSL_SMALL_STACK
01452     XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01453 #endif
01454 
01455     return ret;
01456 }
01457 
01458 
01459 #ifdef HAVE_CAVIUM
01460 
01461 #include "cavium_common.h"
01462 
01463 /* Initiliaze Des3 for use with Nitrox device */
01464 int Des3_InitCavium(Des3* des3, int devId)
01465 {
01466     if (des3 == NULL)
01467         return -1;
01468 
01469     if (CspAllocContext(CONTEXT_SSL, &des3->contextHandle, devId) != 0)
01470         return -1;
01471 
01472     des3->devId = devId;
01473     des3->magic = CYASSL_3DES_CAVIUM_MAGIC;
01474    
01475     return 0;
01476 }
01477 
01478 
01479 /* Free Des3 from use with Nitrox device */
01480 void Des3_FreeCavium(Des3* des3)
01481 {
01482     if (des3 == NULL)
01483         return;
01484 
01485     if (des3->magic != CYASSL_3DES_CAVIUM_MAGIC)
01486         return;
01487 
01488     CspFreeContext(CONTEXT_SSL, des3->contextHandle, des3->devId);
01489     des3->magic = 0;
01490 }
01491 
01492 
01493 static int Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv)
01494 {
01495     if (des3 == NULL)
01496         return -1;
01497 
01498     /* key[0] holds key, iv in reg */
01499     XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3);
01500 
01501     return Des3_SetIV(des3, iv);
01502 }
01503 
01504 
01505 static int Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
01506                                   word32 length)
01507 {
01508     cyassl_word offset = 0;
01509     word32 requestId;
01510    
01511     while (length > CYASSL_MAX_16BIT) {
01512         word16 slen = (word16)CYASSL_MAX_16BIT;
01513         if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01514                            CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
01515                            out + offset, (byte*)des3->reg, (byte*)des3->key[0],
01516                            &requestId, des3->devId) != 0) {
01517             CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt");
01518             return -1;
01519         }
01520         length -= CYASSL_MAX_16BIT;
01521         offset += CYASSL_MAX_16BIT;
01522         XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
01523     }
01524     if (length) {
01525         word16 slen = (word16)length;
01526 
01527         if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01528                            CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
01529                            out + offset, (byte*)des3->reg, (byte*)des3->key[0],
01530                            &requestId, des3->devId) != 0) {
01531             CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt");
01532             return -1;
01533         }
01534         XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
01535     }
01536     return 0;
01537 }
01538 
01539 static int Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
01540                                  word32 length)
01541 {
01542     word32 requestId;
01543     cyassl_word offset = 0;
01544 
01545     while (length > CYASSL_MAX_16BIT) {
01546         word16 slen = (word16)CYASSL_MAX_16BIT;
01547         XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
01548         if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01549                            CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
01550                            (byte*)des3->reg, (byte*)des3->key[0], &requestId,
01551                            des3->devId) != 0) {
01552             CYASSL_MSG("Bad Cavium 3Des Decrypt");
01553             return -1;
01554         }
01555         length -= CYASSL_MAX_16BIT;
01556         offset += CYASSL_MAX_16BIT;
01557         XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
01558     }
01559     if (length) {
01560         word16 slen = (word16)length;
01561         XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE);
01562         if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01563                            CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
01564                            (byte*)des3->reg, (byte*)des3->key[0], &requestId,
01565                            des3->devId) != 0) {
01566             CYASSL_MSG("Bad Cavium 3Des Decrypt");
01567             return -1;
01568         }
01569         XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
01570     }
01571     return 0;
01572 }
01573 
01574 #endif /* HAVE_CAVIUM */
01575 
01576 #endif /* NO_DES3 */