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