No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / pci / n8 / common / api / n8_contextM.c
blob3306d7b67b6c5d87dcd93107c9be25b9c77568e7
1 /*-
2 * Copyright (C) 2001-2003 by NBMK Encryption Technologies.
3 * All rights reserved.
5 * NBMK Encryption Technologies provides no support of any kind for
6 * this software. Questions or concerns about it may be addressed to
7 * the members of the relevant open-source community at
8 * <tech-crypto@netbsd.org>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above
18 * copyright notice, this list of conditions and the following
19 * disclaimer in the documentation and/or other materials provided
20 * with the distribution.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 static char const n8_id[] = "$Id: n8_contextM.c,v 1.1 2008/10/30 12:02:14 darran Exp $";
36 /*****************************************************************************/
37 /** @file n8_contextM.c
38 * @brief Contains Crypto Context management Interface.
40 * Managing the context memory is left to the user.
41 * SAPI provides interfaces to allocate and initialize a context entry, and to
42 * free an entry. The user must allocate and initialize a context entry before
43 * it can be used (presumably when an SSL connection is opened), specify which
44 * context entry to use in the calls that require context memory, and finally
45 * free the context entry when finished (presumably when an SSL connection is
46 * closed). Limited error checking is done, and if the user makes errors such as
47 * specifying the wrong context entry for a call (e.g., specifying a context
48 * entry containing an ARC4 key for encrypting an SSL packet on a connection
49 * established with DES in the cipher suite), incorrect results will be
50 * produced without a warning or error occurring.
52 *****************************************************************************/
54 /*****************************************************************************
55 * Revision history:
56 * 05/20/03 brr Remove obsolete functions resultHandlerFreeContext &
57 * n8_numCommandsToLoadContext
58 * 05/20/02 brr Free the request for all error conditions.
59 * 05/07/02 msz New interface for QUEUE_AND_CHECK for new synchronous support.
60 * 03/29/02 hml Now validate the unit and the context in
61 * N8_Read/WriteContext. (BUGS 657, 658).
62 * 03/26/02 hml Enhanced N8_AllocateContext and N8_FreeContext to retrieve
63 * the status from the lower level calls. (Bugs 637,642).
64 * 03/26/02 brr Allocate the data buffer as part of the API request.
65 * 03/22/02 hml Removed unneeded sessionID param from call to
66 * N8_ContextMemAlloc.
67 * 03/18/02 brr Removed obsolete references to queue_p & validateContextHandle.
68 * 02/28/02 brr Do not include any QMgr include files.
69 * 02/18/02 brr Support queue selection.
70 * 02/15/02 brr Moved context memory management to the driver.
71 * 01/25/02 bac Changed allocation search algorithm to always start at the
72 * index after the one last assigned. This should be a much
73 * better search than simply starting at the beginning every
74 * time, which clusters the allocated contexts from 0..n.
75 * 01/22/02 bac Added function n8_numCommandsToLoadContext.
76 * 01/22/02 bac Conditionally removed the clearing of context memory when
77 * N8_FreeContext is called.
78 * 12/07/01 brr Removed userID to reduce memory consumption until supported.
79 * 12/07/01 mel Fixed bug #404: added checks for aligned address.
80 * 11/24/01 brr Removed include of obsolete EA & PK specifice Queue files.
81 * 11/12/01 hml Fixed bug for freeing lock not held.
82 * 11/08/01 mel Fixed bug #289 : by passing unitID parameter
83 * 11/08/01 mel Fixed comments (bug #292).
84 * 11/08/01 mel Fixed bug #299 : N8_ReadContext does not check length parameter.
85 * Fixed bug #300 : N8_WriteContext does not check length parameter.
86 * 11/07/01 hml Ensured that validateContextHandle only release a semaphore
87 * if it has acquired it (BUG 236).
88 * 11/05/01 hml Added some error checking and the structure verification.
89 * 10/11/01 brr Fixed memory leak in N8_ReadContext.
90 * 10/02/01 bac Added use of RESULT_HANDLER_WARNING in all result handlers.
91 * 10/01/01 hml Completed multichip support.
92 * 09/20/01 hml Added multichip support.
93 * 09/20/01 bac The interface to the command block generators changed and now
94 * accept the command block buffer. All calls to cb_ea methods
95 * changed herein.
96 * 09/18/01 bac Reformat to standardize, changed interaction with cb_ea
97 * functions.
98 * 09/13/01 mel Added event parameter to N8_FreeContext.
99 * 08/29/01 mel Fixed bug #191 : bad DBG print statement.
100 * 08/27/01 mel Added Write/Read context APIs.
101 * 08/20/01 hml Fixed bug in allocate context getting wrong semaphore.
102 * 08/08/01 hml Added use of semaphore to protect the context table.
103 * 08/06/01 bac Fixed a bug in the result handler where it was freeing a
104 * request though it should not.
105 * 07/31/01 bac Added call to N8_preamble for all public interfaces.
106 * 07/30/01 bac Pass chip id to createEARequestBuffer.
107 * 06/25/01 bac Small bug fix for allocationg ccm_register_gp.
108 * 06/20/01 mel Corrected use of kernel memory.
109 * 05/21/01 bac Converted to use N8_ContextHandle_t.
110 * 05/04/01 bac Removed include of n8_define as it duplicated n8_util
111 * definitions.
112 * 04/16/01 mel Original version.
113 ****************************************************************************/
114 /** @defgroup Context Context Management
118 #include "n8_cb_ea.h" /* contains encryption/authentication qeueu declarations */
120 #include "n8_util.h"
121 #include "n8_API_Initialize.h"
122 #include "n8_common.h"
123 #include "n8_malloc_common.h"
126 /*****************************************************************************
127 * N8_AllocateContext
128 *****************************************************************************/
129 /** @ingroup Context
130 * @brief Allocates a context entry for future use.
132 * The context index of the allocated context memory entry is returned in
133 * contextIndex. The context memory entry must then be initialized by a call
134 * to Encrypt Initialize or Packet Initialize before it can be used in
135 * encrypt/decrypt or packet level operations. This call can fail if all
136 * context entries have been allocated. To avoid running out of context entries,
137 * N8_FreeContext should be called when a context entry is no longer needed.
139 * @param contextHandle_p WO: Unsigned integer >= 0 and less than
140 * 2 power of 18 specifying the context entry in context memory allocated to
141 * the caller and whose contents are initialized with Context.
143 * @return
144 * contextHandler_p - context entry in allocated context memory.
145 * ret - returns N8_STATUS_OK if successful or Error value.
147 * @par Locks:
148 * This function acquires the context list semaphore from the queue structure.
150 * @par Errors:
151 * N8_NO_MORE_RESOURCE - There are no more context memory entries available
152 * for allocation. The call may succeed at a later
153 * time if context entries are freed.
154 * N8_MALLOC_FAILED - for some reasons malloc is failed
156 *****************************************************************************/
157 N8_Status_t N8_AllocateContext(N8_ContextHandle_t *contextHandle_p,
158 N8_Unit_t unitID)
162 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
163 unsigned int index;
164 N8_Unit_t validatedUnit = unitID;
166 DBG(("N8_AllocateContext\n"));
170 ret = N8_preamble();
171 CHECK_RETURN(ret);
173 CHECK_OBJECT(contextHandle_p, ret);
175 ret = N8_ContextMemAlloc(&validatedUnit, &index);
177 if (ret == N8_STATUS_OK)
179 contextHandle_p->index = index; /* return allocated context index */
180 contextHandle_p->inUse = N8_TRUE;
181 contextHandle_p->unitID = validatedUnit;
182 /* set the structure pointer to the correct state */
183 contextHandle_p->structureID = N8_CONTEXT_STRUCT_ID;
185 DBG(("Context index %d\n", index));
187 } while(FALSE);
189 DBG(("N8_AllocateContext - FINISHED\n"));
191 return ret;
192 } /* N8_AllocateContext */
195 /*****************************************************************************
196 * N8_FreeContext
197 *****************************************************************************/
198 /** @ingroup Context
199 * @brief Frees previously allocated context entry and allows for its later re-use.
201 * ContextIndex specifies the context memory entry to be deallocated. The contents
202 * of the entry are cleared to zero when this call is made. Any further calls made
203 * with this ContextIndex value will fail (until the entry is re-allocated by an
204 * N8_AllocateContext call). Context memory entries must be freed when no
205 * longer needed to avoid exhausting the supply. Note that by adding the
206 * MEMORY_IN_PROGRESS state we are able to avoid having to use the context
207 * lock in the callback function.
209 * @param ctxHndl RO: A previously allocated context entry value as returned
210 * from N8_AllocateContext that is to be freed.
212 * @return
213 * ret - returns N8_STATUS_OK if successful or Error value.
215 * @par Errors:
216 * N8_INVALID_PARAMETER - The value of contextIndex is less than 0 or more
217 * than (2 power of 18) - 1.
218 * N8_UNALLOCATED_CONTEXT - contextIndex does not specify an allocated context
219 * entry index.
221 * @par Locks:
222 * This function acquires the context list semaphore from the queue structure.
223 * Note that we make sure the lock is released before we queue the request.
225 * @par Assumptions:
226 * Limited error checking is done, and if the user makes errors such as
227 * specifying the wrong context entry for a call (e.g., specifying a context
228 * entry containing an ARC4 key for encrypting an SSL packet on a connection
229 * established with DES in the cipher suite), incorrect results will be
230 * produced without a warning or error occurring
231 *****************************************************************************/
232 N8_Status_t N8_FreeContext(N8_ContextHandle_t ctxHndl,
233 N8_Event_t *event_p)
236 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
238 DBG(("N8_FreeContext\n"));
242 ret = N8_preamble();
243 CHECK_RETURN(ret);
245 if (ctxHndl.inUse != N8_TRUE)
247 ret = N8_UNALLOCATED_CONTEXT;
248 break;
251 if (ctxHndl.structureID != N8_CONTEXT_STRUCT_ID)
253 ret = N8_INVALID_PARAMETER;
254 break;
257 ret = N8_ContextMemFree(ctxHndl.unitID, ctxHndl.index);
259 DBG(("ctxHndl.index = %d\n", ctxHndl.index));
261 } while(FALSE);
263 if (event_p != NULL)
265 N8_SET_EVENT_FINISHED(event_p, N8_EA);
268 DBG(("N8_FreeContext - FINISHED\n"));
270 return ret;
272 } /* N8_FreeContext */
274 /*****************************************************************************
275 * N8_WriteContext
276 *****************************************************************************/
277 /** @ingroup Context
278 * @brief Writes a context entry for future use.
280 * Writes ContextLength number of bytes from Context into the crypto controller
281 * context memory entry denoted by ContextHandle. Up to 512 bytes may be loaded
282 * into a context entry; if less than 512 bytes are supplied the remaining bytes
283 * will be set to bytes of 0. The content / format of the bytes depends on the
284 * intended use, and is specified in the Crypto Controller specification [CCH].
285 * However this routine simply treats them as uninterpreted values; no checking
286 * or processing of the bytes written to the context entry is done. All previous
287 * contents of the context entry are overwritten and lost. It is important to note
288 * that the context information is treated by the hardware as a sequence of 32-bit
289 * values; the byte values written to a hardware context by this call are written
290 * by the hardware as a series of 32-bit quantities, and these 32-bit values must
291 * be in the appropriate big endian or little endian format depending on the byte
292 * order of the host processor. A context read from the hardware via N8_ReadContext
293 * is read in this same way, and is always in the proper format to be written back
294 * via N8_WriteContext
296 * @param contextHandle RO: The handle of a previously allocated context
297 * entry as returned by N8_AllocateContext.
299 * @param context_p RO: The bytes to be written to the context entry
300 * @param contextLength RO: Length of Context in bytes, from 0 to 512
301 * bytes inclusive. A length of 0 is legal,
302 * but no bytes will actually be written
303 * @param event_p RW: On input, if null the call is synchronous
304 * and no event is returned. The operation is
305 * complete when the call returns. If non-null,
306 * then the call is asynchronous; an event is
307 * returned that can be used to determine when
308 * the operation completes
311 * @return
312 * ret - returns N8_STATUS_OK if successful or Error value.
314 * @par Locks:
315 * This function acquires the context list semaphore from the queue structure.
317 * @par Errors:
318 * N8_NO_MORE_RESOURCE - There are no more context memory entries available
319 * for allocation. The call may succeed at a later
320 * time if context entries are freed.
321 * N8_MALLOC_FAILED - for some reasons malloc is failed
322 * N8_INVALID_INPUT_SIZE - context length is more than 512
323 * N8_UNALIGNED_ADDRESS - passed address (context_p) is not 32-bit aligned
325 *****************************************************************************/
326 N8_Status_t N8_WriteContext(N8_ContextHandle_t contextHandle,
327 N8_Buffer_t *context_p,
328 uint32_t contextLength,
329 N8_Event_t *event_p )
333 N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */
334 API_Request_t *req_p = NULL; /* request buffer */
335 N8_Boolean_t unitValid;
337 DBG(("N8_WriteContext\n"));
341 ret = N8_preamble();
342 CHECK_RETURN(ret);
344 CHECK_OBJECT(context_p, ret);
346 if ((int)context_p % 4)
348 ret = N8_UNALIGNED_ADDRESS;
349 break;
352 if (contextLength > EA_CTX_Record_Byte_Length)
354 ret = N8_INVALID_INPUT_SIZE;
355 break;
358 CHECK_STRUCTURE(contextHandle.structureID,
359 N8_CONTEXT_STRUCT_ID,
360 ret);
362 unitValid = n8_validateUnit(contextHandle.unitID);
363 if (!unitValid)
365 ret= N8_INVALID_UNIT;
366 break;
369 ret = N8_ContextMemValidate(contextHandle.unitID, contextHandle.index);
370 CHECK_RETURN(ret);
372 /* allocate request buffer */
373 ret = createEARequestBuffer(&req_p,
374 contextHandle.unitID,
375 N8_CB_EA_WRITECONTEXT_NUMCMDS,
376 resultHandlerGeneric,
377 CONTEXT_ENTRY_SIZE);
378 CHECK_RETURN(ret);
380 /* create "write buffer to context memory" command */
381 ret = cb_ea_writeContext(req_p,
382 req_p->EA_CommandBlock_ptr,
383 contextHandle.index,
384 context_p,
385 contextLength);
386 CHECK_RETURN(ret);
387 /* nothing needs to be done in the result handler. it will be called only
388 * to print a debug messag if an error occurs. */
390 /* send command to write to specified context memory */
391 QUEUE_AND_CHECK(event_p, req_p, ret);
392 HANDLE_EVENT(event_p, req_p, ret);
394 } while(FALSE);
396 DBG(("N8_WriteContext - FINISHED\n"));
399 * Deallocate the request if we arrived from an error condition.
401 if (ret != N8_STATUS_OK)
403 freeRequest(req_p);
405 return ret;
406 } /* N8_WriteContext */
409 /*****************************************************************************
410 * N8_ReadContext
411 *****************************************************************************/
412 /** @ingroup Context
413 * @brief Reads a context entry.
415 * Copies ContextLength number of bytes from the crypto controller context
416 * memory context entry specified by ContextHandle into Context. The contents
417 * of the context memory entry are unchanged. Up to 512 bytes [This value should
418 * really be some sort of configuration constant or value defined that the user
419 * can determine at run time.] may be read from a context entry. If the
420 * specified context entry has not previously been initialized with
421 * N8_EncryptInitialize or N8_PacketInitialize or written with an N8_WriteContext
422 * call, then the bytes returned are undefined. The actual content / format of
423 * the bytes returned depends on how the context entry was used, and is
424 * specified in the Crypto Controller specification [CCH]. However
425 * N8_ReadContext simply treats them as uninterpreted values, suitable for
426 * reloading at a later time using N8_WriteContext. No checking or processing
427 * of the bytes read from the context entry is done. It is important to note
428 * that the context information is treated by the hardware as a sequence of
429 * 32-bit values; the byte values read from a hardware context and returned
430 * by this call are returned as a series of 32-bit quantities, and these
431 * 32-bit values will be returned in either big endian or little endian format
432 * depending on the byte order of the host processor.
434 * @param contextHandle RO: The handle of a previously allocated context
435 * entry as returned by N8_AllocateContext.
437 * @param context_p RO: The bytes to be written to the context entry
438 * @param contextLength RO: Length of Context in bytes, from 0 to 512
439 * bytes inclusive. A length of 0 is legal,
440 * but no bytes will actually be written
441 * @param event_p RW: On input, if null the call is synchronous
442 * and no event is returned. The operation is
443 * complete when the call returns. If non-null,
444 * then the call is asynchronous; an event is
445 * returned that can be used to determine when
446 * the operation completes
448 * @return
449 * ret - returns N8_STATUS_OK if successful or Error value.
451 * @par Locks:
452 * This function acquires the context list semaphore from the queue structure.
454 * @par Errors:
455 * N8_NO_MORE_RESOURCE - There are no more context memory entries available
456 * for allocation. The call may succeed at a later
457 * time if context entries are freed.
458 * N8_MALLOC_FAILED - for some reasons malloc is failed
459 * N8_INVALID_INPUT_SIZE - context length is more than 512
460 * N8_UNALIGNED_ADDRESS - passed address (context_p) is not 32-bit aligned
462 *****************************************************************************/
463 N8_Status_t N8_ReadContext(N8_ContextHandle_t contextHandle,
464 N8_Buffer_t *context_p,
465 uint32_t contextLength,
466 N8_Event_t *event_p )
470 N8_Status_t ret = N8_STATUS_OK; /* return status*/
471 API_Request_t *req_p = NULL; /* request buffer */
472 N8_Buffer_t *contextMemory_p = NULL;
473 uint32_t contextMemory_a;
474 N8_Boolean_t unitValid;
476 DBG(("N8_ReadContext\n"));
480 ret = N8_preamble();
481 CHECK_RETURN(ret);
483 CHECK_OBJECT(context_p, ret);
485 if ((int)context_p % 4)
487 ret = N8_UNALIGNED_ADDRESS;
488 break;
491 if (contextLength > EA_CTX_Record_Byte_Length)
493 ret = N8_INVALID_INPUT_SIZE;
494 break;
497 CHECK_STRUCTURE(contextHandle.structureID,
498 N8_CONTEXT_STRUCT_ID,
499 ret);
501 unitValid = n8_validateUnit(contextHandle.unitID);
502 if (!unitValid)
504 ret= N8_INVALID_UNIT;
505 break;
508 ret = N8_ContextMemValidate(contextHandle.unitID, contextHandle.index);
509 CHECK_RETURN(ret);
511 /* allocate request buffer */
512 ret = createEARequestBuffer(&req_p,
513 contextHandle.unitID,
514 N8_CB_EA_READCONTEXT_NUMCMDS,
515 resultHandlerGeneric,
516 CONTEXT_ENTRY_SIZE);
517 CHECK_RETURN(ret);
519 contextMemory_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset);
520 contextMemory_a = req_p->qr.physicalAddress + req_p->dataoffset;
522 req_p->copyBackTo_p = context_p;
523 req_p->copyBackFrom_p = contextMemory_p;
524 req_p->copyBackSize = contextLength;
526 /* create "write buffer to context memory" command */
527 ret = cb_ea_readContext(req_p,
528 req_p->EA_CommandBlock_ptr,
529 contextHandle.index,
530 contextMemory_a,
531 contextLength);
532 CHECK_RETURN(ret);
534 /* send command to write to specified context memory */
535 QUEUE_AND_CHECK(event_p, req_p, ret);
536 HANDLE_EVENT(event_p, req_p, ret);
538 } while(FALSE);
540 DBG(("N8_ReadContext - FINISHED\n"));
543 * Deallocate the request if we arrived from an error condition.
545 if (ret != N8_STATUS_OK)
547 freeRequest(req_p);
549 return ret;
550 } /* N8_ReadContext */