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