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