2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
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>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided
20 * with the distribution.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 static char const n8_id
[] = "$Id: n8_cb_ea.c,v 1.1 2008/10/30 12:02:15 darran Exp $";
36 /*****************************************************************************/
38 * @brief Command blocks for EA.
40 * Generate command blocks for the Encryption Authentication functions.
42 *****************************************************************************/
44 /*****************************************************************************
46 * 08/18/03 brr Combine Encrypt/Decrypt command block generators for SSL,
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
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
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
80 * 10/15/01 bac Changed some interfaces to take unsigned ints, corrected a bug
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
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
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
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
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'
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
138 * 05/03/01 bac Replaced integer use of NULL with 0.
139 * 05/01/01 bac Support for SSLKeyMaterialHash. Also fixed some merge errors.
140 * 04/24/01 bac Support for hash partial and hash end.
141 * 04/12/01 bac Original version.
142 ****************************************************************************/
143 /** @defgroup cb_ea EA Command Block Generator
146 #include "n8_cb_ea.h"
147 #include "n8_ea_common.h" /* for typedef of EA_CMD_BLOCK_t */
148 #include "n8_common.h"
153 #define BYTES_PER_ITERATION 16
154 #define NUM_RANDOM_BYTES 64
156 static void convertToBits(EA_CMD_BLOCK_t
*cb_p
, const N8_HashObject_t
*obj_p
,
157 const n8_IVSrc_t ivSrc
);
158 static void n8_RC4_set_key(N8_RC4_t
*key
, int len
, const unsigned char *data
);
161 /*****************************************************************************
163 *****************************************************************************/
165 * @brief Cmd Blocks for hash partial
167 * Command Block generation for EA function "Hash N Blocks,
168 * Pre-Load IV from Cmd Block" (opcodes 0x12 and 0x22)
170 * @param req_p RW: Request pointer.
171 * @param obj_p RW: Pointer to hash object.
172 * @param hashMsg_a RO: Physical address of message to be hashed.
173 * @param msgLength RO: Length of message
174 * @param result_a RO: Pointer to allocated buffer for
175 * the results to be placed by the
176 * EA. This value is used but not
177 * written by this function.
186 * N8_MALLOC_FAILED - memory allocation failed<BR>
187 * N8_INVALID_HASH - hash specified was invalid<br>
190 * Caller is responsible to free memory allocated to cmdBlock_pp.<br>
191 *****************************************************************************/
192 N8_Status_t
cb_ea_hashPartial(API_Request_t
*req_p
,
193 EA_CMD_BLOCK_t
*cb_p
,
194 const N8_HashObject_t
*obj_p
,
195 const n8_IVSrc_t ivSrc
,
196 const uint32_t hashMsg_a
,
197 const unsigned int msgLength
,
198 const uint32_t result_a
,
199 EA_CMD_BLOCK_t
**next_cb_pp
,
202 N8_Status_t ret
= N8_STATUS_OK
;
205 CHECK_OBJECT(req_p
, ret
);
206 CHECK_OBJECT(cb_p
, ret
);
208 cb_p
->read_data_addr_ls
= hashMsg_a
;
209 cb_p
->write_data_addr_ls
= result_a
;
211 /* If this is the last command block, set the command complete bit */
212 if (lastCmdBlock
== N8_TRUE
)
214 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
219 memcpy(cb_p
->hash_IV
, obj_p
->ipadHMAC_iv
, sizeof(obj_p
->iv
));
222 memcpy(cb_p
->hash_IV
, obj_p
->opadHMAC_iv
, sizeof(obj_p
->iv
));
225 memcpy(cb_p
->hash_IV
, obj_p
->iv
, sizeof(obj_p
->iv
));
235 cb_p
->opcode_iter_length
= EA_Cmd_MD5_Mid_cmdIV
;
239 case N8_HMAC_SHA1_96
:
240 cb_p
->opcode_iter_length
= EA_Cmd_SHA1_Mid_cmdIV
;
243 ret
= N8_INVALID_HASH
;
247 cb_p
->opcode_iter_length
|= (EA_Cmd_Data_Length_Mask
& msgLength
);
249 /* save next address for future use */
250 if (next_cb_pp
!= NULL
)
252 *next_cb_pp
= (EA_CMD_BLOCK_t
*) (cb_p
+ 1);
258 DBG_PRINT_EA_CMD_BLOCKS("Hash Partial", cb_p
,
259 N8_CB_EA_HASHPARTIAL_NUMCMDS
);
262 } /* cb_ea_hashPartial */
265 /*****************************************************************************
266 * cb_ea_hashCompleteMessage
267 *****************************************************************************/
269 * @brief Cmd Blocks for hash complete message
271 * Command Block generation for EA function "Simple Hash"
272 * (opcodes 0x10 and 0x20)
274 * @param req_p RW: Request pointer.
275 * @param obj_p RW: Pointer to hash object.
276 * @param hashMsg_a RO: Physical address of message to be hashed.
277 * @param msgLength RO: Length of message
278 * @param result_a RO: Pointer to allocated buffer for
279 * the results to be placed by the
280 * EA. This value is used but not
281 * written by this function.
287 * N8_STATUS_OK on success or one of the error codes specified.
290 * N8_MALLOC_FAILED - memory allocation failed<BR>
291 * N8_INVALID_HASH - hash specified was invalid
294 * Caller is responsible to free memory allocated to cmdBlock_pp.<br>
295 *****************************************************************************/
296 N8_Status_t
cb_ea_hashCompleteMessage(API_Request_t
*req_p
,
297 EA_CMD_BLOCK_t
*cb_p
,
298 const N8_HashObject_t
*obj_p
,
299 const uint32_t hashMsg_a
,
300 const unsigned int msgLength
,
301 const uint32_t result_a
)
303 N8_Status_t ret
= N8_STATUS_OK
;
304 EA_HMAC_CMD_BLOCK_t
*cb_HMAC_p
= NULL
;
307 CHECK_OBJECT(req_p
, ret
);
308 CHECK_OBJECT(cb_p
, ret
);
310 cb_HMAC_p
= (EA_HMAC_CMD_BLOCK_t
*) cb_p
;
312 cb_p
->read_data_addr_ls
= hashMsg_a
;
313 cb_p
->write_data_addr_ls
= result_a
;
314 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
320 cb_p
->opcode_iter_length
=
321 EA_Cmd_MD5
| (EA_Cmd_Data_Length_Mask
& msgLength
);
325 memcpy(cb_HMAC_p
->hmac_key
, obj_p
->hashedHMACKey
, sizeof(obj_p
->hashedHMACKey
));
326 cb_p
->opcode_iter_length
=
328 ((1 << EA_Cmd_Iterations_Shift
) & EA_Cmd_Iterations_Mask
) |
329 (EA_Cmd_Data_Length_Mask
& msgLength
));
332 cb_p
->opcode_iter_length
=
333 EA_Cmd_SHA1
| (EA_Cmd_Data_Length_Mask
& msgLength
);
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
=
340 ((1 << EA_Cmd_Iterations_Shift
) & EA_Cmd_Iterations_Mask
) |
341 (EA_Cmd_Data_Length_Mask
& msgLength
));
344 ret
= N8_INVALID_HASH
;
351 DBG_PRINT_EA_CMD_BLOCKS("Hash Complete Message", cb_p
,
352 N8_CB_EA_HASHCOMPLETEMESSAGE_NUMCMDS
);
355 } /* cb_ea_hashCompleteMessage */
357 /*****************************************************************************
359 *****************************************************************************/
361 * @brief Cmd Blocks for hash end
363 * Command Block generation for EA function "Hash Last Segment,
364 * Pre-Load IV from Cmd Block" (opcodes 0x14 and 0x24). This hardware
365 * command does the final hash for a complete message. Note the
366 * message passed is the residual from the previous set of partial
367 * hashes. The length may be from 0 to the maximum of 16K.
369 * @param req_p RW: Request pointer.
370 * @param obj_p RW: Pointer to hash object.
371 * @param hashMsg_a RO: Physical address of message to be hashed.
372 * @param msgLength RO: Length of message
373 * @param result_a RO: Pointer to allocated buffer for
374 * the results to be placed by the
375 * EA. This value is used but not
376 * written by this function.
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>
393 *****************************************************************************/
394 N8_Status_t
cb_ea_hashEnd(API_Request_t
*req_p
,
395 EA_CMD_BLOCK_t
*cb_p
,
396 const N8_HashObject_t
*obj_p
,
397 const n8_IVSrc_t ivSrc
,
398 const uint32_t hashMsg_a
,
399 const unsigned int msgLength
,
400 const uint32_t result_a
,
401 EA_CMD_BLOCK_t
**next_cb_pp
,
404 N8_Status_t ret
= N8_STATUS_OK
;
407 CHECK_OBJECT(req_p
, ret
);
408 CHECK_OBJECT(cb_p
, ret
);
410 cb_p
->read_data_addr_ls
= hashMsg_a
;
411 cb_p
->write_data_addr_ls
= result_a
;
412 /* If this is the last command block, set the command complete bit */
413 if (lastCmdBlock
== N8_TRUE
)
415 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
422 memcpy(cb_p
->hash_IV
, obj_p
->ipadHMAC_iv
, sizeof(obj_p
->iv
));
425 memcpy(cb_p
->hash_IV
, obj_p
->opadHMAC_iv
, sizeof(obj_p
->iv
));
428 memcpy(cb_p
->hash_IV
, obj_p
->iv
, sizeof(obj_p
->iv
));
437 cb_p
->opcode_iter_length
= EA_Cmd_MD5_End_cmdIV
;
441 case N8_HMAC_SHA1_96
:
442 cb_p
->opcode_iter_length
= EA_Cmd_SHA1_End_cmdIV
;
445 ret
= N8_INVALID_HASH
;
450 cb_p
->opcode_iter_length
|= (EA_Cmd_Data_Length_Mask
& msgLength
);
452 /* set the previous length in BITS. */
453 convertToBits(cb_p
, obj_p
, ivSrc
);
455 /* save next address for future use */
456 if (next_cb_pp
!= NULL
)
458 *next_cb_pp
= (EA_CMD_BLOCK_t
*) (cb_p
+ 1);
463 DBG_PRINT_EA_CMD_BLOCKS("Hash End", cb_p
,
464 N8_CB_EA_HASHEND_NUMCMDS
);
466 } /* cb_ea_hashEnd */
469 /*****************************************************************************
471 *****************************************************************************/
473 * @brief Cmd Blocks for HMAC hash end
476 * @param req_p RW: Request pointer.
477 * @param obj_p RW: Pointer to hash object.
478 * @param hashMsg_a RO: Physical address of message to be hashed.
479 * @param msgLength RO: Length of message
480 * @param result_a RO: Pointer to allocated buffer for
481 * the results to be placed by the
482 * EA. This value is used but not
483 * written by this function.
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>
500 *****************************************************************************/
501 N8_Status_t
cb_ea_hashHMACEnd(API_Request_t
*req_p
,
502 EA_CMD_BLOCK_t
*cb_p
,
503 const N8_HashObject_t
*obj_p
,
504 const uint32_t hashMsg_a
,
505 const unsigned int msgLength
,
506 const uint32_t result_a
,
507 EA_CMD_BLOCK_t
**next_cb_pp
)
509 N8_Status_t ret
= N8_STATUS_OK
;
510 EA_HMAC_CMD_BLOCK_t
*cb_HMAC_p
= NULL
;
513 CHECK_OBJECT(req_p
, ret
);
514 CHECK_OBJECT(cb_p
, ret
);
516 cb_HMAC_p
= (EA_HMAC_CMD_BLOCK_t
*) cb_p
;
518 cb_HMAC_p
->read_data_addr_ls
= (unsigned int) hashMsg_a
;
519 cb_HMAC_p
->write_data_addr_ls
= (unsigned int) result_a
;
520 memcpy(cb_HMAC_p
->hmac_key
, obj_p
->hashedHMACKey
, sizeof(obj_p
->hashedHMACKey
));
526 cb_HMAC_p
->opcode_iter_length
= EA_Cmd_MD5_HMAC
| msgLength
|
527 ((1 << EA_Cmd_Iterations_Shift
) & EA_Cmd_Iterations_Mask
);
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
);
535 ret
= N8_INVALID_HASH
;
540 /* save next address for future use */
541 if (next_cb_pp
!= NULL
)
543 *next_cb_pp
= (EA_CMD_BLOCK_t
*) (cb_p
+ 1);
548 DBG_PRINT_EA_CMD_BLOCKS("Hash End", cb_p
,
549 N8_CB_EA_HASHEND_NUMCMDS
);
551 } /* cb_ea_hashEnd */
554 /*****************************************************************************
555 * cb_ea_SSLKeyMaterialHash
556 *****************************************************************************/
558 * @brief Compute SSL key material.
560 * The key material for an SSL hash is computed.
562 * @param req_p RW: Pointer to api request buffer.
563 * @param key_a RO: Physical address of key to use.
564 * @param keyLength RO: Length of the key.
565 * @param random_p RO: Pointer to random data to use.
566 * @param outputLength RO: Length of output.
567 * @param result_a RW: Physical address of pre-allocated buffer
574 * Status. Error condition if raised.
577 * N8_MALLOC_FAILED - memory allocation failed<BR>
580 * Results buffer is pre-allocated and of a sufficient size.
581 *****************************************************************************/
582 N8_Status_t
cb_ea_SSLKeyMaterialHash(API_Request_t
*req_p
,
583 EA_CMD_BLOCK_t
*cmdBlock_p
,
584 const uint32_t key_a
,
586 const N8_Buffer_t
*random_p
,
587 const int outputLength
,
590 N8_Status_t ret
= N8_STATUS_OK
;
591 EA_MSH_CMD_BLOCK_t
*cb_p
= NULL
;
596 CHECK_OBJECT(req_p
, ret
);
597 cb_p
= (EA_MSH_CMD_BLOCK_t
*) cmdBlock_p
;
598 CHECK_OBJECT(cb_p
, ret
);
600 /* create a command block for CCH opcode 0x30:
601 * "Master Secret Hash Command"
604 iterationCount
= (int) ((outputLength
/ (float) BYTES_PER_ITERATION
) +
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
) |
612 /* set the address of the key, or "master secret" in the read
614 cb_p
->read_data_addr_ls
= key_a
;
615 /* set the output address */
616 cb_p
->write_data_addr_ls
= result_a
;
617 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
619 /* set the random data */
620 cb_p
->random1
[0] = BE_to_uint32(random_p
);
621 cb_p
->random1
[1] = BE_to_uint32(random_p
+4);
622 cb_p
->random1
[2] = BE_to_uint32(random_p
+8);
623 cb_p
->random1
[3] = BE_to_uint32(random_p
+12);
624 cb_p
->random1
[4] = BE_to_uint32(random_p
+16);
625 cb_p
->random1
[5] = BE_to_uint32(random_p
+20);
626 cb_p
->random1
[6] = BE_to_uint32(random_p
+24);
627 cb_p
->random1
[7] = BE_to_uint32(random_p
+28);
628 cb_p
->random2
[0] = BE_to_uint32(random_p
+32);
629 cb_p
->random2
[1] = BE_to_uint32(random_p
+36);
630 cb_p
->random2
[2] = BE_to_uint32(random_p
+40);
631 cb_p
->random2
[3] = BE_to_uint32(random_p
+44);
632 cb_p
->random2
[4] = BE_to_uint32(random_p
+48);
633 cb_p
->random2
[5] = BE_to_uint32(random_p
+52);
634 cb_p
->random2
[6] = BE_to_uint32(random_p
+56);
635 cb_p
->random2
[7] = BE_to_uint32(random_p
+60);
638 DBG_PRINT_EA_CMD_BLOCKS("SSL Key Material Hash", (EA_CMD_BLOCK_t
*) cb_p
,
639 N8_CB_EA_SSLKEYMATERIALHASH_NUMCMDS
);
642 /* nothing to clean up */
645 } /* cb_ea_SSLKeyMaterialHash */
647 /*****************************************************************************
649 *****************************************************************************/
651 * @brief Create the command blocks to perform E/A or Decrypt for an SSL packet.
653 * @param cmdBlock_p RO: Pointer to beginning of the command block.
654 * @param packetObj_p RW: Pointer to the packet object.
655 * @param packet_p RO: Pointer to the header/data packet.
656 * @param input_a RO: Physical address of incoming SSL packet
657 * @param result_a RO: Physical address of decrypted SSL packet
658 * @param opCode RO: Op Code to build into the command block.
667 * N8_INVALID_VALUE - the ssl packet type is not recognized<br>
668 * N8_INVALID_VERSION - SSL version is not supported<br>
672 *****************************************************************************/
673 N8_Status_t
cb_ea_SSL(EA_CMD_BLOCK_t
*cmdBlock_p
,
674 N8_Packet_t
*packetObj_p
,
675 const N8_SSLTLSPacket_t
*packet_p
,
676 const uint32_t input_a
,
677 const uint32_t result_a
,
678 const unsigned int opCode
)
680 EA_SSL30_CMD_BLOCK_t
*cb_p
= (EA_SSL30_CMD_BLOCK_t
*) cmdBlock_p
;
685 /* convert network order packet header data to host order */
686 type
= SSLTLS_EXTRACT_TYPE(packet_p
);
687 sslver
= SSLTLS_EXTRACT_VERSION(packet_p
);
688 length
= SSLTLS_EXTRACT_LENGTH(packet_p
);
690 /* ensure the sslProtocol passed is one of the valid values */
693 case N8_CHANGE_CIPHER_SPEC
:
696 case N8_APPLICATION_DATA
:
699 return(N8_INVALID_VALUE
);
702 /* check the version to ensure it is correct */
703 if (sslver
!= N8_SSL_VERSION
)
705 return(N8_INVALID_VERSION
);
708 /* set the common elements */
709 cb_p
->read_data_addr_ls
= input_a
;
710 cb_p
->write_data_addr_ls
= result_a
;
711 cb_p
->result_type
= type
;
712 cb_p
->SSL_version_length
= (sslver
<< 16) + length
;
715 cb_p
->opcode_iter_length
= opCode
| length
;
717 /* Assume context use */
718 cb_p
->cp_si_context
= EA_Cmd_CP_Mask
|
719 (EA_Ctx_Addr_Address_Mask
& packetObj_p
->contextHandle
.index
);
721 /* based on cipher/hash, set the opcode and other specifics */
722 if (packetObj_p
->packetCipher
== N8_CIPHER_DES
)
724 /* DES may use context index or provide data in the command block */
725 if (packetObj_p
->contextHandle
.inUse
== N8_FALSE
)
727 EA_SSL30_DES_MD5_CMD_BLOCK_t
*desMd5_p
;
730 /* Do not use context */
731 cb_p
->cp_si_context
= 0;
732 if (packetObj_p
->packetHashAlgorithm
== N8_MD5
)
734 desMd5_p
= (EA_SSL30_DES_MD5_CMD_BLOCK_t
*) cb_p
;
735 /* set the precompute values */
736 for (i
= 0; i
< 4; i
++)
738 desMd5_p
->precompute1
[i
] =
739 packetObj_p
->cipherInfo
.precompute1
[i
];
740 desMd5_p
->precompute2
[i
] =
741 packetObj_p
->cipherInfo
.precompute2
[i
];
746 for (i
= 0; i
< 5; i
++)
748 cb_p
->write_secret
[i
] = BE_to_uint32(
749 &packetObj_p
->cipherInfo
.macSecret
[i
*sizeof(uint32_t)]);
753 /* set the params common for 3DES */
755 BE_to_uint32(&packetObj_p
->cipherInfo
.IV
[N8_MS_BYTE
]);
757 BE_to_uint32(&packetObj_p
->cipherInfo
.IV
[N8_LS_BYTE
]);
759 BE_to_uint32(&packetObj_p
->cipherInfo
.key1
[N8_MS_BYTE
]);
761 BE_to_uint32(&packetObj_p
->cipherInfo
.key1
[N8_LS_BYTE
]);
763 BE_to_uint32(&packetObj_p
->cipherInfo
.key2
[N8_MS_BYTE
]);
765 BE_to_uint32(&packetObj_p
->cipherInfo
.key2
[N8_LS_BYTE
]);
767 BE_to_uint32(&packetObj_p
->cipherInfo
.key3
[N8_MS_BYTE
]);
769 BE_to_uint32(&packetObj_p
->cipherInfo
.key3
[N8_LS_BYTE
]);
771 cb_p
->sequence_number
[0] = packetObj_p
->cipherInfo
.sequence_number
[0];
772 cb_p
->sequence_number
[1] = packetObj_p
->cipherInfo
.sequence_number
[1];
773 /* increment the sequence number. should we later discover the
774 * operation failed, the sequence number will need to be
775 * returned to its previous value.
777 packetObj_p
->cipherInfo
.sequence_number
[1]++;
778 /* check for wrapping */
779 if (packetObj_p
->cipherInfo
.sequence_number
[1] == 0)
781 /* increment the sequence number ms */
782 packetObj_p
->cipherInfo
.sequence_number
[0]++;
787 DBG_PRINT_EA_CMD_BLOCKS("SSL", (EA_CMD_BLOCK_t
*) cb_p
,
788 N8_CB_EA_SSLENCRYPTAUTHENTICATE_NUMCMDS
);
792 /*****************************************************************************
794 *****************************************************************************/
796 * @brief Create the command block to perform E/A or Decrypt for a TLS packet.
798 * @param cmdBlock_p RO: Pointer to beginning of the command block.
799 * @param packetObj_p RW: Pointer to the packet object.
800 * @param packet_p RO: Pointer to the header/data packet.
801 * @param input_a RO: Physical adress of input data.
802 * @param result_a RO: Physical adress of results area.
803 * @param opCode RO: Op Code to build into the command block.
812 * N8_INVALID_VALUE - the TLS packet type is not recognized<br>
813 * N8_INVALID_VERSION - TLS version is not supported<br>
817 *****************************************************************************/
818 N8_Status_t
cb_ea_TLS(EA_CMD_BLOCK_t
*cmdBlock_p
,
819 N8_Packet_t
*packetObj_p
,
820 const N8_SSLTLSPacket_t
*packet_p
,
821 const uint32_t input_a
,
822 const uint32_t result_a
,
823 const unsigned int opCode
)
825 EA_SSL30_CMD_BLOCK_t
*cb_p
= (EA_SSL30_CMD_BLOCK_t
*) cmdBlock_p
;
830 /* convert network order packet header data to host order */
831 type
= SSLTLS_EXTRACT_TYPE(packet_p
);
832 tlsver
= SSLTLS_EXTRACT_VERSION(packet_p
);
833 length
= SSLTLS_EXTRACT_LENGTH(packet_p
);
835 /* ensure the sslProtocol passed is one of the valid values */
838 case N8_CHANGE_CIPHER_SPEC
:
841 case N8_APPLICATION_DATA
:
844 return (N8_INVALID_VALUE
);
847 /* check the version to ensure it is correct */
848 if (tlsver
!= N8_TLS_VERSION
)
850 return (N8_INVALID_VERSION
);
853 /* set the common elements */
854 cb_p
->read_data_addr_ls
= input_a
;
855 cb_p
->write_data_addr_ls
= result_a
;
856 cb_p
->result_type
= type
;
857 cb_p
->SSL_version_length
= (tlsver
<< 16) + length
;
860 cb_p
->opcode_iter_length
= opCode
| length
;
862 /* Assume context use */
863 cb_p
->cp_si_context
|= EA_Cmd_CP_Mask
|
864 (EA_Ctx_Addr_Address_Mask
& packetObj_p
->contextHandle
.index
);
866 /* based on cipher/hash, set the opcode and other specifics */
867 if (packetObj_p
->packetCipher
== N8_CIPHER_DES
)
869 /* DES may use context index or provide data in the command block */
870 if (packetObj_p
->contextHandle
.inUse
== N8_FALSE
)
872 EA_TLS10_CMD_BLOCK_t
*tls_p
= (EA_TLS10_CMD_BLOCK_t
*) cb_p
;
875 /* Clear context use */
876 cb_p
->cp_si_context
= 0;
878 if (packetObj_p
->packetHashAlgorithm
== N8_HMAC_MD5
)
880 for (i
= 0; i
< 4; i
++)
882 tls_p
->ipad
[i
] = packetObj_p
->hashPacket
.ipadHMAC_iv
[i
];
883 tls_p
->opad
[i
] = packetObj_p
->hashPacket
.opadHMAC_iv
[i
];
886 else /* N8_HMAC_SHA1 */
888 for (i
= 0; i
<5; i
++)
890 tls_p
->ipad
[i
] = packetObj_p
->hashPacket
.ipadHMAC_iv
[i
];
891 tls_p
->opad
[i
] = packetObj_p
->hashPacket
.opadHMAC_iv
[i
];
895 /* set the params common for 3DES */
897 BE_to_uint32(&packetObj_p
->cipherInfo
.IV
[N8_MS_BYTE
]);
899 BE_to_uint32(&packetObj_p
->cipherInfo
.IV
[N8_LS_BYTE
]);
901 BE_to_uint32(&packetObj_p
->cipherInfo
.key1
[N8_MS_BYTE
]);
903 BE_to_uint32(&packetObj_p
->cipherInfo
.key1
[N8_LS_BYTE
]);
905 BE_to_uint32(&packetObj_p
->cipherInfo
.key2
[N8_MS_BYTE
]);
907 BE_to_uint32(&packetObj_p
->cipherInfo
.key2
[N8_LS_BYTE
]);
909 BE_to_uint32(&packetObj_p
->cipherInfo
.key3
[N8_MS_BYTE
]);
911 BE_to_uint32(&packetObj_p
->cipherInfo
.key3
[N8_LS_BYTE
]);
913 cb_p
->sequence_number
[0] = packetObj_p
->cipherInfo
.sequence_number
[0];
914 cb_p
->sequence_number
[1] = packetObj_p
->cipherInfo
.sequence_number
[1];
915 /* increment the sequence number. should we later discover the
916 * operation failed, the sequence number will need to be
917 * returned to its previous value.
919 packetObj_p
->cipherInfo
.sequence_number
[1]++;
920 /* check for wrapping */
921 if (packetObj_p
->cipherInfo
.sequence_number
[1] == 0)
923 /* increment the sequence number ms */
924 packetObj_p
->cipherInfo
.sequence_number
[0]++;
929 DBG_PRINT_EA_CMD_BLOCKS("TLS", (EA_CMD_BLOCK_t
*) cb_p
,
930 N8_CB_EA_TLSENCRYPTAUTHENTICATE_NUMCMDS
);
931 return (N8_STATUS_OK
);
934 /*****************************************************************************
935 * cb_ea_TLSKeyMaterialHash
936 *****************************************************************************/
938 * @brief Compute TLS key material.
940 * The key material for an TLS hash is computed.
942 * @param req_p RW: Pointer to api request buffer.
943 * @param msg_p RO: Virtual address of message to hash.
944 * @param msg_a RO: Physical address of message to hash.
945 * @param dataLength RO: Length of the message.
946 * @param hmacKey_p RO: Virtual address of HMAC key.
947 * @param hmacKey_a RO: Physical address of HMAC key.
948 * @param keyLength RO: Length of HMAC key.
949 * @param outputLength RO: Length of output buffer.
950 * @param pseudorandomStream1_a RO: First part of pseudo-random stream.
951 * @param pseudorandomStream2_a RO: Second part of pseudo-random stream.
957 * Status. Error condition if raised.
962 * All buffers are pre-allocated and of a sufficient size.
963 *****************************************************************************/
964 N8_Status_t
cb_ea_TLSKeyMaterialHash(API_Request_t
*req_p
,
965 EA_CMD_BLOCK_t
*cmdBlock_p
,
966 const N8_Buffer_t
*msg_p
,
967 const uint32_t msg_a
,
968 const int dataLength
,
969 N8_Buffer_t
*hmacKey_p
,
970 const uint32_t hmacKey_a
,
972 const int outputLength
,
973 const uint32_t pseudorandomStream1_a
,
974 const uint32_t pseudorandomStream2_a
,
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;
984 N8_Buffer_t
*secret1_p
= NULL
;
985 N8_Buffer_t
*secret2_p
= NULL
;
986 N8_Buffer_t
*bufferA_MD5_p
= NULL
;
987 N8_Buffer_t
*bufferA_SHA1_p
= NULL
;
988 uint32_t bufferA_MD5_a
;
989 uint32_t bufferA_SHA1_a
;
990 unsigned int numCommands
=0;
994 CHECK_OBJECT(req_p
, ret
);
995 cb_p
= (EA_HMAC_CMD_BLOCK_t
*) cmdBlock_p
;
996 CHECK_OBJECT(cb_p
, ret
);
998 secret1_p
= hmacKey_p
;
999 secret2_p
= &(hmacKey_p
[keyLength
]);
1001 /* 1) compute the first pseudorandom stream */
1002 iterationCount_MD5
= N8_MD5_HASHES_REQUIRED_TLS(outputLength
);
1003 iterationCount_SHA1
= N8_SHA1_HASHES_REQUIRED_TLS(outputLength
);
1005 /* allocate space for the command block */
1006 numCommands
= N8_CB_EA_TLSKEYMATERIALHASH_NUMCMDS(outputLength
);
1008 /* the code needs to be restructured to not depend on the numCommands +1
1009 * for the malloc. it works here where it is local, but if an external
1010 * caller it so preallocate the memory, it cannot be expected to allocate
1011 * n+1. the code herein must be fixed to not have that dependency.
1013 /* allocate a kernel buffer for the hashes */
1014 bufferA_MD5_length
= dataLength
+ EA_MD5_Hash_Length
;
1015 bufferA_SHA1_length
= dataLength
+ EA_SHA1_Hash_Length
;
1017 bufferA_MD5_p
= (N8_Buffer_t
*) ((int)req_p
+ req_p
->dataoffset
+ keyLen
);
1018 bufferA_MD5_a
= req_p
->qr
.physicalAddress
+ req_p
->dataoffset
+ keyLen
;
1019 bufferA_SHA1_p
= (N8_Buffer_t
*) ((int)req_p
+ req_p
->dataoffset
+ keyLen
) +
1020 NEXT_WORD_SIZE(bufferA_MD5_length
);
1021 bufferA_SHA1_a
= req_p
->qr
.physicalAddress
+ req_p
->dataoffset
+ keyLen
+
1022 NEXT_WORD_SIZE(bufferA_MD5_length
);
1025 * Unfortunately HMAC command doesn't do what it supposed to do.
1026 * We have to calculate HMAC values "by hand".
1027 * Create as many commands to do this as we need.
1030 /* Note that the first calculation is an oddball and must be done before
1031 * entering the loop. Due to this, we generate n-1 pairs and have to do
1032 * the final calculation outside of the loop. This is true for both MD5
1035 /* Calculate buffer A first time */
1036 cb_p
->opcode_iter_length
=
1037 EA_Cmd_MD5_HMAC
| (1 << EA_Cmd_Iterations_Shift
) | dataLength
;
1038 cb_p
->read_data_addr_ls
= msg_a
;
1039 cb_p
->write_data_addr_ls
= bufferA_MD5_a
;
1041 /* set the HMAC key data */
1042 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1044 cb_p
->hmac_key
[i
] = BE_to_uint32(secret1_p
+n
);
1047 memcpy(bufferA_MD5_p
+EA_MD5_Hash_Length
, msg_p
, dataLength
);
1051 for (l
= 0, k
= 0; l
< iterationCount_MD5
- 1; l
++, k
+=EA_MD5_Hash_Length
)
1053 /* A) calculate pseudo random stream 1 */
1054 /* set the opcode and length */
1055 cb_p
->opcode_iter_length
=
1056 EA_Cmd_MD5_HMAC
| (1 << EA_Cmd_Iterations_Shift
) |
1058 cb_p
->read_data_addr_ls
= bufferA_MD5_a
;
1059 cb_p
->write_data_addr_ls
= (uint32_t) pseudorandomStream1_a
+ k
;
1061 /* set the HMAC key data */
1062 /* TODO: are both termination tests necessary? will one ever fire
1063 * without the other? if not, just use the most restrictive. */
1064 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1066 cb_p
->hmac_key
[i
] = BE_to_uint32(secret1_p
+n
);
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
) |
1075 cb_p
->read_data_addr_ls
= bufferA_MD5_a
;
1076 cb_p
->write_data_addr_ls
= bufferA_MD5_a
;
1078 /* set the HMAC key data */
1079 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1081 cb_p
->hmac_key
[i
] = BE_to_uint32(secret1_p
+n
);
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
) |
1092 cb_p
->read_data_addr_ls
= bufferA_MD5_a
;
1093 cb_p
->write_data_addr_ls
= (uint32_t) pseudorandomStream1_a
+ k
;
1095 /* set the HMAC key data */
1096 /* TODO: are both termination tests necessary? will one ever fire
1097 * without the other? if not, just use the most restrictive. */
1098 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1100 cb_p
->hmac_key
[i
] = BE_to_uint32(secret1_p
+n
);
1104 /* 2) compute the second pseudorandom stream */
1105 /* Calculate buffer A first time */
1106 cb_p
->opcode_iter_length
=
1108 (1 << EA_Cmd_Iterations_Shift
) |
1110 cb_p
->read_data_addr_ls
= msg_a
;
1111 cb_p
->write_data_addr_ls
= bufferA_SHA1_a
;
1113 /* set the HMAC key data */
1114 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1116 cb_p
->hmac_key
[i
] = BE_to_uint32(secret2_p
+n
);
1119 memcpy(bufferA_SHA1_p
+EA_SHA1_Hash_Length
, msg_p
, dataLength
);
1123 for (l
= 0, k
= 0; l
< iterationCount_SHA1
- 1; l
++, k
+=EA_SHA1_Hash_Length
)
1125 /* A) calculate pseudo random stream 2 */
1126 /* set the opcode and length */
1127 cb_p
->opcode_iter_length
=
1129 (1 << EA_Cmd_Iterations_Shift
) |
1130 bufferA_SHA1_length
;
1132 cb_p
->read_data_addr_ls
= bufferA_SHA1_a
;
1133 cb_p
->write_data_addr_ls
= (uint32_t) pseudorandomStream2_a
+ k
;
1135 /* set the HMAC key data */
1136 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1138 cb_p
->hmac_key
[i
] = BE_to_uint32(secret2_p
+n
);
1142 /* B) calculate buffer A */
1143 /* set the opcode and length */
1144 cb_p
->opcode_iter_length
=
1146 (1 << EA_Cmd_Iterations_Shift
) |
1147 EA_SHA1_Hash_Length
;
1148 cb_p
->read_data_addr_ls
= bufferA_SHA1_a
;
1149 cb_p
->write_data_addr_ls
= bufferA_SHA1_a
;
1151 /* set the HMAC key data */
1152 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1154 cb_p
->hmac_key
[i
] = BE_to_uint32(secret2_p
+n
);
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
=
1164 (1 << EA_Cmd_Iterations_Shift
) |
1165 bufferA_SHA1_length
;
1167 cb_p
->read_data_addr_ls
= bufferA_SHA1_a
;
1168 cb_p
->write_data_addr_ls
= (uint32_t) pseudorandomStream2_a
+ k
;
1169 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
1171 /* set the HMAC key data */
1172 for (i
= 0, n
= 0; (i
< 16) && (n
< keyLength
); i
++, n
+=4)
1174 cb_p
->hmac_key
[i
] = BE_to_uint32(secret2_p
+n
);
1180 DBG_PRINT_EA_CMD_BLOCKS("TLS Key Material Hash",
1181 (EA_CMD_BLOCK_t
*) cmdBlock_p
,
1186 } /* cb_ea_TLSKeyMaterialHash */
1189 /*****************************************************************************
1191 *****************************************************************************/
1193 * @brief Prepares the command blocks for the N8_IKEPrf API
1195 * @param req_p RW: pointer to API request structure
1196 * @param alg RO: hash algorithm (md5 or sha1)
1197 * @param kMsg_a RO: physical address of message to be hashed
1198 * @param msgLength RO: length of message in bytes
1199 * @param kKey_p RO: virtual address of key
1200 * @param keyLength RO: length of key in bytes
1201 * @param kRes_a RO: physical address of result
1209 * N8_INVALID_HASH - hash is neither md5 nor sha1
1210 * N8_MALLOC_FAILED - problem allocating memory
1216 *****************************************************************************/
1217 N8_Status_t
cb_ea_IKEPrf(API_Request_t
*req_p
,
1218 EA_CMD_BLOCK_t
*cmdBlock_p
,
1219 const N8_HashAlgorithm_t alg
,
1220 const uint32_t kMsg_a
,
1221 const uint32_t msgLength
,
1222 const N8_Buffer_t
*kKey_p
,
1223 const uint32_t keyLength
,
1224 const uint32_t kRes_a
)
1226 N8_Status_t ret
= N8_STATUS_OK
;
1227 EA_HMAC_CMD_BLOCK_t
*cb_p
= NULL
;
1228 N8_Buffer_t hmacKey
[EA_HMAC_Key_Length
];
1234 CHECK_OBJECT(req_p
, ret
);
1235 cb_p
= (EA_HMAC_CMD_BLOCK_t
*) cmdBlock_p
;
1236 CHECK_OBJECT(cb_p
, ret
);
1238 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1239 if (keyLength
<= EA_HMAC_Key_Length
)
1241 memcpy(hmacKey
, kKey_p
, keyLength
);
1242 memset(hmacKey
+keyLength
, 0x0, EA_HMAC_Key_Length
- keyLength
);
1246 ret
= N8_INVALID_KEY_SIZE
;
1251 /* choose opcode/iteration count (1) and msg length
1252 * opcode is based on algorithm
1258 cb_p
->opcode_iter_length
=
1259 EA_Cmd_SHA1_IPSEC_KEYMAT
|
1260 (N8_IKE_PRF_ITERATIONS
<< EA_Cmd_Iterations_Shift
) |
1266 cb_p
->opcode_iter_length
=
1267 EA_Cmd_MD5_IPSEC_KEYMAT
|
1268 (N8_IKE_PRF_ITERATIONS
<< EA_Cmd_Iterations_Shift
) |
1274 ret
= N8_INVALID_HASH
;
1281 cb_p
->read_data_addr_ls
= kMsg_a
;
1282 cb_p
->write_data_addr_ls
= kRes_a
;
1283 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
1285 /* set the HMAC key data */
1286 for (i
= 0, n
= 0;i
< EA_HMAC_Key_Length
/sizeof(uint32_t);
1287 i
++, n
+=sizeof(uint32_t))
1289 cb_p
->hmac_key
[i
] = BE_to_uint32(hmacKey
+n
);
1293 DBG_PRINT_EA_CMD_BLOCKS("IKEPrf", cmdBlock_p
,
1294 N8_CB_EA_IKEPRF_NUMCMDS
);
1299 } /* cb_ea_IKEPrf */
1301 /*****************************************************************************
1302 * cb_ea_IKESKEYIDExpand
1303 *****************************************************************************/
1305 * @brief Prepares command blocks for the N8_IKESKEYIDExpand API
1307 * @param req_p RW: pointer to API request structure
1308 * @param alg RO: hash algorithm (md5 or sha1)
1309 * @param kMsg_a RO: physical address of message to be hashed
1310 * @param msgLength RO: length of message to be hashed in bytes
1311 * @param kKey_p RO: virtual address of key
1312 * @param keyLength RO: length of key in bytes
1313 * @param kSKEYIDd_a RO: physical (base) address of result buffer
1321 * N8_INVALID_HASH - hash is neither md5 nor sha1
1322 * N8_MALLOC_FAILED - problem allocating memory
1328 *****************************************************************************/
1330 N8_Status_t
cb_ea_IKESKEYIDExpand(API_Request_t
*req_p
,
1331 EA_CMD_BLOCK_t
*cmdBlock_p
,
1332 const N8_HashAlgorithm_t alg
,
1333 const uint32_t kMsg_a
,
1334 const uint32_t msgLength
,
1335 const N8_Buffer_t
*kKey_p
,
1336 const uint32_t keyLength
,
1337 const uint32_t kSKEYIDd_a
)
1339 N8_Status_t ret
= N8_STATUS_OK
;
1340 EA_HMAC_CMD_BLOCK_t
*cb_p
= NULL
;
1341 N8_Buffer_t hmacKey
[EA_HMAC_Key_Length
];
1346 CHECK_OBJECT(req_p
, ret
);
1347 cb_p
= (EA_HMAC_CMD_BLOCK_t
*) cmdBlock_p
;
1348 CHECK_OBJECT(cb_p
, ret
);
1350 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1351 if (keyLength
<= EA_HMAC_Key_Length
)
1353 memcpy(hmacKey
, kKey_p
, keyLength
);
1354 memset(hmacKey
+keyLength
, 0x0, EA_HMAC_Key_Length
- keyLength
);
1359 ret
= N8_INVALID_KEY_SIZE
;
1363 /* choose opcode/iteration count (3) and msg length
1364 * opcode is based on algorithm
1370 cb_p
->opcode_iter_length
=
1371 EA_Cmd_SHA1_IPSEC_SKEYID
|
1372 (N8_IKE_SKEYID_ITERATIONS
<< EA_Cmd_Iterations_Shift
) |
1378 cb_p
->opcode_iter_length
=
1379 EA_Cmd_MD5_IPSEC_SKEYID
|
1380 (N8_IKE_SKEYID_ITERATIONS
<< EA_Cmd_Iterations_Shift
) |
1386 ret
= N8_INVALID_HASH
;
1393 cb_p
->read_data_addr_ls
= kMsg_a
;
1394 cb_p
->write_data_addr_ls
= kSKEYIDd_a
;
1395 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
1397 /* set the HMAC key data */
1398 for (i
= 0, n
= 0;i
< EA_HMAC_Key_Length
/sizeof(uint32_t);
1399 i
++, n
+=sizeof(uint32_t))
1401 cb_p
->hmac_key
[i
] = BE_to_uint32(hmacKey
+n
);
1407 DBG_PRINT_EA_CMD_BLOCKS("IKESKEYIDExpand", cmdBlock_p
,
1408 N8_CB_EA_IKESKEYIDEXPAND_NUMCMDS
);
1411 } /* cb_ea_IKESKEYIDExpand */
1413 /*****************************************************************************
1414 * cb_ea_IKEKeyMaterialExpand
1415 *****************************************************************************/
1417 * @brief Prepares command blocks for the N8_IKEKeyMaterialExpand API
1419 * @param req_p RW: pointer to API request structure
1420 * @param alg RO: hash algorithm (md5 or sha1)
1421 * @param kMsg_a RO: physical address of message to be hashed
1422 * @param msgLength RO: length of message to be hashed in bytes
1423 * @param kKey_p RO: virtual address of key
1424 * @param keyLength RO: length of key in bytes
1425 * @param kRes_a RO: physical address of result buffer
1426 * @param i_count RO: hash iteration count
1434 * N8_INVALID_HASH - hash is neither md5 nor sha1
1435 * N8_MALLOC_FAILED - problem allocating memory
1441 *****************************************************************************/
1442 N8_Status_t
cb_ea_IKEKeyMaterialExpand(API_Request_t
*req_p
,
1443 EA_CMD_BLOCK_t
*cmdBlock_p
,
1444 const N8_HashAlgorithm_t alg
,
1445 const uint32_t kMsg_a
,
1446 const uint32_t msgLength
,
1447 const N8_Buffer_t
*kKey_p
,
1448 const uint32_t keyLength
,
1449 const uint32_t kRes_a
,
1450 const uint32_t i_count
)
1452 N8_Status_t ret
= N8_STATUS_OK
;
1453 EA_HMAC_CMD_BLOCK_t
*cb_p
= NULL
;
1454 N8_Buffer_t hmacKey
[EA_HMAC_Key_Length
];
1459 CHECK_OBJECT(req_p
, ret
);
1460 cb_p
= (EA_HMAC_CMD_BLOCK_t
*) cmdBlock_p
;
1461 CHECK_OBJECT(cb_p
, ret
);
1463 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1464 if (keyLength
<= EA_HMAC_Key_Length
)
1466 memcpy(hmacKey
, kKey_p
, keyLength
);
1467 memset(hmacKey
+keyLength
, 0x0, EA_HMAC_Key_Length
- keyLength
);
1472 ret
= N8_INVALID_KEY_SIZE
;
1476 /* choose opcode/iteration count (i_count) and msg length
1477 * opcode is based on algorithm
1483 cb_p
->opcode_iter_length
=
1485 (i_count
<< EA_Cmd_Iterations_Shift
) | msgLength
;
1490 cb_p
->opcode_iter_length
=
1492 (i_count
<< EA_Cmd_Iterations_Shift
) | msgLength
;
1497 ret
= N8_INVALID_HASH
;
1504 cb_p
->read_data_addr_ls
= kMsg_a
;
1505 cb_p
->write_data_addr_ls
= kRes_a
;
1506 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
1508 /* set the HMAC key data */
1509 for (i
= 0, n
= 0;i
< EA_HMAC_Key_Length
/sizeof(uint32_t);
1510 i
++, n
+=sizeof(uint32_t))
1512 cb_p
->hmac_key
[i
] = BE_to_uint32(hmacKey
+n
);
1517 DBG_PRINT_EA_CMD_BLOCKS("IKEKeyMaterialExpand",
1519 N8_CB_EA_IKEKEYMATERIALEXPAND_NUMCMDS
);
1524 } /* cb_ea_IKEKeyMaterialExpand */
1526 /*****************************************************************************
1527 * cb_ea_IKEEncryptKeyExpand
1528 *****************************************************************************/
1530 * @brief Prepares command blocks for the N8_IKEEncryptKeyExpand API
1532 * @param req_p RW: pointer to API request structure
1533 * @param alg RO: hash algorithm (md5 or sha1)
1534 * @param kMsg_a RO: physical address of message to be hashed
1535 * @param msgLength RO: length of message to be hashed in bytes
1536 * @param kKey_p RO: virtual address of key
1537 * @param keyLength RO: length of key in bytes
1538 * @param kRes_a RO: physical address of result buffer
1539 * @param i_count RO: hash iteration count
1547 * N8_INVALID_HASH - hash is neither md5 nor sha1
1548 * N8_MALLOC_FAILED - problem allocating memory
1554 *****************************************************************************/
1555 N8_Status_t
cb_ea_IKEEncryptKeyExpand(API_Request_t
*req_p
,
1556 EA_CMD_BLOCK_t
*cmdBlock_p
,
1557 const N8_HashAlgorithm_t alg
,
1558 const uint32_t kMsg_a
,
1559 const uint32_t msgLength
,
1560 const N8_Buffer_t
*kKey_p
,
1561 const uint32_t keyLength
,
1562 const uint32_t kRes_a
,
1563 const uint32_t i_count
)
1565 N8_Status_t ret
= N8_STATUS_OK
;
1566 EA_HMAC_CMD_BLOCK_t
*cb_p
= NULL
;
1567 N8_Buffer_t hmacKey
[EA_HMAC_Key_Length
];
1572 CHECK_OBJECT(req_p
, ret
);
1573 cb_p
= (EA_HMAC_CMD_BLOCK_t
*) cmdBlock_p
;
1574 CHECK_OBJECT(cb_p
, ret
);
1576 /* pad key with zeroes up to B=64 bytes as per RFC 2104 */
1577 if (keyLength
<= EA_HMAC_Key_Length
)
1579 memcpy(hmacKey
, kKey_p
, keyLength
);
1580 memset(hmacKey
+keyLength
, 0x0, EA_HMAC_Key_Length
- keyLength
);
1585 ret
= N8_INVALID_KEY_SIZE
;
1589 /* choose opcode/iteration count (i_count) and msg length
1590 * opcode is based on algorithm
1596 cb_p
->opcode_iter_length
=
1597 EA_Cmd_SHA1_IPSEC_KEYMAT
|
1598 (i_count
<< EA_Cmd_Iterations_Shift
) | msgLength
;
1603 cb_p
->opcode_iter_length
=
1604 EA_Cmd_MD5_IPSEC_KEYMAT
|
1605 (i_count
<< EA_Cmd_Iterations_Shift
) | msgLength
;
1610 ret
= N8_INVALID_HASH
;
1617 cb_p
->read_data_addr_ls
= kMsg_a
;
1618 cb_p
->write_data_addr_ls
= kRes_a
;
1619 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
1621 /* set the HMAC key data */
1622 for (i
= 0, n
= 0;i
< EA_HMAC_Key_Length
/sizeof(uint32_t);
1623 i
++, n
+=sizeof(uint32_t))
1625 cb_p
->hmac_key
[i
] = BE_to_uint32(hmacKey
+n
);
1629 DBG_PRINT_EA_CMD_BLOCKS("IKEEncryptKeyExpand",
1631 N8_CB_EA_IKEENCRYPTKEYEXPAND_NUMCMDS
);
1637 } /* cb_ea_IKEEncryptKeyExpand */
1639 /*****************************************************************************
1640 * cb_ea_writeContext
1641 *****************************************************************************/
1643 * @brief Creates command to Write Buffer to context memory.
1645 * Creates write buffer to context memory specified by contextIndex.
1647 * @param contextIndex RO: context memory to write to
1648 * @param req_p WO: command buffer
1651 * ret - returns N8_STATUS_OK if successful or Error value.
1652 * req_p - pointer to command buffer
1655 * N8_INVALID_OBJECT - request buffer was not allocated.<BR>
1656 * N8_MALLOC_FAILED - memory allocation failed.<BR>
1660 * contextIndex is valid and was passed to us by his rightful owner.
1661 *****************************************************************************/
1663 N8_Status_t
cb_ea_writeContext (API_Request_t
*req_p
,
1664 EA_CMD_BLOCK_t
*cb_p
,
1665 const unsigned int contextIndex
,
1666 const N8_Buffer_t
*bufferToWrite_p
,
1667 const unsigned int length
)
1669 N8_Status_t ret
= N8_STATUS_OK
; /* the return status: OK or ERROR */
1671 DBG(("cb_ea_writeContext\n"));
1675 /* verify passed parameter */
1676 CHECK_OBJECT(req_p
, ret
);
1677 CHECK_OBJECT(cb_p
, ret
);
1679 /* set the context memory index */
1680 cb_p
->cp_si_context
= contextIndex
| EA_Cmd_CP_Mask
| EA_Cmd_SI_Mask
;
1681 /* set write command plus the number of bytes to write */
1682 cb_p
->opcode_iter_length
=
1683 EA_Cmd_Write_Context_Memory
| EA_CTX_Record_Byte_Length
;
1685 /* set the address of Zero buffer (kmalloc sets buffer to zero) */
1686 /* memset(kmem_p->VirtualAddress, 0x0, CONTEXT_ENTRY_SIZE); */
1688 memcpy((void *)((int)req_p
+ req_p
->dataoffset
), bufferToWrite_p
, length
);
1689 cb_p
->read_data_addr_ls
= (uint32_t) req_p
->qr
.physicalAddress
+ req_p
->dataoffset
;
1690 /* free context memory */
1694 DBG(("cb_ea_writeContext - FINISHED\n"));
1696 } /* cb_ea_writeContext */
1698 /*****************************************************************************
1700 *****************************************************************************/
1702 * @brief Creates command to Write Buffer to context memory.
1704 * Creates write buffer to context memory specified by contextIndex.
1706 * @param req_p RW: command buffer
1707 * @param contextIndex RO: context memory to write to
1710 * ret - returns N8_STATUS_OK if successful or Error value.
1711 * req_p - pointer to command buffer
1714 * N8_INVALID_OBJECT - request buffer was not allocated.<BR>
1715 * N8_MALLOC_FAILED - memory allocation failed.<BR>
1719 * contextIndex is valid and was passed to us by his rightful owner.
1720 *****************************************************************************/
1722 N8_Status_t
cb_ea_readContext (API_Request_t
*req_p
,
1723 EA_CMD_BLOCK_t
*cb_p
,
1724 const unsigned int contextIndex
,
1725 const uint32_t bufferToRead_a
,
1726 const unsigned int length
)
1728 N8_Status_t ret
= N8_STATUS_OK
; /* the return status: OK or ERROR */
1730 DBG(("cb_writeContext\n"));
1734 /* verify passed parameter */
1735 CHECK_OBJECT(req_p
, ret
);
1736 CHECK_OBJECT(cb_p
, ret
);
1737 /* set the context memory index */
1738 cb_p
->cp_si_context
= contextIndex
| EA_Cmd_CP_Mask
| EA_Cmd_SI_Mask
;
1739 /* set write command plus the number of bytes to write */
1740 cb_p
->opcode_iter_length
=
1741 EA_Cmd_Read_Context_Memory
| EA_CTX_Record_Byte_Length
;
1742 /* set the address of Zero buffer */
1743 cb_p
->write_data_addr_ls
= (uint32_t) bufferToRead_a
;
1744 /* free context memory */
1748 DBG(("cb_writeContext - FINISHED\n"));
1750 } /* cb_ea_readContext */
1752 /* RC4 as implemented from a posting from
1753 * Newsgroups: sci.crypt
1754 * From: sterndark@netcom.com (David Sterndark)
1755 * Subject: RC4 Algorithm revealed.
1756 * Message-ID: <sternCvKL4B.Hyy@netcom.com>
1757 * Date: Wed, 14 Sep 1994 06:35:31 GMT
1759 /* n8_RC4_set_key - Similar to RC4_set_key in openssl. Used to avoid
1760 dependency on OpenSSL in tests. */
1761 void n8_RC4_set_key(N8_RC4_t
*key
, int len
, const unsigned char *data
)
1764 unsigned int id1
,id2
;
1769 for (i
= 0; i
< N8_ARC4_MAX_LENGTH
; i
++)
1777 #define SK_LOOP(n) { \
1779 id2 = (data[id1] + tmp + id2) & 0xff; \
1780 if (++id1 == len) id1=0; \
1784 for (i
= 0; i
< N8_ARC4_MAX_LENGTH
; i
+= 4)
1794 /***************************************************************************
1795 * cb_ea_loadARC4KeyToContext
1796 *****************************************************************************/
1798 * @brief Loads ARC4 key to context memory.
1800 * @param req_p RW: pointer to request block
1801 * @param cb_p RW: pointer to command block space
1802 * @param packetObj_p RO: pointer to packet object
1803 * @param cipher_p RO: ARC4 key info
1804 * @param hashAlgorithm RO: hash algorithm in use
1805 * @param ctx_p RW: pointer to context - virtaul
1806 * @param ctx_a RW: physical address of context
1807 * @param next_cb_pp RW: pointer to next command block pointer
1811 * ret - returns N8_STATUS_OK if successful or Error value.
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
1820 * contextIndex is valid and was passed to us by his rightful owner.
1821 * ARC4 key is valid.
1822 *****************************************************************************/
1823 N8_Status_t
cb_ea_loadARC4KeyToContext(API_Request_t
*req_p
,
1824 EA_CMD_BLOCK_t
*cb_p
,
1825 const N8_Packet_t
*packetObj_p
,
1826 const N8_CipherInfo_t
*cipher_p
,
1827 const N8_HashAlgorithm_t hashAlgorithm
,
1829 const uint32_t ctx_a
,
1830 EA_CMD_BLOCK_t
**next_cb_pp
)
1833 N8_Status_t ret
= N8_STATUS_OK
; /* the return status: OK or ERROR */
1836 DBG(("Command Block: loadARC4KeyToContext\n"));
1840 /* verify passed parameters */
1841 CHECK_OBJECT(packetObj_p
, ret
);
1842 CHECK_OBJECT(cb_p
, ret
);
1843 CHECK_OBJECT(req_p
, ret
);
1844 CHECK_OBJECT(cipher_p
, ret
);
1846 switch (hashAlgorithm
)
1849 for (i
= 0; i
< N8_PRECOMPUTE_SIZE
; i
++)
1851 ctx_p
->secret1
[i
] = BE_to_uint32(&cipher_p
->macSecret
[i
*sizeof(uint32_t)]);
1855 for (i
= 0; i
< N8_PRECOMPUTE_SIZE
; i
++)
1857 ctx_p
->secret1
[i
] = packetObj_p
->cipherInfo
.precompute1
[i
];
1858 ctx_p
->secret2
[i
] = packetObj_p
->cipherInfo
.precompute2
[i
];
1863 for (i
= 0; i
< N8_PRECOMPUTE_SIZE
; i
++)
1865 ctx_p
->secret1
[i
] = packetObj_p
->hashPacket
.ipadHMAC_iv
[i
];
1866 ctx_p
->secret2
[i
] = packetObj_p
->hashPacket
.opadHMAC_iv
[i
];
1870 ret
= N8_INVALID_HASH
;
1875 ctx_p
->sequence_number
[0] = cipher_p
->sequence_number
[0];
1876 ctx_p
->sequence_number
[1] = cipher_p
->sequence_number
[1];
1878 memset(&keyARC4
, 0x0, sizeof(N8_RC4_t
));
1879 n8_RC4_set_key(&keyARC4
, cipher_p
->keySize
, cipher_p
->key
.keyARC4
);
1880 /* put the i & j counters in the context memory image */
1882 ((keyARC4
.y
<< EA_CTX_J_Shift
) & EA_CTX_J_Mask
) |
1883 ((keyARC4
.x
<< EA_CTX_I_Shift
) & EA_CTX_I_Mask
);
1885 /* put the S-box data in the context memory image */
1886 for (i
= 0,j
= 0; i
< 64; i
++,j
+=4)
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) );
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
++));
1915 cb_p
->cp_si_context
= EA_Cmd_CP_Mask
|
1916 (EA_Ctx_Addr_Address_Mask
& packetObj_p
->contextHandle
.index
);
1917 cb_p
->read_data_addr_ls
= (uint32_t) ctx_a
;
1918 cb_p
->opcode_iter_length
= EA_Cmd_Write_Context_Memory
| sizeof(EA_ARC4_CTX
);
1920 /* save next address for future use */
1921 if (next_cb_pp
!= NULL
)
1923 *next_cb_pp
= (EA_CMD_BLOCK_t
*) (cb_p
+ 1);
1927 DBG_PRINT_EA_CMD_BLOCKS("Load ARC4 Key to Context Memory", cb_p
,
1928 N8_CB_EA_LOADARC4KEYTOCONTEXT_NUMCMDS
);
1930 } /* cb_ea_loadARC4KeyToContext */
1932 /***************************************************************************
1933 * cb_ea_loadARC4key_Only
1934 *****************************************************************************/
1936 * @brief Loads ARC4 key to context memory.
1939 * @param req_p RW: pointer to request block
1940 * @param encryptObject_p RO: pointer to encrypted object
1941 * @param cipher_p RO: ARC4 key info
1942 * @param ctx_p RW: pointer to ARC4 context
1946 * ret - returns N8_STATUS_OK if successful or Error value.
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
1955 * contextIndex is valid and was passed to us by his rightful owner.
1956 * ARC4 key is valid.
1957 *****************************************************************************/
1958 N8_Status_t
cb_ea_loadARC4keyOnly(API_Request_t
*req_p
,
1959 EA_CMD_BLOCK_t
*cb_p
,
1960 const N8_ContextHandle_t
*contextHandle_p
,
1961 const N8_EncryptCipher_t
*cipher_p
)
1963 int i
,j
; /* loop iterators */
1964 N8_Status_t ret
= N8_STATUS_OK
; /* return code */
1965 EA_ARC4_CTX
*ctx_p
= NULL
; /* context virtual pointer */
1969 DBG(("Command Block: cb_ea_loadARC4key_for_CryptoInterface\n"));
1973 /* verify passed parameters */
1974 CHECK_OBJECT(contextHandle_p
, ret
);
1975 CHECK_OBJECT(cipher_p
, ret
);
1976 CHECK_OBJECT(req_p
, ret
);
1977 CHECK_OBJECT(cb_p
, ret
);
1979 ctx_p
= (EA_ARC4_CTX
*) ((int)req_p
+ req_p
->dataoffset
);
1980 ctx_p
->sequence_number
[0] = cipher_p
->sequence_number
[0];
1981 ctx_p
->sequence_number
[1] = cipher_p
->sequence_number
[1];
1983 memset(&keyARC4
, 0x0, sizeof(N8_RC4_t
));
1985 n8_RC4_set_key(&keyARC4
, cipher_p
->keySize
, cipher_p
->key
.keyARC4
);
1986 /* put the i & j counters in the context memory image */
1988 ((keyARC4
.y
<< EA_CTX_J_Shift
) & EA_CTX_J_Mask
) |
1989 ((keyARC4
.x
<< EA_CTX_I_Shift
) & EA_CTX_I_Mask
);
1991 /* put the S-box data in the context memory image */
1992 for (i
=0,j
=0; i
<64; i
++,j
+=4) {
1994 ((keyARC4
.data
[j
] & 0xff) << 24) |
1995 ((keyARC4
.data
[j
+1] & 0xff) << 16) |
1996 ((keyARC4
.data
[j
+2] & 0xff) << 8) |
1997 ((keyARC4
.data
[j
+3] & 0xff));
2000 cb_p
->cp_si_context
= contextHandle_p
->index
| EA_Cmd_CP_Mask
|
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
);
2008 DBG_PRINT_EA_CMD_BLOCKS("Load ARC4 Key Only", cb_p
,
2009 N8_CB_EA_LOADARC4KEYONLY_NUMCMDS
);
2011 } /* cb_ea_loadARC4keyOnly */
2013 /*****************************************************************************
2015 *****************************************************************************/
2017 * @brief Create the command blocks to perform raw encryption.
2019 * @param req_p RW: Request pointer.
2020 * @param encryptObject_p RO: Pointer to the encrypted object.
2021 * @param message_p RO: Address of input message.
2022 * @param encryptedMessage_p RW: Pointer to the encrypted message (result).
2023 * @param messageLength RO: Message length.
2032 * N8_MALLOC_FAILED - memory allocation failed<BR>
2036 *****************************************************************************/
2037 N8_Status_t
cb_ea_encrypt(const API_Request_t
*req_p
,
2038 EA_CMD_BLOCK_t
*cb_p
,
2039 N8_EncryptObject_t
*encryptObject_p
,
2040 const uint32_t message_a
,
2041 const uint32_t encryptedMessage_a
,
2042 const int messageLength
)
2044 N8_Status_t ret
= N8_STATUS_OK
;
2047 CHECK_OBJECT(req_p
, ret
);
2048 CHECK_OBJECT(cb_p
, ret
);
2050 /* set the common elements */
2051 cb_p
->read_data_addr_ls
= message_a
;
2052 cb_p
->write_data_addr_ls
= encryptedMessage_a
;
2053 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
2055 /* based on cipher/hash, set the opcode and other specifics */
2056 if (encryptObject_p
->cipher
== N8_CIPHER_ARC4
)
2058 /* ARC4 must use context index */
2059 cb_p
->cp_si_context
|= EA_Cmd_CP_Mask
|
2060 (EA_Ctx_Addr_Address_Mask
& encryptObject_p
->contextHandle
.index
);
2061 /* set the opcode */
2062 cb_p
->opcode_iter_length
= EA_Cmd_ARC4
| messageLength
;
2064 else if (encryptObject_p
->cipher
== N8_CIPHER_DES
)
2066 /* set the opcode */
2067 cb_p
->opcode_iter_length
= EA_Cmd_3DES_CBC_Encrypt
| messageLength
;
2068 /* DES may use context index or provide data in the command block */
2069 if (encryptObject_p
->contextHandle
.inUse
== N8_FALSE
)
2071 /* set the params common for 3DES */
2073 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.IV
[N8_MS_BYTE
]);
2075 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.IV
[N8_LS_BYTE
]);
2077 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key1
[N8_MS_BYTE
]);
2079 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key1
[N8_LS_BYTE
]);
2081 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key2
[N8_MS_BYTE
]);
2083 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key2
[N8_LS_BYTE
]);
2085 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key3
[N8_MS_BYTE
]);
2087 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key3
[N8_LS_BYTE
]);
2089 /* increment the sequence number. should we later discover the
2090 * operation failed, the sequence number will need to be returned to
2091 * its previous value.
2093 encryptObject_p
->cipherInfo
.sequence_number
[1]++;
2094 /* check for wrapping */
2095 if (encryptObject_p
->cipherInfo
.sequence_number
[1] == 0)
2097 /* increment the sequence number ms */
2098 encryptObject_p
->cipherInfo
.sequence_number
[0]++;
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
);
2110 ret
= N8_INVALID_ENUM
;
2115 DBG_PRINT_EA_CMD_BLOCKS("cb_ea_encrypt", (EA_CMD_BLOCK_t
*) cb_p
,
2116 N8_CB_EA_ENCRYPT_NUMCMDS
);
2118 } /* cb_ea_Encrypt */
2121 /*****************************************************************************
2123 *****************************************************************************/
2125 * @brief Create the command blocks to perform decrypt operation.
2127 * @param req_p RW: Request pointer.
2128 * @param encryptObject_p RO: Pointer to the encrypted object.
2129 * @param message_p RO: Address of results area.
2130 * @param encryptedMessage_p RW: Pointer to the encrypted message.
2131 * @param encryptedMessageLength RO: Encrypted message length.
2140 * N8_MALLOC_FAILED - memory allocation failed<BR>
2144 *****************************************************************************/
2145 N8_Status_t
cb_ea_decrypt(API_Request_t
*req_p
,
2146 EA_CMD_BLOCK_t
*cb_p
,
2147 N8_EncryptObject_t
*encryptObject_p
,
2148 const uint32_t encryptedMessage_a
,
2149 const uint32_t message_a
,
2150 const unsigned int encryptedMessageLength
)
2152 N8_Status_t ret
= N8_STATUS_OK
;
2156 CHECK_OBJECT(req_p
, ret
);
2157 CHECK_OBJECT(cb_p
, ret
);
2159 /* set the common elements */
2160 cb_p
->read_data_addr_ls
= encryptedMessage_a
;
2161 cb_p
->write_data_addr_ls
= message_a
;
2162 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
2164 /* based on cipher, set the opcode and other specifics */
2165 if (encryptObject_p
->cipher
== N8_CIPHER_ARC4
)
2167 /* ARC4 must use context index */
2168 cb_p
->cp_si_context
|= EA_Cmd_CP_Mask
|
2169 (EA_Ctx_Addr_Address_Mask
& encryptObject_p
->contextHandle
.index
);
2170 /* set the opcode */
2171 cb_p
->opcode_iter_length
= EA_Cmd_ARC4
| encryptedMessageLength
;
2173 else /* must be 3DES */
2175 /* set the opcode */
2176 cb_p
->opcode_iter_length
= EA_Cmd_3DES_CBC_Decrypt
| encryptedMessageLength
;
2177 /* DES may use context index or provide data in the command block */
2178 if (encryptObject_p
->contextHandle
.inUse
== N8_FALSE
)
2180 /* set the params common for 3DES */
2182 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.IV
[N8_MS_BYTE
]);
2184 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.IV
[N8_LS_BYTE
]);
2186 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key1
[N8_MS_BYTE
]);
2188 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key1
[N8_LS_BYTE
]);
2190 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key2
[N8_MS_BYTE
]);
2192 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key2
[N8_LS_BYTE
]);
2194 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key3
[N8_MS_BYTE
]);
2196 BE_to_uint32(&encryptObject_p
->cipherInfo
.key
.keyDES
.key3
[N8_LS_BYTE
]);
2198 /* increment the sequence number. should we later discover the
2199 * operation failed, the sequence number will need to be returned to
2200 * its previous value.
2202 encryptObject_p
->cipherInfo
.sequence_number
[1]++;
2203 /* check for wrapping */
2204 if (encryptObject_p
->cipherInfo
.sequence_number
[1] == 0)
2206 /* increment the sequence number ms */
2207 encryptObject_p
->cipherInfo
.sequence_number
[0]++;
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
);
2219 DBG_PRINT_EA_CMD_BLOCKS("cb_ea_decrypt",
2220 (EA_CMD_BLOCK_t
*) cb_p
,
2221 N8_CB_EA_DECRYPT_NUMCMDS
);
2223 } /* cb_ea_decrypt */
2225 /*****************************************************************************
2226 * cb_ea_loadDESKeyToContext
2227 *****************************************************************************/
2229 * @brief Loads DES key to context memory.
2232 * @param packetObj_p RO: pointer to packet object
2233 * @param cipherInfo_p RO: pointer to cipher infor
2234 * @param req_p RW: pointer to request block
2235 * @param hashAlgorithm RW: hash algorithm in use
2239 * ret - returns N8_STATUS_OK if successful or Error value.
2242 * N8_INVALID_OBJECT - context request object is NULL<BR>
2243 * N8_MALLOC_FAILED - memory allocation failed<BR>
2247 * contextIndex is valid and was passed to us by his rightful owner.
2248 * DES keys are valid.
2249 *****************************************************************************/
2251 N8_Status_t
cb_ea_loadDESKeyToContext(API_Request_t
*req_p
,
2252 EA_CMD_BLOCK_t
*cb_p
,
2253 const N8_Packet_t
*packetObj_p
,
2254 const N8_CipherInfo_t
*cipherInfo_p
,
2255 const N8_HashAlgorithm_t hashAlgorithm
,
2256 EA_SSL30_CTX
*ctx_p
,
2257 const uint32_t ctx_a
,
2258 EA_CMD_BLOCK_t
**next_cb_pp
)
2261 N8_Status_t ret
= N8_STATUS_OK
; /* the return status: OK or ERROR */
2263 DBG(("cb_ea_loadDESKeyToContext\n"));
2266 /* verify passed parameters */
2267 CHECK_OBJECT(req_p
, ret
);
2268 CHECK_OBJECT(cb_p
, ret
);
2269 CHECK_OBJECT(packetObj_p
, ret
);
2270 CHECK_OBJECT(cipherInfo_p
, ret
);
2272 /* build a context window image with the keys, IVs and other information*/
2274 BE_to_uint32(&cipherInfo_p
->IV
[N8_MS_BYTE
]);
2276 BE_to_uint32(&cipherInfo_p
->IV
[N8_LS_BYTE
]);
2277 ctx_p
->des_key1_ms
=
2278 BE_to_uint32(&cipherInfo_p
->key1
[N8_MS_BYTE
]);
2279 ctx_p
->des_key1_ls
=
2280 BE_to_uint32(&cipherInfo_p
->key1
[N8_LS_BYTE
]);
2281 ctx_p
->des_key2_ms
=
2282 BE_to_uint32(&cipherInfo_p
->key2
[N8_MS_BYTE
]);
2283 ctx_p
->des_key2_ls
=
2284 BE_to_uint32(&cipherInfo_p
->key2
[N8_LS_BYTE
]);
2285 ctx_p
->des_key3_ms
=
2286 BE_to_uint32(&cipherInfo_p
->key3
[N8_MS_BYTE
]);
2287 ctx_p
->des_key3_ls
=
2288 BE_to_uint32(&cipherInfo_p
->key3
[N8_LS_BYTE
]);
2290 switch (hashAlgorithm
)
2293 for (i
= 0; i
< N8_PRECOMPUTE_SIZE
; i
++)
2295 ctx_p
->secret1
[i
] = packetObj_p
->cipherInfo
.precompute1
[i
];
2296 ctx_p
->secret2
[i
] = packetObj_p
->cipherInfo
.precompute2
[i
];
2299 case N8_HMAC_MD5_96
:
2300 case N8_HMAC_SHA1_96
:
2303 for (i
= 0; i
< N8_PRECOMPUTE_SIZE
; i
++)
2305 ctx_p
->secret1
[i
] = packetObj_p
->hashPacket
.ipadHMAC_iv
[i
];
2306 ctx_p
->secret2
[i
] = packetObj_p
->hashPacket
.opadHMAC_iv
[i
];
2310 for (i
= 0; i
<5; i
++)
2313 BE_to_uint32(&cipherInfo_p
->macSecret
[i
* sizeof(uint32_t)]);
2319 DBG(("Invalid hash: %s\n", N8_HashAlgorithm_t_text(hashAlgorithm
)));
2320 ret
= N8_INVALID_HASH
;
2324 ctx_p
->sequence_number
[0] = cipherInfo_p
->sequence_number
[0];
2325 ctx_p
->sequence_number
[1] = cipherInfo_p
->sequence_number
[1];
2327 /* insert a command to put the keys in context memory window */
2328 cb_p
->cp_si_context
= EA_Cmd_CP_Mask
|
2329 (EA_Ctx_Addr_Address_Mask
& packetObj_p
->contextHandle
.index
);
2330 cb_p
->opcode_iter_length
=
2331 EA_Cmd_Write_Context_Memory
| sizeof(EA_SSL30_CTX
);
2332 cb_p
->read_data_addr_ls
= (uint32_t) ctx_a
;
2334 /* save next address for future use */
2335 if (next_cb_pp
!= NULL
)
2337 *next_cb_pp
= (EA_CMD_BLOCK_t
*) (cb_p
+ 1);
2342 DBG_PRINT_EA_CMD_BLOCKS("Load DES Key to Context Memory", cb_p
,
2343 N8_CB_EA_LOADDESKEYTOCONTEXT_NUMCMDS
);
2345 } /* cb_ea_loadDESKeyToContext */
2349 /*****************************************************************************
2350 * cb_ea_loadDESkeyOnly
2351 *****************************************************************************/
2353 * @brief Loads DES key to context memory.
2355 * @param req_p RW: pointer to request block
2356 * @param encryptObject_p RO: pointer to encrypted object
2357 * @param cipherInfo_p RO: pointer to cipher info
2360 * ret - returns N8_STATUS_OK if successful or Error value.
2363 * N8_INVALID_OBJECT - context request object is NULL<BR>
2364 * N8_MALLOC_FAILED - memory allocation failed<BR>
2368 * contextIndex is valid and was passed to us by his rightful owner.
2369 * DES keys are valid.
2370 *****************************************************************************/
2371 N8_Status_t
cb_ea_loadDESkeyOnly(API_Request_t
*req_p
,
2372 EA_CMD_BLOCK_t
*cb_p
,
2373 const N8_ContextHandle_t
*contextHandle_p
,
2374 const N8_EncryptCipher_t
*cipherInfo_p
)
2376 N8_Status_t ret
= N8_STATUS_OK
; /* the return status: OK or ERROR */
2377 EA_SSL30_CTX
*ctx_p
= NULL
;
2379 DBG(("cb_ea_loadDESkey_for_CryptoInterface\n"));
2383 /* verify passed parameters */
2384 CHECK_OBJECT(contextHandle_p
, ret
);
2385 CHECK_OBJECT(req_p
, ret
);
2386 CHECK_OBJECT(cipherInfo_p
, ret
);
2387 CHECK_OBJECT(cb_p
, ret
);
2389 ctx_p
= (EA_SSL30_CTX
*) ((int)req_p
+ req_p
->dataoffset
);
2391 /* build a context window image with the keys, IVs and other information*/
2393 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.IV
[N8_MS_BYTE
]);
2395 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.IV
[N8_LS_BYTE
]);
2396 ctx_p
->des_key1_ms
=
2397 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.key1
[N8_MS_BYTE
]);
2398 ctx_p
->des_key1_ls
=
2399 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.key1
[N8_LS_BYTE
]);
2400 ctx_p
->des_key2_ms
=
2401 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.key2
[N8_MS_BYTE
]);
2402 ctx_p
->des_key2_ls
=
2403 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.key2
[N8_LS_BYTE
]);
2404 ctx_p
->des_key3_ms
=
2405 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.key3
[N8_MS_BYTE
]);
2406 ctx_p
->des_key3_ls
=
2407 BE_to_uint32(&cipherInfo_p
->key
.keyDES
.key3
[N8_LS_BYTE
]);
2409 ctx_p
->sequence_number
[0] = cipherInfo_p
->sequence_number
[0];
2410 ctx_p
->sequence_number
[1] = cipherInfo_p
->sequence_number
[1];
2412 /* insert a command to put the keys in context memory window */
2413 cb_p
->cp_si_context
= contextHandle_p
->index
| EA_Cmd_CP_Mask
|
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
;
2422 DBG_PRINT_EA_CMD_BLOCKS("Load DES Key Only", cb_p
,
2423 N8_CB_EA_LOADDESKEYONLY_NUMCMDS
);
2425 } /* cb_ea_loadDESkeyOnly */
2427 /*****************************************************************************
2428 * cb_ea_loadIPsecKeyToContext
2429 *****************************************************************************/
2431 * @brief Loads IPsec DES key to context memory.
2434 * @param contextIndex RO: context memory to write
2435 * @param cipherInfo_p RO: pointer to cipher infor
2436 * @param req_p RW: pointer to request block
2440 * ret - returns N8_STATUS_OK if successful or Error value.
2443 * N8_INVALID_OBJECT - context request object is NULL<BR>
2444 * N8_MALLOC_FAILED - memory allocation failed<BR>
2448 * contextIndex is valid and was passed to us by his rightful owner.
2449 * DES keys are valid.
2450 *****************************************************************************/
2452 N8_Status_t
cb_ea_loadIPsecKeyToContext(API_Request_t
*req_p
,
2453 EA_CMD_BLOCK_t
*cb_p
,
2454 const unsigned int contextIndex
,
2455 const N8_CipherInfo_t
*cipherInfo_p
,
2456 EA_IPSEC_CTX
*IPsec_ctx_p
,
2457 const uint32_t IPsec_ctx_a
,
2458 EA_CMD_BLOCK_t
**next_cb_pp
)
2460 N8_Status_t ret
= N8_STATUS_OK
; /* the return status: OK or ERROR */
2462 DBG(("cb_ea_loadIPsecKeyToContext\n"));
2466 /* verify passed parameters */
2467 CHECK_OBJECT(req_p
, ret
);
2468 CHECK_OBJECT(cb_p
, ret
);
2469 CHECK_OBJECT(cipherInfo_p
, ret
);
2472 /* build a context window image with the keys, IVs and other information*/
2473 IPsec_ctx_p
->des_key1_ms
=
2474 BE_to_uint32(&cipherInfo_p
->key1
[N8_MS_BYTE
]);
2475 IPsec_ctx_p
->des_key1_ls
=
2476 BE_to_uint32(&cipherInfo_p
->key1
[N8_LS_BYTE
]);
2477 IPsec_ctx_p
->des_key2_ms
=
2478 BE_to_uint32(&cipherInfo_p
->key2
[N8_MS_BYTE
]);
2479 IPsec_ctx_p
->des_key2_ls
=
2480 BE_to_uint32(&cipherInfo_p
->key2
[N8_LS_BYTE
]);
2481 IPsec_ctx_p
->des_key3_ms
=
2482 BE_to_uint32(&cipherInfo_p
->key3
[N8_MS_BYTE
]);
2483 IPsec_ctx_p
->des_key3_ls
=
2484 BE_to_uint32(&cipherInfo_p
->key3
[N8_LS_BYTE
]);
2487 /* insert a command to put the keys in context memory window */
2488 cb_p
->cp_si_context
= contextIndex
| EA_Cmd_CP_Mask
;
2489 cb_p
->opcode_iter_length
=
2490 EA_Cmd_Write_Context_Memory
| sizeof(EA_IPSEC_CTX
);
2491 cb_p
->read_data_addr_ls
= (uint32_t) IPsec_ctx_a
;
2493 /* save next address for future use */
2494 if (next_cb_pp
!= NULL
)
2496 *next_cb_pp
= (EA_CMD_BLOCK_t
*) (cb_p
+ 1);
2501 DBG_PRINT_EA_CMD_BLOCKS("Load IPsec Key to Context Memory", cb_p
,
2502 N8_CB_EA_LOADIPSECKEYTOCONTEXT_NUMCMDS
);
2504 } /* cb_ea_loadIPsecKeyToContext */
2506 /*****************************************************************************
2508 *****************************************************************************/
2510 * @brief Create IPsec encrypt/authenticate or decrypt/verify command block.
2514 * @param cmdBlock_p RO: Pointer to the beginning of the command block.
2515 * @param packetObj_p RO: The object denoting the decryption and
2516 * verification computation to be done.
2517 * PacketObject must have been initialized
2518 * for use with IPsec.
2519 * The state in PacketObject will be updated if
2520 * necessary as part of the call. <BR>
2521 * @param packet_a RO: Physical address of IPsec packet<BR>
2522 * @param result_a WO: Physical address of the encrypted and
2523 * authenticated result.<BR>
2524 * @param packetLength RO: Packet length.<BR>
2525 * @param SPI RO: The IPsec Security Parameter Index for the
2526 * packet. (4 bytes).<BR>
2527 * @param opCode RO: Op Code to build into the command block.<BR>
2536 * contextIndex is valid and was passed to us by his rightful owner.
2537 * DES keys are valid.
2538 *****************************************************************************/
2539 void cb_ea_IPsec(EA_CMD_BLOCK_t
*cmdBlock_p
,
2540 const N8_Packet_t
*packetObj_p
,
2541 const uint32_t packet_a
,
2542 const uint32_t result_a
,
2543 const unsigned int packetLength
,
2545 const unsigned int opCode
)
2547 EA_IPSEC_CMD_BLOCK_t
*cb_p
= (EA_IPSEC_CMD_BLOCK_t
*)cmdBlock_p
;
2550 DBG(("cb_ea_IPsec\n"));
2552 if (packetObj_p
->contextHandle
.inUse
)
2554 /* read keys from context memory */
2555 cb_p
->cp_si_context
= EA_Cmd_CP_Mask
|
2556 (EA_Ctx_Addr_Address_Mask
& packetObj_p
->contextHandle
.index
);
2560 /* read keys from command block */
2561 for (i
= 0; i
<5; i
++)
2563 cb_p
->ipad
[i
] = packetObj_p
->cipherInfo
.key
.IPsecKeyDES
.ipad
[i
];
2564 cb_p
->opad
[i
] = packetObj_p
->cipherInfo
.key
.IPsecKeyDES
.opad
[i
];
2568 BE_to_uint32(&packetObj_p
->cipherInfo
.key1
[N8_MS_BYTE
]);
2570 BE_to_uint32(&packetObj_p
->cipherInfo
.key1
[N8_LS_BYTE
]);
2572 BE_to_uint32(&packetObj_p
->cipherInfo
.key2
[N8_MS_BYTE
]);
2574 BE_to_uint32(&packetObj_p
->cipherInfo
.key2
[N8_LS_BYTE
]);
2576 BE_to_uint32(&packetObj_p
->cipherInfo
.key3
[N8_MS_BYTE
]);
2578 BE_to_uint32(&packetObj_p
->cipherInfo
.key3
[N8_LS_BYTE
]);
2582 cb_p
->opcode_iter_length
= opCode
| packetLength
;
2584 cb_p
->read_data_addr_ls
= (uint32_t) packet_a
;
2585 cb_p
->write_data_addr_ls
= (uint32_t) result_a
;
2587 cb_p
->sequence_number
= packetObj_p
->cipherInfo
.key
.IPsecKeyDES
.sequence_number
;
2588 cb_p
->des_IV_ms
= BE_to_uint32(&packetObj_p
->cipherInfo
.IV
[N8_MS_BYTE
]);
2589 cb_p
->des_IV_ls
= BE_to_uint32(&packetObj_p
->cipherInfo
.IV
[N8_LS_BYTE
]);
2592 DBG_PRINT_EA_CMD_BLOCKS("IPsec ",
2593 (EA_CMD_BLOCK_t
*) cb_p
,
2594 N8_CB_EA_IPSECENCRYPTAUTHENTICATE_NUMCMDS
);
2598 /**************************************************
2600 **************************************************/
2602 /*****************************************************************************
2604 *****************************************************************************/
2606 * @brief Convert a 64 bit byte length to bits.
2608 * The CCH requires the hash message length be specified in a 64 bit
2609 * quantity representing the number of bits. The API up to this point
2610 * keeps the value as the number of bytes spread across two 32 bit
2611 * quantities. This routine multiplies the two 32-bit quantities by
2612 * 8. It is done by shifting left 3 places. Of course, the upper
2613 * 3 bits of the least significant must be placed back into the most
2616 * @param cb_p RW: command block pointer
2617 * @param obj_p RO: hash object
2623 * If the previous quantity is > 0x000FFFFF FFFFFFFF an overflow
2628 *****************************************************************************/
2629 static void convertToBits(EA_CMD_BLOCK_t
*cb_p
,
2630 const N8_HashObject_t
*obj_p
,
2631 const n8_IVSrc_t ivSrc
)
2638 high
= obj_p
->opad_Nh
;
2639 low
= obj_p
->opad_Nl
;
2647 cb_p
->prev_length_ms
= (high
<< 3) | (low
>> 29);
2648 cb_p
->prev_length_ls
= low
<< 3;
2649 } /* convertToBits */
2651 /*****************************************************************************
2652 * cb_ea_TLSHandshakeHash
2653 *****************************************************************************/
2655 * @brief Generate the command blocks for the N8_HandshakeHashEnd
2656 * N8_TLS_CERT and N8_TLS_FINISH modes.
2658 * This function generates the command blocks for the N8_TLS_CERT and
2659 * N8_TLS_FINISH modes. The algorithm is defined in RFC 2246 section 5.
2662 * @param req_p RO: The API request.
2663 * @param protocol RO: The protocol (N8_TLS_CERT or N8_TLS_FINISH).
2664 * @param resMD5_a RO: Physical address for MD5 result.
2665 * @param hashMsgMD5_a RO: Physical address for MD5 input.
2666 * @param md5Length RO: Length of MD5 input.
2667 * @param resSHA_a RO: Physical address for SHA1 result.
2668 * @param hashMsgSHA_a RO: Physical address for SHA1 input.
2669 * @param sha1Length RO: Length of SHA1 input.
2670 * @param resMD5PRF_a RO: Physical address for MD5 TLS PRF result.
2671 * @param resSHA1PRF_a RO: Physical address for SHA TLS PRF result.
2672 * @param key_p RO: The key for this transaction.
2673 * @param keyLength RO: The length of the key.
2674 * @param roleStr_a RO: Physical address for the role string.
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.
2685 * See return section.
2691 * We are assuming that the command blocks are all memset to zero before
2692 * they are passed in to this function.
2693 *****************************************************************************/
2696 cb_ea_TLSHandshakeHash(API_Request_t
*req_p
,
2697 N8_HashProtocol_t protocol
,
2699 uint32_t hashMsgMD5_a
,
2700 N8_HashObject_t
*hashMsgMD5_p
,
2703 uint32_t hashMsgSHA1_a
,
2704 N8_HashObject_t
*hashMsgSHA1_p
,
2706 uint32_t resMD5PRF_a
,
2707 uint32_t resSHA1PRF_a
,
2708 const N8_Buffer_t
*key_p
,
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 */
2717 int nCmdBlocks
= N8_CB_EA_CERTTLSHANDSHAKE_NUMCMDS
;
2718 uint32_t keyBuffer
[N8_HASH_BLOCK_SIZE
];
2721 DBG(("cb_ea_TLSHandshakeHash\n"));
2725 /* verify passed parameters */
2726 CHECK_OBJECT(req_p
, ret
);
2727 CHECK_OBJECT(req_p
->EA_CommandBlock_ptr
, ret
);
2729 if (keyLength
> N8_HASH_BLOCK_SIZE
* 2)
2731 /* Note that eventually the upper level function
2732 will hash the key if it is too long. At the moment
2733 we are just going to return an error */
2734 ret
= N8_INVALID_PARAMETER
;
2738 cb_p
= req_p
->EA_CommandBlock_ptr
;
2740 /* Command block 1: Complete the MD5 hash using command 0x14 */
2741 cb_p
->read_data_addr_ls
= hashMsgMD5_a
;
2742 cb_p
->write_data_addr_ls
= resMD5_a
;
2743 memcpy(cb_p
->hash_IV
, hashMsgMD5_p
->iv
, sizeof(hashMsgMD5_p
->iv
));
2744 cb_p
->opcode_iter_length
= EA_Cmd_MD5_End_cmdIV
;
2745 cb_p
->opcode_iter_length
|= (EA_Cmd_Data_Length_Mask
& md5Length
);
2746 convertToBits(cb_p
, hashMsgMD5_p
, N8_IV
);
2749 /* Command block 2: Complete the SHA1 hash using command 0x24 */
2750 cb_p
->read_data_addr_ls
= hashMsgSHA1_a
;
2751 cb_p
->write_data_addr_ls
= resSHA1_a
;
2752 cb_p
->opcode_iter_length
= EA_Cmd_SHA1_End_cmdIV
;
2753 cb_p
->opcode_iter_length
|= (EA_Cmd_Data_Length_Mask
& sha1Length
);
2754 memcpy(cb_p
->hash_IV
, hashMsgSHA1_p
->iv
, sizeof(hashMsgSHA1_p
->iv
));
2755 convertToBits(cb_p
, hashMsgSHA1_p
, N8_IV
);
2756 cb_HMAC_p
= (EA_HMAC_CMD_BLOCK_t
*) (cb_p
+ 1);
2758 if (protocol
== N8_TLS_FINISH
)
2760 /* At this point we have completed the MD5 and the SHA1 hash. So
2761 we should have the label, the MD5 hash and the SHA1 right next to
2762 each other ready to be used as input for the TLS pseudo random
2763 function (PRF). Please see RFC 2246 section 5 for a description of
2764 the PRF we are implementing. */
2766 /* According to the RFC, we use half of the key for the MD5 Hash and
2767 half for the SHA1 hash. If the key length is odd, we use the
2768 middle byte in both. So first we find the ceiling of half the
2770 halfKey
= CEIL(keyLength
, 2);
2772 /* The length of the label, MD5 hash and SHA1 hash */
2773 dataLength
= N8_TLS_ROLE_STRING_LENGTH
+ MD5_HASH_RESULT_LENGTH
+
2774 SHA1_HASH_RESULT_LENGTH
;
2776 /* This is for the debug printing */
2777 nCmdBlocks
= N8_CB_EA_FINISHTLSHANDSHAKE_NUMCMDS
;
2779 /* Command block 3: The MD5 portion of the PRF */
2780 /* set the HMAC key data */
2782 /* Copy the first halfKey bytes of the key to the command block */
2783 memset(keyBuffer
, 0, sizeof(keyBuffer
));
2784 memcpy(keyBuffer
, key_p
, halfKey
);
2786 for (i
= 0; i
< halfKey
; i
+= 4)
2788 cb_HMAC_p
->hmac_key
[i
] = BE_to_uint32(keyBuffer
+ i
);
2791 /* This is the role string plus the MD5 and SHA1 hash results */
2792 cb_HMAC_p
->read_data_addr_ls
= roleStr_a
;
2794 cb_HMAC_p
->write_data_addr_ls
= resMD5PRF_a
;
2795 cb_HMAC_p
->opcode_iter_length
= EA_Cmd_MD5_HMAC
;
2796 cb_HMAC_p
->opcode_iter_length
|= (2 << EA_Cmd_Iterations_Shift
);
2797 cb_HMAC_p
->opcode_iter_length
|= (EA_Cmd_Data_Length_Mask
& dataLength
);
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 */
2808 /* The key length was odd */
2809 memcpy(keyBuffer
, &(key_p
[halfKey
- 1]), halfKey
);
2813 memcpy(keyBuffer
, &(key_p
[halfKey
]), halfKey
);
2816 for (i
= 0; i
< halfKey
; i
+= 4)
2818 cb_HMAC_p
->hmac_key
[i
] = BE_to_uint32(keyBuffer
+ i
);
2821 /* This is STILL the role string plus MD5 and SHA1 hash results */
2822 cb_HMAC_p
->read_data_addr_ls
= roleStr_a
;
2824 cb_HMAC_p
->write_data_addr_ls
= resSHA1PRF_a
;
2825 cb_HMAC_p
->cp_si_context
= EA_Cmd_SI_Mask
;
2826 cb_HMAC_p
->opcode_iter_length
= EA_Cmd_SHA1_HMAC
;
2827 cb_HMAC_p
->opcode_iter_length
|= (2 << EA_Cmd_Iterations_Shift
);
2828 cb_HMAC_p
->opcode_iter_length
|= (EA_Cmd_Data_Length_Mask
& dataLength
);
2832 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
2836 DBG_PRINT_EA_CMD_BLOCKS("TLS Handshake End/Cert",
2837 (EA_CMD_BLOCK_t
*) req_p
->EA_CommandBlock_ptr
,
2844 /*****************************************************************************
2845 * cb_ea_SSLHandshakeHash
2846 *****************************************************************************/
2848 * @brief Generate the command blocks for the N8_HandshakeHashEnd
2849 * N8_SSL_CERT and N8_SSL_FINISH modes.
2851 * This function generates the command blocks for the N8_SSL_CERT and
2852 * N8_SSL_FINISH modes.
2855 * @param req_p RO: The API request.
2856 * @param resMD5_a RO: Physical address for MD5 result.
2857 * @param hashMsgMD5_a RO: Physical address for MD5 input.
2858 * @param md5Length RO: Length of MD5 input.
2859 * @param resSHA_a RO: Physical address for SHA1 result.
2860 * @param hashMsgSHA_a RO: Physical address for SHA1 input.
2861 * @param sha1Length RO: Length of SHA1 input.
2862 * @param endresMD5_a RO: Physical address for MD5 SSL result.
2863 * @param endresSHA1_a RO: Physical address for SHA SSL result.
2864 * @param outerMsgMD5_a RO: Physical address for the outerMsg.
2865 * @param outerMsgSHA_a RO: Physical address for the outerMsg.
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.
2876 * See return section.
2882 * We are assuming that the command blocks are all memset to zero before
2883 * they are passed in to this function.
2884 *****************************************************************************/
2886 N8_Status_t
cb_ea_SSLHandshakeHash(API_Request_t
*req_p
,
2887 EA_CMD_BLOCK_t
*cb_p
,
2888 N8_HashObject_t
*hObjMD5_p
,
2889 uint32_t innerResult_md5_a
,
2890 uint32_t hashMsgMD5_a
,
2891 int hashingLength_md5
,
2892 N8_HashObject_t
*hObjSHA_p
,
2893 uint32_t innerResult_sha_a
,
2894 uint32_t hashMsgSHA_a
,
2895 int hashingLength_sha
,
2896 uint32_t endresMD5_a
,
2897 uint32_t endresSHA1_a
,
2898 uint32_t outerMsgMD5_a
,
2899 unsigned int outer_md5Length
,
2900 uint32_t outerMsgSHA1_a
,
2901 unsigned int outer_shaLength
)
2903 N8_Status_t ret
= N8_STATUS_OK
; /* return status: OK or ERROR */
2905 DBG(("cb_ea_SSLHandshakeHash\n"));
2909 /* verify passed parameters */
2910 CHECK_OBJECT(req_p
, ret
);
2911 CHECK_OBJECT(cb_p
, ret
);
2912 /* Command block 1: Complete the inner MD5 hash */
2913 cb_p
->read_data_addr_ls
= hashMsgMD5_a
;
2914 cb_p
->write_data_addr_ls
= innerResult_md5_a
;
2915 memcpy(cb_p
->hash_IV
, hObjMD5_p
->iv
, sizeof(hObjMD5_p
->iv
));
2916 cb_p
->opcode_iter_length
= EA_Cmd_MD5_End_cmdIV
| hashingLength_md5
;
2917 convertToBits(cb_p
, hObjMD5_p
, N8_IV
);
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
);
2928 /* Command block 3: Complete the outer MD5 hash using command 0x10 */
2930 /* Copy the first halfKey bytes of the key to the command block */
2931 cb_p
->read_data_addr_ls
= outerMsgMD5_a
;
2932 cb_p
->write_data_addr_ls
= endresMD5_a
;
2933 cb_p
->opcode_iter_length
= EA_Cmd_MD5
| outer_md5Length
;
2936 /* Command block 4: Complete the outer SHA1 hash using command 0x20 */
2938 cb_p
->read_data_addr_ls
= outerMsgSHA1_a
;
2939 cb_p
->write_data_addr_ls
= endresSHA1_a
;
2940 cb_p
->cp_si_context
= EA_Cmd_SI_Mask
;
2941 cb_p
->opcode_iter_length
= EA_Cmd_SHA1
| outer_shaLength
;
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
);
2949 } /* cb_ea_SSLHandshakeHash */