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