1/*- 2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies. 3 * All rights reserved. 4 * 5 * NBMK Encryption Technologies provides no support of any kind for 6 * this software. Questions or concerns about it may be addressed to 7 * the members of the relevant open-source community at 8 * <tech-crypto@netbsd.org>. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are 12 * met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer in the documentation and/or other materials provided 20 * with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35static char const n8_id[] = "$Id: n8_cb_ea.c,v 1.1 2008/10/30 12:02:15 darran Exp $"; 36/*****************************************************************************/ 37/** @file n8_cb_ea.c 38 * @brief Command blocks for EA. 39 * 40 * Generate command blocks for the Encryption Authentication functions. 41 * 42 *****************************************************************************/ 43 44/***************************************************************************** 45 * Revision history: 46 * 08/18/03 brr Combine Encrypt/Decrypt command block generators for SSL, 47 * TLS, & IPsec. 48 * 07/01/03 brr Support N8_HASH_NONE for IPsec. 49 * 06/06/03 brr Remove uneeded includes. 50 * 09/10/02 brr Set command complete bit on last command block. 51 * 06/12/02 bac Use symbol N8_ARC4_MAX_LENGTH instead of hard-coded 52 * constant. (Bug #768) 53 * 03/26/02 brr Allocate the data buffer as part of the API request. 54 * 02/22/02 spm Converted printf's to DBG's. 55 * 02/19/02 brr Removed byteSwapContext. (only required for FPGA support) 56 * 01/22/02 bac Changes to load contexts so they may be deferred until the 57 * first use rather than at initialization. 58 * 01/12/02 bac Simplified calls which used various ipad/opad/iv values. 59 * Introduced n8_IVSrc to specify where to get the IV for a 60 * command. Reworked 'convertToBits' to update the correct 61 * counter. 62 * 12/06/01 bac Fixed NSP2000 Bug #10 -- use EA_Ctx_Addr_Address_Mask 63 * when dealing with context indices. 64 * 11/28/01 mel Fixed bug #365 : ARC4 key type N8_RC4_t incorrectly declared 65 * 11/24/01 brr Removed include of obsolete EA & PK specifice Queue files. 66 * 11/09/01 mel Fixed bug #253 : N8_HashCompleteMessage not compute HMAC 67 * hashes correctly - added HMAC opcode to command block 68 * 11/08/01 mel Fixed bug #289 : Some calls use N8_SINGLE_CHIP in the 69 * commands directory 70 * 10/30/01 bac Added some debugging, updates to spell IPsec correctly, made 71 * nextCommandBlock_p optional. 72 * 10/22/01 mel Added cb_ea_hashHMACEnd command 73 * 10/16/01 mel Added 2 hashend commands to cb_ea_SSLHandshakeHash 74 * 10/16/01 spm IKE APIs: removed key physical addr parms 75 * 10/15/01 spm IKE APIs: changed if-else on alg to switch on alg. Removed 76 * virtual pointer to message. Had to keep virtual pointer 77 * to key, since the key needs to be copied into the command 78 * block itself. Fixed bug, where 64 byte (exactly)key 79 * doesn't get copied. 80 * 10/15/01 bac Changed some interfaces to take unsigned ints, corrected a bug 81 * when DBG was used. 82 * 10/12/01 mel Added the command block cb_ea_SSLHandshakeHash. 83 * 10/11/01 hml Removed an errant 'i' to fix a compiler warning. 84 * 10/11/01 hml Added the command block generators for N8_HashCompleteMessage 85 * and the TLS modes of the N8_HandshakeHashEnd. 86 * 10/08/01 bac Fixed a bug in calling DBG_PRINT_EA_COMMAND_BLOCKS. A pointer 87 * which had been incremented was being passed. 88 * 09/21/01 bac Rearranged cb_ea_TLSKeyMaterialHash to not require an extra 89 * allocated command block. 90 * 09/21/01 bac Corrected signature on cb_ea_encrypt to take physical 91 * addresses. 92 * 09/20/01 bac The interface to the command block generators changed and now 93 * accept the command block buffer. 94 * 09/18/01 bac Massive changes to support model where the caller allocates 95 * the command buffer. Lots of reorganization and renaming to be 96 * more standard. 97 * 09/17/01 spm Truncated lines >80 chars. 98 * 09/14/01 bac Use new DBG_PRINT_PK_CMD_BLOCKS macros. 99 * 09/07/01 spm Added CB support for IKE APIs. 100 * 08/27/01 mel Added Write/Read context command blocks. 101 * 08/10/01 bac In the FPGA, the context memory is read in the same manner as 102 * the command blocks. Therefore, under our current FPGA 103 * implementation the contexts must always be endian byte-swapped 104 * before passing to the FPGA. This fix was put in place. 105 * 07/02/01 mel Fixed comments. 106 * 06/25/01 bac More on conversion to use physical memory. 107 * 06/21/01 mel Corrected use of kernel memory. 108 * 06/17/01 bac Changes per code review. 109 * 06/08/01 mel Added Cryptographic command blocks. 110 * 06/05/01 bac Changes to not rely on N8_SSLTLSPacket_t being packed (Bug 111 * #31). 112 * 05/31/01 mel Changed keys and IVs to be a char[] instead of uint32_t[]. 113 * 06/19/01 bac Correct use of kernel space memory. 114 * 05/23/01 bac macSecret is a char[] now and is converted to big endian 115 * order before putting into command block. 116 * 05/22/01 bac Changed SSL Encrypt and Decrypt commands to pass 117 * packets instead of buffers. 118 * 05/21/01 bac Converted to use N8_ContextHandle_t and N8_Packet_t 119 * with integrated cipher and hash packet. 120 * 05/21/01 bac Fixed SSLAuthenticate to insert the context index when doing 121 * RC4. 122 * 05/19/01 bac Added debugging for printing contexts. 123 * 05/18/01 bac Corrected SSLDecrypt logic for setting non-context command 124 * block parameters. Fixed printCommandBlock to work on lil' 125 * endian machines. 126 * 05/16/01 dws Modified cb_loadARC4key_to_contextMemory to use the ARC4 127 * i and j masks and shift counts in a more general way. This 128 * was done to accomodate the change in the i and j locations 129 * in the ARC4 context block. 130 * 05/11/01 bac Merge sanity changes. Naming standardization. 131 * 05/09/01 bac Added support for SSL Encrypt/Authenticate. Converted to use 132 * new N8_MALLOC/N8_FREE macros. 133 * 05/09/01 dws Changed the way that the random bytes are loaded into the 134 * command block in cb_ea_SSLKeyMaterialHash. It now uses a 135 * series of BE_to_uint32 operations instead of memcpy. 136 * 05/04/01 bac Fixed some compilation problems for prematurely checked in 137 * code. 138 * 05/03/01 bac Replaced integer use of NULL with 0. 139 * 05/01/01 bac Support for SSLKeyMaterialHash. Also fixed some merge errors. 140 * 04/24/01 bac Support for hash partial and hash end. 141 * 04/12/01 bac Original version. 142 ****************************************************************************/ 143/** @defgroup cb_ea EA Command Block Generator 144 */ 145 146#include "n8_cb_ea.h" 147#include "n8_ea_common.h" /* for typedef of EA_CMD_BLOCK_t */ 148#include "n8_common.h" 149#include "n8_util.h" 150 151 152 153#define BYTES_PER_ITERATION 16 154#define NUM_RANDOM_BYTES 64 155 156static void convertToBits(EA_CMD_BLOCK_t *cb_p, const N8_HashObject_t *obj_p, 157 const n8_IVSrc_t ivSrc); 158static void n8_RC4_set_key(N8_RC4_t *key, int len, const unsigned char *data); 159 160 161/***************************************************************************** 162 * cb_ea_hashPartial 163 *****************************************************************************/ 164/** @ingroup cb_ea 165 * @brief Cmd Blocks for hash partial 166 * 167 * Command Block generation for EA function "Hash N Blocks, 168 * Pre-Load IV from Cmd Block" (opcodes 0x12 and 0x22) 169 * 170 * @param req_p RW: Request pointer. 171 * @param obj_p RW: Pointer to hash object. 172 * @param hashMsg_a RO: Physical address of message to be hashed. 173 * @param msgLength RO: Length of message 174 * @param result_a RO: Pointer to allocated buffer for 175 * the results to be placed by the 176 * EA. This value is used but not 177 * written by this function. 178 * 179 * @par Externals 180 * None 181 * 182 * @return 183 * Status 184 * 185 * @par Errors 186 * N8_MALLOC_FAILED - memory allocation failed<BR> 187 * N8_INVALID_HASH - hash specified was invalid<br> 188 * 189 * @par Assumptions 190 * Caller is responsible to free memory allocated to cmdBlock_pp.<br> 191 *****************************************************************************/ 192N8_Status_t cb_ea_hashPartial(API_Request_t *req_p, 193 EA_CMD_BLOCK_t *cb_p, 194 const N8_HashObject_t *obj_p, 195 const n8_IVSrc_t ivSrc, 196 const uint32_t hashMsg_a, 197 const unsigned int msgLength, 198 const uint32_t result_a, 199 EA_CMD_BLOCK_t **next_cb_pp, 200 int lastCmdBlock) 201{ 202 N8_Status_t ret = N8_STATUS_OK; 203 do 204 { 205 CHECK_OBJECT(req_p, ret); 206 CHECK_OBJECT(cb_p, ret); 207 208 cb_p->read_data_addr_ls = hashMsg_a; 209 cb_p->write_data_addr_ls = result_a; 210 211 /* If this is the last command block, set the command complete bit */ 212 if (lastCmdBlock == N8_TRUE) 213 { 214 cb_p->cp_si_context = EA_Cmd_SI_Mask; 215 } 216 switch (ivSrc) 217 { 218 case N8_IPAD: 219 memcpy(cb_p->hash_IV, obj_p->ipadHMAC_iv, sizeof(obj_p->iv)); 220 break; 221 case N8_OPAD: 222 memcpy(cb_p->hash_IV, obj_p->opadHMAC_iv, sizeof(obj_p->iv)); 223 break; 224 default: 225 memcpy(cb_p->hash_IV, obj_p->iv, sizeof(obj_p->iv)); 226 break; 227 } 228 229 /* set opcode */ 230 switch (obj_p->type) 231 { 232 case N8_MD5: 233 case N8_HMAC_MD5: 234 case N8_HMAC_MD5_96: 235 cb_p->opcode_iter_length = EA_Cmd_MD5_Mid_cmdIV; 236 break; 237 case N8_SHA1: 238 case N8_HMAC_SHA1: 239 case N8_HMAC_SHA1_96: 240 cb_p->opcode_iter_length = EA_Cmd_SHA1_Mid_cmdIV; 241 break; 242 default: 243 ret = N8_INVALID_HASH; 244 break; 245 } 246 CHECK_RETURN(ret); 247 cb_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & msgLength); 248 249 /* save next address for future use */ 250 if (next_cb_pp != NULL) 251 { 252 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1); 253 } 254 255 256 } while (FALSE); 257 258 DBG_PRINT_EA_CMD_BLOCKS("Hash Partial", cb_p, 259 N8_CB_EA_HASHPARTIAL_NUMCMDS); 260 261 return ret; 262} /* cb_ea_hashPartial */ 263 264 265/***************************************************************************** 266 * cb_ea_hashCompleteMessage 267 *****************************************************************************/ 268/** @ingroup cb_ea 269 * @brief Cmd Blocks for hash complete message 270 * 271 * Command Block generation for EA function "Simple Hash" 272 * (opcodes 0x10 and 0x20) 273 * 274 * @param req_p RW: Request pointer. 275 * @param obj_p RW: Pointer to hash object. 276 * @param hashMsg_a RO: Physical address of message to be hashed. 277 * @param msgLength RO: Length of message 278 * @param result_a RO: Pointer to allocated buffer for 279 * the results to be placed by the 280 * EA. This value is used but not 281 * written by this function. 282 * 283 * @par Externals 284 * None 285 * 286 * @return 287 * N8_STATUS_OK on success or one of the error codes specified. 288 * 289 * @par Errors 290 * N8_MALLOC_FAILED - memory allocation failed<BR> 291 * N8_INVALID_HASH - hash specified was invalid 292 * 293 * @par Assumptions 294 * Caller is responsible to free memory allocated to cmdBlock_pp.<br> 295 *****************************************************************************/ 296N8_Status_t cb_ea_hashCompleteMessage(API_Request_t *req_p, 297 EA_CMD_BLOCK_t *cb_p, 298 const N8_HashObject_t *obj_p, 299 const uint32_t hashMsg_a, 300 const unsigned int msgLength, 301 const uint32_t result_a) 302{ 303 N8_Status_t ret = N8_STATUS_OK; 304 EA_HMAC_CMD_BLOCK_t *cb_HMAC_p = NULL; 305 do 306 { 307 CHECK_OBJECT(req_p, ret); 308 CHECK_OBJECT(cb_p, ret); 309 310 cb_HMAC_p = (EA_HMAC_CMD_BLOCK_t *) cb_p; 311 312 cb_p->read_data_addr_ls = hashMsg_a; 313 cb_p->write_data_addr_ls = result_a; 314 cb_p->cp_si_context = EA_Cmd_SI_Mask; 315 316 /* set opcode */ 317 switch (obj_p->type) 318 { 319 case N8_MD5: 320 cb_p->opcode_iter_length = 321 EA_Cmd_MD5 | (EA_Cmd_Data_Length_Mask & msgLength); 322 break; 323 case N8_HMAC_MD5: 324 case N8_HMAC_MD5_96: 325 memcpy(cb_HMAC_p->hmac_key, obj_p->hashedHMACKey, sizeof(obj_p->hashedHMACKey)); 326 cb_p->opcode_iter_length = 327 (EA_Cmd_MD5_HMAC | 328 ((1 << EA_Cmd_Iterations_Shift) & EA_Cmd_Iterations_Mask) | 329 (EA_Cmd_Data_Length_Mask & msgLength)); 330 break; 331 case N8_SHA1: 332 cb_p->opcode_iter_length = 333 EA_Cmd_SHA1 | (EA_Cmd_Data_Length_Mask & msgLength); 334 break; 335 case N8_HMAC_SHA1: 336 case N8_HMAC_SHA1_96: 337 memcpy(cb_HMAC_p->hmac_key, obj_p->hashedHMACKey, sizeof(obj_p->hashedHMACKey)); 338 cb_p->opcode_iter_length = 339 (EA_Cmd_SHA1_HMAC | 340 ((1 << EA_Cmd_Iterations_Shift) & EA_Cmd_Iterations_Mask) | 341 (EA_Cmd_Data_Length_Mask & msgLength)); 342 break; 343 default: 344 ret = N8_INVALID_HASH; 345 break; 346 } 347 CHECK_RETURN(ret); 348 349 } while (FALSE); 350 351 DBG_PRINT_EA_CMD_BLOCKS("Hash Complete Message", cb_p, 352 N8_CB_EA_HASHCOMPLETEMESSAGE_NUMCMDS); 353 354 return ret; 355} /* cb_ea_hashCompleteMessage */ 356 357/***************************************************************************** 358 * cb_ea_hashEnd 359 *****************************************************************************/ 360/** @ingroup cb_ea 361 * @brief Cmd Blocks for hash end 362 * 363 * Command Block generation for EA function "Hash Last Segment, 364 * Pre-Load IV from Cmd Block" (opcodes 0x14 and 0x24). This hardware 365 * command does the final hash for a complete message. Note the 366 * message passed is the residual from the previous set of partial 367 * hashes. The length may be from 0 to the maximum of 16K. 368 * 369 * @param req_p RW: Request pointer. 370 * @param obj_p RW: Pointer to hash object. 371 * @param hashMsg_a RO: Physical address of message to be hashed. 372 * @param msgLength RO: Length of message 373 * @param result_a RO: Pointer to allocated buffer for 374 * the results to be placed by the 375 * EA. This value is used but not 376 * written by this function. 377 * 378 * @par Externals 379 * None 380 * 381 * @return 382 * Status 383 * 384 * @par Errors 385 * N8_INVALID_VALUE - the ssl packet type is not recognized<br> 386 * N8_MALLOC_FAILED - memory allocation failed<BR> 387 * N8_INVALID_HASH - hash specified was invalid<br> 388 * N8_INVALID_CIPHER - cipher specified was invalid<br> 389 * N8_INVALID_VERSION - SSL version is not supported<br> 390 * 391 * @par Assumptions 392 * None 393 *****************************************************************************/ 394N8_Status_t cb_ea_hashEnd(API_Request_t *req_p, 395 EA_CMD_BLOCK_t *cb_p, 396 const N8_HashObject_t *obj_p, 397 const n8_IVSrc_t ivSrc, 398 const uint32_t hashMsg_a, 399 const unsigned int msgLength, 400 const uint32_t result_a, 401 EA_CMD_BLOCK_t **next_cb_pp, 402 int lastCmdBlock) 403{ 404 N8_Status_t ret = N8_STATUS_OK; 405 do 406 { 407 CHECK_OBJECT(req_p, ret); 408 CHECK_OBJECT(cb_p, ret); 409 410 cb_p->read_data_addr_ls = hashMsg_a; 411 cb_p->write_data_addr_ls = result_a; 412 /* If this is the last command block, set the command complete bit */ 413 if (lastCmdBlock == N8_TRUE) 414 { 415 cb_p->cp_si_context = EA_Cmd_SI_Mask; 416 } 417 418 /* copy the iv */ 419 switch (ivSrc) 420 { 421 case N8_IPAD: 422 memcpy(cb_p->hash_IV, obj_p->ipadHMAC_iv, sizeof(obj_p->iv)); 423 break; 424 case N8_OPAD: 425 memcpy(cb_p->hash_IV, obj_p->opadHMAC_iv, sizeof(obj_p->iv)); 426 break; 427 default: 428 memcpy(cb_p->hash_IV, obj_p->iv, sizeof(obj_p->iv)); 429 break; 430 } 431 /* set opcode */ 432 switch (obj_p->type) 433 { 434 case N8_MD5: 435 case N8_HMAC_MD5: 436 case N8_HMAC_MD5_96: 437 cb_p->opcode_iter_length = EA_Cmd_MD5_End_cmdIV; 438 break; 439 case N8_SHA1: 440 case N8_HMAC_SHA1: 441 case N8_HMAC_SHA1_96: 442 cb_p->opcode_iter_length = EA_Cmd_SHA1_End_cmdIV; 443 break; 444 default: 445 ret = N8_INVALID_HASH; 446 break; 447 } 448 CHECK_RETURN(ret); 449 450 cb_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & msgLength); 451 452 /* set the previous length in BITS. */ 453 convertToBits(cb_p, obj_p, ivSrc); 454 455 /* save next address for future use */ 456 if (next_cb_pp != NULL) 457 { 458 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1); 459 } 460 461 } while (FALSE); 462 463 DBG_PRINT_EA_CMD_BLOCKS("Hash End", cb_p, 464 N8_CB_EA_HASHEND_NUMCMDS); 465 return ret; 466} /* cb_ea_hashEnd */ 467 468 469/***************************************************************************** 470 * cb_ea_hashHMACEnd 471 *****************************************************************************/ 472/** @ingroup cb_ea 473 * @brief Cmd Blocks for HMAC hash end 474 * 475 * 476 * @param req_p RW: Request pointer. 477 * @param obj_p RW: Pointer to hash object. 478 * @param hashMsg_a RO: Physical address of message to be hashed. 479 * @param msgLength RO: Length of message 480 * @param result_a RO: Pointer to allocated buffer for 481 * the results to be placed by the 482 * EA. This value is used but not 483 * written by this function. 484 * 485 * @par Externals 486 * None 487 * 488 * @return 489 * Status 490 * 491 * @par Errors 492 * N8_INVALID_VALUE - the ssl packet type is not recognized<br> 493 * N8_MALLOC_FAILED - memory allocation failed<BR> 494 * N8_INVALID_HASH - hash specified was invalid<br> 495 * N8_INVALID_CIPHER - cipher specified was invalid<br> 496 * N8_INVALID_VERSION - SSL version is not supported<br> 497 * 498 * @par Assumptions 499 * None 500 *****************************************************************************/ 501N8_Status_t cb_ea_hashHMACEnd(API_Request_t *req_p, 502 EA_CMD_BLOCK_t *cb_p, 503 const N8_HashObject_t *obj_p, 504 const uint32_t hashMsg_a, 505 const unsigned int msgLength, 506 const uint32_t result_a, 507 EA_CMD_BLOCK_t **next_cb_pp) 508{ 509 N8_Status_t ret = N8_STATUS_OK; 510 EA_HMAC_CMD_BLOCK_t *cb_HMAC_p = NULL; 511 do 512 { 513 CHECK_OBJECT(req_p, ret); 514 CHECK_OBJECT(cb_p, ret); 515 516 cb_HMAC_p = (EA_HMAC_CMD_BLOCK_t *) cb_p; 517 518 cb_HMAC_p->read_data_addr_ls = (unsigned int) hashMsg_a; 519 cb_HMAC_p->write_data_addr_ls = (unsigned int) result_a; 520 memcpy(cb_HMAC_p->hmac_key, obj_p->hashedHMACKey, sizeof(obj_p->hashedHMACKey)); 521 /* set opcode */ 522 switch (obj_p->type) 523 { 524 case N8_HMAC_MD5: 525 case N8_HMAC_MD5_96: 526 cb_HMAC_p->opcode_iter_length = EA_Cmd_MD5_HMAC | msgLength | 527 ((1 << EA_Cmd_Iterations_Shift) & EA_Cmd_Iterations_Mask); 528 break; 529 case N8_HMAC_SHA1: 530 case N8_HMAC_SHA1_96: 531 cb_HMAC_p->opcode_iter_length = EA_Cmd_SHA1_HMAC | msgLength | 532 ((1 << EA_Cmd_Iterations_Shift) & EA_Cmd_Iterations_Mask); 533 break; 534 default: 535 ret = N8_INVALID_HASH; 536 break; 537 } 538 CHECK_RETURN(ret); 539 540 /* save next address for future use */ 541 if (next_cb_pp != NULL) 542 { 543 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1); 544 } 545 546 } while (FALSE); 547 548 DBG_PRINT_EA_CMD_BLOCKS("Hash End", cb_p, 549 N8_CB_EA_HASHEND_NUMCMDS); 550 return ret; 551} /* cb_ea_hashEnd */ 552 553 554/***************************************************************************** 555 * cb_ea_SSLKeyMaterialHash 556 *****************************************************************************/ 557/** @ingroup cb_ea 558 * @brief Compute SSL key material. 559 * 560 * The key material for an SSL hash is computed. 561 * 562 * @param req_p RW: Pointer to api request buffer. 563 * @param key_a RO: Physical address of key to use. 564 * @param keyLength RO: Length of the key. 565 * @param random_p RO: Pointer to random data to use. 566 * @param outputLength RO: Length of output. 567 * @param result_a RW: Physical address of pre-allocated buffer 568 * for the results. 569 * 570 * @par Externals 571 * None 572 * 573 * @return 574 * Status. Error condition if raised. 575 * 576 * @par Errors 577 * N8_MALLOC_FAILED - memory allocation failed<BR> 578 * 579 * @par Assumptions 580 * Results buffer is pre-allocated and of a sufficient size. 581 *****************************************************************************/ 582N8_Status_t cb_ea_SSLKeyMaterialHash(API_Request_t *req_p, 583 EA_CMD_BLOCK_t *cmdBlock_p, 584 const uint32_t key_a, 585 const int keyLength, 586 const N8_Buffer_t *random_p, 587 const int outputLength, 588 uint32_t result_a) 589{ 590 N8_Status_t ret = N8_STATUS_OK; 591 EA_MSH_CMD_BLOCK_t *cb_p = NULL; 592 int iterationCount; 593 594 do 595 { 596 CHECK_OBJECT(req_p, ret); 597 cb_p = (EA_MSH_CMD_BLOCK_t *) cmdBlock_p; 598 CHECK_OBJECT(cb_p, ret); 599 600 /* create a command block for CCH opcode 0x30: 601 * "Master Secret Hash Command" 602 */ 603 604 iterationCount = (int) ((outputLength / (float) BYTES_PER_ITERATION) + 605 0.5); 606 607 /* set the opcode and length */ 608 cb_p->opcode_iter_length = 609 EA_Cmd_SSL30_Master_Secret_Hash | 610 (iterationCount << EA_Cmd_Iterations_Shift) | 611 keyLength; 612 /* set the address of the key, or "master secret" in the read 613 * pointer */ 614 cb_p->read_data_addr_ls = key_a; 615 /* set the output address */ 616 cb_p->write_data_addr_ls = result_a; 617 cb_p->cp_si_context = EA_Cmd_SI_Mask; 618 619 /* set the random data */ 620 cb_p->random1[0] = BE_to_uint32(random_p); 621 cb_p->random1[1] = BE_to_uint32(random_p+4); 622 cb_p->random1[2] = BE_to_uint32(random_p+8); 623 cb_p->random1[3] = BE_to_uint32(random_p+12); 624 cb_p->random1[4] = BE_to_uint32(random_p+16); 625 cb_p->random1[5] = BE_to_uint32(random_p+20); 626 cb_p->random1[6] = BE_to_uint32(random_p+24); 627 cb_p->random1[7] = BE_to_uint32(random_p+28); 628 cb_p->random2[0] = BE_to_uint32(random_p+32); 629 cb_p->random2[1] = BE_to_uint32(random_p+36); 630 cb_p->random2[2] = BE_to_uint32(random_p+40); 631 cb_p->random2[3] = BE_to_uint32(random_p+44); 632 cb_p->random2[4] = BE_to_uint32(random_p+48); 633 cb_p->random2[5] = BE_to_uint32(random_p+52); 634 cb_p->random2[6] = BE_to_uint32(random_p+56); 635 cb_p->random2[7] = BE_to_uint32(random_p+60); 636 } 637 while (FALSE); 638 DBG_PRINT_EA_CMD_BLOCKS("SSL Key Material Hash", (EA_CMD_BLOCK_t *) cb_p, 639 N8_CB_EA_SSLKEYMATERIALHASH_NUMCMDS); 640 641 /* clean up */ 642 /* nothing to clean up */ 643 644 return ret; 645} /* cb_ea_SSLKeyMaterialHash */ 646 647/***************************************************************************** 648 * cb_ea_SSL 649 *****************************************************************************/ 650/** @ingroup cb_ea 651 * @brief Create the command blocks to perform E/A or Decrypt for an SSL packet. 652 * 653 * @param cmdBlock_p RO: Pointer to beginning of the command block. 654 * @param packetObj_p RW: Pointer to the packet object. 655 * @param packet_p RO: Pointer to the header/data packet. 656 * @param input_a RO: Physical address of incoming SSL packet 657 * @param result_a RO: Physical address of decrypted SSL packet 658 * @param opCode RO: Op Code to build into the command block. 659 * 660 * @par Externals 661 * None 662 * 663 * @return 664 * Error if raised. 665 * 666 * @par Errors 667 * N8_INVALID_VALUE - the ssl packet type is not recognized<br> 668 * N8_INVALID_VERSION - SSL version is not supported<br> 669 * 670 * @par Assumptions 671 * None 672 *****************************************************************************/ 673N8_Status_t cb_ea_SSL(EA_CMD_BLOCK_t *cmdBlock_p, 674 N8_Packet_t *packetObj_p, 675 const N8_SSLTLSPacket_t *packet_p, 676 const uint32_t input_a, 677 const uint32_t result_a, 678 const unsigned int opCode) 679{ 680 EA_SSL30_CMD_BLOCK_t *cb_p = (EA_SSL30_CMD_BLOCK_t *) cmdBlock_p; 681 uint16_t length; 682 uint16_t sslver; 683 uint8_t type; 684 685 /* convert network order packet header data to host order */ 686 type = SSLTLS_EXTRACT_TYPE(packet_p); 687 sslver = SSLTLS_EXTRACT_VERSION(packet_p); 688 length = SSLTLS_EXTRACT_LENGTH(packet_p); 689 690 /* ensure the sslProtocol passed is one of the valid values */ 691 switch (type) 692 { 693 case N8_CHANGE_CIPHER_SPEC: 694 case N8_ALERT: 695 case N8_HANDSHAKE: 696 case N8_APPLICATION_DATA: 697 break; 698 default: 699 return(N8_INVALID_VALUE); 700 } 701 702 /* check the version to ensure it is correct */ 703 if (sslver != N8_SSL_VERSION) 704 { 705 return(N8_INVALID_VERSION); 706 } 707 708 /* set the common elements */ 709 cb_p->read_data_addr_ls = input_a; 710 cb_p->write_data_addr_ls = result_a; 711 cb_p->result_type = type; 712 cb_p->SSL_version_length = (sslver << 16) + length; 713 714 /* set the opcode */ 715 cb_p->opcode_iter_length = opCode | length; 716 717 /* Assume context use */ 718 cb_p->cp_si_context = EA_Cmd_CP_Mask | 719 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index); 720 721 /* based on cipher/hash, set the opcode and other specifics */ 722 if (packetObj_p->packetCipher == N8_CIPHER_DES) 723 { 724 /* DES may use context index or provide data in the command block */ 725 if (packetObj_p->contextHandle.inUse == N8_FALSE) 726 { 727 EA_SSL30_DES_MD5_CMD_BLOCK_t *desMd5_p; 728 int i; 729 730 /* Do not use context */ 731 cb_p->cp_si_context = 0; 732 if (packetObj_p->packetHashAlgorithm == N8_MD5) 733 { 734 desMd5_p = (EA_SSL30_DES_MD5_CMD_BLOCK_t *) cb_p; 735 /* set the precompute values */ 736 for (i = 0; i < 4; i++) 737 { 738 desMd5_p->precompute1[i] = 739 packetObj_p->cipherInfo.precompute1[i]; 740 desMd5_p->precompute2[i] = 741 packetObj_p->cipherInfo.precompute2[i]; 742 } 743 } 744 else /* N8_SHA1 */ 745 { 746 for (i = 0; i < 5; i++) 747 { 748 cb_p->write_secret[i] = BE_to_uint32( 749 &packetObj_p->cipherInfo.macSecret[i*sizeof(uint32_t)]); 750 } 751 } 752 753 /* set the params common for 3DES */ 754 cb_p->des_IV_ms = 755 BE_to_uint32(&packetObj_p->cipherInfo.IV[N8_MS_BYTE]); 756 cb_p->des_IV_ls = 757 BE_to_uint32(&packetObj_p->cipherInfo.IV[N8_LS_BYTE]); 758 cb_p->des_key1_ms = 759 BE_to_uint32(&packetObj_p->cipherInfo.key1[N8_MS_BYTE]); 760 cb_p->des_key1_ls = 761 BE_to_uint32(&packetObj_p->cipherInfo.key1[N8_LS_BYTE]); 762 cb_p->des_key2_ms = 763 BE_to_uint32(&packetObj_p->cipherInfo.key2[N8_MS_BYTE]); 764 cb_p->des_key2_ls = 765 BE_to_uint32(&packetObj_p->cipherInfo.key2[N8_LS_BYTE]); 766 cb_p->des_key3_ms = 767 BE_to_uint32(&packetObj_p->cipherInfo.key3[N8_MS_BYTE]); 768 cb_p->des_key3_ls = 769 BE_to_uint32(&packetObj_p->cipherInfo.key3[N8_LS_BYTE]); 770 771 cb_p->sequence_number[0] = packetObj_p->cipherInfo.sequence_number[0]; 772 cb_p->sequence_number[1] = packetObj_p->cipherInfo.sequence_number[1]; 773 /* increment the sequence number. should we later discover the 774 * operation failed, the sequence number will need to be 775 * returned to its previous value. 776 */ 777 packetObj_p->cipherInfo.sequence_number[1]++; 778 /* check for wrapping */ 779 if (packetObj_p->cipherInfo.sequence_number[1] == 0) 780 { 781 /* increment the sequence number ms */ 782 packetObj_p->cipherInfo.sequence_number[0]++; 783 } 784 } 785 } 786 787 DBG_PRINT_EA_CMD_BLOCKS("SSL", (EA_CMD_BLOCK_t *) cb_p, 788 N8_CB_EA_SSLENCRYPTAUTHENTICATE_NUMCMDS); 789 return N8_STATUS_OK; 790} /* cb_ea_SSL */ 791 792/***************************************************************************** 793 * cb_ea_TLS 794 *****************************************************************************/ 795/** @ingroup cb_ea 796 * @brief Create the command block to perform E/A or Decrypt for a TLS packet. 797 * 798 * @param cmdBlock_p RO: Pointer to beginning of the command block. 799 * @param packetObj_p RW: Pointer to the packet object. 800 * @param packet_p RO: Pointer to the header/data packet. 801 * @param input_a RO: Physical adress of input data. 802 * @param result_a RO: Physical adress of results area. 803 * @param opCode RO: Op Code to build into the command block. 804 * 805 * @par Externals 806 * None 807 * 808 * @return 809 * Error if raised. 810 * 811 * @par Errors 812 * N8_INVALID_VALUE - the TLS packet type is not recognized<br> 813 * N8_INVALID_VERSION - TLS version is not supported<br> 814 * 815 * @par Assumptions 816 * None 817 *****************************************************************************/ 818N8_Status_t cb_ea_TLS(EA_CMD_BLOCK_t *cmdBlock_p, 819 N8_Packet_t *packetObj_p, 820 const N8_SSLTLSPacket_t *packet_p, 821 const uint32_t input_a, 822 const uint32_t result_a, 823 const unsigned int opCode) 824{ 825 EA_SSL30_CMD_BLOCK_t *cb_p = (EA_SSL30_CMD_BLOCK_t *) cmdBlock_p; 826 uint16_t length; 827 uint16_t tlsver; 828 uint8_t type; 829 830 /* convert network order packet header data to host order */ 831 type = SSLTLS_EXTRACT_TYPE(packet_p); 832 tlsver = SSLTLS_EXTRACT_VERSION(packet_p); 833 length = SSLTLS_EXTRACT_LENGTH(packet_p); 834 835 /* ensure the sslProtocol passed is one of the valid values */ 836 switch (type) 837 { 838 case N8_CHANGE_CIPHER_SPEC: 839 case N8_ALERT: 840 case N8_HANDSHAKE: 841 case N8_APPLICATION_DATA: 842 break; 843 default: 844 return (N8_INVALID_VALUE); 845 } 846 847 /* check the version to ensure it is correct */ 848 if (tlsver != N8_TLS_VERSION) 849 { 850 return (N8_INVALID_VERSION); 851 } 852 853 /* set the common elements */ 854 cb_p->read_data_addr_ls = input_a; 855 cb_p->write_data_addr_ls = result_a; 856 cb_p->result_type = type; 857 cb_p->SSL_version_length = (tlsver << 16) + length; 858 859 /* set the opcode */ 860 cb_p->opcode_iter_length = opCode | length; 861 862 /* Assume context use */ 863 cb_p->cp_si_context |= EA_Cmd_CP_Mask | 864 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index); 865 866 /* based on cipher/hash, set the opcode and other specifics */ 867 if (packetObj_p->packetCipher == N8_CIPHER_DES) 868 { 869 /* DES may use context index or provide data in the command block */ 870 if (packetObj_p->contextHandle.inUse == N8_FALSE) 871 { 872 EA_TLS10_CMD_BLOCK_t *tls_p = (EA_TLS10_CMD_BLOCK_t *) cb_p; 873 int i; 874 875 /* Clear context use */ 876 cb_p->cp_si_context = 0; 877 878 if (packetObj_p->packetHashAlgorithm == N8_HMAC_MD5) 879 { 880 for (i = 0; i < 4; i++) 881 { 882 tls_p->ipad[i] = packetObj_p->hashPacket.ipadHMAC_iv[i]; 883 tls_p->opad[i] = packetObj_p->hashPacket.opadHMAC_iv[i]; 884 } 885 } 886 else /* N8_HMAC_SHA1 */ 887 { 888 for (i = 0; i<5; i++) 889 { 890 tls_p->ipad[i] = packetObj_p->hashPacket.ipadHMAC_iv[i]; 891 tls_p->opad[i] = packetObj_p->hashPacket.opadHMAC_iv[i]; 892 } 893 } 894 895 /* set the params common for 3DES */ 896 cb_p->des_IV_ms = 897 BE_to_uint32(&packetObj_p->cipherInfo.IV[N8_MS_BYTE]); 898 cb_p->des_IV_ls = 899 BE_to_uint32(&packetObj_p->cipherInfo.IV[N8_LS_BYTE]); 900 cb_p->des_key1_ms = 901 BE_to_uint32(&packetObj_p->cipherInfo.key1[N8_MS_BYTE]); 902 cb_p->des_key1_ls = 903 BE_to_uint32(&packetObj_p->cipherInfo.key1[N8_LS_BYTE]); 904 cb_p->des_key2_ms = 905 BE_to_uint32(&packetObj_p->cipherInfo.key2[N8_MS_BYTE]); 906 cb_p->des_key2_ls = 907 BE_to_uint32(&packetObj_p->cipherInfo.key2[N8_LS_BYTE]); 908 cb_p->des_key3_ms = 909 BE_to_uint32(&packetObj_p->cipherInfo.key3[N8_MS_BYTE]); 910 cb_p->des_key3_ls = 911 BE_to_uint32(&packetObj_p->cipherInfo.key3[N8_LS_BYTE]); 912 913 cb_p->sequence_number[0] = packetObj_p->cipherInfo.sequence_number[0]; 914 cb_p->sequence_number[1] = packetObj_p->cipherInfo.sequence_number[1]; 915 /* increment the sequence number. should we later discover the 916 * operation failed, the sequence number will need to be 917 * returned to its previous value. 918 */ 919 packetObj_p->cipherInfo.sequence_number[1]++; 920 /* check for wrapping */ 921 if (packetObj_p->cipherInfo.sequence_number[1] == 0) 922 { 923 /* increment the sequence number ms */ 924 packetObj_p->cipherInfo.sequence_number[0]++; 925 } 926 } 927 } 928 929 DBG_PRINT_EA_CMD_BLOCKS("TLS", (EA_CMD_BLOCK_t *) cb_p, 930 N8_CB_EA_TLSENCRYPTAUTHENTICATE_NUMCMDS); 931 return (N8_STATUS_OK); 932} /* cb_ea_TLS */ 933 934/***************************************************************************** 935 * cb_ea_TLSKeyMaterialHash 936 *****************************************************************************/ 937/** @ingroup cb_ea 938 * @brief Compute TLS key material. 939 * 940 * The key material for an TLS hash is computed. 941 * 942 * @param req_p RW: Pointer to api request buffer. 943 * @param msg_p RO: Virtual address of message to hash. 944 * @param msg_a RO: Physical address of message to hash. 945 * @param dataLength RO: Length of the message. 946 * @param hmacKey_p RO: Virtual address of HMAC key. 947 * @param hmacKey_a RO: Physical address of HMAC key. 948 * @param keyLength RO: Length of HMAC key. 949 * @param outputLength RO: Length of output buffer. 950 * @param pseudorandomStream1_a RO: First part of pseudo-random stream. 951 * @param pseudorandomStream2_a RO: Second part of pseudo-random stream. 952 * 953 * @par Externals 954 * None 955 * 956 * @return 957 * Status. Error condition if raised. 958 * 959 * @par Errors 960 * 961 * @par Assumptions 962 * All buffers are pre-allocated and of a sufficient size. 963 *****************************************************************************/ 964N8_Status_t cb_ea_TLSKeyMaterialHash(API_Request_t *req_p, 965 EA_CMD_BLOCK_t *cmdBlock_p, 966 const N8_Buffer_t *msg_p, 967 const uint32_t msg_a, 968 const int dataLength, 969 N8_Buffer_t *hmacKey_p, 970 const uint32_t hmacKey_a, 971 const int keyLength, 972 const int outputLength, 973 const uint32_t pseudorandomStream1_a, 974 const uint32_t pseudorandomStream2_a, 975 const int keyLen) 976{ 977 N8_Status_t ret = N8_STATUS_OK; 978 EA_HMAC_CMD_BLOCK_t *cb_p = NULL; 979 int iterationCount_MD5; 980 int iterationCount_SHA1; 981 int bufferA_MD5_length = 0; 982 int bufferA_SHA1_length = 0; 983 int i, n, k, l; 984 N8_Buffer_t *secret1_p = NULL; 985 N8_Buffer_t *secret2_p = NULL; 986 N8_Buffer_t *bufferA_MD5_p = NULL; 987 N8_Buffer_t *bufferA_SHA1_p = NULL; 988 uint32_t bufferA_MD5_a; 989 uint32_t bufferA_SHA1_a; 990 unsigned int numCommands=0; 991 992 do 993 { 994 CHECK_OBJECT(req_p, ret); 995 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p; 996 CHECK_OBJECT(cb_p, ret); 997 998 secret1_p = hmacKey_p; 999 secret2_p = &(hmacKey_p[keyLength]); 1000 1001 /* 1) compute the first pseudorandom stream */ 1002 iterationCount_MD5 = N8_MD5_HASHES_REQUIRED_TLS(outputLength); 1003 iterationCount_SHA1 = N8_SHA1_HASHES_REQUIRED_TLS(outputLength); 1004 1005 /* allocate space for the command block */ 1006 numCommands = N8_CB_EA_TLSKEYMATERIALHASH_NUMCMDS(outputLength); 1007 1008 /* the code needs to be restructured to not depend on the numCommands +1 1009 * for the malloc. it works here where it is local, but if an external 1010 * caller it so preallocate the memory, it cannot be expected to allocate 1011 * n+1. the code herein must be fixed to not have that dependency. 1012 */ 1013 /* allocate a kernel buffer for the hashes */ 1014 bufferA_MD5_length = dataLength + EA_MD5_Hash_Length; 1015 bufferA_SHA1_length = dataLength + EA_SHA1_Hash_Length; 1016 1017 bufferA_MD5_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset + keyLen); 1018 bufferA_MD5_a = req_p->qr.physicalAddress + req_p->dataoffset + keyLen; 1019 bufferA_SHA1_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset + keyLen) + 1020 NEXT_WORD_SIZE(bufferA_MD5_length); 1021 bufferA_SHA1_a = req_p->qr.physicalAddress + req_p->dataoffset + keyLen + 1022 NEXT_WORD_SIZE(bufferA_MD5_length); 1023 1024 /* 1025 * Unfortunately HMAC command doesn't do what it supposed to do. 1026 * We have to calculate HMAC values "by hand". 1027 * Create as many commands to do this as we need. 1028 */ 1029 1030 /* Note that the first calculation is an oddball and must be done before 1031 * entering the loop. Due to this, we generate n-1 pairs and have to do 1032 * the final calculation outside of the loop. This is true for both MD5 1033 * and SHA1. */ 1034 1035 /* Calculate buffer A first time */ 1036 cb_p->opcode_iter_length = 1037 EA_Cmd_MD5_HMAC | (1 << EA_Cmd_Iterations_Shift) | dataLength; 1038 cb_p->read_data_addr_ls = msg_a; 1039 cb_p->write_data_addr_ls = bufferA_MD5_a; 1040 1041 /* set the HMAC key data */ 1042 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1043 { 1044 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n); 1045 } 1046 1047 memcpy(bufferA_MD5_p+EA_MD5_Hash_Length, msg_p, dataLength); 1048 1049 cb_p++; 1050 1051 for (l = 0, k = 0; l < iterationCount_MD5 - 1; l++, k+=EA_MD5_Hash_Length) 1052 { 1053 /* A) calculate pseudo random stream 1 */ 1054 /* set the opcode and length */ 1055 cb_p->opcode_iter_length = 1056 EA_Cmd_MD5_HMAC | (1 << EA_Cmd_Iterations_Shift) | 1057 bufferA_MD5_length; 1058 cb_p->read_data_addr_ls = bufferA_MD5_a; 1059 cb_p->write_data_addr_ls = (uint32_t) pseudorandomStream1_a + k; 1060 1061 /* set the HMAC key data */ 1062 /* TODO: are both termination tests necessary? will one ever fire 1063 * without the other? if not, just use the most restrictive. */ 1064 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1065 { 1066 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n); 1067 } 1068 1069 cb_p++; 1070 /* B) calculate buffer A */ 1071 /* set the opcode and length */ 1072 cb_p->opcode_iter_length = 1073 EA_Cmd_MD5_HMAC | (1 << EA_Cmd_Iterations_Shift) | 1074 EA_MD5_Hash_Length; 1075 cb_p->read_data_addr_ls = bufferA_MD5_a; 1076 cb_p->write_data_addr_ls = bufferA_MD5_a; 1077 1078 /* set the HMAC key data */ 1079 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1080 { 1081 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n); 1082 } 1083 1084 cb_p++; 1085 } 1086 /* compute the last psuedo random stream 1 */ 1087 /* A) calculate pseudo random stream 1 */ 1088 /* set the opcode and length */ 1089 cb_p->opcode_iter_length = 1090 EA_Cmd_MD5_HMAC | (1 << EA_Cmd_Iterations_Shift) | 1091 bufferA_MD5_length; 1092 cb_p->read_data_addr_ls = bufferA_MD5_a; 1093 cb_p->write_data_addr_ls = (uint32_t) pseudorandomStream1_a + k; 1094 1095 /* set the HMAC key data */ 1096 /* TODO: are both termination tests necessary? will one ever fire 1097 * without the other? if not, just use the most restrictive. */ 1098 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1099 { 1100 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n); 1101 } 1102 cb_p++; 1103 1104 /* 2) compute the second pseudorandom stream */ 1105 /* Calculate buffer A first time */ 1106 cb_p->opcode_iter_length = 1107 EA_Cmd_SHA1_HMAC | 1108 (1 << EA_Cmd_Iterations_Shift) | 1109 dataLength; 1110 cb_p->read_data_addr_ls = msg_a; 1111 cb_p->write_data_addr_ls = bufferA_SHA1_a; 1112 1113 /* set the HMAC key data */ 1114 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1115 { 1116 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n); 1117 } 1118 1119 memcpy(bufferA_SHA1_p+EA_SHA1_Hash_Length, msg_p, dataLength); 1120 1121 cb_p++; 1122 1123 for (l = 0, k = 0; l < iterationCount_SHA1 - 1; l++, k+=EA_SHA1_Hash_Length) 1124 { 1125 /* A) calculate pseudo random stream 2 */ 1126 /* set the opcode and length */ 1127 cb_p->opcode_iter_length = 1128 EA_Cmd_SHA1_HMAC | 1129 (1 << EA_Cmd_Iterations_Shift) | 1130 bufferA_SHA1_length; 1131 1132 cb_p->read_data_addr_ls = bufferA_SHA1_a; 1133 cb_p->write_data_addr_ls = (uint32_t) pseudorandomStream2_a + k; 1134 1135 /* set the HMAC key data */ 1136 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1137 { 1138 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n); 1139 } 1140 cb_p++; 1141 1142 /* B) calculate buffer A */ 1143 /* set the opcode and length */ 1144 cb_p->opcode_iter_length = 1145 EA_Cmd_SHA1_HMAC | 1146 (1 << EA_Cmd_Iterations_Shift) | 1147 EA_SHA1_Hash_Length; 1148 cb_p->read_data_addr_ls = bufferA_SHA1_a; 1149 cb_p->write_data_addr_ls = bufferA_SHA1_a; 1150 1151 /* set the HMAC key data */ 1152 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1153 { 1154 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n); 1155 } 1156 cb_p++; 1157 } 1158 1159 /* do the final calculation for psuedo random stream 2 */ 1160 /* A) calculate pseudo random stream 2 */ 1161 /* set the opcode and length */ 1162 cb_p->opcode_iter_length = 1163 EA_Cmd_SHA1_HMAC | 1164 (1 << EA_Cmd_Iterations_Shift) | 1165 bufferA_SHA1_length; 1166 1167 cb_p->read_data_addr_ls = bufferA_SHA1_a; 1168 cb_p->write_data_addr_ls = (uint32_t) pseudorandomStream2_a + k; 1169 cb_p->cp_si_context = EA_Cmd_SI_Mask; 1170 1171 /* set the HMAC key data */ 1172 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4) 1173 { 1174 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n); 1175 } 1176 1177 } 1178 while (FALSE); 1179 1180 DBG_PRINT_EA_CMD_BLOCKS("TLS Key Material Hash", 1181 (EA_CMD_BLOCK_t *) cmdBlock_p, 1182 numCommands); 1183 1184 /* clean up */ 1185 return ret; 1186} /* cb_ea_TLSKeyMaterialHash */ 1187 1188 1189/***************************************************************************** 1190 * cb_ea_IKEPrf 1191 *****************************************************************************/ 1192/** @ingroup cb_ea 1193 * @brief Prepares the command blocks for the N8_IKEPrf API 1194 * 1195 * @param req_p RW: pointer to API request structure 1196 * @param alg RO: hash algorithm (md5 or sha1) 1197 * @param kMsg_a RO: physical address of message to be hashed 1198 * @param msgLength RO: length of message in bytes 1199 * @param kKey_p RO: virtual address of key 1200 * @param keyLength RO: length of key in bytes 1201 * @param kRes_a RO: physical address of result 1202 * 1203 * @par Externals: 1204 * 1205 * @return 1206 * N8_STATUS_OK 1207 * 1208 * @par Errors: 1209 * N8_INVALID_HASH - hash is neither md5 nor sha1 1210 * N8_MALLOC_FAILED - problem allocating memory 1211 * 1212 * @par Locks: 1213 * None. 1214 * 1215 * @par Assumptions: 1216 *****************************************************************************/ 1217N8_Status_t cb_ea_IKEPrf(API_Request_t *req_p, 1218 EA_CMD_BLOCK_t *cmdBlock_p, 1219 const N8_HashAlgorithm_t alg, 1220 const uint32_t kMsg_a, 1221 const uint32_t msgLength, 1222 const N8_Buffer_t *kKey_p, 1223 const uint32_t keyLength, 1224 const uint32_t kRes_a) 1225{ 1226 N8_Status_t ret = N8_STATUS_OK; 1227 EA_HMAC_CMD_BLOCK_t *cb_p = NULL; 1228 N8_Buffer_t hmacKey[EA_HMAC_Key_Length]; 1229 int i, n; 1230 1231 1232 do 1233 { 1234 CHECK_OBJECT(req_p, ret); 1235 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p; 1236 CHECK_OBJECT(cb_p, ret); 1237 1238 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */ 1239 if (keyLength <= EA_HMAC_Key_Length) 1240 { 1241 memcpy(hmacKey, kKey_p, keyLength); 1242 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength); 1243 } 1244 else 1245 { 1246 ret = N8_INVALID_KEY_SIZE; 1247 break; 1248 } 1249 1250 1251 /* choose opcode/iteration count (1) and msg length 1252 * opcode is based on algorithm 1253 */ 1254 switch (alg) 1255 { 1256 case N8_HMAC_SHA1: 1257 { 1258 cb_p->opcode_iter_length = 1259 EA_Cmd_SHA1_IPSEC_KEYMAT | 1260 (N8_IKE_PRF_ITERATIONS << EA_Cmd_Iterations_Shift) | 1261 msgLength; 1262 break; 1263 } 1264 case N8_HMAC_MD5: 1265 { 1266 cb_p->opcode_iter_length = 1267 EA_Cmd_MD5_IPSEC_KEYMAT | 1268 (N8_IKE_PRF_ITERATIONS << EA_Cmd_Iterations_Shift) | 1269 msgLength; 1270 break; 1271 } 1272 default: 1273 { 1274 ret = N8_INVALID_HASH; 1275 break; 1276 } 1277 } 1278 1279 CHECK_RETURN(ret); 1280 1281 cb_p->read_data_addr_ls = kMsg_a; 1282 cb_p->write_data_addr_ls = kRes_a; 1283 cb_p->cp_si_context = EA_Cmd_SI_Mask; 1284 1285 /* set the HMAC key data */ 1286 for (i = 0, n = 0;i < EA_HMAC_Key_Length/sizeof(uint32_t); 1287 i++, n +=sizeof(uint32_t)) 1288 { 1289 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n); 1290 } 1291 } while (FALSE); 1292 1293 DBG_PRINT_EA_CMD_BLOCKS("IKEPrf", cmdBlock_p, 1294 N8_CB_EA_IKEPRF_NUMCMDS); 1295 1296 /* clean up */ 1297 return ret; 1298 1299} /* cb_ea_IKEPrf */ 1300 1301/***************************************************************************** 1302 * cb_ea_IKESKEYIDExpand 1303 *****************************************************************************/ 1304/** @ingroup cb_ea 1305 * @brief Prepares command blocks for the N8_IKESKEYIDExpand API 1306 * 1307 * @param req_p RW: pointer to API request structure 1308 * @param alg RO: hash algorithm (md5 or sha1) 1309 * @param kMsg_a RO: physical address of message to be hashed 1310 * @param msgLength RO: length of message to be hashed in bytes 1311 * @param kKey_p RO: virtual address of key 1312 * @param keyLength RO: length of key in bytes 1313 * @param kSKEYIDd_a RO: physical (base) address of result buffer 1314 * 1315 * @par Externals: 1316 * 1317 * @return 1318 * N8_STATUS_OK 1319 * 1320 * @par Errors: 1321 * N8_INVALID_HASH - hash is neither md5 nor sha1 1322 * N8_MALLOC_FAILED - problem allocating memory 1323 * 1324 * @par Locks: 1325 * None. 1326 * 1327 * @par Assumptions: 1328 *****************************************************************************/ 1329 1330N8_Status_t cb_ea_IKESKEYIDExpand(API_Request_t *req_p, 1331 EA_CMD_BLOCK_t *cmdBlock_p, 1332 const N8_HashAlgorithm_t alg, 1333 const uint32_t kMsg_a, 1334 const uint32_t msgLength, 1335 const N8_Buffer_t *kKey_p, 1336 const uint32_t keyLength, 1337 const uint32_t kSKEYIDd_a) 1338{ 1339 N8_Status_t ret = N8_STATUS_OK; 1340 EA_HMAC_CMD_BLOCK_t *cb_p = NULL; 1341 N8_Buffer_t hmacKey[EA_HMAC_Key_Length]; 1342 int i, n; 1343 1344 do 1345 { 1346 CHECK_OBJECT(req_p, ret); 1347 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p; 1348 CHECK_OBJECT(cb_p, ret); 1349 1350 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */ 1351 if (keyLength <= EA_HMAC_Key_Length) 1352 { 1353 memcpy(hmacKey, kKey_p, keyLength); 1354 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength); 1355 1356 } 1357 else 1358 { 1359 ret = N8_INVALID_KEY_SIZE; 1360 break; 1361 } 1362 1363 /* choose opcode/iteration count (3) and msg length 1364 * opcode is based on algorithm 1365 */ 1366 switch (alg) 1367 { 1368 case N8_HMAC_SHA1: 1369 { 1370 cb_p->opcode_iter_length = 1371 EA_Cmd_SHA1_IPSEC_SKEYID | 1372 (N8_IKE_SKEYID_ITERATIONS << EA_Cmd_Iterations_Shift) | 1373 msgLength; 1374 break; 1375 } 1376 case N8_HMAC_MD5: 1377 { 1378 cb_p->opcode_iter_length = 1379 EA_Cmd_MD5_IPSEC_SKEYID | 1380 (N8_IKE_SKEYID_ITERATIONS << EA_Cmd_Iterations_Shift) | 1381 msgLength; 1382 break; 1383 } 1384 default: 1385 { 1386 ret = N8_INVALID_HASH; 1387 break; 1388 } 1389 } 1390 1391 CHECK_RETURN(ret); 1392 1393 cb_p->read_data_addr_ls = kMsg_a; 1394 cb_p->write_data_addr_ls = kSKEYIDd_a; 1395 cb_p->cp_si_context = EA_Cmd_SI_Mask; 1396 1397 /* set the HMAC key data */ 1398 for (i = 0, n = 0;i < EA_HMAC_Key_Length/sizeof(uint32_t); 1399 i++, n +=sizeof(uint32_t)) 1400 { 1401 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n); 1402 } 1403 1404 1405 } while (FALSE); 1406 1407 DBG_PRINT_EA_CMD_BLOCKS("IKESKEYIDExpand", cmdBlock_p, 1408 N8_CB_EA_IKESKEYIDEXPAND_NUMCMDS); 1409 /* clean up */ 1410 return ret; 1411} /* cb_ea_IKESKEYIDExpand */ 1412 1413/***************************************************************************** 1414 * cb_ea_IKEKeyMaterialExpand 1415 *****************************************************************************/ 1416/** @ingroup cb_ea 1417 * @brief Prepares command blocks for the N8_IKEKeyMaterialExpand API 1418 * 1419 * @param req_p RW: pointer to API request structure 1420 * @param alg RO: hash algorithm (md5 or sha1) 1421 * @param kMsg_a RO: physical address of message to be hashed 1422 * @param msgLength RO: length of message to be hashed in bytes 1423 * @param kKey_p RO: virtual address of key 1424 * @param keyLength RO: length of key in bytes 1425 * @param kRes_a RO: physical address of result buffer 1426 * @param i_count RO: hash iteration count 1427 * 1428 * @par Externals: 1429 * 1430 * @return 1431 * N8_STATUS_OK 1432 * 1433 * @par Errors: 1434 * N8_INVALID_HASH - hash is neither md5 nor sha1 1435 * N8_MALLOC_FAILED - problem allocating memory 1436 * 1437 * @par Locks: 1438 * None. 1439 * 1440 * @par Assumptions: 1441 *****************************************************************************/ 1442N8_Status_t cb_ea_IKEKeyMaterialExpand(API_Request_t *req_p, 1443 EA_CMD_BLOCK_t *cmdBlock_p, 1444 const N8_HashAlgorithm_t alg, 1445 const uint32_t kMsg_a, 1446 const uint32_t msgLength, 1447 const N8_Buffer_t *kKey_p, 1448 const uint32_t keyLength, 1449 const uint32_t kRes_a, 1450 const uint32_t i_count) 1451{ 1452 N8_Status_t ret = N8_STATUS_OK; 1453 EA_HMAC_CMD_BLOCK_t *cb_p = NULL; 1454 N8_Buffer_t hmacKey[EA_HMAC_Key_Length]; 1455 int i, n; 1456 1457 do 1458 { 1459 CHECK_OBJECT(req_p, ret); 1460 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p; 1461 CHECK_OBJECT(cb_p, ret); 1462 1463 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */ 1464 if (keyLength <= EA_HMAC_Key_Length) 1465 { 1466 memcpy(hmacKey, kKey_p, keyLength); 1467 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength); 1468 1469 } 1470 else 1471 { 1472 ret = N8_INVALID_KEY_SIZE; 1473 break; 1474 } 1475 1476 /* choose opcode/iteration count (i_count) and msg length 1477 * opcode is based on algorithm 1478 */ 1479 switch (alg) 1480 { 1481 case N8_HMAC_SHA1: 1482 { 1483 cb_p->opcode_iter_length = 1484 EA_Cmd_SHA1_HMAC | 1485 (i_count << EA_Cmd_Iterations_Shift) | msgLength; 1486 break; 1487 } 1488 case N8_HMAC_MD5: 1489 { 1490 cb_p->opcode_iter_length = 1491 EA_Cmd_MD5_HMAC | 1492 (i_count << EA_Cmd_Iterations_Shift) | msgLength; 1493 break; 1494 } 1495 default: 1496 { 1497 ret = N8_INVALID_HASH; 1498 break; 1499 } 1500 } 1501 1502 CHECK_RETURN(ret); 1503 1504 cb_p->read_data_addr_ls = kMsg_a; 1505 cb_p->write_data_addr_ls = kRes_a; 1506 cb_p->cp_si_context = EA_Cmd_SI_Mask; 1507 1508 /* set the HMAC key data */ 1509 for (i = 0, n = 0;i < EA_HMAC_Key_Length/sizeof(uint32_t); 1510 i++, n +=sizeof(uint32_t)) 1511 { 1512 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n); 1513 } 1514 1515 } while ( FALSE ); 1516 1517 DBG_PRINT_EA_CMD_BLOCKS("IKEKeyMaterialExpand", 1518 cmdBlock_p, 1519 N8_CB_EA_IKEKEYMATERIALEXPAND_NUMCMDS); 1520 1521 /* clean up */ 1522 return ret; 1523 1524} /* cb_ea_IKEKeyMaterialExpand */ 1525 1526/***************************************************************************** 1527 * cb_ea_IKEEncryptKeyExpand 1528 *****************************************************************************/ 1529/** @ingroup cb_ea 1530 * @brief Prepares command blocks for the N8_IKEEncryptKeyExpand API 1531 * 1532 * @param req_p RW: pointer to API request structure 1533 * @param alg RO: hash algorithm (md5 or sha1) 1534 * @param kMsg_a RO: physical address of message to be hashed 1535 * @param msgLength RO: length of message to be hashed in bytes 1536 * @param kKey_p RO: virtual address of key 1537 * @param keyLength RO: length of key in bytes 1538 * @param kRes_a RO: physical address of result buffer 1539 * @param i_count RO: hash iteration count 1540 * 1541 * @par Externals: 1542 * 1543 * @return 1544 * N8_STATUS_OK 1545 * 1546 * @par Errors: 1547 * N8_INVALID_HASH - hash is neither md5 nor sha1 1548 * N8_MALLOC_FAILED - problem allocating memory 1549 * 1550 * @par Locks: 1551 * None. 1552 * 1553 * @par Assumptions: 1554 *****************************************************************************/ 1555N8_Status_t cb_ea_IKEEncryptKeyExpand(API_Request_t *req_p, 1556 EA_CMD_BLOCK_t *cmdBlock_p, 1557 const N8_HashAlgorithm_t alg, 1558 const uint32_t kMsg_a, 1559 const uint32_t msgLength, 1560 const N8_Buffer_t *kKey_p, 1561 const uint32_t keyLength, 1562 const uint32_t kRes_a, 1563 const uint32_t i_count) 1564{ 1565 N8_Status_t ret = N8_STATUS_OK; 1566 EA_HMAC_CMD_BLOCK_t *cb_p = NULL; 1567 N8_Buffer_t hmacKey[EA_HMAC_Key_Length]; 1568 int i, n; 1569 1570 do 1571 { 1572 CHECK_OBJECT(req_p, ret); 1573 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p; 1574 CHECK_OBJECT(cb_p, ret); 1575 1576 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */ 1577 if (keyLength <= EA_HMAC_Key_Length) 1578 { 1579 memcpy(hmacKey, kKey_p, keyLength); 1580 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength); 1581 1582 } 1583 else 1584 { 1585 ret = N8_INVALID_KEY_SIZE; 1586 break; 1587 } 1588 1589 /* choose opcode/iteration count (i_count) and msg length 1590 * opcode is based on algorithm 1591 */ 1592 switch (alg) 1593 { 1594 case N8_HMAC_SHA1: 1595 { 1596 cb_p->opcode_iter_length = 1597 EA_Cmd_SHA1_IPSEC_KEYMAT | 1598 (i_count << EA_Cmd_Iterations_Shift) | msgLength; 1599 break; 1600 } 1601 case N8_HMAC_MD5: 1602 { 1603 cb_p->opcode_iter_length = 1604 EA_Cmd_MD5_IPSEC_KEYMAT | 1605 (i_count << EA_Cmd_Iterations_Shift) | msgLength; 1606 break; 1607 } 1608 default: 1609 { 1610 ret = N8_INVALID_HASH; 1611 break; 1612 } 1613 } 1614 1615 CHECK_RETURN(ret); 1616 1617 cb_p->read_data_addr_ls = kMsg_a; 1618 cb_p->write_data_addr_ls = kRes_a; 1619 cb_p->cp_si_context = EA_Cmd_SI_Mask; 1620 1621 /* set the HMAC key data */ 1622 for (i = 0, n = 0;i < EA_HMAC_Key_Length/sizeof(uint32_t); 1623 i++, n +=sizeof(uint32_t)) 1624 { 1625 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n); 1626 } 1627 } while ( FALSE ); 1628 1629 DBG_PRINT_EA_CMD_BLOCKS("IKEEncryptKeyExpand", 1630 cmdBlock_p, 1631 N8_CB_EA_IKEENCRYPTKEYEXPAND_NUMCMDS); 1632 1633 /* clean up */ 1634 return ret; 1635 1636 1637} /* cb_ea_IKEEncryptKeyExpand */ 1638 1639/***************************************************************************** 1640 * cb_ea_writeContext 1641 *****************************************************************************/ 1642/** @ingroup cb_ea 1643 * @brief Creates command to Write Buffer to context memory. 1644 * 1645 * Creates write buffer to context memory specified by contextIndex. 1646 * 1647 * @param contextIndex RO: context memory to write to 1648 * @param req_p WO: command buffer 1649 * 1650 * @return 1651 * ret - returns N8_STATUS_OK if successful or Error value. 1652 * req_p - pointer to command buffer 1653 * 1654 * @par Errors: 1655 * N8_INVALID_OBJECT - request buffer was not allocated.<BR> 1656 * N8_MALLOC_FAILED - memory allocation failed.<BR> 1657 * 1658 * 1659 * @par Assumptions: 1660 * contextIndex is valid and was passed to us by his rightful owner. 1661 *****************************************************************************/ 1662 1663N8_Status_t cb_ea_writeContext (API_Request_t *req_p, 1664 EA_CMD_BLOCK_t *cb_p, 1665 const unsigned int contextIndex, 1666 const N8_Buffer_t *bufferToWrite_p, 1667 const unsigned int length) 1668{ 1669 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ 1670 1671 DBG(("cb_ea_writeContext\n")); 1672 1673 do 1674 { 1675 /* verify passed parameter */ 1676 CHECK_OBJECT(req_p, ret); 1677 CHECK_OBJECT(cb_p, ret); 1678 1679 /* set the context memory index */ 1680 cb_p->cp_si_context = contextIndex | EA_Cmd_CP_Mask | EA_Cmd_SI_Mask; 1681 /* set write command plus the number of bytes to write */ 1682 cb_p->opcode_iter_length = 1683 EA_Cmd_Write_Context_Memory | EA_CTX_Record_Byte_Length; 1684 1685 /* set the address of Zero buffer (kmalloc sets buffer to zero) */ 1686 /* memset(kmem_p->VirtualAddress, 0x0, CONTEXT_ENTRY_SIZE); */ 1687 1688 memcpy((void *)((int)req_p + req_p->dataoffset), bufferToWrite_p, length); 1689 cb_p->read_data_addr_ls = (uint32_t) req_p->qr.physicalAddress + req_p->dataoffset; 1690 /* free context memory */ 1691 1692 } while(FALSE); 1693 1694 DBG(("cb_ea_writeContext - FINISHED\n")); 1695 return ret; 1696} /* cb_ea_writeContext */ 1697 1698/***************************************************************************** 1699 * cb_ea_readContext 1700 *****************************************************************************/ 1701/** @ingroup cb_ea 1702 * @brief Creates command to Write Buffer to context memory. 1703 * 1704 * Creates write buffer to context memory specified by contextIndex. 1705 * 1706 * @param req_p RW: command buffer 1707 * @param contextIndex RO: context memory to write to 1708 * 1709 * @return 1710 * ret - returns N8_STATUS_OK if successful or Error value. 1711 * req_p - pointer to command buffer 1712 * 1713 * @par Errors: 1714 * N8_INVALID_OBJECT - request buffer was not allocated.<BR> 1715 * N8_MALLOC_FAILED - memory allocation failed.<BR> 1716 * 1717 * 1718 * @par Assumptions: 1719 * contextIndex is valid and was passed to us by his rightful owner. 1720 *****************************************************************************/ 1721 1722N8_Status_t cb_ea_readContext (API_Request_t *req_p, 1723 EA_CMD_BLOCK_t *cb_p, 1724 const unsigned int contextIndex, 1725 const uint32_t bufferToRead_a, 1726 const unsigned int length) 1727{ 1728 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ 1729 1730 DBG(("cb_writeContext\n")); 1731 1732 do 1733 { 1734 /* verify passed parameter */ 1735 CHECK_OBJECT(req_p, ret); 1736 CHECK_OBJECT(cb_p, ret); 1737 /* set the context memory index */ 1738 cb_p->cp_si_context = contextIndex | EA_Cmd_CP_Mask | EA_Cmd_SI_Mask; 1739 /* set write command plus the number of bytes to write */ 1740 cb_p->opcode_iter_length = 1741 EA_Cmd_Read_Context_Memory | EA_CTX_Record_Byte_Length; 1742 /* set the address of Zero buffer */ 1743 cb_p->write_data_addr_ls = (uint32_t) bufferToRead_a; 1744 /* free context memory */ 1745 1746 } while(FALSE); 1747 1748 DBG(("cb_writeContext - FINISHED\n")); 1749 return ret; 1750} /* cb_ea_readContext */ 1751 1752/* RC4 as implemented from a posting from 1753 * Newsgroups: sci.crypt 1754 * From: sterndark@netcom.com (David Sterndark) 1755 * Subject: RC4 Algorithm revealed. 1756 * Message-ID: <sternCvKL4B.Hyy@netcom.com> 1757 * Date: Wed, 14 Sep 1994 06:35:31 GMT 1758 */ 1759/* n8_RC4_set_key - Similar to RC4_set_key in openssl. Used to avoid 1760 dependency on OpenSSL in tests. */ 1761void n8_RC4_set_key(N8_RC4_t *key, int len, const unsigned char *data) 1762 { 1763 unsigned int tmp; 1764 unsigned int id1,id2; 1765 unsigned int *d; 1766 unsigned int i; 1767 1768 d= &(key->data[0]); 1769 for (i = 0; i < N8_ARC4_MAX_LENGTH; i++) 1770 { 1771 d[i]=i; 1772 } 1773 key->x = 0; 1774 key->y = 0; 1775 id1=id2=0; 1776 1777#define SK_LOOP(n) { \ 1778 tmp=d[(n)]; \ 1779 id2 = (data[id1] + tmp + id2) & 0xff; \ 1780 if (++id1 == len) id1=0; \ 1781 d[(n)]=d[id2]; \ 1782 d[id2]=tmp; } 1783 1784 for (i = 0; i < N8_ARC4_MAX_LENGTH; i += 4) 1785 { 1786 SK_LOOP(i+0); 1787 SK_LOOP(i+1); 1788 SK_LOOP(i+2); 1789 SK_LOOP(i+3); 1790 } 1791} 1792 1793 1794/*************************************************************************** 1795 * cb_ea_loadARC4KeyToContext 1796 *****************************************************************************/ 1797/** @ingroup cb_ea 1798 * @brief Loads ARC4 key to context memory. 1799 * 1800 * @param req_p RW: pointer to request block 1801 * @param cb_p RW: pointer to command block space 1802 * @param packetObj_p RO: pointer to packet object 1803 * @param cipher_p RO: ARC4 key info 1804 * @param hashAlgorithm RO: hash algorithm in use 1805 * @param ctx_p RW: pointer to context - virtaul 1806 * @param ctx_a RW: physical address of context 1807 * @param next_cb_pp RW: pointer to next command block pointer 1808 * 1809 * 1810 * @return 1811 * ret - returns N8_STATUS_OK if successful or Error value. 1812 * 1813 * @par Errors: 1814 * N8_INVALID_OBJECT - context request object is NULL<BR> 1815 * N8_MALLOC_FAILED - memory allocation failed<BR> 1816 * N8_INVALID_HASH - unsupported hash algorithm 1817 * 1818 * 1819 * @par Assumptions: 1820 * contextIndex is valid and was passed to us by his rightful owner. 1821 * ARC4 key is valid. 1822 *****************************************************************************/ 1823N8_Status_t cb_ea_loadARC4KeyToContext(API_Request_t *req_p, 1824 EA_CMD_BLOCK_t *cb_p, 1825 const N8_Packet_t *packetObj_p, 1826 const N8_CipherInfo_t *cipher_p, 1827 const N8_HashAlgorithm_t hashAlgorithm, 1828 EA_ARC4_CTX *ctx_p, 1829 const uint32_t ctx_a, 1830 EA_CMD_BLOCK_t **next_cb_pp) 1831{ 1832 int i,j; 1833 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ 1834 1835 N8_RC4_t keyARC4; 1836 DBG(("Command Block: loadARC4KeyToContext\n")); 1837 1838 do 1839 { 1840 /* verify passed parameters */ 1841 CHECK_OBJECT(packetObj_p, ret); 1842 CHECK_OBJECT(cb_p, ret); 1843 CHECK_OBJECT(req_p, ret); 1844 CHECK_OBJECT(cipher_p, ret); 1845 1846 switch (hashAlgorithm) 1847 { 1848 case N8_SHA1: 1849 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++) 1850 { 1851 ctx_p->secret1[i] = BE_to_uint32(&cipher_p->macSecret[i*sizeof(uint32_t)]); 1852 } 1853 break; 1854 case N8_MD5: 1855 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++) 1856 { 1857 ctx_p->secret1[i] = packetObj_p->cipherInfo.precompute1[i]; 1858 ctx_p->secret2[i] = packetObj_p->cipherInfo.precompute2[i]; 1859 } 1860 break; 1861 case N8_HMAC_MD5: 1862 case N8_HMAC_SHA1: 1863 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++) 1864 { 1865 ctx_p->secret1[i] = packetObj_p->hashPacket.ipadHMAC_iv[i]; 1866 ctx_p->secret2[i] = packetObj_p->hashPacket.opadHMAC_iv[i]; 1867 } 1868 break; 1869 default: 1870 ret = N8_INVALID_HASH; 1871 break; 1872 } 1873 CHECK_RETURN(ret); 1874 1875 ctx_p->sequence_number[0] = cipher_p->sequence_number[0]; 1876 ctx_p->sequence_number[1] = cipher_p->sequence_number[1]; 1877 1878 memset(&keyARC4, 0x0, sizeof(N8_RC4_t)); 1879 n8_RC4_set_key(&keyARC4, cipher_p->keySize, cipher_p->key.keyARC4); 1880 /* put the i & j counters in the context memory image */ 1881 ctx_p->i_j = 1882 ((keyARC4.y << EA_CTX_J_Shift) & EA_CTX_J_Mask) | 1883 ((keyARC4.x << EA_CTX_I_Shift) & EA_CTX_I_Mask); 1884 1885 /* put the S-box data in the context memory image */ 1886 for (i = 0,j = 0; i < 64; i++,j+=4) 1887 { 1888 ctx_p->s_box[i] = 1889 ((keyARC4.data[j] & 0xff) << 24) | 1890 ((keyARC4.data[j+1] & 0xff) << 16) | 1891 ((keyARC4.data[j+2] & 0xff) << 8) | 1892 ((keyARC4.data[j+3] & 0xff) ); 1893 1894 } 1895 1896#if 0 1897 { 1898 unsigned char *ptr; 1899 ptr = (unsigned char *) ctx_p; 1900 DBG(("Context window image\n")); 1901 for (i=0; i<EA_CTX_Record_Byte_Length; i+=16) { 1902 DBG(("%02x%02x%02x%02x ", 1903 *ptr++, *ptr++, *ptr++, *ptr++)); 1904 DBG(("%02x%02x%02x%02x ", 1905 *ptr++, *ptr++, *ptr++, *ptr++)); 1906 DBG(("%02x%02x%02x%02x ", 1907 *ptr++, *ptr++, *ptr++, *ptr++)); 1908 DBG(("%02x%02x%02x%02x ", 1909 *ptr++, *ptr++, *ptr++, *ptr++)); 1910 DBG(("\n")); 1911 } 1912 } 1913#endif 1914 1915 cb_p->cp_si_context = EA_Cmd_CP_Mask | 1916 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index); 1917 cb_p->read_data_addr_ls = (uint32_t) ctx_a; 1918 cb_p->opcode_iter_length = EA_Cmd_Write_Context_Memory | sizeof(EA_ARC4_CTX); 1919 1920 /* save next address for future use */ 1921 if (next_cb_pp != NULL) 1922 { 1923 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1); 1924 } 1925 1926 } while(FALSE); 1927 DBG_PRINT_EA_CMD_BLOCKS("Load ARC4 Key to Context Memory", cb_p, 1928 N8_CB_EA_LOADARC4KEYTOCONTEXT_NUMCMDS); 1929 return ret; 1930} /* cb_ea_loadARC4KeyToContext */ 1931 1932/*************************************************************************** 1933 * cb_ea_loadARC4key_Only 1934 *****************************************************************************/ 1935/** @ingroup cb_ea 1936 * @brief Loads ARC4 key to context memory. 1937 * 1938 * 1939 * @param req_p RW: pointer to request block 1940 * @param encryptObject_p RO: pointer to encrypted object 1941 * @param cipher_p RO: ARC4 key info 1942 * @param ctx_p RW: pointer to ARC4 context 1943 * 1944 * 1945 * @return 1946 * ret - returns N8_STATUS_OK if successful or Error value. 1947 * 1948 * @par Errors: 1949 * N8_INVALID_OBJECT - context request object is NULL<BR> 1950 * N8_MALLOC_FAILED - memory allocation failed<BR> 1951 * N8_INVALID_HASH - unsupported hash algorithm 1952 * 1953 * 1954 * @par Assumptions: 1955 * contextIndex is valid and was passed to us by his rightful owner. 1956 * ARC4 key is valid. 1957 *****************************************************************************/ 1958N8_Status_t cb_ea_loadARC4keyOnly(API_Request_t *req_p, 1959 EA_CMD_BLOCK_t *cb_p, 1960 const N8_ContextHandle_t *contextHandle_p, 1961 const N8_EncryptCipher_t *cipher_p) 1962{ 1963 int i,j; /* loop iterators */ 1964 N8_Status_t ret = N8_STATUS_OK; /* return code */ 1965 EA_ARC4_CTX *ctx_p = NULL; /* context virtual pointer */ 1966 1967 N8_RC4_t keyARC4; 1968 1969 DBG(("Command Block: cb_ea_loadARC4key_for_CryptoInterface\n")); 1970 1971 do 1972 { 1973 /* verify passed parameters */ 1974 CHECK_OBJECT(contextHandle_p, ret); 1975 CHECK_OBJECT(cipher_p, ret); 1976 CHECK_OBJECT(req_p, ret); 1977 CHECK_OBJECT(cb_p, ret); 1978 1979 ctx_p = (EA_ARC4_CTX *) ((int)req_p + req_p->dataoffset); 1980 ctx_p->sequence_number[0] = cipher_p->sequence_number[0]; 1981 ctx_p->sequence_number[1] = cipher_p->sequence_number[1]; 1982 1983 memset(&keyARC4, 0x0, sizeof(N8_RC4_t)); 1984 1985 n8_RC4_set_key(&keyARC4, cipher_p->keySize, cipher_p->key.keyARC4); 1986 /* put the i & j counters in the context memory image */ 1987 ctx_p->i_j = 1988 ((keyARC4.y << EA_CTX_J_Shift) & EA_CTX_J_Mask) | 1989 ((keyARC4.x << EA_CTX_I_Shift) & EA_CTX_I_Mask); 1990 1991 /* put the S-box data in the context memory image */ 1992 for (i=0,j=0; i<64; i++,j+=4) { 1993 ctx_p->s_box[i] = 1994 ((keyARC4.data[j] & 0xff) << 24) | 1995 ((keyARC4.data[j+1] & 0xff) << 16) | 1996 ((keyARC4.data[j+2] & 0xff) << 8) | 1997 ((keyARC4.data[j+3] & 0xff)); 1998 } 1999 2000 cb_p->cp_si_context = contextHandle_p->index | EA_Cmd_CP_Mask | 2001 EA_Cmd_SI_Mask; 2002 cb_p->opcode_iter_length = 2003 cb_p->read_data_addr_ls = req_p->qr.physicalAddress + req_p->dataoffset; 2004 cb_p->opcode_iter_length = EA_Cmd_Write_Context_Memory | sizeof(EA_ARC4_CTX); 2005 2006 2007 } while(FALSE); 2008 DBG_PRINT_EA_CMD_BLOCKS("Load ARC4 Key Only", cb_p, 2009 N8_CB_EA_LOADARC4KEYONLY_NUMCMDS); 2010 return ret; 2011} /* cb_ea_loadARC4keyOnly */ 2012 2013/***************************************************************************** 2014 * cb_ea_encrypt 2015 *****************************************************************************/ 2016/** @ingroup cb_ea 2017 * @brief Create the command blocks to perform raw encryption. 2018 * 2019 * @param req_p RW: Request pointer. 2020 * @param encryptObject_p RO: Pointer to the encrypted object. 2021 * @param message_p RO: Address of input message. 2022 * @param encryptedMessage_p RW: Pointer to the encrypted message (result). 2023 * @param messageLength RO: Message length. 2024 * 2025 * @par Externals 2026 * None 2027 * 2028 * @return 2029 * Error if raised. 2030 * 2031 * @par Errors 2032 * N8_MALLOC_FAILED - memory allocation failed<BR> 2033 * 2034 * @par Assumptions 2035 * None 2036 *****************************************************************************/ 2037N8_Status_t cb_ea_encrypt(const API_Request_t *req_p, 2038 EA_CMD_BLOCK_t *cb_p, 2039 N8_EncryptObject_t *encryptObject_p, 2040 const uint32_t message_a, 2041 const uint32_t encryptedMessage_a, 2042 const int messageLength) 2043{ 2044 N8_Status_t ret = N8_STATUS_OK; 2045 do 2046 { 2047 CHECK_OBJECT(req_p, ret); 2048 CHECK_OBJECT(cb_p, ret); 2049 2050 /* set the common elements */ 2051 cb_p->read_data_addr_ls = message_a; 2052 cb_p->write_data_addr_ls = encryptedMessage_a; 2053 cb_p->cp_si_context = EA_Cmd_SI_Mask; 2054 2055 /* based on cipher/hash, set the opcode and other specifics */ 2056 if (encryptObject_p->cipher == N8_CIPHER_ARC4) 2057 { 2058 /* ARC4 must use context index */ 2059 cb_p->cp_si_context |= EA_Cmd_CP_Mask | 2060 (EA_Ctx_Addr_Address_Mask & encryptObject_p->contextHandle.index); 2061 /* set the opcode */ 2062 cb_p->opcode_iter_length = EA_Cmd_ARC4 | messageLength; 2063 } 2064 else if (encryptObject_p->cipher == N8_CIPHER_DES) 2065 { 2066 /* set the opcode */ 2067 cb_p->opcode_iter_length = EA_Cmd_3DES_CBC_Encrypt | messageLength; 2068 /* DES may use context index or provide data in the command block */ 2069 if (encryptObject_p->contextHandle.inUse == N8_FALSE) 2070 { 2071 /* set the params common for 3DES */ 2072 cb_p->des_IV_ms = 2073 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.IV[N8_MS_BYTE]); 2074 cb_p->des_IV_ls = 2075 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.IV[N8_LS_BYTE]); 2076 cb_p->des_key1_ms = 2077 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key1[N8_MS_BYTE]); 2078 cb_p->des_key1_ls = 2079 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key1[N8_LS_BYTE]); 2080 cb_p->des_key2_ms = 2081 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key2[N8_MS_BYTE]); 2082 cb_p->des_key2_ls = 2083 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key2[N8_LS_BYTE]); 2084 cb_p->des_key3_ms = 2085 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key3[N8_MS_BYTE]); 2086 cb_p->des_key3_ls = 2087 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key3[N8_LS_BYTE]); 2088 2089 /* increment the sequence number. should we later discover the 2090 * operation failed, the sequence number will need to be returned to 2091 * its previous value. 2092 */ 2093 encryptObject_p->cipherInfo.sequence_number[1]++; 2094 /* check for wrapping */ 2095 if (encryptObject_p->cipherInfo.sequence_number[1] == 0) 2096 { 2097 /* increment the sequence number ms */ 2098 encryptObject_p->cipherInfo.sequence_number[0]++; 2099 } 2100 } 2101 else 2102 { 2103 /* set the CP bit and the context index */ 2104 cb_p->cp_si_context |= EA_Cmd_CP_Mask | 2105 (EA_Ctx_Addr_Address_Mask & encryptObject_p->contextHandle.index); 2106 } 2107 } 2108 else 2109 { 2110 ret = N8_INVALID_ENUM; 2111 break; 2112 } 2113 } while (FALSE); 2114 2115 DBG_PRINT_EA_CMD_BLOCKS("cb_ea_encrypt", (EA_CMD_BLOCK_t *) cb_p, 2116 N8_CB_EA_ENCRYPT_NUMCMDS); 2117 return ret; 2118} /* cb_ea_Encrypt */ 2119 2120 2121/***************************************************************************** 2122 * cb_ea_decrypt 2123 *****************************************************************************/ 2124/** @ingroup cb_ea 2125 * @brief Create the command blocks to perform decrypt operation. 2126 * 2127 * @param req_p RW: Request pointer. 2128 * @param encryptObject_p RO: Pointer to the encrypted object. 2129 * @param message_p RO: Address of results area. 2130 * @param encryptedMessage_p RW: Pointer to the encrypted message. 2131 * @param encryptedMessageLength RO: Encrypted message length. 2132 * 2133 * @par Externals 2134 * None 2135 * 2136 * @return 2137 * Error if raised. 2138 * 2139 * @par Errors 2140 * N8_MALLOC_FAILED - memory allocation failed<BR> 2141 * 2142 * @par Assumptions 2143 * None 2144 *****************************************************************************/ 2145N8_Status_t cb_ea_decrypt(API_Request_t *req_p, 2146 EA_CMD_BLOCK_t *cb_p, 2147 N8_EncryptObject_t *encryptObject_p, 2148 const uint32_t encryptedMessage_a, 2149 const uint32_t message_a, 2150 const unsigned int encryptedMessageLength) 2151{ 2152 N8_Status_t ret = N8_STATUS_OK; 2153 2154 do 2155 { 2156 CHECK_OBJECT(req_p, ret); 2157 CHECK_OBJECT(cb_p, ret); 2158 2159 /* set the common elements */ 2160 cb_p->read_data_addr_ls = encryptedMessage_a; 2161 cb_p->write_data_addr_ls = message_a; 2162 cb_p->cp_si_context = EA_Cmd_SI_Mask; 2163 2164 /* based on cipher, set the opcode and other specifics */ 2165 if (encryptObject_p->cipher == N8_CIPHER_ARC4) 2166 { 2167 /* ARC4 must use context index */ 2168 cb_p->cp_si_context |= EA_Cmd_CP_Mask | 2169 (EA_Ctx_Addr_Address_Mask & encryptObject_p->contextHandle.index); 2170 /* set the opcode */ 2171 cb_p->opcode_iter_length = EA_Cmd_ARC4 | encryptedMessageLength; 2172 } 2173 else /* must be 3DES */ 2174 { 2175 /* set the opcode */ 2176 cb_p->opcode_iter_length = EA_Cmd_3DES_CBC_Decrypt | encryptedMessageLength; 2177 /* DES may use context index or provide data in the command block */ 2178 if (encryptObject_p->contextHandle.inUse == N8_FALSE) 2179 { 2180 /* set the params common for 3DES */ 2181 cb_p->des_IV_ms = 2182 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.IV[N8_MS_BYTE]); 2183 cb_p->des_IV_ls = 2184 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.IV[N8_LS_BYTE]); 2185 cb_p->des_key1_ms = 2186 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key1[N8_MS_BYTE]); 2187 cb_p->des_key1_ls = 2188 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key1[N8_LS_BYTE]); 2189 cb_p->des_key2_ms = 2190 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key2[N8_MS_BYTE]); 2191 cb_p->des_key2_ls = 2192 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key2[N8_LS_BYTE]); 2193 cb_p->des_key3_ms = 2194 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key3[N8_MS_BYTE]); 2195 cb_p->des_key3_ls = 2196 BE_to_uint32(&encryptObject_p->cipherInfo.key.keyDES.key3[N8_LS_BYTE]); 2197 2198 /* increment the sequence number. should we later discover the 2199 * operation failed, the sequence number will need to be returned to 2200 * its previous value. 2201 */ 2202 encryptObject_p->cipherInfo.sequence_number[1]++; 2203 /* check for wrapping */ 2204 if (encryptObject_p->cipherInfo.sequence_number[1] == 0) 2205 { 2206 /* increment the sequence number ms */ 2207 encryptObject_p->cipherInfo.sequence_number[0]++; 2208 } 2209 } 2210 else 2211 { 2212 /* set the CP bit and the context index */ 2213 cb_p->cp_si_context |= EA_Cmd_CP_Mask | 2214 (EA_Ctx_Addr_Address_Mask & encryptObject_p->contextHandle.index); 2215 } 2216 } 2217 } while (FALSE); 2218 2219 DBG_PRINT_EA_CMD_BLOCKS("cb_ea_decrypt", 2220 (EA_CMD_BLOCK_t *) cb_p, 2221 N8_CB_EA_DECRYPT_NUMCMDS); 2222 return ret; 2223} /* cb_ea_decrypt */ 2224 2225/***************************************************************************** 2226 * cb_ea_loadDESKeyToContext 2227 *****************************************************************************/ 2228/** @ingroup cb_ea 2229 * @brief Loads DES key to context memory. 2230 * 2231 * 2232 * @param packetObj_p RO: pointer to packet object 2233 * @param cipherInfo_p RO: pointer to cipher infor 2234 * @param req_p RW: pointer to request block 2235 * @param hashAlgorithm RW: hash algorithm in use 2236 * 2237 * 2238 * @return 2239 * ret - returns N8_STATUS_OK if successful or Error value. 2240 * 2241 * @par Errors: 2242 * N8_INVALID_OBJECT - context request object is NULL<BR> 2243 * N8_MALLOC_FAILED - memory allocation failed<BR> 2244 * 2245 * 2246 * @par Assumptions: 2247 * contextIndex is valid and was passed to us by his rightful owner. 2248 * DES keys are valid. 2249 *****************************************************************************/ 2250 2251N8_Status_t cb_ea_loadDESKeyToContext(API_Request_t *req_p, 2252 EA_CMD_BLOCK_t *cb_p, 2253 const N8_Packet_t *packetObj_p, 2254 const N8_CipherInfo_t *cipherInfo_p, 2255 const N8_HashAlgorithm_t hashAlgorithm, 2256 EA_SSL30_CTX *ctx_p, 2257 const uint32_t ctx_a, 2258 EA_CMD_BLOCK_t **next_cb_pp) 2259{ 2260 unsigned int i; 2261 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ 2262 2263 DBG(("cb_ea_loadDESKeyToContext\n")); 2264 do 2265 { 2266 /* verify passed parameters */ 2267 CHECK_OBJECT(req_p, ret); 2268 CHECK_OBJECT(cb_p, ret); 2269 CHECK_OBJECT(packetObj_p, ret); 2270 CHECK_OBJECT(cipherInfo_p, ret); 2271 2272 /* build a context window image with the keys, IVs and other information*/ 2273 ctx_p->des_IV_ms = 2274 BE_to_uint32(&cipherInfo_p->IV[N8_MS_BYTE]); 2275 ctx_p->des_IV_ls = 2276 BE_to_uint32(&cipherInfo_p->IV[N8_LS_BYTE]); 2277 ctx_p->des_key1_ms = 2278 BE_to_uint32(&cipherInfo_p->key1[N8_MS_BYTE]); 2279 ctx_p->des_key1_ls = 2280 BE_to_uint32(&cipherInfo_p->key1[N8_LS_BYTE]); 2281 ctx_p->des_key2_ms = 2282 BE_to_uint32(&cipherInfo_p->key2[N8_MS_BYTE]); 2283 ctx_p->des_key2_ls = 2284 BE_to_uint32(&cipherInfo_p->key2[N8_LS_BYTE]); 2285 ctx_p->des_key3_ms = 2286 BE_to_uint32(&cipherInfo_p->key3[N8_MS_BYTE]); 2287 ctx_p->des_key3_ls = 2288 BE_to_uint32(&cipherInfo_p->key3[N8_LS_BYTE]); 2289 2290 switch (hashAlgorithm) 2291 { 2292 case N8_MD5: 2293 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++) 2294 { 2295 ctx_p->secret1[i] = packetObj_p->cipherInfo.precompute1[i]; 2296 ctx_p->secret2[i] = packetObj_p->cipherInfo.precompute2[i]; 2297 } 2298 break; 2299 case N8_HMAC_MD5_96: 2300 case N8_HMAC_SHA1_96: 2301 case N8_HMAC_MD5: 2302 case N8_HMAC_SHA1: 2303 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++) 2304 { 2305 ctx_p->secret1[i] = packetObj_p->hashPacket.ipadHMAC_iv[i]; 2306 ctx_p->secret2[i] = packetObj_p->hashPacket.opadHMAC_iv[i]; 2307 } 2308 break; 2309 case N8_SHA1: 2310 for (i = 0; i<5; i++) 2311 { 2312 ctx_p->secret1[i] = 2313 BE_to_uint32(&cipherInfo_p->macSecret[i * sizeof(uint32_t)]); 2314 } 2315 break; 2316 case N8_HASH_NONE: 2317 break; 2318 default: 2319 DBG(("Invalid hash: %s\n", N8_HashAlgorithm_t_text(hashAlgorithm))); 2320 ret = N8_INVALID_HASH; 2321 break; 2322 } 2323 CHECK_RETURN(ret); 2324 ctx_p->sequence_number[0] = cipherInfo_p->sequence_number[0]; 2325 ctx_p->sequence_number[1] = cipherInfo_p->sequence_number[1]; 2326 2327 /* insert a command to put the keys in context memory window */ 2328 cb_p->cp_si_context = EA_Cmd_CP_Mask | 2329 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index); 2330 cb_p->opcode_iter_length = 2331 EA_Cmd_Write_Context_Memory | sizeof(EA_SSL30_CTX); 2332 cb_p->read_data_addr_ls = (uint32_t) ctx_a; 2333 2334 /* save next address for future use */ 2335 if (next_cb_pp != NULL) 2336 { 2337 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1); 2338 } 2339 2340 } while (FALSE); 2341 2342 DBG_PRINT_EA_CMD_BLOCKS("Load DES Key to Context Memory", cb_p, 2343 N8_CB_EA_LOADDESKEYTOCONTEXT_NUMCMDS); 2344 return ret; 2345} /* cb_ea_loadDESKeyToContext */ 2346 2347 2348 2349/***************************************************************************** 2350 * cb_ea_loadDESkeyOnly 2351 *****************************************************************************/ 2352/** @ingroup cb_ea 2353 * @brief Loads DES key to context memory. 2354 * 2355 * @param req_p RW: pointer to request block 2356 * @param encryptObject_p RO: pointer to encrypted object 2357 * @param cipherInfo_p RO: pointer to cipher info 2358 * 2359 * @return 2360 * ret - returns N8_STATUS_OK if successful or Error value. 2361 * 2362 * @par Errors: 2363 * N8_INVALID_OBJECT - context request object is NULL<BR> 2364 * N8_MALLOC_FAILED - memory allocation failed<BR> 2365 * 2366 * 2367 * @par Assumptions: 2368 * contextIndex is valid and was passed to us by his rightful owner. 2369 * DES keys are valid. 2370 *****************************************************************************/ 2371N8_Status_t cb_ea_loadDESkeyOnly(API_Request_t *req_p, 2372 EA_CMD_BLOCK_t *cb_p, 2373 const N8_ContextHandle_t *contextHandle_p, 2374 const N8_EncryptCipher_t *cipherInfo_p) 2375{ 2376 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ 2377 EA_SSL30_CTX *ctx_p = NULL; 2378 2379 DBG(("cb_ea_loadDESkey_for_CryptoInterface\n")); 2380 2381 do 2382 { 2383 /* verify passed parameters */ 2384 CHECK_OBJECT(contextHandle_p, ret); 2385 CHECK_OBJECT(req_p, ret); 2386 CHECK_OBJECT(cipherInfo_p, ret); 2387 CHECK_OBJECT(cb_p, ret); 2388 2389 ctx_p = (EA_SSL30_CTX *) ((int)req_p + req_p->dataoffset); 2390 2391 /* build a context window image with the keys, IVs and other information*/ 2392 ctx_p->des_IV_ms = 2393 BE_to_uint32(&cipherInfo_p->key.keyDES.IV[N8_MS_BYTE]); 2394 ctx_p->des_IV_ls = 2395 BE_to_uint32(&cipherInfo_p->key.keyDES.IV[N8_LS_BYTE]); 2396 ctx_p->des_key1_ms = 2397 BE_to_uint32(&cipherInfo_p->key.keyDES.key1[N8_MS_BYTE]); 2398 ctx_p->des_key1_ls = 2399 BE_to_uint32(&cipherInfo_p->key.keyDES.key1[N8_LS_BYTE]); 2400 ctx_p->des_key2_ms = 2401 BE_to_uint32(&cipherInfo_p->key.keyDES.key2[N8_MS_BYTE]); 2402 ctx_p->des_key2_ls = 2403 BE_to_uint32(&cipherInfo_p->key.keyDES.key2[N8_LS_BYTE]); 2404 ctx_p->des_key3_ms = 2405 BE_to_uint32(&cipherInfo_p->key.keyDES.key3[N8_MS_BYTE]); 2406 ctx_p->des_key3_ls = 2407 BE_to_uint32(&cipherInfo_p->key.keyDES.key3[N8_LS_BYTE]); 2408 2409 ctx_p->sequence_number[0] = cipherInfo_p->sequence_number[0]; 2410 ctx_p->sequence_number[1] = cipherInfo_p->sequence_number[1]; 2411 2412 /* insert a command to put the keys in context memory window */ 2413 cb_p->cp_si_context = contextHandle_p->index | EA_Cmd_CP_Mask | 2414 EA_Cmd_SI_Mask; 2415 cb_p->opcode_iter_length = 2416 EA_Cmd_Write_Context_Memory | sizeof(EA_SSL30_CTX); 2417 cb_p->read_data_addr_ls = req_p->qr.physicalAddress + req_p->dataoffset; 2418 2419 2420 } while(FALSE); 2421 2422 DBG_PRINT_EA_CMD_BLOCKS("Load DES Key Only", cb_p, 2423 N8_CB_EA_LOADDESKEYONLY_NUMCMDS); 2424 return ret; 2425} /* cb_ea_loadDESkeyOnly */ 2426 2427/***************************************************************************** 2428 * cb_ea_loadIPsecKeyToContext 2429 *****************************************************************************/ 2430/** @ingroup cb_ea 2431 * @brief Loads IPsec DES key to context memory. 2432 * 2433 * 2434 * @param contextIndex RO: context memory to write 2435 * @param cipherInfo_p RO: pointer to cipher infor 2436 * @param req_p RW: pointer to request block 2437 * 2438 * 2439 * @return 2440 * ret - returns N8_STATUS_OK if successful or Error value. 2441 * 2442 * @par Errors: 2443 * N8_INVALID_OBJECT - context request object is NULL<BR> 2444 * N8_MALLOC_FAILED - memory allocation failed<BR> 2445 * 2446 * 2447 * @par Assumptions: 2448 * contextIndex is valid and was passed to us by his rightful owner. 2449 * DES keys are valid. 2450 *****************************************************************************/ 2451 2452N8_Status_t cb_ea_loadIPsecKeyToContext(API_Request_t *req_p, 2453 EA_CMD_BLOCK_t *cb_p, 2454 const unsigned int contextIndex, 2455 const N8_CipherInfo_t *cipherInfo_p, 2456 EA_IPSEC_CTX *IPsec_ctx_p, 2457 const uint32_t IPsec_ctx_a, 2458 EA_CMD_BLOCK_t **next_cb_pp) 2459{ 2460 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ 2461 2462 DBG(("cb_ea_loadIPsecKeyToContext\n")); 2463 2464 do 2465 { 2466 /* verify passed parameters */ 2467 CHECK_OBJECT(req_p, ret); 2468 CHECK_OBJECT(cb_p, ret); 2469 CHECK_OBJECT(cipherInfo_p, ret); 2470 2471 2472 /* build a context window image with the keys, IVs and other information*/ 2473 IPsec_ctx_p->des_key1_ms = 2474 BE_to_uint32(&cipherInfo_p->key1[N8_MS_BYTE]); 2475 IPsec_ctx_p->des_key1_ls = 2476 BE_to_uint32(&cipherInfo_p->key1[N8_LS_BYTE]); 2477 IPsec_ctx_p->des_key2_ms = 2478 BE_to_uint32(&cipherInfo_p->key2[N8_MS_BYTE]); 2479 IPsec_ctx_p->des_key2_ls = 2480 BE_to_uint32(&cipherInfo_p->key2[N8_LS_BYTE]); 2481 IPsec_ctx_p->des_key3_ms = 2482 BE_to_uint32(&cipherInfo_p->key3[N8_MS_BYTE]); 2483 IPsec_ctx_p->des_key3_ls = 2484 BE_to_uint32(&cipherInfo_p->key3[N8_LS_BYTE]); 2485 2486 2487 /* insert a command to put the keys in context memory window */ 2488 cb_p->cp_si_context = contextIndex | EA_Cmd_CP_Mask; 2489 cb_p->opcode_iter_length = 2490 EA_Cmd_Write_Context_Memory | sizeof(EA_IPSEC_CTX); 2491 cb_p->read_data_addr_ls = (uint32_t) IPsec_ctx_a; 2492 2493 /* save next address for future use */ 2494 if (next_cb_pp != NULL) 2495 { 2496 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1); 2497 } 2498 2499 } while(FALSE); 2500 2501 DBG_PRINT_EA_CMD_BLOCKS("Load IPsec Key to Context Memory", cb_p, 2502 N8_CB_EA_LOADIPSECKEYTOCONTEXT_NUMCMDS); 2503 return ret; 2504} /* cb_ea_loadIPsecKeyToContext */ 2505 2506/***************************************************************************** 2507 * cb_ea_IPsec 2508 *****************************************************************************/ 2509/** @ingroup cb_ea 2510 * @brief Create IPsec encrypt/authenticate or decrypt/verify command block. 2511 * 2512 * 2513 * 2514 * @param cmdBlock_p RO: Pointer to the beginning of the command block. 2515 * @param packetObj_p RO: The object denoting the decryption and 2516 * verification computation to be done. 2517 * PacketObject must have been initialized 2518 * for use with IPsec. 2519 * The state in PacketObject will be updated if 2520 * necessary as part of the call. <BR> 2521 * @param packet_a RO: Physical address of IPsec packet<BR> 2522 * @param result_a WO: Physical address of the encrypted and 2523 * authenticated result.<BR> 2524 * @param packetLength RO: Packet length.<BR> 2525 * @param SPI RO: The IPsec Security Parameter Index for the 2526 * packet. (4 bytes).<BR> 2527 * @param opCode RO: Op Code to build into the command block.<BR> 2528 * 2529 * @return 2530 * N/A 2531 * 2532 * @par Errors: 2533 * N/A 2534 * 2535 * @par Assumptions: 2536 * contextIndex is valid and was passed to us by his rightful owner. 2537 * DES keys are valid. 2538 *****************************************************************************/ 2539void cb_ea_IPsec(EA_CMD_BLOCK_t *cmdBlock_p, 2540 const N8_Packet_t *packetObj_p, 2541 const uint32_t packet_a, 2542 const uint32_t result_a, 2543 const unsigned int packetLength, 2544 const int SPI, 2545 const unsigned int opCode) 2546{ 2547 EA_IPSEC_CMD_BLOCK_t *cb_p = (EA_IPSEC_CMD_BLOCK_t *)cmdBlock_p; 2548 int i; 2549 2550 DBG(("cb_ea_IPsec\n")); 2551 2552 if (packetObj_p->contextHandle.inUse) 2553 { 2554 /* read keys from context memory */ 2555 cb_p->cp_si_context = EA_Cmd_CP_Mask | 2556 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index); 2557 } 2558 else 2559 { 2560 /* read keys from command block */ 2561 for (i = 0; i<5; i++) 2562 { 2563 cb_p->ipad[i] = packetObj_p->cipherInfo.key.IPsecKeyDES.ipad[i]; 2564 cb_p->opad[i] = packetObj_p->cipherInfo.key.IPsecKeyDES.opad[i]; 2565 } 2566 2567 cb_p->des_key1_ms = 2568 BE_to_uint32(&packetObj_p->cipherInfo.key1[N8_MS_BYTE]); 2569 cb_p->des_key1_ls = 2570 BE_to_uint32(&packetObj_p->cipherInfo.key1[N8_LS_BYTE]); 2571 cb_p->des_key2_ms = 2572 BE_to_uint32(&packetObj_p->cipherInfo.key2[N8_MS_BYTE]); 2573 cb_p->des_key2_ls = 2574 BE_to_uint32(&packetObj_p->cipherInfo.key2[N8_LS_BYTE]); 2575 cb_p->des_key3_ms = 2576 BE_to_uint32(&packetObj_p->cipherInfo.key3[N8_MS_BYTE]); 2577 cb_p->des_key3_ls = 2578 BE_to_uint32(&packetObj_p->cipherInfo.key3[N8_LS_BYTE]); 2579 2580 } 2581 2582 cb_p->opcode_iter_length = opCode | packetLength; 2583 2584 cb_p->read_data_addr_ls = (uint32_t) packet_a; 2585 cb_p->write_data_addr_ls = (uint32_t) result_a; 2586 cb_p->SPI = SPI; 2587 cb_p->sequence_number = packetObj_p->cipherInfo.key.IPsecKeyDES.sequence_number; 2588 cb_p->des_IV_ms = BE_to_uint32(&packetObj_p->cipherInfo.IV[N8_MS_BYTE]); 2589 cb_p->des_IV_ls = BE_to_uint32(&packetObj_p->cipherInfo.IV[N8_LS_BYTE]); 2590 2591 2592 DBG_PRINT_EA_CMD_BLOCKS("IPsec ", 2593 (EA_CMD_BLOCK_t *) cb_p, 2594 N8_CB_EA_IPSECENCRYPTAUTHENTICATE_NUMCMDS); 2595} /* cb_ea_IPsec */ 2596 2597 2598/************************************************** 2599 * Local Functions 2600 **************************************************/ 2601 2602/***************************************************************************** 2603 * convertToBits 2604 *****************************************************************************/ 2605/** @ingroup cb_ea 2606 * @brief Convert a 64 bit byte length to bits. 2607 * 2608 * The CCH requires the hash message length be specified in a 64 bit 2609 * quantity representing the number of bits. The API up to this point 2610 * keeps the value as the number of bytes spread across two 32 bit 2611 * quantities. This routine multiplies the two 32-bit quantities by 2612 * 8. It is done by shifting left 3 places. Of course, the upper 2613 * 3 bits of the least significant must be placed back into the most 2614 * significant. 2615 * 2616 * @param cb_p RW: command block pointer 2617 * @param obj_p RO: hash object 2618 * 2619 * @par Externals 2620 * None 2621 * 2622 * @par Errors 2623 * If the previous quantity is > 0x000FFFFF FFFFFFFF an overflow 2624 * will occur.<br> 2625 * 2626 * @par Assumptions 2627 * None 2628 *****************************************************************************/ 2629static void convertToBits(EA_CMD_BLOCK_t *cb_p, 2630 const N8_HashObject_t *obj_p, 2631 const n8_IVSrc_t ivSrc) 2632 2633{ 2634 uint32_t high, low; 2635 switch (ivSrc) 2636 { 2637 case N8_OPAD: 2638 high = obj_p->opad_Nh; 2639 low = obj_p->opad_Nl; 2640 break; 2641 default: 2642 high = obj_p->Nh; 2643 low = obj_p->Nl; 2644 break; 2645 } 2646 2647 cb_p->prev_length_ms = (high << 3) | (low >> 29); 2648 cb_p->prev_length_ls = low << 3; 2649} /* convertToBits */ 2650 2651/***************************************************************************** 2652 * cb_ea_TLSHandshakeHash 2653 *****************************************************************************/ 2654/** @ingroup cb_ea 2655 * @brief Generate the command blocks for the N8_HandshakeHashEnd 2656 * N8_TLS_CERT and N8_TLS_FINISH modes. 2657 * 2658 * This function generates the command blocks for the N8_TLS_CERT and 2659 * N8_TLS_FINISH modes. The algorithm is defined in RFC 2246 section 5. 2660 * 2661 * 2662 * @param req_p RO: The API request. 2663 * @param protocol RO: The protocol (N8_TLS_CERT or N8_TLS_FINISH). 2664 * @param resMD5_a RO: Physical address for MD5 result. 2665 * @param hashMsgMD5_a RO: Physical address for MD5 input. 2666 * @param md5Length RO: Length of MD5 input. 2667 * @param resSHA_a RO: Physical address for SHA1 result. 2668 * @param hashMsgSHA_a RO: Physical address for SHA1 input. 2669 * @param sha1Length RO: Length of SHA1 input. 2670 * @param resMD5PRF_a RO: Physical address for MD5 TLS PRF result. 2671 * @param resSHA1PRF_a RO: Physical address for SHA TLS PRF result. 2672 * @param key_p RO: The key for this transaction. 2673 * @param keyLength RO: The length of the key. 2674 * @param roleStr_a RO: Physical address for the role string. 2675 * 2676 * @par Externals: 2677 * None. 2678 * 2679 * @return 2680 * N8_STATUS_OK on success. 2681 * N8_INVALID_PARAMETER if the key is too long. 2682 * N8_INVALID_OBJECT if one of the inputs is invalid. 2683 * 2684 * @par Errors: 2685 * See return section. 2686 * 2687 * @par Locks: 2688 * None. 2689 * 2690 * @par Assumptions: 2691 * We are assuming that the command blocks are all memset to zero before 2692 * they are passed in to this function. 2693 *****************************************************************************/ 2694 2695N8_Status_t 2696cb_ea_TLSHandshakeHash(API_Request_t *req_p, 2697 N8_HashProtocol_t protocol, 2698 uint32_t resMD5_a, 2699 uint32_t hashMsgMD5_a, 2700 N8_HashObject_t *hashMsgMD5_p, 2701 int md5Length, 2702 uint32_t resSHA1_a, 2703 uint32_t hashMsgSHA1_a, 2704 N8_HashObject_t *hashMsgSHA1_p, 2705 int sha1Length, 2706 uint32_t resMD5PRF_a, 2707 uint32_t resSHA1PRF_a, 2708 const N8_Buffer_t *key_p, 2709 int keyLength, 2710 uint32_t roleStr_a) 2711{ 2712 EA_CMD_BLOCK_t *cb_p = NULL; 2713 EA_HMAC_CMD_BLOCK_t *cb_HMAC_p = NULL; 2714 N8_Status_t ret = N8_STATUS_OK; /* return status: OK or ERROR */ 2715 int halfKey; 2716 int dataLength; 2717 int nCmdBlocks = N8_CB_EA_CERTTLSHANDSHAKE_NUMCMDS; 2718 uint32_t keyBuffer[N8_HASH_BLOCK_SIZE]; 2719 int i; 2720 2721 DBG(("cb_ea_TLSHandshakeHash\n")); 2722 2723 do 2724 { 2725 /* verify passed parameters */ 2726 CHECK_OBJECT(req_p, ret); 2727 CHECK_OBJECT(req_p->EA_CommandBlock_ptr, ret); 2728 2729 if (keyLength > N8_HASH_BLOCK_SIZE * 2) 2730 { 2731 /* Note that eventually the upper level function 2732 will hash the key if it is too long. At the moment 2733 we are just going to return an error */ 2734 ret = N8_INVALID_PARAMETER; 2735 break; 2736 } 2737 2738 cb_p = req_p->EA_CommandBlock_ptr; 2739 2740 /* Command block 1: Complete the MD5 hash using command 0x14 */ 2741 cb_p->read_data_addr_ls = hashMsgMD5_a; 2742 cb_p->write_data_addr_ls = resMD5_a; 2743 memcpy(cb_p->hash_IV, hashMsgMD5_p->iv, sizeof(hashMsgMD5_p->iv)); 2744 cb_p->opcode_iter_length = EA_Cmd_MD5_End_cmdIV; 2745 cb_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & md5Length); 2746 convertToBits(cb_p, hashMsgMD5_p, N8_IV); 2747 cb_p ++; 2748 2749 /* Command block 2: Complete the SHA1 hash using command 0x24 */ 2750 cb_p->read_data_addr_ls = hashMsgSHA1_a; 2751 cb_p->write_data_addr_ls = resSHA1_a; 2752 cb_p->opcode_iter_length = EA_Cmd_SHA1_End_cmdIV; 2753 cb_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & sha1Length); 2754 memcpy(cb_p->hash_IV, hashMsgSHA1_p->iv, sizeof(hashMsgSHA1_p->iv)); 2755 convertToBits(cb_p, hashMsgSHA1_p, N8_IV); 2756 cb_HMAC_p = (EA_HMAC_CMD_BLOCK_t*) (cb_p + 1); 2757 2758 if (protocol == N8_TLS_FINISH) 2759 { 2760 /* At this point we have completed the MD5 and the SHA1 hash. So 2761 we should have the label, the MD5 hash and the SHA1 right next to 2762 each other ready to be used as input for the TLS pseudo random 2763 function (PRF). Please see RFC 2246 section 5 for a description of 2764 the PRF we are implementing. */ 2765 2766 /* According to the RFC, we use half of the key for the MD5 Hash and 2767 half for the SHA1 hash. If the key length is odd, we use the 2768 middle byte in both. So first we find the ceiling of half the 2769 key length */ 2770 halfKey = CEIL(keyLength, 2); 2771 2772 /* The length of the label, MD5 hash and SHA1 hash */ 2773 dataLength = N8_TLS_ROLE_STRING_LENGTH + MD5_HASH_RESULT_LENGTH + 2774 SHA1_HASH_RESULT_LENGTH; 2775 2776 /* This is for the debug printing */ 2777 nCmdBlocks = N8_CB_EA_FINISHTLSHANDSHAKE_NUMCMDS; 2778 2779 /* Command block 3: The MD5 portion of the PRF */ 2780 /* set the HMAC key data */ 2781 2782 /* Copy the first halfKey bytes of the key to the command block */ 2783 memset(keyBuffer, 0, sizeof(keyBuffer)); 2784 memcpy(keyBuffer, key_p, halfKey); 2785 2786 for (i = 0; i < halfKey; i+= 4) 2787 { 2788 cb_HMAC_p->hmac_key[i] = BE_to_uint32(keyBuffer + i); 2789 } 2790 2791 /* This is the role string plus the MD5 and SHA1 hash results */ 2792 cb_HMAC_p->read_data_addr_ls = roleStr_a; 2793 2794 cb_HMAC_p->write_data_addr_ls = resMD5PRF_a; 2795 cb_HMAC_p->opcode_iter_length = EA_Cmd_MD5_HMAC; 2796 cb_HMAC_p->opcode_iter_length |= (2 << EA_Cmd_Iterations_Shift); 2797 cb_HMAC_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & dataLength); 2798 cb_HMAC_p ++; 2799 2800 /* Command block 4: The SHA1 portion of the PRF. Uses the same 2801 input data as command block 3 */ 2802 /* Copy the second halfKey bytes of the key to the command block */ 2803 /* if the number of bytes was odd, we start the copy a byte earlier */ 2804 /* Note that since the two keys are guaranteed to be the same size 2805 we don't need to memset the key buffer again */ 2806 if (keyLength % 2) 2807 { 2808 /* The key length was odd */ 2809 memcpy(keyBuffer, &(key_p[halfKey - 1]), halfKey); 2810 } 2811 else 2812 { 2813 memcpy(keyBuffer, &(key_p[halfKey]), halfKey); 2814 } 2815 2816 for (i = 0; i < halfKey; i+= 4) 2817 { 2818 cb_HMAC_p->hmac_key[i] = BE_to_uint32(keyBuffer + i); 2819 } 2820 2821 /* This is STILL the role string plus MD5 and SHA1 hash results */ 2822 cb_HMAC_p->read_data_addr_ls = roleStr_a; 2823 2824 cb_HMAC_p->write_data_addr_ls = resSHA1PRF_a; 2825 cb_HMAC_p->cp_si_context = EA_Cmd_SI_Mask; 2826 cb_HMAC_p->opcode_iter_length = EA_Cmd_SHA1_HMAC; 2827 cb_HMAC_p->opcode_iter_length |= (2 << EA_Cmd_Iterations_Shift); 2828 cb_HMAC_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & dataLength); 2829 } 2830 else 2831 { 2832 cb_p->cp_si_context = EA_Cmd_SI_Mask; 2833 } 2834 } while (FALSE); 2835 2836 DBG_PRINT_EA_CMD_BLOCKS("TLS Handshake End/Cert", 2837 (EA_CMD_BLOCK_t *) req_p->EA_CommandBlock_ptr, 2838 nCmdBlocks); 2839 return ret; 2840 2841} 2842 2843 2844/***************************************************************************** 2845 * cb_ea_SSLHandshakeHash 2846 *****************************************************************************/ 2847/** @ingroup cb_ea 2848 * @brief Generate the command blocks for the N8_HandshakeHashEnd 2849 * N8_SSL_CERT and N8_SSL_FINISH modes. 2850 * 2851 * This function generates the command blocks for the N8_SSL_CERT and 2852 * N8_SSL_FINISH modes. 2853 * 2854 * 2855 * @param req_p RO: The API request. 2856 * @param resMD5_a RO: Physical address for MD5 result. 2857 * @param hashMsgMD5_a RO: Physical address for MD5 input. 2858 * @param md5Length RO: Length of MD5 input. 2859 * @param resSHA_a RO: Physical address for SHA1 result. 2860 * @param hashMsgSHA_a RO: Physical address for SHA1 input. 2861 * @param sha1Length RO: Length of SHA1 input. 2862 * @param endresMD5_a RO: Physical address for MD5 SSL result. 2863 * @param endresSHA1_a RO: Physical address for SHA SSL result. 2864 * @param outerMsgMD5_a RO: Physical address for the outerMsg. 2865 * @param outerMsgSHA_a RO: Physical address for the outerMsg. 2866 * 2867 * @par Externals: 2868 * None. 2869 * 2870 * @return 2871 * N8_STATUS_OK on success. 2872 * N8_INVALID_PARAMETER if the key is too long. 2873 * N8_INVALID_OBJECT if one of the inputs is invalid. 2874 * 2875 * @par Errors: 2876 * See return section. 2877 * 2878 * @par Locks: 2879 * None. 2880 * 2881 * @par Assumptions: 2882 * We are assuming that the command blocks are all memset to zero before 2883 * they are passed in to this function. 2884 *****************************************************************************/ 2885 2886N8_Status_t cb_ea_SSLHandshakeHash(API_Request_t *req_p, 2887 EA_CMD_BLOCK_t *cb_p, 2888 N8_HashObject_t *hObjMD5_p, 2889 uint32_t innerResult_md5_a, 2890 uint32_t hashMsgMD5_a, 2891 int hashingLength_md5, 2892 N8_HashObject_t *hObjSHA_p, 2893 uint32_t innerResult_sha_a, 2894 uint32_t hashMsgSHA_a, 2895 int hashingLength_sha, 2896 uint32_t endresMD5_a, 2897 uint32_t endresSHA1_a, 2898 uint32_t outerMsgMD5_a, 2899 unsigned int outer_md5Length, 2900 uint32_t outerMsgSHA1_a, 2901 unsigned int outer_shaLength) 2902{ 2903 N8_Status_t ret = N8_STATUS_OK; /* return status: OK or ERROR */ 2904 2905 DBG(("cb_ea_SSLHandshakeHash\n")); 2906 2907 do 2908 { 2909 /* verify passed parameters */ 2910 CHECK_OBJECT(req_p, ret); 2911 CHECK_OBJECT(cb_p, ret); 2912 /* Command block 1: Complete the inner MD5 hash */ 2913 cb_p->read_data_addr_ls = hashMsgMD5_a; 2914 cb_p->write_data_addr_ls = innerResult_md5_a; 2915 memcpy(cb_p->hash_IV, hObjMD5_p->iv, sizeof(hObjMD5_p->iv)); 2916 cb_p->opcode_iter_length = EA_Cmd_MD5_End_cmdIV | hashingLength_md5; 2917 convertToBits(cb_p, hObjMD5_p, N8_IV); 2918 cb_p ++; 2919 2920 /* Command block 2: Complete the inner SHA1 hash */ 2921 cb_p->read_data_addr_ls = hashMsgSHA_a; 2922 cb_p->write_data_addr_ls = innerResult_sha_a; 2923 memcpy(cb_p->hash_IV, hObjSHA_p->iv, sizeof(hObjSHA_p->iv)); 2924 cb_p->opcode_iter_length = EA_Cmd_SHA1_End_cmdIV | hashingLength_sha; 2925 convertToBits(cb_p, hObjSHA_p, N8_IV); 2926 cb_p ++; 2927 2928 /* Command block 3: Complete the outer MD5 hash using command 0x10 */ 2929 2930 /* Copy the first halfKey bytes of the key to the command block */ 2931 cb_p->read_data_addr_ls = outerMsgMD5_a; 2932 cb_p->write_data_addr_ls = endresMD5_a; 2933 cb_p->opcode_iter_length = EA_Cmd_MD5 | outer_md5Length; 2934 cb_p ++; 2935 2936 /* Command block 4: Complete the outer SHA1 hash using command 0x20 */ 2937 2938 cb_p->read_data_addr_ls = outerMsgSHA1_a; 2939 cb_p->write_data_addr_ls = endresSHA1_a; 2940 cb_p->cp_si_context = EA_Cmd_SI_Mask; 2941 cb_p->opcode_iter_length = EA_Cmd_SHA1 | outer_shaLength; 2942 } while (FALSE); 2943 2944 DBG_PRINT_EA_CMD_BLOCKS("SSL Handshake End", 2945 (EA_CMD_BLOCK_t *) req_p->EA_CommandBlock_ptr, 2946 N8_CB_EA_SSLSHANDSHAKEHASH_NUMCMDS); 2947 return ret; 2948 2949} /* cb_ea_SSLHandshakeHash */ 2950 2951 2952 2953 2954 2955