Xuyi Wang / wolfcrypt

Dependents:   OS

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