This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers des3.c Source File

des3.c

00001 /* des3.c
00002  *
00003  * Copyright (C) 2006-2013 wolfSSL Inc.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 #ifdef HAVE_CONFIG_H
00023     #include <config.h>
00024 #endif
00025 
00026 #include <cyassl/ctaocrypt/settings.h>
00027 
00028 #ifndef NO_DES3
00029 
00030 #include <cyassl/ctaocrypt/des3.h>
00031 
00032 #ifdef NO_INLINE
00033     #include <cyassl/ctaocrypt/misc.h>
00034 #else
00035     #include <ctaocrypt/src/misc.c>
00036 #endif
00037 
00038 
00039 #ifdef HAVE_CAVIUM
00040     static void Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv);
00041     static void Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
00042                                       word32 length);
00043     static void Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
00044                                       word32 length);
00045 #endif
00046 
00047 #ifdef STM32F2_CRYPTO
00048     /*
00049      * STM32F2 hardware DES/3DES support through the STM32F2 standard
00050      * peripheral library. Documentation located in STM32F2xx Standard
00051      * Peripheral Library document (See note in README).
00052      */
00053     #include "stm32f2xx.h"
00054         #include "stm32f2xx_cryp.h"
00055 
00056     void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
00057     {
00058         word32 *dkey = des->key;
00059 
00060         XMEMCPY(dkey, key, 8);
00061         ByteReverseWords(dkey, dkey, 8);
00062 
00063         Des_SetIV(des, iv);
00064     }
00065 
00066     void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
00067     {
00068         word32 *dkey1 = des->key[0];
00069         word32 *dkey2 = des->key[1];
00070         word32 *dkey3 = des->key[2];
00071 
00072         XMEMCPY(dkey1, key, 8);         /* set key 1 */
00073         XMEMCPY(dkey2, key + 8, 8);     /* set key 2 */
00074         XMEMCPY(dkey3, key + 16, 8);    /* set key 3 */
00075 
00076         ByteReverseWords(dkey1, dkey1, 8);
00077         ByteReverseWords(dkey2, dkey2, 8);
00078         ByteReverseWords(dkey3, dkey3, 8);
00079 
00080         Des3_SetIV(des, iv);
00081     }
00082 
00083     void DesCrypt(Des* des, byte* out, const byte* in, word32 sz,
00084                   int dir, int mode)
00085     {
00086         word32 *dkey, *iv;
00087         CRYP_InitTypeDef DES_CRYP_InitStructure;
00088         CRYP_KeyInitTypeDef DES_CRYP_KeyInitStructure;
00089         CRYP_IVInitTypeDef DES_CRYP_IVInitStructure;
00090 
00091         dkey = des->key;
00092         iv = des->reg;
00093 
00094         /* crypto structure initialization */
00095         CRYP_KeyStructInit(&DES_CRYP_KeyInitStructure);
00096         CRYP_StructInit(&DES_CRYP_InitStructure);
00097         CRYP_IVStructInit(&DES_CRYP_IVInitStructure);
00098 
00099         /* reset registers to their default values */
00100         CRYP_DeInit();
00101 
00102         /* set direction, mode, and datatype */
00103         if (dir == DES_ENCRYPTION) {
00104             DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
00105         } else { /* DES_DECRYPTION */
00106             DES_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
00107         }
00108 
00109         if (mode == DES_CBC) {
00110             DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_CBC;
00111         } else { /* DES_ECB */
00112             DES_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_DES_ECB;
00113         }
00114 
00115         DES_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
00116         CRYP_Init(&DES_CRYP_InitStructure);
00117 
00118         /* load key into correct registers */
00119         DES_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey[0];
00120         DES_CRYP_KeyInitStructure.CRYP_Key1Right = dkey[1];
00121         CRYP_KeyInit(&DES_CRYP_KeyInitStructure);
00122 
00123         /* set iv */
00124         ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
00125         DES_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
00126         DES_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
00127         CRYP_IVInit(&DES_CRYP_IVInitStructure);
00128 
00129         /* enable crypto processor */
00130         CRYP_Cmd(ENABLE);
00131 
00132         while (sz > 0)
00133         {
00134             /* flush IN/OUT FIFOs */
00135             CRYP_FIFOFlush();
00136 
00137             /* if input and output same will overwrite input iv */
00138             XMEMCPY(des->tmp, in + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00139 
00140             CRYP_DataIn(*(uint32_t*)&in[0]);
00141             CRYP_DataIn(*(uint32_t*)&in[4]);
00142 
00143             /* wait until the complete message has been processed */
00144             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00145 
00146             *(uint32_t*)&out[0]  = CRYP_DataOut();
00147             *(uint32_t*)&out[4]  = CRYP_DataOut();
00148 
00149             /* store iv for next call */
00150             XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
00151 
00152             sz  -= DES_BLOCK_SIZE;
00153             in  += DES_BLOCK_SIZE;
00154             out += DES_BLOCK_SIZE;
00155         }
00156 
00157         /* disable crypto processor */
00158         CRYP_Cmd(DISABLE);
00159     }
00160 
00161     void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00162     {
00163         DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_CBC);
00164     }
00165 
00166     void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
00167     {
00168         DesCrypt(des, out, in, sz, DES_DECRYPTION, DES_CBC);
00169     }
00170 
00171     void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00172     {
00173         DesCrypt(des, out, in, sz, DES_ENCRYPTION, DES_ECB);
00174     }
00175 
00176     void Des3Crypt(Des3* des, byte* out, const byte* in, word32 sz,
00177                    int dir)
00178     {
00179         word32 *dkey1, *dkey2, *dkey3, *iv;
00180         CRYP_InitTypeDef DES3_CRYP_InitStructure;
00181         CRYP_KeyInitTypeDef DES3_CRYP_KeyInitStructure;
00182         CRYP_IVInitTypeDef DES3_CRYP_IVInitStructure;
00183 
00184         dkey1 = des->key[0];
00185         dkey2 = des->key[1];
00186         dkey3 = des->key[2];
00187         iv = des->reg;
00188 
00189         /* crypto structure initialization */
00190         CRYP_KeyStructInit(&DES3_CRYP_KeyInitStructure);
00191         CRYP_StructInit(&DES3_CRYP_InitStructure);
00192         CRYP_IVStructInit(&DES3_CRYP_IVInitStructure);
00193 
00194         /* reset registers to their default values */
00195         CRYP_DeInit();
00196 
00197         /* set direction, mode, and datatype */
00198         if (dir == DES_ENCRYPTION) {
00199             DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Encrypt;
00200         } else {
00201             DES3_CRYP_InitStructure.CRYP_AlgoDir  = CRYP_AlgoDir_Decrypt;
00202         }
00203 
00204         DES3_CRYP_InitStructure.CRYP_AlgoMode = CRYP_AlgoMode_TDES_CBC;
00205         DES3_CRYP_InitStructure.CRYP_DataType = CRYP_DataType_8b;
00206         CRYP_Init(&DES3_CRYP_InitStructure);
00207 
00208         /* load key into correct registers */
00209         DES3_CRYP_KeyInitStructure.CRYP_Key1Left  = dkey1[0];
00210         DES3_CRYP_KeyInitStructure.CRYP_Key1Right = dkey1[1];
00211         DES3_CRYP_KeyInitStructure.CRYP_Key2Left  = dkey2[0];
00212         DES3_CRYP_KeyInitStructure.CRYP_Key2Right = dkey2[1];
00213         DES3_CRYP_KeyInitStructure.CRYP_Key3Left  = dkey3[0];
00214         DES3_CRYP_KeyInitStructure.CRYP_Key3Right = dkey3[1];
00215         CRYP_KeyInit(&DES3_CRYP_KeyInitStructure);
00216 
00217         /* set iv */
00218         ByteReverseWords(iv, iv, DES_BLOCK_SIZE);
00219         DES3_CRYP_IVInitStructure.CRYP_IV0Left  = iv[0];
00220         DES3_CRYP_IVInitStructure.CRYP_IV0Right = iv[1];
00221         CRYP_IVInit(&DES3_CRYP_IVInitStructure);
00222 
00223         /* enable crypto processor */
00224         CRYP_Cmd(ENABLE);
00225 
00226         while (sz > 0)
00227         {
00228             /* flush IN/OUT FIFOs */
00229             CRYP_FIFOFlush();
00230 
00231             CRYP_DataIn(*(uint32_t*)&in[0]);
00232             CRYP_DataIn(*(uint32_t*)&in[4]);
00233 
00234             /* wait until the complete message has been processed */
00235             while(CRYP_GetFlagStatus(CRYP_FLAG_BUSY) != RESET) {}
00236 
00237             *(uint32_t*)&out[0]  = CRYP_DataOut();
00238             *(uint32_t*)&out[4]  = CRYP_DataOut();
00239 
00240             /* store iv for next call */
00241             XMEMCPY(des->reg, out + sz - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00242 
00243             sz  -= DES_BLOCK_SIZE;
00244             in  += DES_BLOCK_SIZE;
00245             out += DES_BLOCK_SIZE;
00246         }
00247 
00248         /* disable crypto processor */
00249         CRYP_Cmd(DISABLE);
00250 
00251     }
00252 
00253     void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
00254     {
00255         Des3Crypt(des, out, in, sz, DES_ENCRYPTION);
00256     }
00257 
00258     void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
00259     {
00260         Des3Crypt(des, out, in, sz, DES_DECRYPTION);
00261     }
00262 
00263 #else /* CTaoCrypt software implementation */
00264 
00265 /* permuted choice table (key) */
00266 static const byte pc1[] = {
00267        57, 49, 41, 33, 25, 17,  9,
00268         1, 58, 50, 42, 34, 26, 18,
00269        10,  2, 59, 51, 43, 35, 27,
00270        19, 11,  3, 60, 52, 44, 36,
00271 
00272        63, 55, 47, 39, 31, 23, 15,
00273         7, 62, 54, 46, 38, 30, 22,
00274        14,  6, 61, 53, 45, 37, 29,
00275        21, 13,  5, 28, 20, 12,  4
00276 };
00277 
00278 /* number left rotations of pc1 */
00279 static const byte totrot[] = {
00280        1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
00281 };
00282 
00283 /* permuted choice key (table) */
00284 static const byte pc2[] = {
00285        14, 17, 11, 24,  1,  5,
00286         3, 28, 15,  6, 21, 10,
00287        23, 19, 12,  4, 26,  8,
00288        16,  7, 27, 20, 13,  2,
00289        41, 52, 31, 37, 47, 55,
00290        30, 40, 51, 45, 33, 48,
00291        44, 49, 39, 56, 34, 53,
00292        46, 42, 50, 36, 29, 32
00293 };
00294 
00295 /* End of DES-defined tables */
00296 
00297 /* bit 0 is left-most in byte */
00298 static const int bytebit[] = {
00299        0200,0100,040,020,010,04,02,01
00300 };
00301 
00302 const word32 Spbox[8][64] = {
00303 {
00304 0x01010400,0x00000000,0x00010000,0x01010404,
00305 0x01010004,0x00010404,0x00000004,0x00010000,
00306 0x00000400,0x01010400,0x01010404,0x00000400,
00307 0x01000404,0x01010004,0x01000000,0x00000004,
00308 0x00000404,0x01000400,0x01000400,0x00010400,
00309 0x00010400,0x01010000,0x01010000,0x01000404,
00310 0x00010004,0x01000004,0x01000004,0x00010004,
00311 0x00000000,0x00000404,0x00010404,0x01000000,
00312 0x00010000,0x01010404,0x00000004,0x01010000,
00313 0x01010400,0x01000000,0x01000000,0x00000400,
00314 0x01010004,0x00010000,0x00010400,0x01000004,
00315 0x00000400,0x00000004,0x01000404,0x00010404,
00316 0x01010404,0x00010004,0x01010000,0x01000404,
00317 0x01000004,0x00000404,0x00010404,0x01010400,
00318 0x00000404,0x01000400,0x01000400,0x00000000,
00319 0x00010004,0x00010400,0x00000000,0x01010004},
00320 {
00321 0x80108020,0x80008000,0x00008000,0x00108020,
00322 0x00100000,0x00000020,0x80100020,0x80008020,
00323 0x80000020,0x80108020,0x80108000,0x80000000,
00324 0x80008000,0x00100000,0x00000020,0x80100020,
00325 0x00108000,0x00100020,0x80008020,0x00000000,
00326 0x80000000,0x00008000,0x00108020,0x80100000,
00327 0x00100020,0x80000020,0x00000000,0x00108000,
00328 0x00008020,0x80108000,0x80100000,0x00008020,
00329 0x00000000,0x00108020,0x80100020,0x00100000,
00330 0x80008020,0x80100000,0x80108000,0x00008000,
00331 0x80100000,0x80008000,0x00000020,0x80108020,
00332 0x00108020,0x00000020,0x00008000,0x80000000,
00333 0x00008020,0x80108000,0x00100000,0x80000020,
00334 0x00100020,0x80008020,0x80000020,0x00100020,
00335 0x00108000,0x00000000,0x80008000,0x00008020,
00336 0x80000000,0x80100020,0x80108020,0x00108000},
00337 {
00338 0x00000208,0x08020200,0x00000000,0x08020008,
00339 0x08000200,0x00000000,0x00020208,0x08000200,
00340 0x00020008,0x08000008,0x08000008,0x00020000,
00341 0x08020208,0x00020008,0x08020000,0x00000208,
00342 0x08000000,0x00000008,0x08020200,0x00000200,
00343 0x00020200,0x08020000,0x08020008,0x00020208,
00344 0x08000208,0x00020200,0x00020000,0x08000208,
00345 0x00000008,0x08020208,0x00000200,0x08000000,
00346 0x08020200,0x08000000,0x00020008,0x00000208,
00347 0x00020000,0x08020200,0x08000200,0x00000000,
00348 0x00000200,0x00020008,0x08020208,0x08000200,
00349 0x08000008,0x00000200,0x00000000,0x08020008,
00350 0x08000208,0x00020000,0x08000000,0x08020208,
00351 0x00000008,0x00020208,0x00020200,0x08000008,
00352 0x08020000,0x08000208,0x00000208,0x08020000,
00353 0x00020208,0x00000008,0x08020008,0x00020200},
00354 {
00355 0x00802001,0x00002081,0x00002081,0x00000080,
00356 0x00802080,0x00800081,0x00800001,0x00002001,
00357 0x00000000,0x00802000,0x00802000,0x00802081,
00358 0x00000081,0x00000000,0x00800080,0x00800001,
00359 0x00000001,0x00002000,0x00800000,0x00802001,
00360 0x00000080,0x00800000,0x00002001,0x00002080,
00361 0x00800081,0x00000001,0x00002080,0x00800080,
00362 0x00002000,0x00802080,0x00802081,0x00000081,
00363 0x00800080,0x00800001,0x00802000,0x00802081,
00364 0x00000081,0x00000000,0x00000000,0x00802000,
00365 0x00002080,0x00800080,0x00800081,0x00000001,
00366 0x00802001,0x00002081,0x00002081,0x00000080,
00367 0x00802081,0x00000081,0x00000001,0x00002000,
00368 0x00800001,0x00002001,0x00802080,0x00800081,
00369 0x00002001,0x00002080,0x00800000,0x00802001,
00370 0x00000080,0x00800000,0x00002000,0x00802080},
00371 {
00372 0x00000100,0x02080100,0x02080000,0x42000100,
00373 0x00080000,0x00000100,0x40000000,0x02080000,
00374 0x40080100,0x00080000,0x02000100,0x40080100,
00375 0x42000100,0x42080000,0x00080100,0x40000000,
00376 0x02000000,0x40080000,0x40080000,0x00000000,
00377 0x40000100,0x42080100,0x42080100,0x02000100,
00378 0x42080000,0x40000100,0x00000000,0x42000000,
00379 0x02080100,0x02000000,0x42000000,0x00080100,
00380 0x00080000,0x42000100,0x00000100,0x02000000,
00381 0x40000000,0x02080000,0x42000100,0x40080100,
00382 0x02000100,0x40000000,0x42080000,0x02080100,
00383 0x40080100,0x00000100,0x02000000,0x42080000,
00384 0x42080100,0x00080100,0x42000000,0x42080100,
00385 0x02080000,0x00000000,0x40080000,0x42000000,
00386 0x00080100,0x02000100,0x40000100,0x00080000,
00387 0x00000000,0x40080000,0x02080100,0x40000100},
00388 {
00389 0x20000010,0x20400000,0x00004000,0x20404010,
00390 0x20400000,0x00000010,0x20404010,0x00400000,
00391 0x20004000,0x00404010,0x00400000,0x20000010,
00392 0x00400010,0x20004000,0x20000000,0x00004010,
00393 0x00000000,0x00400010,0x20004010,0x00004000,
00394 0x00404000,0x20004010,0x00000010,0x20400010,
00395 0x20400010,0x00000000,0x00404010,0x20404000,
00396 0x00004010,0x00404000,0x20404000,0x20000000,
00397 0x20004000,0x00000010,0x20400010,0x00404000,
00398 0x20404010,0x00400000,0x00004010,0x20000010,
00399 0x00400000,0x20004000,0x20000000,0x00004010,
00400 0x20000010,0x20404010,0x00404000,0x20400000,
00401 0x00404010,0x20404000,0x00000000,0x20400010,
00402 0x00000010,0x00004000,0x20400000,0x00404010,
00403 0x00004000,0x00400010,0x20004010,0x00000000,
00404 0x20404000,0x20000000,0x00400010,0x20004010},
00405 {
00406 0x00200000,0x04200002,0x04000802,0x00000000,
00407 0x00000800,0x04000802,0x00200802,0x04200800,
00408 0x04200802,0x00200000,0x00000000,0x04000002,
00409 0x00000002,0x04000000,0x04200002,0x00000802,
00410 0x04000800,0x00200802,0x00200002,0x04000800,
00411 0x04000002,0x04200000,0x04200800,0x00200002,
00412 0x04200000,0x00000800,0x00000802,0x04200802,
00413 0x00200800,0x00000002,0x04000000,0x00200800,
00414 0x04000000,0x00200800,0x00200000,0x04000802,
00415 0x04000802,0x04200002,0x04200002,0x00000002,
00416 0x00200002,0x04000000,0x04000800,0x00200000,
00417 0x04200800,0x00000802,0x00200802,0x04200800,
00418 0x00000802,0x04000002,0x04200802,0x04200000,
00419 0x00200800,0x00000000,0x00000002,0x04200802,
00420 0x00000000,0x00200802,0x04200000,0x00000800,
00421 0x04000002,0x04000800,0x00000800,0x00200002},
00422 {
00423 0x10001040,0x00001000,0x00040000,0x10041040,
00424 0x10000000,0x10001040,0x00000040,0x10000000,
00425 0x00040040,0x10040000,0x10041040,0x00041000,
00426 0x10041000,0x00041040,0x00001000,0x00000040,
00427 0x10040000,0x10000040,0x10001000,0x00001040,
00428 0x00041000,0x00040040,0x10040040,0x10041000,
00429 0x00001040,0x00000000,0x00000000,0x10040040,
00430 0x10000040,0x10001000,0x00041040,0x00040000,
00431 0x00041040,0x00040000,0x10041000,0x00001000,
00432 0x00000040,0x10040040,0x00001000,0x00041040,
00433 0x10001000,0x00000040,0x10000040,0x10040000,
00434 0x10040040,0x10000000,0x00040000,0x10001040,
00435 0x00000000,0x10041040,0x00040040,0x10000040,
00436 0x10040000,0x10001000,0x10001040,0x00000000,
00437 0x10041040,0x00041000,0x00041000,0x00001040,
00438 0x00001040,0x00040040,0x10000000,0x10041000}
00439 };
00440 
00441 
00442 static INLINE void IPERM(word32* left, word32* right)
00443 {
00444     word32 work;
00445 
00446     *right = rotlFixed(*right, 4U);
00447     work = (*left ^ *right) & 0xf0f0f0f0;
00448     *left ^= work;
00449 
00450     *right = rotrFixed(*right^work, 20U);
00451     work = (*left ^ *right) & 0xffff0000;
00452     *left ^= work;
00453 
00454     *right = rotrFixed(*right^work, 18U);
00455     work = (*left ^ *right) & 0x33333333;
00456     *left ^= work;
00457 
00458     *right = rotrFixed(*right^work, 6U);
00459     work = (*left ^ *right) & 0x00ff00ff;
00460     *left ^= work;
00461 
00462     *right = rotlFixed(*right^work, 9U);
00463     work = (*left ^ *right) & 0xaaaaaaaa;
00464     *left = rotlFixed(*left^work, 1U);
00465     *right ^= work;
00466 }
00467 
00468 
00469 static INLINE void FPERM(word32* left, word32* right)
00470 {
00471     word32 work;
00472 
00473     *right = rotrFixed(*right, 1U);
00474     work = (*left ^ *right) & 0xaaaaaaaa;
00475     *right ^= work;
00476 
00477     *left = rotrFixed(*left^work, 9U);
00478     work = (*left ^ *right) & 0x00ff00ff;
00479     *right ^= work;
00480 
00481     *left = rotlFixed(*left^work, 6U);
00482     work = (*left ^ *right) & 0x33333333;
00483     *right ^= work;
00484 
00485     *left = rotlFixed(*left^work, 18U);
00486     work = (*left ^ *right) & 0xffff0000;
00487     *right ^= work;
00488 
00489     *left = rotlFixed(*left^work, 20U);
00490     work = (*left ^ *right) & 0xf0f0f0f0;
00491     *right ^= work;
00492 
00493     *left = rotrFixed(*left^work, 4U);
00494 }
00495 
00496 
00497 static void DesSetKey(const byte* key, int dir, word32* out)
00498 {
00499     byte buffer[56+56+8];
00500     byte *const pc1m = buffer;                 /* place to modify pc1 into */
00501     byte *const pcr = pc1m + 56;               /* place to rotate pc1 into */
00502     byte *const ks = pcr + 56;
00503     register int i,j,l;
00504     int m;
00505 
00506     for (j = 0; j < 56; j++) {          /* convert pc1 to bits of key */
00507         l = pc1[j] - 1;                 /* integer bit location  */
00508         m = l & 07;                     /* find bit              */
00509         pc1m[j] = (key[l >> 3] &        /* find which key byte l is in */
00510             bytebit[m])                 /* and which bit of that byte */
00511             ? 1 : 0;                    /* and store 1-bit result */
00512     }
00513     for (i = 0; i < 16; i++) {          /* key chunk for each iteration */
00514         XMEMSET(ks, 0, 8);               /* Clear key schedule */
00515         for (j = 0; j < 56; j++)        /* rotate pc1 the right amount */
00516             pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
00517         /* rotate left and right halves independently */
00518         for (j = 0; j < 48; j++){   /* select bits individually */
00519             /* check bit that goes to ks[j] */
00520             if (pcr[pc2[j] - 1]){
00521                 /* mask it in if it's there */
00522                 l= j % 6;
00523                 ks[j/6] |= bytebit[l] >> 2;
00524             }
00525         }
00526         /* Now convert to odd/even interleaved form for use in F */
00527         out[2*i] = ((word32)ks[0] << 24)
00528             | ((word32)ks[2] << 16)
00529             | ((word32)ks[4] << 8)
00530             | ((word32)ks[6]);
00531         out[2*i + 1] = ((word32)ks[1] << 24)
00532             | ((word32)ks[3] << 16)
00533             | ((word32)ks[5] << 8)
00534             | ((word32)ks[7]);
00535     }
00536     
00537     /* reverse key schedule order */
00538     if (dir == DES_DECRYPTION)
00539         for (i = 0; i < 16; i += 2) {
00540             word32 swap = out[i];
00541             out[i] = out[DES_KS_SIZE - 2 - i];
00542             out[DES_KS_SIZE - 2 - i] = swap;
00543 
00544             swap = out[i + 1];
00545             out[i + 1] = out[DES_KS_SIZE - 1 - i];
00546             out[DES_KS_SIZE - 1 - i] = swap;
00547         }
00548    
00549 }
00550 
00551 
00552 static INLINE int Reverse(int dir)
00553 {
00554     return !dir;
00555 }
00556 
00557 
00558 void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
00559 {
00560     DesSetKey(key, dir, des->key);
00561 
00562     Des_SetIV(des, iv);
00563 }
00564 
00565 
00566 void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
00567 {
00568 #ifdef HAVE_CAVIUM
00569     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
00570         return Des3_CaviumSetKey(des, key, iv);
00571 #endif
00572 
00573     DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]);
00574     DesSetKey(key + 8, Reverse(dir), des->key[1]);
00575     DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]);
00576 
00577     Des3_SetIV(des, iv);  
00578 }
00579 
00580 
00581 static void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
00582 {
00583     word32 l = *lIn, r = *rIn, i;
00584 
00585     for (i=0; i<8; i++)
00586     {
00587         word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
00588         l ^= Spbox[6][(work) & 0x3f]
00589           ^  Spbox[4][(work >> 8) & 0x3f]
00590           ^  Spbox[2][(work >> 16) & 0x3f]
00591           ^  Spbox[0][(work >> 24) & 0x3f];
00592         work = r ^ kptr[4*i+1];
00593         l ^= Spbox[7][(work) & 0x3f]
00594           ^  Spbox[5][(work >> 8) & 0x3f]
00595           ^  Spbox[3][(work >> 16) & 0x3f]
00596           ^  Spbox[1][(work >> 24) & 0x3f];
00597 
00598         work = rotrFixed(l, 4U) ^ kptr[4*i+2];
00599         r ^= Spbox[6][(work) & 0x3f]
00600           ^  Spbox[4][(work >> 8) & 0x3f]
00601           ^  Spbox[2][(work >> 16) & 0x3f]
00602           ^  Spbox[0][(work >> 24) & 0x3f];
00603         work = l ^ kptr[4*i+3];
00604         r ^= Spbox[7][(work) & 0x3f]
00605           ^  Spbox[5][(work >> 8) & 0x3f]
00606           ^  Spbox[3][(work >> 16) & 0x3f]
00607           ^  Spbox[1][(work >> 24) & 0x3f];
00608     }
00609 
00610     *lIn = l; *rIn = r;
00611 }
00612 
00613 
00614 static void DesProcessBlock(Des* des, const byte* in, byte* out)
00615 {
00616     word32 l, r;
00617 
00618     XMEMCPY(&l, in, sizeof(l));
00619     XMEMCPY(&r, in + sizeof(l), sizeof(r));
00620     #ifdef LITTLE_ENDIAN_ORDER
00621         l = ByteReverseWord32(l);
00622         r = ByteReverseWord32(r);
00623     #endif
00624     IPERM(&l,&r);
00625     
00626     DesRawProcessBlock(&l, &r, des->key);   
00627 
00628     FPERM(&l,&r);
00629     #ifdef LITTLE_ENDIAN_ORDER
00630         l = ByteReverseWord32(l);
00631         r = ByteReverseWord32(r);
00632     #endif
00633     XMEMCPY(out, &r, sizeof(r));
00634     XMEMCPY(out + sizeof(r), &l, sizeof(l));
00635 }
00636 
00637 
00638 static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
00639 {
00640     word32 l, r;
00641 
00642     XMEMCPY(&l, in, sizeof(l));
00643     XMEMCPY(&r, in + sizeof(l), sizeof(r));
00644     #ifdef LITTLE_ENDIAN_ORDER
00645         l = ByteReverseWord32(l);
00646         r = ByteReverseWord32(r);
00647     #endif
00648     IPERM(&l,&r);
00649     
00650     DesRawProcessBlock(&l, &r, des->key[0]);   
00651     DesRawProcessBlock(&r, &l, des->key[1]);   
00652     DesRawProcessBlock(&l, &r, des->key[2]);   
00653 
00654     FPERM(&l,&r);
00655     #ifdef LITTLE_ENDIAN_ORDER
00656         l = ByteReverseWord32(l);
00657         r = ByteReverseWord32(r);
00658     #endif
00659     XMEMCPY(out, &r, sizeof(r));
00660     XMEMCPY(out + sizeof(r), &l, sizeof(l));
00661 }
00662 
00663 
00664 void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00665 {
00666     word32 blocks = sz / DES_BLOCK_SIZE;
00667 
00668     while (blocks--) {
00669         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
00670         DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
00671         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
00672 
00673         out += DES_BLOCK_SIZE;
00674         in  += DES_BLOCK_SIZE; 
00675     }
00676 }
00677 
00678 
00679 void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
00680 {
00681     word32 blocks = sz / DES_BLOCK_SIZE;
00682     byte   hold[DES_BLOCK_SIZE];
00683 
00684     while (blocks--) {
00685         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
00686         DesProcessBlock(des, (byte*)des->tmp, out);
00687         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
00688 
00689         XMEMCPY(hold, des->reg, DES_BLOCK_SIZE);
00690         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
00691         XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE);
00692 
00693         out += DES_BLOCK_SIZE;
00694         in  += DES_BLOCK_SIZE; 
00695     }
00696 }
00697 
00698 
00699 void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
00700 {
00701     word32 blocks;
00702 
00703 #ifdef HAVE_CAVIUM
00704     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
00705         return Des3_CaviumCbcEncrypt(des, out, in, sz);
00706 #endif
00707 
00708     blocks = sz / DES_BLOCK_SIZE;
00709     while (blocks--) {
00710         xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
00711         Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
00712         XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
00713 
00714         out += DES_BLOCK_SIZE;
00715         in  += DES_BLOCK_SIZE; 
00716     }
00717 }
00718 
00719 
00720 void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
00721 {
00722     word32 blocks;
00723 
00724 #ifdef HAVE_CAVIUM
00725     if (des->magic == CYASSL_3DES_CAVIUM_MAGIC)
00726         return Des3_CaviumCbcDecrypt(des, out, in, sz);
00727 #endif
00728 
00729     blocks = sz / DES_BLOCK_SIZE;
00730     while (blocks--) {
00731         XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
00732         Des3ProcessBlock(des, (byte*)des->tmp, out);
00733         xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
00734         XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
00735 
00736         out += DES_BLOCK_SIZE;
00737         in  += DES_BLOCK_SIZE; 
00738     }
00739 }
00740 
00741 #ifdef CYASSL_DES_ECB
00742 
00743 /* One block, compatibility only */
00744 void Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz)
00745 {
00746     word32 blocks = sz / DES_BLOCK_SIZE;
00747 
00748     while (blocks--) {
00749         DesProcessBlock(des, in, out);
00750 
00751         out += DES_BLOCK_SIZE;
00752         in  += DES_BLOCK_SIZE; 
00753     }
00754 }
00755 
00756 #endif /* CYASSL_DES_ECB */
00757 
00758 #endif /* STM32F2_CRYPTO */
00759 
00760 void Des_SetIV(Des* des, const byte* iv)
00761 {
00762     if (des && iv)
00763         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
00764 }
00765 
00766 
00767 void Des3_SetIV(Des3* des, const byte* iv)
00768 {
00769     if (des && iv)
00770         XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
00771 }
00772 
00773 
00774 #ifdef HAVE_CAVIUM
00775 
00776 #include <cyassl/ctaocrypt/logging.h>
00777 #include "cavium_common.h"
00778 
00779 /* Initiliaze Des3 for use with Nitrox device */
00780 int Des3_InitCavium(Des3* des3, int devId)
00781 {
00782     if (des3 == NULL)
00783         return -1;
00784 
00785     if (CspAllocContext(CONTEXT_SSL, &des3->contextHandle, devId) != 0)
00786         return -1;
00787 
00788     des3->devId = devId;
00789     des3->magic = CYASSL_3DES_CAVIUM_MAGIC;
00790    
00791     return 0;
00792 }
00793 
00794 
00795 /* Free Des3 from use with Nitrox device */
00796 void Des3_FreeCavium(Des3* des3)
00797 {
00798     if (des3 == NULL)
00799         return;
00800 
00801     if (des3->magic != CYASSL_3DES_CAVIUM_MAGIC)
00802         return;
00803 
00804     CspFreeContext(CONTEXT_SSL, des3->contextHandle, des3->devId);
00805     des3->magic = 0;
00806 }
00807 
00808 
00809 static void Des3_CaviumSetKey(Des3* des3, const byte* key, const byte* iv)
00810 {
00811     if (des3 == NULL)
00812         return;
00813 
00814     /* key[0] holds key, iv in reg */
00815     XMEMCPY(des3->key[0], key, DES_BLOCK_SIZE*3);
00816 
00817     Des3_SetIV(des3, iv);
00818 }
00819 
00820 
00821 static void Des3_CaviumCbcEncrypt(Des3* des3, byte* out, const byte* in,
00822                                   word32 length)
00823 {
00824     word   offset = 0;
00825     word32 requestId;
00826    
00827     while (length > CYASSL_MAX_16BIT) {
00828         word16 slen = (word16)CYASSL_MAX_16BIT;
00829         if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
00830                            CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
00831                            out + offset, (byte*)des3->reg, (byte*)des3->key[0],
00832                            &requestId, des3->devId) != 0) {
00833             CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt");
00834         }
00835         length -= CYASSL_MAX_16BIT;
00836         offset += CYASSL_MAX_16BIT;
00837         XMEMCPY(des3->reg, out + offset - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00838     }
00839     if (length) {
00840         word16 slen = (word16)length;
00841 
00842         if (CspEncrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
00843                            CAVIUM_NO_UPDATE, slen, (byte*)in + offset,
00844                            out + offset, (byte*)des3->reg, (byte*)des3->key[0],
00845                            &requestId, des3->devId) != 0) {
00846             CYASSL_MSG("Bad Cavium 3DES Cbc Encrypt");
00847         }
00848         XMEMCPY(des3->reg, out+offset+length - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00849     }
00850 }
00851 
00852 static void Des3_CaviumCbcDecrypt(Des3* des3, byte* out, const byte* in,
00853                                   word32 length)
00854 {
00855     word32 requestId;
00856     word   offset = 0;
00857 
00858     while (length > CYASSL_MAX_16BIT) {
00859         word16 slen = (word16)CYASSL_MAX_16BIT;
00860         XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE, DES_BLOCK_SIZE);
00861         if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
00862                            CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
00863                            (byte*)des3->reg, (byte*)des3->key[0], &requestId,
00864                            des3->devId) != 0) {
00865             CYASSL_MSG("Bad Cavium 3Des Decrypt");
00866         }
00867         length -= CYASSL_MAX_16BIT;
00868         offset += CYASSL_MAX_16BIT;
00869         XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
00870     }
00871     if (length) {
00872         word16 slen = (word16)length;
00873         XMEMCPY(des3->tmp, in + offset + slen - DES_BLOCK_SIZE,DES_BLOCK_SIZE);
00874         if (CspDecrypt3Des(CAVIUM_BLOCKING, des3->contextHandle,
00875                            CAVIUM_NO_UPDATE, slen, (byte*)in+offset, out+offset,
00876                            (byte*)des3->reg, (byte*)des3->key[0], &requestId,
00877                            des3->devId) != 0) {
00878             CYASSL_MSG("Bad Cavium 3Des Decrypt");
00879         }
00880         XMEMCPY(des3->reg, des3->tmp, DES_BLOCK_SIZE);
00881     }
00882 }
00883 
00884 #endif /* HAVE_CAVIUM */
00885 
00886 #endif /* NO_DES3 */