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_packet.c,v 1.1 2008/10/30 12:02:14 darran Exp $";
36/*****************************************************************************/
37/** @file n8_packet.c
38 *  @brief Contains packet functions.
39 *
40 * Functions:
41 *          N8_PacketInitializeMemory
42 *               Initializes (makes ready for use in packet operations) the
43 *               packet object. This version uses supplied kernel memory
44 *               buffers.
45 *          N8_PacketInitialize
46 *               Initializes (makes ready for use in packet operations) the
47 *               packet object.
48 *
49 *****************************************************************************/
50
51/*****************************************************************************
52 * Revision history:
53 *
54 * 08/18/03 brr   Combine Encrypt/Decrypt command block generators for SSL,
55 *                TLS, & IPsec.
56 * 07/30/03 bac   Removed obsolete and confusing code referring to chained
57 *                requests in N8_PacketInitializeMemory.
58 * 07/28/03 brr   Removed obsolete #ifdefs. (Bug 918)
59 * 07/01/03 brr   Added option to use no hashing algorithm.
60 * 05/20/03 brr   Modified N8_PacketInitialize to setup function pointers &
61 *                lengths used in the Encrypt/Decrypt operations. Eliminated
62 *                several switch statements from Encrypt/Decrypt operations.
63 * 03/05/03 brr   Allow mode = N8_PACKETMEMORY_REQUEST for IPsec.
64 * 08/06/02 bac   Fixed Bug #842 -- user's cipher info was being modified.
65 * 07/16/02 arh   Fixed N8_PacketInitializeMemory: 1) check mode parameter
66 *                for correctness; 2) to return an error if protocol is
67 *                N8_IPSEC & mode != N8_PACKETMEMORY_NONE. (Fix Bug #815)
68 * 06/14/02 hml   Added new call N8_PacketInitializeMemory. The old packet
69 *                init call is still supported.
70 * 06/11/02 bac   Removed #ifdef'd reference to obsolete and missing
71 *                n8_validateContext.
72 * 06/10/02 hml   Initialize the request field in the packet to NULL.
73 * 05/07/02 msz   New interface for QUEUE_AND_CHECK for new synchronous support.
74 * 04/04/02 msz   BUG 520, have N8_PacketInitialize check for weak keys.
75 * 03/26/02 hml   Calls n8_validateUnit in packet init routine (BUG 643).
76 * 03/25/02 hml   Fix for bug 642.  Initialing a packet for ARC4 with a
77 *                NULL context returns N8_UnallocatedContext.
78 * 03/26/02 brr   Allocate the data buffer as part of the API request.
79 * 03/14/02 hml   Cleaned and commented.
80 * 02/12/02 hml   Added N8_PacketBuffersSet.
81 * 02/28/02 brr   Do not include any QMgr include files.
82 * 01/31/02 brr   Eliminated the memory allocation for postProcessingData.
83 * 01/22/02 bac   Added code to use software to do SSL and HMAC precomputes.
84 * 01/22/02 bac   Removed loading of context.  It is deferred until the packet
85 *                object is used the first time.
86 * 01/21/02 bac   Changes to support new kernel allocation scheme.
87 * 01/14/02 bac   Changed use of loadContext_req to take a physical and virtual
88 *                address to a pre-formed context.  This allows the use of the
89 *                results of a previous initialization to work properly.
90 * 01/12/02 bac   Removed all blocking calls within a single API method.  This
91 *                required restructuring the N8_PacketInitialize call and taking
92 *                advantage of Queue Manager sub-requests.  (BUG #313)
93 * 11/24/01 brr   Removed include of obsolete EA & PK specifice Queue files.
94 * 11/16/01 bac   Fixed a memory leak in handleIPsec.
95 * 11/14/01 bac   Cleaned up debugging messages.
96 * 11/12/01 hml   Updated initMD5 and initSha1 calls.
97 * 11/12/01 hml   Changed PI_PROTOCOL_* to N8_PI_PROTOCOL_*.
98 * 11/09/01 hml   Added structure verification code.
99 * 11/05/01 bac   Replaced reference to SINGLE_CHIP with correct unitID.  Fixed
100 *                a memory leak in handleHmac.
101 * 10/30/01 bac   Changed to not block on N8_PacketInitialize unless context is
102 *                actually being used.
103 * 10/30/01 bac   Fixes to defer loading of the context during a call to
104 *                N8_PacketInitialize.  This was required due to the need for
105 *                the partial hash IV values to be byte-swapped before loading
106 *                into the context.  The result handler is the only place
107 *                available to do the byte-swapping, but it occurs after the
108 *                context is loaded.  Thus the need to do the load in a separate
109 *                request.  Please note this causes N8_PacketInitialize to block
110 *                while the partial hashes are computed IFF a context is to be
111 *                loaded.
112 * 10/19/01 hml   Fixed compiler warnings.
113 * 10/17/01 mel   Cleaned: deleted unnecessary createEARequestBuffer calls.
114 * 10/11/01 bac   Fixed a bug where kernel memory was being freed incorrectly.
115 * 10/05/01 mel   Added comments to handleIPsec.
116 * 10/04/01 mel   IPsec code optimization. Added handleIPsec function
117 * 10/04/01 mel   SSL/TLS code optimization. Added handleHMAC function
118 * 09/24/01 mel   Code optimization.
119 * 09/20/01 bac   The interface to the command block generators changed and now
120 *                accept the command block buffer.  All calls to cb_ea methods
121 *                changed herein.
122 * 09/12/01 mel   Increased speed by using initMD5/initSHA1 directly instead
123 *                of N8_HashInitialize. Added event parameter to N8_PacketInitialize.
124 * 07/31/01 bac   Added call to N8_preamble for all public interfaces.
125 * 07/30/01 bac   Pass chip id to createEARequestBuffer.
126 * 07/02/01 mel   Fixed comments.
127 * 06/28/01 bac   Changes to get event handling to work properly.
128 * 06/25/01 bac   Memory management changes.
129 * 06/20/01 mel   Corrected use of kernel memory.
130 * 05/31/01 mel   Changed keys and IVs to be a char[] instead of uint32_t[].
131 * 05/30/01 bac   Doxygenation
132 * 05/23/01 bac   Changed macSecret to be a char[] instead of uint32_t[].
133 * 05/23/01 bac   Fixed a bug where there was a ; after an if.
134 * 05/21/01 bac   Converted to use N8_ContextHandle_t and N8_Packet_t
135 *                with integrated cipher and hash packet.
136 * 05/19/01 bac   Formatting changes.  Pass NULL not 0 when appropriate.
137 * 05/18/01 bac   Set contextIndex to 0 even when not used for safety.
138 * 05/18/01 mel   Moved context index validation from configuration block
139 *                to protocol block.
140 * 05/18/01 bac   Reformat to standard.  Cleaned up memory allocation/free.
141 * 05/11/01 bac   Naming standardization.
142 * 05/11/01 bac   Slight formatting changes.  Changed ProtocolConfiguration
143 *                to use the new PROTOCOL_CIPHER_HASH macro.
144 * 05/03/01 bac   Replaced integer use of NULL with 0.
145 * 04/18/01 mel   Original version.
146 ****************************************************************************/
147/** @defgroup n8_packet API Packet-Level functions
148 */
149
150
151#include "n8_common.h"          /* common definitions */
152#include "n8_pub_errors.h"      /* Errors definition */
153#include "n8_enqueue_common.h"  /* common definitions for enqueue */
154#include "n8_cb_ea.h"
155#include "n8_util.h"
156#include "n8_hash.h"
157#include "n8_key_works.h"
158#include "n8_packet.h"
159#include "n8_API_Initialize.h"
160#include "n8_pub_buffer.h"
161#include "n8_precompute.h"
162
163typedef struct
164{
165   N8_Buffer_t *result1_p;
166   N8_Buffer_t *result2_p;
167} n8_PacketResults_t;
168
169
170/*****************************************************************************
171 * n8_initializeSSL_req
172 *****************************************************************************/
173/** @ingroup n8_packet
174 * @brief Precomputes values for MD5 hashes.
175 *
176 *  @param cipherInfo_p        RW:  Cipher information
177 *  @param packetObject_p      RO:  Pointer to packet object.  May be NULL.
178 *  @param req_pp              RW:  Pointer to request pointer.
179 *
180 * @par Externals
181 *    None
182 *
183 * @return
184 *    Status code
185 *
186 * @par Errors
187 *    None
188 * @par Assumptions
189 *    None
190 *****************************************************************************/
191static N8_Status_t n8_initializeSSL_req(N8_CipherInfo_t *cipherInfo_p,
192                                        N8_Packet_t  *packetObject_p,
193                                        N8_Buffer_t **ctx_pp,
194                                        uint32_t *ctxa_p,
195                                        API_Request_t **req_pp)
196{
197   N8_Status_t        ret = N8_STATUS_OK;
198   API_Request_t     *req_p = NULL;
199
200   do
201   {
202      CHECK_OBJECT(cipherInfo_p, ret);
203      CHECK_OBJECT(packetObject_p, ret);
204      /* initialize set the return request pointer to NULL.  it wil be reset
205       * with an actual value later if necessary. */
206      *req_pp = NULL;
207
208      ret =
209         n8_precompute_ssl_ipad_opad(packetObject_p->cipherInfo.macSecret,
210                                     packetObject_p->cipherInfo.precompute1,
211                                     packetObject_p->cipherInfo.precompute2);
212      CHECK_RETURN(ret);
213
214   } while (FALSE);
215   /*
216    * Clean up if we arrived from an error condition.
217    */
218   if (ret != N8_STATUS_OK)
219   {
220      freeRequest(req_p);
221   }
222   return ret;
223} /* n8_initializeSSL_req */
224
225
226/*****************************************************************************
227 * N8_PacketInitializeMemory
228 *****************************************************************************/
229/** @ingroup n8_packet
230 * @brief Initializes (makes ready for use in packet operations) the packet object.
231 *
232 * Typically a packet object will be initialized at the beginning of an SSL,
233 * TLS, or IPSec session with the cipher and hash information particular to
234 * that session.  The packet object can then be used in all subsequent packet
235 * operations until the session is terminated.  Note however that if a new key
236 * is negotiated during the session, then the packet object must be re-initialized
237 * with the new key material.
238 *
239 * @param packetObject_p WO:    The packet object to be initialized with the
240 *                              specified information.<BR>
241 * @param contextHandle_p RO:   A valid context index as returned by
242 *                              N8_AllocateContext, if Cipher = ARC4.
243 *                              Optional, if Cipher = DES.<BR>
244 * @param protocol RO:          One of the values SSL, TLS, or IPSec.
245 *                              Denotes the protocol that PacketObject should
246 *                              be initialized for.<BR>
247 * @param cipher RO:            If Protocol = SSL or TLS, one of the values ARC4
248 *                              or  DES.
249 *                              If Protocol = IPSec, then Cipher must be DES.
250 *                              Specifies the cipher algorithm to use, and hence the
251 *                              type and format of the information in
252 *                              CipherInfo_p.<BR>
253 * @param cipherInfo_p RO:      The specific information to be used in the
254 *                              initialization of the cipher algorithm. Its
255 *                              contents depend on the value of ContextType, as
256 *                              specified above.<BR>
257 * @param hashAlgorithm RO:     One of the values MD5, SHA-1, HMAC-MD5, HMAC-SHA-1,
258 *                              HMAC-MD5-96 or HMAC-SHA-1-96 denoting the hash
259 *                              algorithm to be used.
260 * @param mode          RO:     One of the values from N8_PacketMemoryMode_t
261 *
262 *
263 * @return
264 *    packetObject_p - initialized packet object.
265 *    ret - returns N8_STATUS_OK if successful or Error value.
266 *
267 * @par Errors:
268 *    N8_INVALID_PROTOCOL - The value of Protocol is not one of the legal
269 *                          values SSL, TSL or IPSec.<BR>
270 *    N8_INVALID_OBJECT   - packet object is zero, couldn't write to unspecified
271 *                          address<BR>
272 *    N8_INVALID_CIPHER   - The value of Cipher is not one of the legal values
273 *                          ARC4 or DES.<BR>
274 *    N8_INVALID_HASH     - The value of HashAlgorithm is not one of the legal
275 *                          values MD5,  SHA-1, HMAC-MD5, HMAC-SHA-1, HMAC-MD5-96
276 *                          or HMAC-SHA-1-96<BR>
277 *    N8_INVALID_VALUE    - The value of ContextIndex is not a valid context
278 *                          index, or ContextIndex is null but a context index
279 *                          is required because ARC4 is specified.<BR>
280 *    N8_UNALLOCATED_CONTEXT - ContextIndex denotes a context memory index that
281 *                          has not been allocated by N8_AllocateContext.<BR>
282 *    N8_INVALID_KEY_SIZE -     The size of the key specified in CipherInfo_p is
283 *                          outside the valid range for the encryption algorithm
284 *                          specified in Cipher, or the size of an HMAC key
285 *                          specified in CipherInfo_p is outside the valid range
286 *                          for the hash algorithm specified in HashAlgorithm.<BR>
287 *    N8_INCONSISTENT  -        The information in  CipherInfo_p and/or its type is
288 *                          different than or inconsistent with the type
289 *                          specified by Cipher or HashAlgorithm, or the
290 *                          combination of values specified by Protocol, Cipher,
291 *                          and HashAlgorithm is invalid (for example, SSL is
292 *                          specified with HMAC-MD5, or IPSec is specified with
293 *                          ARC4).<BR>
294 *    N8_MALLOC_FAILED    - memory allocation failed
295 *    N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested
296 *    N8_HARDWARE_ERROR   - couldn't write to context memory
297 *
298 *
299 * @par Assumptions:
300 *    The context entry specified in this call should not be in use with any
301 *    other current  encrypt object or packet object. This condition is not
302 *    checked for;  incorrect / indeterminate results and / or errors are likely
303 *    in this situation.<BR>
304 *    If a new key is negotiated during the session, then the packet object must
305 *    be re-initialized with the new key material.<BR>
306 *****************************************************************************/
307N8_Status_t
308N8_PacketInitializeMemory(N8_Packet_t                *packetObject_p,
309                          const N8_ContextHandle_t   *contextHandle_p,
310                          const N8_Protocol_t         protocol,
311                          const N8_Cipher_t           cipher,
312                          const N8_CipherInfo_t            *cipherInfo_p,
313                          const N8_HashAlgorithm_t    hashAlgorithm,
314                          const N8_PacketMemoryMode_t mode,
315                          N8_Event_t                 *event_p)
316
317{
318   API_Request_t *req_p = NULL;
319   N8_Status_t ret = N8_STATUS_OK;             /* the return status: OK or ERROR */
320   int         protocolConfiguration = 0;
321   int         i;
322   key_cblock_t key1, key2, key3;               /* Keys to be checked */
323   N8_Buffer_t *ctx_p = NULL;
324   uint32_t ctx_a;              /* physical address of context for
325                                 * post-computation processing */
326   N8_Boolean_t  unitValid;
327
328   DBG(("N8_PacketInitializeMemory\n"));
329
330   do
331   {
332      ret = N8_preamble();
333      CHECK_RETURN(ret);
334
335      /* verify packet object */
336      CHECK_OBJECT(packetObject_p, ret);
337
338      /* verify cipher object */
339      CHECK_OBJECT(cipherInfo_p, ret);
340
341      /* Check mode paramter & Init the mode to the user value */
342      if (mode != N8_PACKETMEMORY_REQUEST && mode != N8_PACKETMEMORY_NONE)
343      {
344         ret = N8_INVALID_ENUM;
345         break;
346      }
347      packetObject_p->mode =  mode;
348
349      if (contextHandle_p != NULL)
350      {
351         DBG(("N8_PacketInitialize using context\n"));
352
353         /* Make sure the context struct is valid */
354         CHECK_STRUCTURE(contextHandle_p->structureID,
355                         N8_CONTEXT_STRUCT_ID,
356                         ret);
357         unitValid = n8_validateUnit(contextHandle_p->unitID);
358         if (!unitValid)
359         {
360            ret= N8_INVALID_UNIT;
361            break;
362         }
363         memcpy(&packetObject_p->contextHandle, contextHandle_p, sizeof(N8_ContextHandle_t));
364         packetObject_p->contextHandle.inUse = N8_TRUE;
365         packetObject_p->unitID = contextHandle_p->unitID;
366      }
367      else
368      {
369         if (cipher == N8_CIPHER_ARC4)
370         {
371            /* The use of ARC4 requires a context */
372            ret = N8_UNALLOCATED_CONTEXT;
373            break;
374         }
375         else
376         {
377            DBG(("N8_PacketInitialize not using context\n"));
378            unitValid = n8_validateUnit(cipherInfo_p->unitID);
379            if (!unitValid)
380            {
381               ret= N8_INVALID_UNIT;
382               break;
383            }
384            packetObject_p->contextHandle.inUse = N8_FALSE;
385            packetObject_p->contextHandle.index = 0xFFFF;
386            packetObject_p->unitID = cipherInfo_p->unitID;
387         }
388      }
389
390      /* copy the supplied cipher info into the packet object */
391      memcpy(&packetObject_p->cipherInfo, cipherInfo_p, sizeof(N8_CipherInfo_t));
392
393      /* verify cipher */
394      switch (cipher)
395      {
396         case   N8_CIPHER_ARC4:
397
398            /* verify key size */
399            if ((packetObject_p->cipherInfo.keySize < 1) ||
400                (packetObject_p->cipherInfo.keySize > ARC4_KEY_SIZE_BYTES_MAX))
401            {
402               DBG(("Key size specified for ARC4 is outside the"
403                    " valid range:  %d\n",
404                    packetObject_p->cipherInfo.keySize));
405               DBG(("N8_PacketInitialize - return Error\n"));
406               ret = N8_INVALID_KEY_SIZE;
407               break;
408            }
409            packetObject_p->ctxLoadFcn = &cb_ea_loadARC4KeyToContext;
410            packetObject_p->ctxLoadCmds = N8_CB_EA_LOADARC4KEYTOCONTEXT_NUMCMDS;
411            break;
412
413         case   N8_CIPHER_DES:
414            /* verify key size */
415
416            if (packetObject_p->cipherInfo.keySize != DES_KEY_SIZE_BYTES)
417            {
418               DBG(("Key size specified for DES is outside "
419                    "the valid range: %d\n",
420                    packetObject_p->cipherInfo.keySize));
421               DBG(("N8_PacketInitialize - return Error\n"));
422               ret = N8_INVALID_KEY_SIZE;
423               break;
424            }
425
426            /* build keys for parity verification */
427            /* force key parity */
428            for (i=0 ; i < sizeof(key_cblock_t); i++)
429            {
430               key1[i] = packetObject_p->cipherInfo.key1[i];
431               key2[i] = packetObject_p->cipherInfo.key2[i];
432               key3[i] = packetObject_p->cipherInfo.key3[i];
433            }
434            if (checkKeyParity(&key1) == FALSE)
435            {
436               forceParity(&key1);
437               for (i=0 ; i < sizeof(key_cblock_t); i++)
438               {
439                  packetObject_p->cipherInfo.key1[i] = key1[i];
440               }
441            }
442            if (checkKeyParity(&key2) == FALSE)
443            {
444               forceParity(&key2);
445               for (i=0 ; i < sizeof(key_cblock_t); i++)
446               {
447                  packetObject_p->cipherInfo.key2[i] = key2[i];
448               }
449            }
450            if (checkKeyParity(&key3) == FALSE)
451            {
452               forceParity(&key3);
453               for (i=0 ; i < sizeof(key_cblock_t); i++)
454               {
455                  packetObject_p->cipherInfo.key3[i] = key3[i];
456               }
457            }
458
459            /* check key1 and key2 for weakness */
460            if (checkKeyForWeakness(&key1) == N8_TRUE ||
461                checkKeyForWeakness(&key2) == N8_TRUE ||
462                checkKeyForWeakness(&key3) == N8_TRUE)
463            {
464               DBG(("Weak key\nN8_PacketInitialize - return Error\n"));
465               ret = N8_WEAK_KEY;
466               break;
467            }
468            packetObject_p->ctxLoadFcn = &cb_ea_loadDESKeyToContext;
469            packetObject_p->ctxLoadCmds = N8_CB_EA_LOADDESKEYTOCONTEXT_NUMCMDS;
470            break;
471
472         default:
473            /* invalid cipher */
474            DBG(("Invalid cipher\n"));
475            DBG(("N8_PacketInitialize - return Error\n"));
476            ret = N8_INVALID_CIPHER;
477            break;
478      }
479      CHECK_RETURN(ret);
480
481      /* create request buffer */
482      /* protocol in use */
483      packetObject_p->packetProtocol = protocol;
484      /* encription algorithm */
485      packetObject_p->packetCipher = cipher;
486      /* hash algorithm */
487      packetObject_p->packetHashAlgorithm = hashAlgorithm;
488      /* verify protocol configuration */
489      protocolConfiguration = PROTOCOL_CIPHER_HASH(protocol, cipher, hashAlgorithm);
490
491      /* after the memcpy, ensure we aren't pointing to dynamically allocated
492         space the user set up in the cipher info. */
493      packetObject_p->cipherInfo.hmac_key = NULL;
494
495      /* verify hash algorithm and HMAC keys if appropriate */
496      switch (hashAlgorithm)
497      {
498         case N8_MD5:
499         case N8_SHA1:
500         case N8_HASH_NONE:
501            break;
502         case N8_HMAC_SHA1:
503         case N8_HMAC_SHA1_96:
504         case N8_HMAC_MD5:
505         case N8_HMAC_MD5_96:
506            if ((packetObject_p->cipherInfo.hmacKeyLength < 0) ||
507                (packetObject_p->cipherInfo.hmacKeyLength > N8_MAX_HASH_LENGTH))
508            {
509               ret = N8_INVALID_KEY_SIZE;
510            }
511            break;
512         default:
513            /* invalid hash algorithm */
514            DBG(("Invalid hash algorithm\n"));
515            DBG(("N8_PacketInitialize - return Error\n"));
516            ret = N8_INVALID_HASH;
517            break;
518
519      }
520      CHECK_RETURN(ret);
521
522
523      /* verify protocol */
524      switch (protocol)
525      {
526         case N8_PROTOCOL_SSL:
527            packetObject_p->encCommands = N8_CB_EA_SSLENCRYPTAUTHENTICATE_NUMCMDS;
528            packetObject_p->decCommands = N8_CB_EA_SSLDECRYPTVERIFY_NUMCMDS;
529            packetObject_p->SSLTLScmdFcn = &cb_ea_SSL;
530            break;
531         case N8_PROTOCOL_TLS:
532            packetObject_p->encCommands = N8_CB_EA_TLSENCRYPTAUTHENTICATE_NUMCMDS;
533            packetObject_p->decCommands = N8_CB_EA_TLSDECRYPTVERIFY_NUMCMDS;
534            packetObject_p->SSLTLScmdFcn = &cb_ea_TLS;
535            break;
536         case N8_PROTOCOL_IPSEC:
537            if (cipher != N8_CIPHER_DES)
538            {
539               ret = N8_INVALID_CIPHER;
540            }
541            break;
542         default:
543            /* invalid protocol */
544            DBG(("Invalid protocol\n"));
545            DBG(("N8_PacketInitialize - return Error\n"));
546            ret = N8_INVALID_PROTOCOL;
547            break;
548      }
549      CHECK_RETURN(ret);
550
551
552      /* initialize the hash packet */
553      n8_setInitialIVs(&packetObject_p->hashPacket,
554                       hashAlgorithm,
555                       packetObject_p->unitID);
556      packetObject_p->hashPacket.hashSize = N8_GetHashLength(hashAlgorithm);
557
558      switch (protocolConfiguration)
559      {
560         case PACKET_SSL_ARC4_MD5:
561            /* Initialize for use with MD5 encryption/decryption */
562            ret = n8_initializeSSL_req(&packetObject_p->cipherInfo,
563                                       packetObject_p,
564                                       &ctx_p,
565                                       &ctx_a,
566                                       &req_p);
567            packetObject_p->encOpCode = EA_Cmd_SSL30_ARC4_MD5_Encrypt;
568            packetObject_p->decOpCode = EA_Cmd_SSL30_ARC4_MD5_Decrypt;
569            break;
570
571         case PACKET_SSL_ARC4_SHA1:
572            /* Initialize for use with ARC4 encryption/decryption */
573            ret = n8_initializeSSL_req(&packetObject_p->cipherInfo,
574                                       packetObject_p,
575                                       &ctx_p,
576                                       &ctx_a,
577                                       &req_p);
578            packetObject_p->encOpCode = EA_Cmd_SSL30_ARC4_SHA1_Encrypt;
579            packetObject_p->decOpCode = EA_Cmd_SSL30_ARC4_SHA1_Decrypt;
580            break;
581
582         case PACKET_SSL_DES_MD5:
583            /* Initialize for use with DES encryption/decryption */
584            if (packetObject_p->contextHandle.inUse == N8_TRUE)
585            {
586               ret = n8_initializeSSL_req(&packetObject_p->cipherInfo,
587                                          packetObject_p,
588                                          &ctx_p,
589                                          &ctx_a,
590                                          &req_p);
591            }
592            packetObject_p->encOpCode = EA_Cmd_SSL30_3DES_MD5_Encrypt;
593            packetObject_p->decOpCode = EA_Cmd_SSL30_3DES_MD5_Decrypt;
594            break;
595
596         case PACKET_SSL_DES_SHA1:
597            /* Initialize for use with DES encryption/decryption */
598            if (packetObject_p->contextHandle.inUse == N8_TRUE)
599            {
600               ret = n8_initializeSSL_req(&packetObject_p->cipherInfo,
601                                          packetObject_p,
602                                          &ctx_p,
603                                          &ctx_a,
604                                          &req_p);
605            }
606            packetObject_p->encOpCode = EA_Cmd_SSL30_3DES_SHA1_Encrypt;
607            packetObject_p->decOpCode = EA_Cmd_SSL30_3DES_SHA1_Decrypt;
608            break;
609
610         case PACKET_TLS_ARC4_HMAC_MD5:
611            ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key,
612                                        packetObject_p->cipherInfo.hmacKeyLength,
613                                        &packetObject_p->hashPacket,
614                                        NULL,
615                                        &ctx_p,
616                                        &ctx_a,
617                                        &req_p);
618            packetObject_p->encOpCode = EA_Cmd_TLS10_ARC4_MD5_Encrypt;
619            packetObject_p->decOpCode = EA_Cmd_TLS10_ARC4_MD5_Decrypt;
620            break;
621
622         case PACKET_TLS_ARC4_HMAC_SHA1:
623            ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key,
624                                        packetObject_p->cipherInfo.hmacKeyLength,
625                                        &packetObject_p->hashPacket,
626                                        NULL,
627                                        &ctx_p,
628                                        &ctx_a,
629                                        &req_p);
630            packetObject_p->encOpCode = EA_Cmd_TLS10_ARC4_SHA1_Encrypt;
631            packetObject_p->decOpCode = EA_Cmd_TLS10_ARC4_SHA1_Decrypt;
632            break;
633
634         case PACKET_TLS_DES_HMAC_MD5:
635            ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key,
636                                        packetObject_p->cipherInfo.hmacKeyLength,
637                                        &packetObject_p->hashPacket,
638                                        NULL,
639                                        &ctx_p,
640                                        &ctx_a,
641                                        &req_p);
642            packetObject_p->encOpCode = EA_Cmd_TLS10_3DES_MD5_Encrypt;
643            packetObject_p->decOpCode = EA_Cmd_TLS10_3DES_MD5_Decrypt;
644            break;
645
646         case PACKET_TLS_DES_HMAC_SHA1:
647            ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key,
648                                        packetObject_p->cipherInfo.hmacKeyLength,
649                                        &packetObject_p->hashPacket,
650                                        NULL,
651                                        &ctx_p,
652                                        &ctx_a,
653                                        &req_p);
654            packetObject_p->encOpCode = EA_Cmd_TLS10_3DES_SHA1_Encrypt;
655            packetObject_p->decOpCode = EA_Cmd_TLS10_3DES_SHA1_Decrypt;
656            break;
657
658         case PACKET_IPSEC_DES_HMAC_MD5_96:
659            ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key,
660                                        packetObject_p->cipherInfo.hmacKeyLength,
661                                        &packetObject_p->hashPacket,
662                                        &packetObject_p->cipherInfo,
663                                        &ctx_p,
664                                        &ctx_a,
665                                        &req_p);
666            packetObject_p->encOpCode = EA_Cmd_ESP_3DES_MD5_Encrypt;
667            packetObject_p->decOpCode = EA_Cmd_ESP_3DES_MD5_Decrypt;
668            break;
669
670         case PACKET_IPSEC_DES_HMAC_SHA1_96:
671            ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key,
672                                        packetObject_p->cipherInfo.hmacKeyLength,
673                                        &packetObject_p->hashPacket,
674                                        &packetObject_p->cipherInfo,
675                                        &ctx_p,
676                                        &ctx_a,
677                                        &req_p);
678            packetObject_p->encOpCode = EA_Cmd_ESP_3DES_SHA1_Encrypt;
679            packetObject_p->decOpCode = EA_Cmd_ESP_3DES_SHA1_Decrypt;
680            break;
681
682         case PACKET_IPSEC_DES_HASH_NONE:
683            packetObject_p->encOpCode = EA_Cmd_3DES_CBC_Encrypt;
684            packetObject_p->decOpCode = EA_Cmd_ESP_3DES_SHA1_Decrypt;
685            break;
686
687         default:
688            /* invalid protocol configuration */
689            DBG(("Invalid protocol configuration\n"));
690            DBG(("N8_PacketInitialize - return Error\n"));
691            ret = N8_INCONSISTENT;
692            break;
693      }
694      CHECK_RETURN(ret);
695
696
697      /* set up the minimum length & macLength */
698      switch (protocolConfiguration)
699      {
700         case PACKET_SSL_DES_MD5:
701         case PACKET_TLS_DES_HMAC_MD5:
702            packetObject_p->minLength = N8_DES_MD5_MIN_LENGTH;
703            packetObject_p->macLength = MD5_HASH_RESULT_LENGTH;
704            break;
705         case PACKET_SSL_DES_SHA1:
706         case PACKET_TLS_DES_HMAC_SHA1:
707            packetObject_p->minLength = N8_DES_SHA1_MIN_LENGTH;
708            packetObject_p->macLength = SHA1_HASH_RESULT_LENGTH;
709            break;
710         case PACKET_SSL_ARC4_MD5:
711         case PACKET_TLS_ARC4_HMAC_MD5:
712            packetObject_p->minLength = N8_ARC4_MD5_MIN_LENGTH;
713            packetObject_p->macLength = MD5_HASH_RESULT_LENGTH;
714            break;
715         case PACKET_SSL_ARC4_SHA1:
716         case PACKET_TLS_ARC4_HMAC_SHA1:
717            packetObject_p->minLength = N8_ARC4_SHA1_MIN_LENGTH;
718            packetObject_p->macLength = SHA1_HASH_RESULT_LENGTH;
719            break;
720         default:
721            break;
722      }
723      CHECK_RETURN(ret);
724
725      packetObject_p->contextLoadNeeded = packetObject_p->contextHandle.inUse;
726   } while (FALSE);
727
728   if (ret == N8_STATUS_OK)
729   {
730      /* set the structure pointer to the correct state */
731      packetObject_p->structureID = N8_PACKET_STRUCT_ID;
732   }
733
734   DBG(("N8_PacketInitialize - FINISHED\n"));
735
736   return ret;
737} /* N8_PacketInitializeMemory */
738
739/*****************************************************************************
740 * N8_PacketInitialize
741 *****************************************************************************/
742/** @ingroup n8_packet
743 * @brief Initializes (makes ready for use in packet operations) the packet object.
744 *
745 * Typically a packet object will be initialized at the beginning of an SSL,
746 * TLS, or IPSec session with the cipher and hash information particular to
747 * that session.  The packet object can then be used in all subsequent packet
748 * operations until the session is terminated.  Note however that if a new key
749 * is negotiated during the session, then the packet object must be re-initialized
750 * with the new key material.
751 *
752 * @param packetObject_p WO:    The packet object to be initialized with the
753 *                              specified information.<BR>
754 * @param contextHandle_p RO:   A valid context index as returned by
755 *                              N8_AllocateContext, if Cipher = ARC4.
756 *                              Optional, if Cipher = DES.<BR>
757 * @param protocol RO:          One of the values SSL, TLS, or IPSec.
758 *                              Denotes the protocol that PacketObject should
759 *                              be initialized for.<BR>
760 * @param cipher RO:            If Protocol = SSL or TLS, one of the values ARC4
761 *                              or  DES.
762 *                              If Protocol = IPSec, then Cipher must be DES.
763 *                              Specifies the cipher algorithm to use, and hence the
764 *                              type and format of the information in
765 *                              CipherInfo_p.<BR>
766 * @param cipherInfo_p RO:      The specific information to be used in the
767 *                              initialization of the cipher algorithm. Its
768 *                              contents depend on the value of ContextType, as
769 *                              specified above.<BR>
770 * @param hashAlgorithm RO:     One of the values MD5, SHA-1, HMAC-MD5, HMAC-SHA-1,
771 *                              HMAC-MD5-96 or HMAC-SHA-1-96 denoting the hash
772 *                              algorithm to be used.
773 *
774 *
775 * @return
776 *    packetObject_p - initialized packet object.
777 *    ret - returns N8_STATUS_OK if successful or Error value.
778 *
779 * @par Errors:
780 *    N8_INVALID_PROTOCOL - The value of Protocol is not one of the legal
781 *                          values SSL, TSL or IPSec.<BR>
782 *    N8_INVALID_OBJECT   - packet object is zero, couldn't write to unspecified
783 *                          address<BR>
784 *    N8_INVALID_CIPHER   - The value of Cipher is not one of the legal values
785 *                          ARC4 or DES.<BR>
786 *    N8_INVALID_HASH     - The value of HashAlgorithm is not one of the legal
787 *                          values MD5,  SHA-1, HMAC-MD5, HMAC-SHA-1, HMAC-MD5-96
788 *                          or HMAC-SHA-1-96<BR>
789 *    N8_INVALID_VALUE    - The value of ContextIndex is not a valid context
790 *                          index, or ContextIndex is null but a context index
791 *                          is required because ARC4 is specified.<BR>
792 *    N8_UNALLOCATED_CONTEXT - ContextIndex denotes a context memory index that
793 *                          has not been allocated by N8_AllocateContext.<BR>
794 *    N8_INVALID_KEY_SIZE -     The size of the key specified in CipherInfo_p is
795 *                          outside the valid range for the encryption algorithm
796 *                          specified in Cipher, or the size of an HMAC key
797 *                          specified in CipherInfo_p is outside the valid range
798 *                          for the hash algorithm specified in HashAlgorithm.<BR>
799 *    N8_INCONSISTENT  -        The information in  CipherInfo_p and/or its type is
800 *                          different than or inconsistent with the type
801 *                          specified by Cipher or HashAlgorithm, or the
802 *                          combination of values specified by Protocol, Cipher,
803 *                          and HashAlgorithm is invalid (for example, SSL is
804 *                          specified with HMAC-MD5, or IPSec is specified with
805 *                          ARC4).<BR>
806 *    N8_MALLOC_FAILED    - memory allocation failed
807 *    N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested
808 *    N8_HARDWARE_ERROR   - couldn't write to context memory
809 *
810 *
811 * @par Assumptions:
812 *    The context entry specified in this call should not be in use with any
813 *    other current  encrypt object or packet object. This condition is not
814 *    checked for;  incorrect / indeterminate results and / or errors are likely
815 *    in this situation.<BR>
816 *    If a new key is negotiated during the session, then the packet object must
817 *    be re-initialized with the new key material.<BR>
818 *****************************************************************************/
819N8_Status_t N8_PacketInitialize(N8_Packet_t                *packetObject_p,
820                                const N8_ContextHandle_t   *contextHandle_p,
821                                const N8_Protocol_t         protocol,
822                                const N8_Cipher_t           cipher,
823                                const N8_CipherInfo_t            *cipherInfo_p,
824                                const N8_HashAlgorithm_t    hashAlgorithm,
825                                N8_Event_t                 *event_p)
826
827{
828   N8_Status_t retCode;
829
830   retCode = N8_PacketInitializeMemory(packetObject_p,
831                                       contextHandle_p,
832                                       protocol,
833                                       cipher,
834                                       cipherInfo_p,
835                                       hashAlgorithm,
836                                       N8_PACKETMEMORY_NONE,
837                                       event_p);
838   return retCode;
839}
840