No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / pci / n8 / common / api / commands / n8_cb_ea.c
blob014b44fe4fc085a8687ff9f83e5b422a22a92d10
1 /*-
2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
3 * All rights reserved.
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:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
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.
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.
35 static 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.
40 * Generate command blocks for the Encryption Authentication functions.
42 *****************************************************************************/
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
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"
153 #define BYTES_PER_ITERATION 16
154 #define NUM_RANDOM_BYTES 64
156 static void convertToBits(EA_CMD_BLOCK_t *cb_p, const N8_HashObject_t *obj_p,
157 const n8_IVSrc_t ivSrc);
158 static void n8_RC4_set_key(N8_RC4_t *key, int len, const unsigned char *data);
161 /*****************************************************************************
162 * cb_ea_hashPartial
163 *****************************************************************************/
164 /** @ingroup cb_ea
165 * @brief Cmd Blocks for hash partial
167 * Command Block generation for EA function "Hash N Blocks,
168 * Pre-Load IV from Cmd Block" (opcodes 0x12 and 0x22)
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.
179 * @par Externals
180 * None
182 * @return
183 * Status
185 * @par Errors
186 * N8_MALLOC_FAILED - memory allocation failed<BR>
187 * N8_INVALID_HASH - hash specified was invalid<br>
189 * @par Assumptions
190 * Caller is responsible to free memory allocated to cmdBlock_pp.<br>
191 *****************************************************************************/
192 N8_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)
202 N8_Status_t ret = N8_STATUS_OK;
205 CHECK_OBJECT(req_p, ret);
206 CHECK_OBJECT(cb_p, ret);
208 cb_p->read_data_addr_ls = hashMsg_a;
209 cb_p->write_data_addr_ls = result_a;
211 /* If this is the last command block, set the command complete bit */
212 if (lastCmdBlock == N8_TRUE)
214 cb_p->cp_si_context = EA_Cmd_SI_Mask;
216 switch (ivSrc)
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;
229 /* set opcode */
230 switch (obj_p->type)
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;
246 CHECK_RETURN(ret);
247 cb_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & msgLength);
249 /* save next address for future use */
250 if (next_cb_pp != NULL)
252 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1);
256 } while (FALSE);
258 DBG_PRINT_EA_CMD_BLOCKS("Hash Partial", cb_p,
259 N8_CB_EA_HASHPARTIAL_NUMCMDS);
261 return ret;
262 } /* cb_ea_hashPartial */
265 /*****************************************************************************
266 * cb_ea_hashCompleteMessage
267 *****************************************************************************/
268 /** @ingroup cb_ea
269 * @brief Cmd Blocks for hash complete message
271 * Command Block generation for EA function "Simple Hash"
272 * (opcodes 0x10 and 0x20)
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.
283 * @par Externals
284 * None
286 * @return
287 * N8_STATUS_OK on success or one of the error codes specified.
289 * @par Errors
290 * N8_MALLOC_FAILED - memory allocation failed<BR>
291 * N8_INVALID_HASH - hash specified was invalid
293 * @par Assumptions
294 * Caller is responsible to free memory allocated to cmdBlock_pp.<br>
295 *****************************************************************************/
296 N8_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)
303 N8_Status_t ret = N8_STATUS_OK;
304 EA_HMAC_CMD_BLOCK_t *cb_HMAC_p = NULL;
307 CHECK_OBJECT(req_p, ret);
308 CHECK_OBJECT(cb_p, ret);
310 cb_HMAC_p = (EA_HMAC_CMD_BLOCK_t *) cb_p;
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;
316 /* set opcode */
317 switch (obj_p->type)
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;
347 CHECK_RETURN(ret);
349 } while (FALSE);
351 DBG_PRINT_EA_CMD_BLOCKS("Hash Complete Message", cb_p,
352 N8_CB_EA_HASHCOMPLETEMESSAGE_NUMCMDS);
354 return ret;
355 } /* cb_ea_hashCompleteMessage */
357 /*****************************************************************************
358 * cb_ea_hashEnd
359 *****************************************************************************/
360 /** @ingroup cb_ea
361 * @brief Cmd Blocks for hash end
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.
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.
378 * @par Externals
379 * None
381 * @return
382 * Status
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>
391 * @par Assumptions
392 * None
393 *****************************************************************************/
394 N8_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)
404 N8_Status_t ret = N8_STATUS_OK;
407 CHECK_OBJECT(req_p, ret);
408 CHECK_OBJECT(cb_p, ret);
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)
415 cb_p->cp_si_context = EA_Cmd_SI_Mask;
418 /* copy the iv */
419 switch (ivSrc)
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;
431 /* set opcode */
432 switch (obj_p->type)
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;
448 CHECK_RETURN(ret);
450 cb_p->opcode_iter_length |= (EA_Cmd_Data_Length_Mask & msgLength);
452 /* set the previous length in BITS. */
453 convertToBits(cb_p, obj_p, ivSrc);
455 /* save next address for future use */
456 if (next_cb_pp != NULL)
458 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1);
461 } while (FALSE);
463 DBG_PRINT_EA_CMD_BLOCKS("Hash End", cb_p,
464 N8_CB_EA_HASHEND_NUMCMDS);
465 return ret;
466 } /* cb_ea_hashEnd */
469 /*****************************************************************************
470 * cb_ea_hashHMACEnd
471 *****************************************************************************/
472 /** @ingroup cb_ea
473 * @brief Cmd Blocks for HMAC hash end
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.
485 * @par Externals
486 * None
488 * @return
489 * Status
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>
498 * @par Assumptions
499 * None
500 *****************************************************************************/
501 N8_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)
509 N8_Status_t ret = N8_STATUS_OK;
510 EA_HMAC_CMD_BLOCK_t *cb_HMAC_p = NULL;
513 CHECK_OBJECT(req_p, ret);
514 CHECK_OBJECT(cb_p, ret);
516 cb_HMAC_p = (EA_HMAC_CMD_BLOCK_t *) cb_p;
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)
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;
538 CHECK_RETURN(ret);
540 /* save next address for future use */
541 if (next_cb_pp != NULL)
543 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1);
546 } while (FALSE);
548 DBG_PRINT_EA_CMD_BLOCKS("Hash End", cb_p,
549 N8_CB_EA_HASHEND_NUMCMDS);
550 return ret;
551 } /* cb_ea_hashEnd */
554 /*****************************************************************************
555 * cb_ea_SSLKeyMaterialHash
556 *****************************************************************************/
557 /** @ingroup cb_ea
558 * @brief Compute SSL key material.
560 * The key material for an SSL hash is computed.
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.
570 * @par Externals
571 * None
573 * @return
574 * Status. Error condition if raised.
576 * @par Errors
577 * N8_MALLOC_FAILED - memory allocation failed<BR>
579 * @par Assumptions
580 * Results buffer is pre-allocated and of a sufficient size.
581 *****************************************************************************/
582 N8_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)
590 N8_Status_t ret = N8_STATUS_OK;
591 EA_MSH_CMD_BLOCK_t *cb_p = NULL;
592 int iterationCount;
596 CHECK_OBJECT(req_p, ret);
597 cb_p = (EA_MSH_CMD_BLOCK_t *) cmdBlock_p;
598 CHECK_OBJECT(cb_p, ret);
600 /* create a command block for CCH opcode 0x30:
601 * "Master Secret Hash Command"
604 iterationCount = (int) ((outputLength / (float) BYTES_PER_ITERATION) +
605 0.5);
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;
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);
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);
641 /* clean up */
642 /* nothing to clean up */
644 return ret;
645 } /* cb_ea_SSLKeyMaterialHash */
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.
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.
660 * @par Externals
661 * None
663 * @return
664 * Error if raised.
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>
670 * @par Assumptions
671 * None
672 *****************************************************************************/
673 N8_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)
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;
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);
690 /* ensure the sslProtocol passed is one of the valid values */
691 switch (type)
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);
702 /* check the version to ensure it is correct */
703 if (sslver != N8_SSL_VERSION)
705 return(N8_INVALID_VERSION);
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;
714 /* set the opcode */
715 cb_p->opcode_iter_length = opCode | length;
717 /* Assume context use */
718 cb_p->cp_si_context = EA_Cmd_CP_Mask |
719 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index);
721 /* based on cipher/hash, set the opcode and other specifics */
722 if (packetObj_p->packetCipher == N8_CIPHER_DES)
724 /* DES may use context index or provide data in the command block */
725 if (packetObj_p->contextHandle.inUse == N8_FALSE)
727 EA_SSL30_DES_MD5_CMD_BLOCK_t *desMd5_p;
728 int i;
730 /* Do not use context */
731 cb_p->cp_si_context = 0;
732 if (packetObj_p->packetHashAlgorithm == N8_MD5)
734 desMd5_p = (EA_SSL30_DES_MD5_CMD_BLOCK_t *) cb_p;
735 /* set the precompute values */
736 for (i = 0; i < 4; i++)
738 desMd5_p->precompute1[i] =
739 packetObj_p->cipherInfo.precompute1[i];
740 desMd5_p->precompute2[i] =
741 packetObj_p->cipherInfo.precompute2[i];
744 else /* N8_SHA1 */
746 for (i = 0; i < 5; i++)
748 cb_p->write_secret[i] = BE_to_uint32(
749 &packetObj_p->cipherInfo.macSecret[i*sizeof(uint32_t)]);
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]);
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.
777 packetObj_p->cipherInfo.sequence_number[1]++;
778 /* check for wrapping */
779 if (packetObj_p->cipherInfo.sequence_number[1] == 0)
781 /* increment the sequence number ms */
782 packetObj_p->cipherInfo.sequence_number[0]++;
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 */
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.
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.
805 * @par Externals
806 * None
808 * @return
809 * Error if raised.
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>
815 * @par Assumptions
816 * None
817 *****************************************************************************/
818 N8_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)
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;
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);
835 /* ensure the sslProtocol passed is one of the valid values */
836 switch (type)
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);
847 /* check the version to ensure it is correct */
848 if (tlsver != N8_TLS_VERSION)
850 return (N8_INVALID_VERSION);
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;
859 /* set the opcode */
860 cb_p->opcode_iter_length = opCode | length;
862 /* Assume context use */
863 cb_p->cp_si_context |= EA_Cmd_CP_Mask |
864 (EA_Ctx_Addr_Address_Mask & packetObj_p->contextHandle.index);
866 /* based on cipher/hash, set the opcode and other specifics */
867 if (packetObj_p->packetCipher == N8_CIPHER_DES)
869 /* DES may use context index or provide data in the command block */
870 if (packetObj_p->contextHandle.inUse == N8_FALSE)
872 EA_TLS10_CMD_BLOCK_t *tls_p = (EA_TLS10_CMD_BLOCK_t *) cb_p;
873 int i;
875 /* Clear context use */
876 cb_p->cp_si_context = 0;
878 if (packetObj_p->packetHashAlgorithm == N8_HMAC_MD5)
880 for (i = 0; i < 4; i++)
882 tls_p->ipad[i] = packetObj_p->hashPacket.ipadHMAC_iv[i];
883 tls_p->opad[i] = packetObj_p->hashPacket.opadHMAC_iv[i];
886 else /* N8_HMAC_SHA1 */
888 for (i = 0; i<5; i++)
890 tls_p->ipad[i] = packetObj_p->hashPacket.ipadHMAC_iv[i];
891 tls_p->opad[i] = packetObj_p->hashPacket.opadHMAC_iv[i];
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]);
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.
919 packetObj_p->cipherInfo.sequence_number[1]++;
920 /* check for wrapping */
921 if (packetObj_p->cipherInfo.sequence_number[1] == 0)
923 /* increment the sequence number ms */
924 packetObj_p->cipherInfo.sequence_number[0]++;
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 */
934 /*****************************************************************************
935 * cb_ea_TLSKeyMaterialHash
936 *****************************************************************************/
937 /** @ingroup cb_ea
938 * @brief Compute TLS key material.
940 * The key material for an TLS hash is computed.
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.
953 * @par Externals
954 * None
956 * @return
957 * Status. Error condition if raised.
959 * @par Errors
961 * @par Assumptions
962 * All buffers are pre-allocated and of a sufficient size.
963 *****************************************************************************/
964 N8_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)
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;
994 CHECK_OBJECT(req_p, ret);
995 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p;
996 CHECK_OBJECT(cb_p, ret);
998 secret1_p = hmacKey_p;
999 secret2_p = &(hmacKey_p[keyLength]);
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);
1005 /* allocate space for the command block */
1006 numCommands = N8_CB_EA_TLSKEYMATERIALHASH_NUMCMDS(outputLength);
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.
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;
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);
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.
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. */
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;
1041 /* set the HMAC key data */
1042 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4)
1044 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n);
1047 memcpy(bufferA_MD5_p+EA_MD5_Hash_Length, msg_p, dataLength);
1049 cb_p++;
1051 for (l = 0, k = 0; l < iterationCount_MD5 - 1; l++, k+=EA_MD5_Hash_Length)
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;
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)
1066 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n);
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;
1078 /* set the HMAC key data */
1079 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4)
1081 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n);
1084 cb_p++;
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;
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)
1100 cb_p->hmac_key[i] = BE_to_uint32(secret1_p+n);
1102 cb_p++;
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;
1113 /* set the HMAC key data */
1114 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4)
1116 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n);
1119 memcpy(bufferA_SHA1_p+EA_SHA1_Hash_Length, msg_p, dataLength);
1121 cb_p++;
1123 for (l = 0, k = 0; l < iterationCount_SHA1 - 1; l++, k+=EA_SHA1_Hash_Length)
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;
1132 cb_p->read_data_addr_ls = bufferA_SHA1_a;
1133 cb_p->write_data_addr_ls = (uint32_t) pseudorandomStream2_a + k;
1135 /* set the HMAC key data */
1136 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4)
1138 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n);
1140 cb_p++;
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;
1151 /* set the HMAC key data */
1152 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4)
1154 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n);
1156 cb_p++;
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;
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;
1171 /* set the HMAC key data */
1172 for (i = 0, n = 0; (i < 16) && (n < keyLength); i++, n +=4)
1174 cb_p->hmac_key[i] = BE_to_uint32(secret2_p+n);
1178 while (FALSE);
1180 DBG_PRINT_EA_CMD_BLOCKS("TLS Key Material Hash",
1181 (EA_CMD_BLOCK_t *) cmdBlock_p,
1182 numCommands);
1184 /* clean up */
1185 return ret;
1186 } /* cb_ea_TLSKeyMaterialHash */
1189 /*****************************************************************************
1190 * cb_ea_IKEPrf
1191 *****************************************************************************/
1192 /** @ingroup cb_ea
1193 * @brief Prepares the command blocks for the N8_IKEPrf API
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
1203 * @par Externals:
1205 * @return
1206 * N8_STATUS_OK
1208 * @par Errors:
1209 * N8_INVALID_HASH - hash is neither md5 nor sha1
1210 * N8_MALLOC_FAILED - problem allocating memory
1212 * @par Locks:
1213 * None.
1215 * @par Assumptions:
1216 *****************************************************************************/
1217 N8_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)
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;
1234 CHECK_OBJECT(req_p, ret);
1235 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p;
1236 CHECK_OBJECT(cb_p, ret);
1238 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1239 if (keyLength <= EA_HMAC_Key_Length)
1241 memcpy(hmacKey, kKey_p, keyLength);
1242 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength);
1244 else
1246 ret = N8_INVALID_KEY_SIZE;
1247 break;
1251 /* choose opcode/iteration count (1) and msg length
1252 * opcode is based on algorithm
1254 switch (alg)
1256 case N8_HMAC_SHA1:
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;
1264 case N8_HMAC_MD5:
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;
1272 default:
1274 ret = N8_INVALID_HASH;
1275 break;
1279 CHECK_RETURN(ret);
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;
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))
1289 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n);
1291 } while (FALSE);
1293 DBG_PRINT_EA_CMD_BLOCKS("IKEPrf", cmdBlock_p,
1294 N8_CB_EA_IKEPRF_NUMCMDS);
1296 /* clean up */
1297 return ret;
1299 } /* cb_ea_IKEPrf */
1301 /*****************************************************************************
1302 * cb_ea_IKESKEYIDExpand
1303 *****************************************************************************/
1304 /** @ingroup cb_ea
1305 * @brief Prepares command blocks for the N8_IKESKEYIDExpand API
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
1315 * @par Externals:
1317 * @return
1318 * N8_STATUS_OK
1320 * @par Errors:
1321 * N8_INVALID_HASH - hash is neither md5 nor sha1
1322 * N8_MALLOC_FAILED - problem allocating memory
1324 * @par Locks:
1325 * None.
1327 * @par Assumptions:
1328 *****************************************************************************/
1330 N8_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)
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;
1346 CHECK_OBJECT(req_p, ret);
1347 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p;
1348 CHECK_OBJECT(cb_p, ret);
1350 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1351 if (keyLength <= EA_HMAC_Key_Length)
1353 memcpy(hmacKey, kKey_p, keyLength);
1354 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength);
1357 else
1359 ret = N8_INVALID_KEY_SIZE;
1360 break;
1363 /* choose opcode/iteration count (3) and msg length
1364 * opcode is based on algorithm
1366 switch (alg)
1368 case N8_HMAC_SHA1:
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;
1376 case N8_HMAC_MD5:
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;
1384 default:
1386 ret = N8_INVALID_HASH;
1387 break;
1391 CHECK_RETURN(ret);
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;
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))
1401 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n);
1405 } while (FALSE);
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 */
1413 /*****************************************************************************
1414 * cb_ea_IKEKeyMaterialExpand
1415 *****************************************************************************/
1416 /** @ingroup cb_ea
1417 * @brief Prepares command blocks for the N8_IKEKeyMaterialExpand API
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
1428 * @par Externals:
1430 * @return
1431 * N8_STATUS_OK
1433 * @par Errors:
1434 * N8_INVALID_HASH - hash is neither md5 nor sha1
1435 * N8_MALLOC_FAILED - problem allocating memory
1437 * @par Locks:
1438 * None.
1440 * @par Assumptions:
1441 *****************************************************************************/
1442 N8_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)
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;
1459 CHECK_OBJECT(req_p, ret);
1460 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p;
1461 CHECK_OBJECT(cb_p, ret);
1463 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1464 if (keyLength <= EA_HMAC_Key_Length)
1466 memcpy(hmacKey, kKey_p, keyLength);
1467 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength);
1470 else
1472 ret = N8_INVALID_KEY_SIZE;
1473 break;
1476 /* choose opcode/iteration count (i_count) and msg length
1477 * opcode is based on algorithm
1479 switch (alg)
1481 case N8_HMAC_SHA1:
1483 cb_p->opcode_iter_length =
1484 EA_Cmd_SHA1_HMAC |
1485 (i_count << EA_Cmd_Iterations_Shift) | msgLength;
1486 break;
1488 case N8_HMAC_MD5:
1490 cb_p->opcode_iter_length =
1491 EA_Cmd_MD5_HMAC |
1492 (i_count << EA_Cmd_Iterations_Shift) | msgLength;
1493 break;
1495 default:
1497 ret = N8_INVALID_HASH;
1498 break;
1502 CHECK_RETURN(ret);
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;
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))
1512 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n);
1515 } while ( FALSE );
1517 DBG_PRINT_EA_CMD_BLOCKS("IKEKeyMaterialExpand",
1518 cmdBlock_p,
1519 N8_CB_EA_IKEKEYMATERIALEXPAND_NUMCMDS);
1521 /* clean up */
1522 return ret;
1524 } /* cb_ea_IKEKeyMaterialExpand */
1526 /*****************************************************************************
1527 * cb_ea_IKEEncryptKeyExpand
1528 *****************************************************************************/
1529 /** @ingroup cb_ea
1530 * @brief Prepares command blocks for the N8_IKEEncryptKeyExpand API
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
1541 * @par Externals:
1543 * @return
1544 * N8_STATUS_OK
1546 * @par Errors:
1547 * N8_INVALID_HASH - hash is neither md5 nor sha1
1548 * N8_MALLOC_FAILED - problem allocating memory
1550 * @par Locks:
1551 * None.
1553 * @par Assumptions:
1554 *****************************************************************************/
1555 N8_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)
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;
1572 CHECK_OBJECT(req_p, ret);
1573 cb_p = (EA_HMAC_CMD_BLOCK_t *) cmdBlock_p;
1574 CHECK_OBJECT(cb_p, ret);
1576 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1577 if (keyLength <= EA_HMAC_Key_Length)
1579 memcpy(hmacKey, kKey_p, keyLength);
1580 memset(hmacKey+keyLength, 0x0, EA_HMAC_Key_Length - keyLength);
1583 else
1585 ret = N8_INVALID_KEY_SIZE;
1586 break;
1589 /* choose opcode/iteration count (i_count) and msg length
1590 * opcode is based on algorithm
1592 switch (alg)
1594 case N8_HMAC_SHA1:
1596 cb_p->opcode_iter_length =
1597 EA_Cmd_SHA1_IPSEC_KEYMAT |
1598 (i_count << EA_Cmd_Iterations_Shift) | msgLength;
1599 break;
1601 case N8_HMAC_MD5:
1603 cb_p->opcode_iter_length =
1604 EA_Cmd_MD5_IPSEC_KEYMAT |
1605 (i_count << EA_Cmd_Iterations_Shift) | msgLength;
1606 break;
1608 default:
1610 ret = N8_INVALID_HASH;
1611 break;
1615 CHECK_RETURN(ret);
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;
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))
1625 cb_p->hmac_key[i] = BE_to_uint32(hmacKey+n);
1627 } while ( FALSE );
1629 DBG_PRINT_EA_CMD_BLOCKS("IKEEncryptKeyExpand",
1630 cmdBlock_p,
1631 N8_CB_EA_IKEENCRYPTKEYEXPAND_NUMCMDS);
1633 /* clean up */
1634 return ret;
1637 } /* cb_ea_IKEEncryptKeyExpand */
1639 /*****************************************************************************
1640 * cb_ea_writeContext
1641 *****************************************************************************/
1642 /** @ingroup cb_ea
1643 * @brief Creates command to Write Buffer to context memory.
1645 * Creates write buffer to context memory specified by contextIndex.
1647 * @param contextIndex RO: context memory to write to
1648 * @param req_p WO: command buffer
1650 * @return
1651 * ret - returns N8_STATUS_OK if successful or Error value.
1652 * req_p - pointer to command buffer
1654 * @par Errors:
1655 * N8_INVALID_OBJECT - request buffer was not allocated.<BR>
1656 * N8_MALLOC_FAILED - memory allocation failed.<BR>
1659 * @par Assumptions:
1660 * contextIndex is valid and was passed to us by his rightful owner.
1661 *****************************************************************************/
1663 N8_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)
1669 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
1671 DBG(("cb_ea_writeContext\n"));
1675 /* verify passed parameter */
1676 CHECK_OBJECT(req_p, ret);
1677 CHECK_OBJECT(cb_p, ret);
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;
1685 /* set the address of Zero buffer (kmalloc sets buffer to zero) */
1686 /* memset(kmem_p->VirtualAddress, 0x0, CONTEXT_ENTRY_SIZE); */
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 */
1692 } while(FALSE);
1694 DBG(("cb_ea_writeContext - FINISHED\n"));
1695 return ret;
1696 } /* cb_ea_writeContext */
1698 /*****************************************************************************
1699 * cb_ea_readContext
1700 *****************************************************************************/
1701 /** @ingroup cb_ea
1702 * @brief Creates command to Write Buffer to context memory.
1704 * Creates write buffer to context memory specified by contextIndex.
1706 * @param req_p RW: command buffer
1707 * @param contextIndex RO: context memory to write to
1709 * @return
1710 * ret - returns N8_STATUS_OK if successful or Error value.
1711 * req_p - pointer to command buffer
1713 * @par Errors:
1714 * N8_INVALID_OBJECT - request buffer was not allocated.<BR>
1715 * N8_MALLOC_FAILED - memory allocation failed.<BR>
1718 * @par Assumptions:
1719 * contextIndex is valid and was passed to us by his rightful owner.
1720 *****************************************************************************/
1722 N8_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)
1728 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
1730 DBG(("cb_writeContext\n"));
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 */
1746 } while(FALSE);
1748 DBG(("cb_writeContext - FINISHED\n"));
1749 return ret;
1750 } /* cb_ea_readContext */
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
1759 /* n8_RC4_set_key - Similar to RC4_set_key in openssl. Used to avoid
1760 dependency on OpenSSL in tests. */
1761 void n8_RC4_set_key(N8_RC4_t *key, int len, const unsigned char *data)
1763 unsigned int tmp;
1764 unsigned int id1,id2;
1765 unsigned int *d;
1766 unsigned int i;
1768 d= &(key->data[0]);
1769 for (i = 0; i < N8_ARC4_MAX_LENGTH; i++)
1771 d[i]=i;
1773 key->x = 0;
1774 key->y = 0;
1775 id1=id2=0;
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; }
1784 for (i = 0; i < N8_ARC4_MAX_LENGTH; i += 4)
1786 SK_LOOP(i+0);
1787 SK_LOOP(i+1);
1788 SK_LOOP(i+2);
1789 SK_LOOP(i+3);
1794 /***************************************************************************
1795 * cb_ea_loadARC4KeyToContext
1796 *****************************************************************************/
1797 /** @ingroup cb_ea
1798 * @brief Loads ARC4 key to context memory.
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
1810 * @return
1811 * ret - returns N8_STATUS_OK if successful or Error value.
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
1819 * @par Assumptions:
1820 * contextIndex is valid and was passed to us by his rightful owner.
1821 * ARC4 key is valid.
1822 *****************************************************************************/
1823 N8_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)
1832 int i,j;
1833 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
1835 N8_RC4_t keyARC4;
1836 DBG(("Command Block: loadARC4KeyToContext\n"));
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);
1846 switch (hashAlgorithm)
1848 case N8_SHA1:
1849 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++)
1851 ctx_p->secret1[i] = BE_to_uint32(&cipher_p->macSecret[i*sizeof(uint32_t)]);
1853 break;
1854 case N8_MD5:
1855 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++)
1857 ctx_p->secret1[i] = packetObj_p->cipherInfo.precompute1[i];
1858 ctx_p->secret2[i] = packetObj_p->cipherInfo.precompute2[i];
1860 break;
1861 case N8_HMAC_MD5:
1862 case N8_HMAC_SHA1:
1863 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++)
1865 ctx_p->secret1[i] = packetObj_p->hashPacket.ipadHMAC_iv[i];
1866 ctx_p->secret2[i] = packetObj_p->hashPacket.opadHMAC_iv[i];
1868 break;
1869 default:
1870 ret = N8_INVALID_HASH;
1871 break;
1873 CHECK_RETURN(ret);
1875 ctx_p->sequence_number[0] = cipher_p->sequence_number[0];
1876 ctx_p->sequence_number[1] = cipher_p->sequence_number[1];
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);
1885 /* put the S-box data in the context memory image */
1886 for (i = 0,j = 0; i < 64; i++,j+=4)
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) );
1896 #if 0
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"));
1913 #endif
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);
1920 /* save next address for future use */
1921 if (next_cb_pp != NULL)
1923 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1);
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 */
1932 /***************************************************************************
1933 * cb_ea_loadARC4key_Only
1934 *****************************************************************************/
1935 /** @ingroup cb_ea
1936 * @brief Loads ARC4 key to context memory.
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
1945 * @return
1946 * ret - returns N8_STATUS_OK if successful or Error value.
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
1954 * @par Assumptions:
1955 * contextIndex is valid and was passed to us by his rightful owner.
1956 * ARC4 key is valid.
1957 *****************************************************************************/
1958 N8_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)
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 */
1967 N8_RC4_t keyARC4;
1969 DBG(("Command Block: cb_ea_loadARC4key_for_CryptoInterface\n"));
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);
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];
1983 memset(&keyARC4, 0x0, sizeof(N8_RC4_t));
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);
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));
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);
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 */
2013 /*****************************************************************************
2014 * cb_ea_encrypt
2015 *****************************************************************************/
2016 /** @ingroup cb_ea
2017 * @brief Create the command blocks to perform raw encryption.
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.
2025 * @par Externals
2026 * None
2028 * @return
2029 * Error if raised.
2031 * @par Errors
2032 * N8_MALLOC_FAILED - memory allocation failed<BR>
2034 * @par Assumptions
2035 * None
2036 *****************************************************************************/
2037 N8_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)
2044 N8_Status_t ret = N8_STATUS_OK;
2047 CHECK_OBJECT(req_p, ret);
2048 CHECK_OBJECT(cb_p, ret);
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;
2055 /* based on cipher/hash, set the opcode and other specifics */
2056 if (encryptObject_p->cipher == N8_CIPHER_ARC4)
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;
2064 else if (encryptObject_p->cipher == N8_CIPHER_DES)
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)
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]);
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.
2093 encryptObject_p->cipherInfo.sequence_number[1]++;
2094 /* check for wrapping */
2095 if (encryptObject_p->cipherInfo.sequence_number[1] == 0)
2097 /* increment the sequence number ms */
2098 encryptObject_p->cipherInfo.sequence_number[0]++;
2101 else
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);
2108 else
2110 ret = N8_INVALID_ENUM;
2111 break;
2113 } while (FALSE);
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 */
2121 /*****************************************************************************
2122 * cb_ea_decrypt
2123 *****************************************************************************/
2124 /** @ingroup cb_ea
2125 * @brief Create the command blocks to perform decrypt operation.
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.
2133 * @par Externals
2134 * None
2136 * @return
2137 * Error if raised.
2139 * @par Errors
2140 * N8_MALLOC_FAILED - memory allocation failed<BR>
2142 * @par Assumptions
2143 * None
2144 *****************************************************************************/
2145 N8_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)
2152 N8_Status_t ret = N8_STATUS_OK;
2156 CHECK_OBJECT(req_p, ret);
2157 CHECK_OBJECT(cb_p, ret);
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;
2164 /* based on cipher, set the opcode and other specifics */
2165 if (encryptObject_p->cipher == N8_CIPHER_ARC4)
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;
2173 else /* must be 3DES */
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)
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]);
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.
2202 encryptObject_p->cipherInfo.sequence_number[1]++;
2203 /* check for wrapping */
2204 if (encryptObject_p->cipherInfo.sequence_number[1] == 0)
2206 /* increment the sequence number ms */
2207 encryptObject_p->cipherInfo.sequence_number[0]++;
2210 else
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);
2217 } while (FALSE);
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 */
2225 /*****************************************************************************
2226 * cb_ea_loadDESKeyToContext
2227 *****************************************************************************/
2228 /** @ingroup cb_ea
2229 * @brief Loads DES key to context memory.
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
2238 * @return
2239 * ret - returns N8_STATUS_OK if successful or Error value.
2241 * @par Errors:
2242 * N8_INVALID_OBJECT - context request object is NULL<BR>
2243 * N8_MALLOC_FAILED - memory allocation failed<BR>
2246 * @par Assumptions:
2247 * contextIndex is valid and was passed to us by his rightful owner.
2248 * DES keys are valid.
2249 *****************************************************************************/
2251 N8_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)
2260 unsigned int i;
2261 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
2263 DBG(("cb_ea_loadDESKeyToContext\n"));
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);
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]);
2290 switch (hashAlgorithm)
2292 case N8_MD5:
2293 for (i = 0; i < N8_PRECOMPUTE_SIZE; i++)
2295 ctx_p->secret1[i] = packetObj_p->cipherInfo.precompute1[i];
2296 ctx_p->secret2[i] = packetObj_p->cipherInfo.precompute2[i];
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++)
2305 ctx_p->secret1[i] = packetObj_p->hashPacket.ipadHMAC_iv[i];
2306 ctx_p->secret2[i] = packetObj_p->hashPacket.opadHMAC_iv[i];
2308 break;
2309 case N8_SHA1:
2310 for (i = 0; i<5; i++)
2312 ctx_p->secret1[i] =
2313 BE_to_uint32(&cipherInfo_p->macSecret[i * sizeof(uint32_t)]);
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;
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];
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;
2334 /* save next address for future use */
2335 if (next_cb_pp != NULL)
2337 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1);
2340 } while (FALSE);
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 */
2349 /*****************************************************************************
2350 * cb_ea_loadDESkeyOnly
2351 *****************************************************************************/
2352 /** @ingroup cb_ea
2353 * @brief Loads DES key to context memory.
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
2359 * @return
2360 * ret - returns N8_STATUS_OK if successful or Error value.
2362 * @par Errors:
2363 * N8_INVALID_OBJECT - context request object is NULL<BR>
2364 * N8_MALLOC_FAILED - memory allocation failed<BR>
2367 * @par Assumptions:
2368 * contextIndex is valid and was passed to us by his rightful owner.
2369 * DES keys are valid.
2370 *****************************************************************************/
2371 N8_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)
2376 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
2377 EA_SSL30_CTX *ctx_p = NULL;
2379 DBG(("cb_ea_loadDESkey_for_CryptoInterface\n"));
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);
2389 ctx_p = (EA_SSL30_CTX *) ((int)req_p + req_p->dataoffset);
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]);
2409 ctx_p->sequence_number[0] = cipherInfo_p->sequence_number[0];
2410 ctx_p->sequence_number[1] = cipherInfo_p->sequence_number[1];
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;
2420 } while(FALSE);
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 */
2427 /*****************************************************************************
2428 * cb_ea_loadIPsecKeyToContext
2429 *****************************************************************************/
2430 /** @ingroup cb_ea
2431 * @brief Loads IPsec DES key to context memory.
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
2439 * @return
2440 * ret - returns N8_STATUS_OK if successful or Error value.
2442 * @par Errors:
2443 * N8_INVALID_OBJECT - context request object is NULL<BR>
2444 * N8_MALLOC_FAILED - memory allocation failed<BR>
2447 * @par Assumptions:
2448 * contextIndex is valid and was passed to us by his rightful owner.
2449 * DES keys are valid.
2450 *****************************************************************************/
2452 N8_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)
2460 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
2462 DBG(("cb_ea_loadIPsecKeyToContext\n"));
2466 /* verify passed parameters */
2467 CHECK_OBJECT(req_p, ret);
2468 CHECK_OBJECT(cb_p, ret);
2469 CHECK_OBJECT(cipherInfo_p, ret);
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]);
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;
2493 /* save next address for future use */
2494 if (next_cb_pp != NULL)
2496 *next_cb_pp = (EA_CMD_BLOCK_t *) (cb_p + 1);
2499 } while(FALSE);
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 */
2506 /*****************************************************************************
2507 * cb_ea_IPsec
2508 *****************************************************************************/
2509 /** @ingroup cb_ea
2510 * @brief Create IPsec encrypt/authenticate or decrypt/verify command block.
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>
2529 * @return
2530 * N/A
2532 * @par Errors:
2533 * N/A
2535 * @par Assumptions:
2536 * contextIndex is valid and was passed to us by his rightful owner.
2537 * DES keys are valid.
2538 *****************************************************************************/
2539 void 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)
2547 EA_IPSEC_CMD_BLOCK_t *cb_p = (EA_IPSEC_CMD_BLOCK_t *)cmdBlock_p;
2548 int i;
2550 DBG(("cb_ea_IPsec\n"));
2552 if (packetObj_p->contextHandle.inUse)
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);
2558 else
2560 /* read keys from command block */
2561 for (i = 0; i<5; i++)
2563 cb_p->ipad[i] = packetObj_p->cipherInfo.key.IPsecKeyDES.ipad[i];
2564 cb_p->opad[i] = packetObj_p->cipherInfo.key.IPsecKeyDES.opad[i];
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]);
2582 cb_p->opcode_iter_length = opCode | packetLength;
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]);
2592 DBG_PRINT_EA_CMD_BLOCKS("IPsec ",
2593 (EA_CMD_BLOCK_t *) cb_p,
2594 N8_CB_EA_IPSECENCRYPTAUTHENTICATE_NUMCMDS);
2595 } /* cb_ea_IPsec */
2598 /**************************************************
2599 * Local Functions
2600 **************************************************/
2602 /*****************************************************************************
2603 * convertToBits
2604 *****************************************************************************/
2605 /** @ingroup cb_ea
2606 * @brief Convert a 64 bit byte length to bits.
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.
2616 * @param cb_p RW: command block pointer
2617 * @param obj_p RO: hash object
2619 * @par Externals
2620 * None
2622 * @par Errors
2623 * If the previous quantity is > 0x000FFFFF FFFFFFFF an overflow
2624 * will occur.<br>
2626 * @par Assumptions
2627 * None
2628 *****************************************************************************/
2629 static void convertToBits(EA_CMD_BLOCK_t *cb_p,
2630 const N8_HashObject_t *obj_p,
2631 const n8_IVSrc_t ivSrc)
2634 uint32_t high, low;
2635 switch (ivSrc)
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;
2647 cb_p->prev_length_ms = (high << 3) | (low >> 29);
2648 cb_p->prev_length_ls = low << 3;
2649 } /* convertToBits */
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.
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.
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.
2676 * @par Externals:
2677 * None.
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.
2684 * @par Errors:
2685 * See return section.
2687 * @par Locks:
2688 * None.
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 *****************************************************************************/
2695 N8_Status_t
2696 cb_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)
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;
2721 DBG(("cb_ea_TLSHandshakeHash\n"));
2725 /* verify passed parameters */
2726 CHECK_OBJECT(req_p, ret);
2727 CHECK_OBJECT(req_p->EA_CommandBlock_ptr, ret);
2729 if (keyLength > N8_HASH_BLOCK_SIZE * 2)
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;
2738 cb_p = req_p->EA_CommandBlock_ptr;
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 ++;
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);
2758 if (protocol == N8_TLS_FINISH)
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. */
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);
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;
2776 /* This is for the debug printing */
2777 nCmdBlocks = N8_CB_EA_FINISHTLSHANDSHAKE_NUMCMDS;
2779 /* Command block 3: The MD5 portion of the PRF */
2780 /* set the HMAC key data */
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);
2786 for (i = 0; i < halfKey; i+= 4)
2788 cb_HMAC_p->hmac_key[i] = BE_to_uint32(keyBuffer + i);
2791 /* This is the role string plus the MD5 and SHA1 hash results */
2792 cb_HMAC_p->read_data_addr_ls = roleStr_a;
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 ++;
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)
2808 /* The key length was odd */
2809 memcpy(keyBuffer, &(key_p[halfKey - 1]), halfKey);
2811 else
2813 memcpy(keyBuffer, &(key_p[halfKey]), halfKey);
2816 for (i = 0; i < halfKey; i+= 4)
2818 cb_HMAC_p->hmac_key[i] = BE_to_uint32(keyBuffer + i);
2821 /* This is STILL the role string plus MD5 and SHA1 hash results */
2822 cb_HMAC_p->read_data_addr_ls = roleStr_a;
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);
2830 else
2832 cb_p->cp_si_context = EA_Cmd_SI_Mask;
2834 } while (FALSE);
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;
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.
2851 * This function generates the command blocks for the N8_SSL_CERT and
2852 * N8_SSL_FINISH modes.
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.
2867 * @par Externals:
2868 * None.
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.
2875 * @par Errors:
2876 * See return section.
2878 * @par Locks:
2879 * None.
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 *****************************************************************************/
2886 N8_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)
2903 N8_Status_t ret = N8_STATUS_OK; /* return status: OK or ERROR */
2905 DBG(("cb_ea_SSLHandshakeHash\n"));
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 ++;
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 ++;
2928 /* Command block 3: Complete the outer MD5 hash using command 0x10 */
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 ++;
2936 /* Command block 4: Complete the outer SHA1 hash using command 0x20 */
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);
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;
2949 } /* cb_ea_SSLHandshakeHash */