cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

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