wolf SSL / CyaSSL-2.9.4

Dependents:  

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-2013 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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     byte* buffer = (byte*)XMALLOC(56+56+8, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00992 
00993     if (!buffer) {
00994         return MEMORY_E;
00995     }
00996     else {
00997         byte* const  pc1m = buffer;               /* place to modify pc1 into */
00998         byte* const  pcr  = pc1m + 56;            /* place to rotate pc1 into */
00999         byte* const  ks   = pcr  + 56;
01000         register int i, j, l;
01001         int          m;
01002 
01003         for (j = 0; j < 56; j++) {             /* convert pc1 to bits of key  */
01004             l = pc1[j] - 1;                    /* integer bit location        */
01005             m = l & 07;                        /* find bit                    */
01006             pc1m[j] = (key[l >> 3] &           /* find which key byte l is in */
01007                 bytebit[m])                    /* and which bit of that byte  */
01008                 ? 1 : 0;                       /* and store 1-bit result      */
01009         }
01010 
01011         for (i = 0; i < 16; i++) {            /* key chunk for each iteration */
01012             XMEMSET(ks, 0, 8);                /* Clear key schedule */
01013 
01014             for (j = 0; j < 56; j++)          /* rotate pc1 the right amount  */
01015                 pcr[j] =
01016                       pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28];
01017 
01018             /* rotate left and right halves independently */
01019             for (j = 0; j < 48; j++) {        /* select bits individually     */
01020                 if (pcr[pc2[j] - 1]) {        /* check bit that goes to ks[j] */
01021                     l= j % 6;                 /* mask it in if it's there     */
01022                     ks[j/6] |= bytebit[l] >> 2;
01023                 }
01024             }
01025 
01026             /* Now convert to odd/even interleaved form for use in F */
01027             out[2*i] = ((word32) ks[0] << 24)
01028                      | ((word32) ks[2] << 16)
01029                      | ((word32) ks[4] << 8)
01030                      | ((word32) ks[6]);
01031 
01032             out[2*i + 1] = ((word32) ks[1] << 24)
01033                          | ((word32) ks[3] << 16)
01034                          | ((word32) ks[5] << 8)
01035                          | ((word32) ks[7]);
01036         }
01037 
01038         /* reverse key schedule order */
01039         if (dir == DES_DECRYPTION) {
01040             for (i = 0; i < 16; i += 2) {
01041                 word32 swap = out[i];
01042                 out[i] = out[DES_KS_SIZE - 2 - i];
01043                 out[DES_KS_SIZE - 2 - i] = swap;
01044     
01045                 swap = out[i + 1];
01046                 out[i + 1] = out[DES_KS_SIZE - 1 - i];
01047                 out[DES_KS_SIZE - 1 - i] = swap;
01048             }
01049         }
01050 
01051         XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01052     }
01053 
01054     return 0;
01055 }
01056 
01057 
01058 static INLINE int Reverse(int dir)
01059 {
01060     return !dir;
01061 }
01062 
01063 
01064 int Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
01065 {
01066     Des_SetIV(des, iv);
01067 
01068     return DesSetKey(key, dir, des->key);
01069 }
01070 
01071 
01072 int Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
01073 {
01074     int ret;
01075 
01076 #ifdef HAVE_CAVIUM
01077     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
01078         return Des3_CaviumSetKey(des, key, iv);
01079 #endif
01080 
01081     ret = DesSetKey(key + (dir == DES_ENCRYPTION ? 0:16), dir, des->key[0]);
01082     if (ret != 0)
01083         return ret;
01084 
01085     ret = DesSetKey(key + 8, Reverse(dir), des->key[1]);
01086     if (ret != 0)
01087         return ret;
01088 
01089     ret = DesSetKey(key + (dir == DES_DECRYPTION ? 0:16), dir, des->key[2]);
01090     if (ret != 0)
01091         return ret;
01092 
01093     return Des3_SetIV(des, iv);
01094 }
01095 
01096 
01097 static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
01098 {
01099     word32 l = *lIn, r = *rIn, i;
01100 
01101     for (i=0; i<8; i++)
01102     {
01103         word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
01104         l ^= Spbox[6][(work) & 0x3f]
01105           ^  Spbox[4][(work >> 8) & 0x3f]
01106           ^  Spbox[2][(work >> 16) & 0x3f]
01107           ^  Spbox[0][(work >> 24) & 0x3f];
01108         work = r ^ kptr[4*i+1];
01109         l ^= Spbox[7][(work) & 0x3f]
01110           ^  Spbox[5][(work >> 8) & 0x3f]
01111           ^  Spbox[3][(work >> 16) & 0x3f]
01112           ^  Spbox[1][(work >> 24) & 0x3f];
01113 
01114         work = rotrFixed(l, 4U) ^ kptr[4*i+2];
01115         r ^= Spbox[6][(work) & 0x3f]
01116           ^  Spbox[4][(work >> 8) & 0x3f]
01117           ^  Spbox[2][(work >> 16) & 0x3f]
01118           ^  Spbox[0][(work >> 24) & 0x3f];
01119         work = l ^ kptr[4*i+3];
01120         r ^= Spbox[7][(work) & 0x3f]
01121           ^  Spbox[5][(work >> 8) & 0x3f]
01122           ^  Spbox[3][(work >> 16) & 0x3f]
01123           ^  Spbox[1][(work >> 24) & 0x3f];
01124     }
01125 
01126     *lIn = l; *rIn = r;
01127 }
01128 
01129 
01130 static void DesProcessBlock(Des* des, const byte* in, byte* out)
01131 {
01132     word32 l, r;
01133 
01134     XMEMCPY(&l, in, sizeof(l));
01135     XMEMCPY(&r, in + sizeof(l), sizeof(r));
01136     #ifdef LITTLE_ENDIAN_ORDER
01137         l = ByteReverseWord32(l);
01138         r = ByteReverseWord32(r);
01139     #endif
01140     IPERM(&l,&r);
01141     
01142     DesRawProcessBlock(&l, &r, des->key);   
01143 
01144     FPERM(&l,&r);
01145     #ifdef LITTLE_ENDIAN_ORDER
01146         l = ByteReverseWord32(l);
01147         r = ByteReverseWord32(r);
01148     #endif
01149     XMEMCPY(out, &r, sizeof(r));
01150     XMEMCPY(out + sizeof(r), &l, sizeof(l));
01151 }
01152 
01153 
01154 static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
01155 {
01156     word32 l, r;
01157 
01158     XMEMCPY(&l, in, sizeof(l));
01159     XMEMCPY(&r, in + sizeof(l), sizeof(r));
01160     #ifdef LITTLE_ENDIAN_ORDER
01161         l = ByteReverseWord32(l);
01162         r = ByteReverseWord32(r);
01163     #endif
01164     IPERM(&l,&r);
01165     
01166     DesRawProcessBlock(&l, &r, des->key[0]);   
01167     DesRawProcessBlock(&r, &l, des->key[1]);   
01168     DesRawProcessBlock(&l, &r, des->key[2]);   
01169 
01170     FPERM(&l,&r);
01171     #ifdef LITTLE_ENDIAN_ORDER
01172         l = ByteReverseWord32(l);
01173         r = ByteReverseWord32(r);
01174     #endif
01175     XMEMCPY(out, &r, sizeof(r));
01176     XMEMCPY(out + sizeof(r), &l, sizeof(l));
01177 }
01178 
01179 
01180 void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
01181 {
01182     word32 blocks = sz / DES_BLOCK_SIZE;
01183 
01184     while (blocks--) {
01185         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
01186         DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
01187         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
01188 
01189         out += DES_BLOCK_SIZE;
01190         in  += DES_BLOCK_SIZE; 
01191     }
01192 }
01193 
01194 
01195 void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
01196 {
01197     word32 blocks = sz / DES_BLOCK_SIZE;
01198     byte   hold[DES_BLOCK_SIZE];
01199 
01200     while (blocks--) {
01201         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
01202         DesProcessBlock(des, (byte*)des->tmp, out);
01203         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
01204 
01205         XMEMCPY(hold, des->reg, DES_BLOCK_SIZE);
01206         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
01207         XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE);
01208 
01209         out += DES_BLOCK_SIZE;
01210         in  += DES_BLOCK_SIZE; 
01211     }
01212 }
01213 
01214 
01215 int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
01216 {
01217     word32 blocks;
01218 
01219 #ifdef HAVE_CAVIUM
01220     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
01221         return Des3_CaviumCbcEncrypt(des, out, in, sz);
01222 #endif
01223 
01224     blocks = sz / DES_BLOCK_SIZE;
01225     while (blocks--) {
01226         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
01227         Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
01228         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
01229 
01230         out += DES_BLOCK_SIZE;
01231         in  += DES_BLOCK_SIZE; 
01232     }
01233     return 0;
01234 }
01235 
01236 
01237 int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
01238 {
01239     word32 blocks;
01240 
01241 #ifdef HAVE_CAVIUM
01242     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
01243         return Des3_CaviumCbcDecrypt(des, out, in, sz);
01244 #endif
01245 
01246     blocks = sz / DES_BLOCK_SIZE;
01247     while (blocks--) {
01248         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
01249         Des3ProcessBlock(des, (byte*)des->tmp, out);
01250         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
01251         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
01252 
01253         out += DES_BLOCK_SIZE;
01254         in  += DES_BLOCK_SIZE; 
01255     }
01256     return 0;
01257 }
01258 
01259 #ifdef CYASSL_DES_ECB
01260 
01261 /* One block, compatibility only */
01262 void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
01263 {
01264     word32 blocks = sz / DES_BLOCK_SIZE;
01265 
01266     while (blocks--) {
01267         DesProcessBlock(des, in, out);
01268 
01269         out += DES_BLOCK_SIZE;
01270         in  += DES_BLOCK_SIZE; 
01271     }
01272 }
01273 
01274 #endif /* CYASSL_DES_ECB */
01275 
01276 #endif /* STM32F2_CRYPTO */
01277 
01278 void Des_SetIV(Des* des, const byte* iv)
01279 {
01280     if (des && iv)
01281         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
01282     else if (des)
01283         XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
01284 }
01285 
01286 
01287 int Des3_SetIV(Des3* des, const byte* iv)
01288 {
01289     if (des && iv)
01290         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
01291     else if (des)
01292         XMEMSET(des->reg,  0, DES_BLOCK_SIZE);
01293 
01294     return 0;
01295 }
01296 
01297 
01298 #ifdef HAVE_CAVIUM
01299 
01300 #include <cyassl/ctaocrypt/logging.h>
01301 #include "cavium_common.h"
01302 
01303 /* Initiliaze Des3 for use with Nitrox device */
01304 int Des3_InitCavium(Des3* des3, int devId)
01305 {
01306     if (des3 == NULL)
01307         return -1;
01308 
01309     if (CspAllocContext(CONTEXT_SSL, &des3->contextHandle, devId) != 0)
01310         return -1;
01311 
01312     des3->devId = devId;
01313     des3->magic = CYASSL_3DES_CAVIUM_MAGIC;
01314    
01315     return 0;
01316 }
01317 
01318 
01319 /* Free Des3 from use with Nitrox device */
01320 void Des3_FreeCavium(Des3* des3)
01321 {
01322     if (des3 == NULL)
01323         return;
01324 
01325     if (des3->magic != CYASSL_3DES_CAVIUM_MAGIC)
01326         return;
01327 
01328     CspFreeContext(CONTEXT_SSL, des3->contextHandle, des3->devId);
01329     des3->magic = 0;
01330 }
01331 
01332 
01333 static int Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv)
01334 {
01335     if (des3 == NULL)
01336         return -1;
01337 
01338     /* key[0] holds key, iv in reg */
01339     XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3);
01340 
01341     return Des3_SetIV(des3, iv);
01342 }
01343 
01344 
01345 static int Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
01346                                   word32 length)
01347 {
01348     word   offset = 0;
01349     word32 requestId;
01350    
01351     while (length > CYASSL_MAX_16BIT) {
01352         word16 slen = (word16)CYASSL_MAX_16BIT;
01353         if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01354                            CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
01355                            out + offset, (byte*)des3->reg, (byte*)des3->key[0],
01356                            &requestId, des3->devId) != 0) {
01357             CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt");
01358             return -1;
01359         }
01360         length -= CYASSL_MAX_16BIT;
01361         offset += CYASSL_MAX_16BIT;
01362         XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
01363     }
01364     if (length) {
01365         word16 slen = (word16)length;
01366 
01367         if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01368                            CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
01369                            out + offset, (byte*)des3->reg, (byte*)des3->key[0],
01370                            &requestId, des3->devId) != 0) {
01371             CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt");
01372             return -1;
01373         }
01374         XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
01375     }
01376     return 0;
01377 }
01378 
01379 static int Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
01380                                  word32 length)
01381 {
01382     word32 requestId;
01383     word   offset = 0;
01384 
01385     while (length > CYASSL_MAX_16BIT) {
01386         word16 slen = (word16)CYASSL_MAX_16BIT;
01387         XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
01388         if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01389                            CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
01390                            (byte*)des3->reg, (byte*)des3->key[0], &requestId,
01391                            des3->devId) != 0) {
01392             CYASSL_MSG("Bad Cavium 3Des Decrypt");
01393             return -1;
01394         }
01395         length -= CYASSL_MAX_16BIT;
01396         offset += CYASSL_MAX_16BIT;
01397         XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
01398     }
01399     if (length) {
01400         word16 slen = (word16)length;
01401         XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE);
01402         if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
01403                            CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
01404                            (byte*)des3->reg, (byte*)des3->key[0], &requestId,
01405                            des3->devId) != 0) {
01406             CYASSL_MSG("Bad Cavium 3Des Decrypt");
01407             return -1;
01408         }
01409         XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
01410     }
01411     return 0;
01412 }
01413 
01414 #endif /* HAVE_CAVIUM */
01415 
01416 #endif /* NO_DES3 */