wolf SSL / CyaSSL

Dependents:   HTTPClient-SSL HTTPClient HTTPClient-SSL http_access ... more

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