void gfx_events_update (void) { SDL_Event event; while (SDL_PollEvent (&event)) { HANDLE_EVENT( SDL_KEYDOWN ) { Controls.kb[event.key.keysym.sym] = 1; Controls.last = event.key.keysym.sym; } HANDLE_EVENT( SDL_KEYUP ) Controls.kb[event.key.keysym.sym] = 0; HANDLE_EVENT( SDL_MOUSEMOTION ) { Controls.mousex = event.motion.x; Controls.mousey = event.motion.y; } HANDLE_EVENT( SDL_MOUSEBUTTONDOWN ) Controls.mouse[event.button.button - 1] = 1; HANDLE_EVENT( SDL_MOUSEBUTTONUP ) Controls.mouse[event.button.button - 1] = 0; HANDLE_EVENT( SDL_QUIT ) Controls.quit = 1; } }
/** * @brief Handles UIComponent event. * @param[in] componentID component ID * @param[in] eventCode event code * @param[in] param1 parameter 1 * @param[in] param2 parameter 2 */ void SelectLanguageDlg::HandleUICEvent(SInt32 componentID, int eventCode, SInt32 /* param1 */, void* /* param2 */) { #define HANDLE_EVENT(cid, evt, handler) \ if (cid == componentID && evt == eventCode) handler HANDLE_EVENT(CID_OKButton, UICE_ButtonClicked, handleOK()); HANDLE_EVENT(CID_CancelButton, UICE_ButtonClicked, handleCancel()); #undef HANDLE_EVENT }
/** * @brief Handles UIComponent event. * @param[in] componentID component ID * @param[in] eventCode event code * @param[in] param1 parameter 1 * @param[in] param2 parameter 2 */ void EditKeymapDlg::HandleUICEvent(SInt32 componentID, int eventCode, SInt32 /* param1 */, void* /* param2 */) { #define HANDLE_EVENT(cid, evt, handler) \ if (cid == componentID && evt == eventCode) handler HANDLE_EVENT(CID_NameTextEdit, UICE_TextChanged, handleNameTextEditChanged()); HANDLE_EVENT(CID_FunctionListBox, UICE_SelectionChanged, handleFunctionListBoxSelectionChanged()); HANDLE_EVENT(CID_CurrentKeysListBox, UICE_SelectionChanged, handleCurrentKeysListBoxSelectionChanged()); HANDLE_EVENT(CID_KeyInput, UICE_TextChanged, handleKeyInputChanged()); HANDLE_EVENT(CID_AssignButton, UICE_ButtonClicked, handleAssignButtonClicked()); HANDLE_EVENT(CID_RemoveButton, UICE_ButtonClicked, handleRemoveButtonClicked()); HANDLE_EVENT(CID_OKButton, UICE_ButtonClicked, handleOK()); HANDLE_EVENT(CID_CancelButton, UICE_ButtonClicked, handleCancel()); #undef HANDLE_EVENT }
/** @ingroup ipsec_packet * @brief Decrypt and verify an entire IPSec record. * * Decrypt and verify an entire IPSec record. PacketObject is a packet object * previously initialized by a call to N8_PacketInitialize specifying IPSec * as the packet protocol to use. PacketObject provides encryption and * authentication information to be used in the call. The decryption algorithm * can only be DES as specified when PacketObject was initialized. The * authentication algorithm can be HMAC-MD5-96 or HMAC-SHA-1-96 as specified * when PacketObject was initialized. Thus, two combinations of * decryption/verification can be performed: DES/HMAC-MD5-96 and DES/HMAC-SHA-1-96. * The SPI parameter specifies the IPSec Security Parameter Index of the message. * The SPI is used along with the sequence number and the DES initialization * vector (taken from PacketObject) in the authentication computation. The * message contents of the encrypted and authenticated IPSec packet is given * in EncryptedData; its length in bytes must be specified in encryptedPacketLength. * Note that EncryptedData must end with the unencrypted12-byte authentication * value as required by the IPSec specification. The byte length of EncryptedData * including the 12 byte authentication value is specified in encryptedPacketLength. * encryptedPacketLength must be at least 20 (i.e., EncryptedData must consist of * at least one DES block to be decrypted plus the mandatory 12 byte * authentication value), and must be of the form 12 + n*8 for n > 0. The decrypted * EncryptedData is returned in Result, including the decrypted data followed by * the 12 bytes of authentication data. Result is always encryptedPacketLength * bytes in length. The caller is responsible for ensuring that Result is at * least this size. This call also calculates the authentication value on the * EncryptedData and compares this calculated value to the value at the end of * EncryptedData. If these two values are equal, the verification succeeds and * True is returned in Verify, otherwise False is returned in Verify. * * * @param packetObject_p RW: The object denoting the decryption and * verification computation to be done. PacketObject * must have been initialized for use with IPSec. * The state in PacketObject will be updated if * necessary as part of the call. <BR> * @param encryptedPacket_p RO: The message portion / contents of the IPSec packet.<BR> * @param encryptedPacketLength RO: The length of EncryptedData, in bytes, * from 20 bytes - 18 KBytes inclusive. A length * less than 20 or not of the form 12+n*8 is illegal * and results in an error.<BR> * @param Verify WO: Returned as True if the computed authentication * value on EncryptedData matches the authentication * value contained at the end of EncryptedData; * otherwise False is returned. If Verify is False, * the contents of Result may be gibberish and/or * have been altered.<BR> * @param result_p WO: The decrypted / authenticated data, complete * with authentication data. Result must be of * sufficient size to hold the decrypted & * authenticated message; its size must be at least * EncryptedDataLeng.<BR> * @param event_p RW: On input, if null the call is synchronous and no * event is returned. The operation is complete when * the call returns. If non-null, then the call is * asynchronous; an event is returned that can be used * to determine when the operation completes. * * * @return * packetObject_p - The state in PacketObject will be updated if necessary as * part of the call. * result_p - The encrypted / authenticated data, complete with * authentication data. * ret - returns N8_STATUS_OK if successful or Error value. * * @par Errors: * N8_INVALID_OBJECT - packet object is zero, couldn't write to unspecified * address<BR> * N8_INVALID_INPUT_SIZE - The value of packetLength is < 20 or > 18 KBytes or * is not of the form 12 + n*8; no operation is * performed and no result is returned. * N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested * N8_HARDWARE_ERROR - couldn't write to context memory * * * @par Assumptions: * packetObject_p was initialized and all parameters checked. *****************************************************************************/ N8_Status_t N8_IPSecDecryptVerify( N8_Packet_t *packetObject_p, N8_IPSecPacket_t *encryptedPacket_p, int encryptedPacketLength, N8_Buffer_t *computedHMAC_p, N8_Boolean_t *verify_p, N8_IPSecPacket_t *result_p, N8_Event_t *event_p ) { N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ API_Request_t *req_p = NULL; /* request buffer */ EA_CMD_BLOCK_t *next_cb_p = NULL; int dataLength; unsigned long pack_a; N8_Buffer_t *pack_p = NULL; unsigned long res_a; N8_Buffer_t *res_p = NULL; N8_Buffer_t *ctx_p = NULL; uint32_t ctx_a; int nBytes; int numCommands; int numCtxBytes = 0; ipsecVerifyPostDataStruct_t *postData_p = NULL; n8_ctxLoadFcn_t ctxLoadFcn; DBG(("N8_IPSecDecryptVerify\n")); do { *verify_p = N8_FALSE; /* verify data length */ if ((encryptedPacketLength < IPSEC_DECRYPTED_DATA_LENGTH_MIN) || (encryptedPacketLength > IPSEC_DATA_LENGTH_MAX)) { DBG(("Data length is out of range\n")); ret = N8_INVALID_INPUT_SIZE; break; } if ((encryptedPacketLength - IPSEC_AUTHENTICATION_DATA_LENGTH) % IPSEC_DATA_BLOCK_SIZE) { DBG(("Data length is not a multiple of %d\n", IPSEC_DATA_BLOCK_SIZE)); ret = N8_INVALID_INPUT_SIZE; break; } /* verify packet object */ CHECK_OBJECT(packetObject_p, ret); CHECK_STRUCTURE(packetObject_p->structureID, N8_PACKET_STRUCT_ID, ret); /* verify encrypted data object */ CHECK_OBJECT(encryptedPacket_p, ret); /* verify result object */ CHECK_OBJECT(result_p, ret); #ifdef NO_MAC_COPYBACK CHECK_OBJECT(computedHMAC_p, ret); #endif dataLength = encryptedPacketLength - IPSEC_PACKET_HEADER_LENGTH; numCommands = N8_CB_EA_IPSECDECRYPTVERIFY_NUMCMDS; if (packetObject_p->contextLoadNeeded == N8_TRUE) { numCommands += packetObject_p->ctxLoadCmds; numCtxBytes = NEXT_WORD_SIZE(sizeof(EA_ARC4_CTX)); } /* compute the space needed for the chip to place the result */ nBytes = NEXT_WORD_SIZE(HMAC_LENGTH) + numCtxBytes; /* context to load */ if (packetObject_p->mode == N8_PACKETMEMORY_NONE) { nBytes += NEXT_WORD_SIZE(dataLength * 2); } /* create request buffer */ ret = createEARequestBuffer(&req_p, packetObject_p->unitID, numCommands, resultHandlerIPSecVerify, nBytes); CHECK_RETURN(ret); req_p->copyBackCommandBlock = N8_TRUE; /* Compute the addresses for the context. */ ctx_a = req_p->qr.physicalAddress + req_p->dataoffset; ctx_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset); /* Compute the addresses for the packet and result buffer. */ if (packetObject_p->mode == N8_PACKETMEMORY_NONE) { /* The data must be copied to this kernel before the chip can operate */ /* on it, compute the addresses within the kernel buffer and copy in */ /* the packet. */ pack_a = ctx_a + numCtxBytes; pack_p = ctx_p + numCtxBytes; res_a = pack_a + NEXT_WORD_SIZE(dataLength); res_p = pack_p + NEXT_WORD_SIZE(dataLength); memcpy(pack_p, encryptedPacket_p + IPSEC_DATA_OFFSET, dataLength); } else { /* The chip can access the data directly, compute the */ /* physical addresses of the packet & result buffer. */ pack_a = N8_VirtToPhys(encryptedPacket_p + IPSEC_DATA_OFFSET); res_a = N8_VirtToPhys(result_p + IPSEC_DATA_OFFSET); } next_cb_p = req_p->EA_CommandBlock_ptr; /* generate the command blocks necessary to load the context, if required */ if (packetObject_p->contextLoadNeeded == N8_TRUE) { /* Generate the command blocks for the Context Load */ ctxLoadFcn = (n8_ctxLoadFcn_t)packetObject_p->ctxLoadFcn; ret = ctxLoadFcn(req_p, next_cb_p, packetObject_p, &packetObject_p->cipherInfo, packetObject_p->packetHashAlgorithm, ctx_p, ctx_a, &next_cb_p); CHECK_RETURN(ret); packetObject_p->contextLoadNeeded = N8_FALSE; } memcpy(&packetObject_p->cipherInfo.IV[0], encryptedPacket_p+8,8); packetObject_p->cipherInfo.key.IPsecKeyDES.sequence_number = IPSEC_EXTRACT_SEQUENCE_NIMBER(encryptedPacket_p); cb_ea_IPsec(next_cb_p, packetObject_p, pack_a, res_a, dataLength, IPSEC_EXTRACT_SPI(encryptedPacket_p), packetObject_p->decOpCode); postData_p = (ipsecVerifyPostDataStruct_t *)req_p->postProcessBuffer; postData_p->computedHMAC_p = computedHMAC_p; postData_p->data_p = result_p + IPSEC_DATA_OFFSET; postData_p->res_p = res_p; postData_p->dataLength = dataLength; postData_p->verify_p = verify_p; postData_p->hashAlgorithm = packetObject_p->packetHashAlgorithm; /* setup post processing buffer pointer */ req_p->postProcessingData_p = (void *) postData_p; /* decrypt data */ QUEUE_AND_CHECK(event_p, req_p, ret) HANDLE_EVENT(event_p, req_p, ret); /* compare authentication values */ memcpy(result_p, encryptedPacket_p, IPSEC_PACKET_HEADER_LENGTH); if (*verify_p == N8_TRUE) { packetObject_p->cipherInfo.key.IPsecKeyDES.sequence_number = IPSEC_EXTRACT_SEQUENCE_NIMBER(encryptedPacket_p); memcpy(&packetObject_p->cipherInfo.IV[0], encryptedPacket_p+IPSEC_IV_OFFSET, N8_DES_KEY_LENGTH); } } while (FALSE); if (ret != N8_STATUS_OK) { freeRequest(req_p); } DBG(("N8_IPSecDecryptVerify - FINISHED\n")); return ret; } /* N8_IPSecDecryptVerify */
/** @ingroup ipsec_packet * @brief Encrypt and authenticate an entire IPSec record. * * Encrypt and authenticate an entire IPSec record. PacketObject is a packet * object previously initialized by a call to N8_PacketInitialize specifying * IPSec as the packet protocol to use. PacketObject provides encryption and * authentication information to be used in the call. The decryption algorithm * can only be DES as specified when PacketObject was initialized. The * authentication algorithm can be HMAC-MD5-96 or HMACSHA-1-96 as specified * when PacketObject was initialized. Thus, two combinations of * encryption/authentication can be performed: DES/HMAC-MD5-96 and * DES/HMAC-SHA-1-96. The SPI parameter specifies the IPSec Security Parameter * Index of the message. The SPI is used along with the sequence number and * the DES initialization vector (taken from information specified in the * PacketObject) in the authentication computation. The message contents of the * IPSec packet is given in Data; its length in bytes must be specified in * packetLength. Note that Data must include all of the information to be * encrypted according to the IPSec specification; this includes the TCP and * IP headers if present (the IP header is only present in tunnel mode) and must * also include the terminating pad, pad length and next header fields. * The byte length of Data is specified in packetLength and must also include all * of these fields. packetLength must be a multiple of 8. The fully encrypted and * authenticated Data is returned in Result, including the encrypted data * followed by the HMAC-MD5-96 or HMAC-SHA-1-96 authentication value. * * @param packetObject_p RW: The object denoting the decryption and * verification computation to be done. PacketObject * must have been initialized for use with IPSec. * The state in PacketObject will be updated if * necessary as part of the call. <BR> * @param packet_p RO: The ESP packet beginning with the Security * Parameter Index, Sequence Number and data payload * including DES initialization vector and ending * with the pad, pad length, and next header fields * as specified by the IPSec protocol.<BR> * @param packetLength RO: The length of Data, in bytes, from 8 bytes - 17 KBytes * inclusive. A length < 8 or not a multiple of 8 is * illegal and results in an error.<BR> * @param result_p WO: The encrypted / authenticated data, complete with * authentication data. Result must be of sufficient * size to hold the fully encrypted & authenticated * message; its size must be at least packetLength + * IPSEC_AUTHENTICATION_DATA_LENGTH * (hash size for all hash algorithms).<BR> * @param event_p RW: On input, if null the call is synchronous and no * event is returned. The operation is complete when * the call returns. If non-null, then the call is * asynchronous; an event is returned that can be used * to determine when the operation completes. * * * @return * packetObject_p - The state in PacketObject will be updated if necessary as * part of the call. * result_p - The encrypted / authenticated data, complete with * authentication data. * ret - returns N8_STATUS_OK if successful or Error value. * * @par Errors: * N8_INVALID_OBJECT - packet object is zero, couldn't write to unspecified * address<BR> * N8_INVALID_INPUT_SIZE - The value of packetLength is less then 8 or bigger * then 17 KBytes or is not a multiple of 8. * N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested * N8_HARDWARE_ERROR - couldn't write to context memory * * * @par Assumptions: * packetObject_p was initialized and all parameters checked.<BR> * For IPSec, the authentication data is always * 12 (IPSEC_AUTHENTICATION_DATA_LENGTH) bytes (the 12 most * significant bytes of the standard 16 byte MD5 or 20 byte SHA-1 value) and * is not encrypted. Result is always packetLength + 12 bytes in length. * The caller is responsible for ensuring that Result is this size. *****************************************************************************/ N8_Status_t N8_IPSecEncryptAuthenticate(N8_Packet_t *packetObject_p, N8_IPSecPacket_t *packet_p, int packetLength, N8_IPSecPacket_t *result_p, N8_Event_t *event_p ) { N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ API_Request_t *req_p = NULL; /* request buffer */ EA_CMD_BLOCK_t *next_cb_p = NULL; int dataLength; unsigned long pack_a; N8_Buffer_t *pack_p = NULL; unsigned long res_a; N8_Buffer_t *res_p = NULL; N8_Buffer_t *ctx_p = NULL; uint32_t ctx_a; int nBytes; int numCommands; int numCtxBytes = 0; void *callbackFcn = NULL; n8_ctxLoadFcn_t ctxLoadFcn; DBG(("N8_IPSecEncryptAuthenticate\n")); do { /* verify data length */ if ((packetLength < IPSEC_DATA_LENGTH_MIN) || (packetLength > IPSEC_DATA_LENGTH_MAX)) { DBG(("Data length is out of range\n")); ret = N8_INVALID_INPUT_SIZE; break; } if (packetLength % IPSEC_DATA_BLOCK_SIZE) { DBG(("Data length is not a multiple of %d\n", IPSEC_DATA_BLOCK_SIZE)); ret = N8_INVALID_INPUT_SIZE; break; } /* verify packet object */ CHECK_OBJECT(packetObject_p, ret); CHECK_STRUCTURE(packetObject_p->structureID, N8_PACKET_STRUCT_ID, ret); /* verify data object */ CHECK_OBJECT(packet_p, ret); /* verify result object */ CHECK_OBJECT(result_p, ret); dataLength = packetLength - IPSEC_PACKET_HEADER_LENGTH; numCommands = N8_CB_EA_IPSECENCRYPTAUTHENTICATE_NUMCMDS; if (packetObject_p->contextLoadNeeded == N8_TRUE) { numCommands += packetObject_p->ctxLoadCmds; numCtxBytes = NEXT_WORD_SIZE(EA_CTX_Record_Byte_Length); } /* compute the space needed for the size of context load, if required */ nBytes = NEXT_WORD_SIZE(HMAC_LENGTH) + numCtxBytes; /* If the data must be copied to a kernel before the chip can operate */ /* on it, compute the additional space required and setup the callback */ /* function to copy the result once the operation has completed. */ if (packetObject_p->mode == N8_PACKETMEMORY_NONE) { nBytes += NEXT_WORD_SIZE(dataLength) + /* packet data length pack_p */ NEXT_WORD_SIZE(packetLength);/* result packet length res_p */ callbackFcn = resultHandlerGeneric; } /* create request buffer */ ret = createEARequestBuffer(&req_p, packetObject_p->unitID, numCommands, callbackFcn, nBytes); CHECK_RETURN(ret); /* Compute the context memory pointers. */ ctx_a = req_p->qr.physicalAddress + req_p->dataoffset; ctx_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset); /* Compute the addresses for the packet and result buffer. */ if (packetObject_p->mode == N8_PACKETMEMORY_NONE) { /* The data must be copied to this kernel before the chip can operate */ /* on it, compute the addresses within the kernel buffer and copy in */ /* the packet. */ pack_a = ctx_a + numCtxBytes; pack_p = ctx_p + numCtxBytes; res_a = pack_a + NEXT_WORD_SIZE(dataLength); res_p = pack_p + NEXT_WORD_SIZE(dataLength); memcpy(pack_p, &packet_p[IPSEC_DATA_OFFSET], dataLength); } else { /* The chip can access the data directly, compute the */ /* physical addresses of the packet & result buffer. */ pack_a = N8_VirtToPhys(&packet_p[IPSEC_DATA_OFFSET]); res_a = N8_VirtToPhys(&result_p[IPSEC_DATA_OFFSET]); } next_cb_p = req_p->EA_CommandBlock_ptr; memcpy(result_p, packet_p, IPSEC_PACKET_HEADER_LENGTH); packetObject_p->cipherInfo.key.IPsecKeyDES.sequence_number = IPSEC_EXTRACT_SEQUENCE_NIMBER(packet_p); /* generate the command blocks necessary to load the context, if required */ if (packetObject_p->contextLoadNeeded == N8_TRUE) { /* Generate the command blocks for the Context Load */ ctxLoadFcn = (n8_ctxLoadFcn_t)packetObject_p->ctxLoadFcn; ret = ctxLoadFcn(req_p, next_cb_p, packetObject_p, &packetObject_p->cipherInfo, packetObject_p->packetHashAlgorithm, ctx_p, ctx_a, &next_cb_p); CHECK_RETURN(ret); packetObject_p->contextLoadNeeded = N8_FALSE; } memcpy(&packetObject_p->cipherInfo.IV[0], packet_p+IPSEC_IV_OFFSET, N8_DES_KEY_LENGTH); cb_ea_IPsec(next_cb_p, packetObject_p, pack_a, res_a, dataLength, IPSEC_EXTRACT_SPI(packet_p), packetObject_p->encOpCode); req_p->copyBackTo_p = result_p + IPSEC_DATA_OFFSET; req_p->copyBackFrom_p = res_p; req_p->copyBackSize = dataLength + HMAC_LENGTH; QUEUE_AND_CHECK(event_p, req_p, ret) HANDLE_EVENT(event_p, req_p, ret); } while (FALSE); if (ret != N8_STATUS_OK) { freeRequest(req_p); } DBG(("N8_IPSecEncryptAuthenticate - FINISHED\n")); return ret; } /* N8_IPSecEncryptAuthenticate */
/** @ingroup dh * @brief Computes a Diffie-Hellman exponentiation as required to compute * Diffie-Hellman public values from a secret value and a Diffie-Hellman * key (or group). * * Description: * The key or group is specified by DHKeyObject which must have been * previously initialized with the appropriate group generator g, modulus p, * and modulus size by a call to N8_DHInitializeKey. The DH secret value * used as the exponent is specified in XValue, and must be of the same * size as the modulus size in DHKeyObject. GValue specifies the value * to be exponentiated and must also be the same size as the modulus. * GValue may be null, in which case the generator g from DHKeyObject is * used as the GValue. The result of the calculation is returned in * GXValue and is the same size as the modulus. The value computed is * GXValue = ( GValue ** XValue ) mod p. Thus this routine computes a * modular exponentiation. * This call can be used to compute from a private x value the value * X = g**x mod p that is the public X value sent to the other respondent * in a Diffie-Hellman exchange. (In this case the GValue is set to null, * and x is used for XValue.) When the respondent's corresponding Y value * (Y = g**y mod p, y = the respondent's private y) is received, this call * can then be used to compute the common shared secret XY = g**(xy) = YX by * using X for the GValue and the received Y as the XValue. * * Parameters: * @param key_p RO: The caller supplied DHKeyObject containing * the appropriate Diffie-Hellman values * and pre-computed DH constants. * @param gValue RO: The value to be raised to a power. * If null, then the generator g value from * DHKeyObject is used. GValue must be the * same size as the modulus p from DHKeyObject. * @param xValue RO: The exponent. Must be supplied. XValue * must be the same size as the * modulus p from DHKeyObject * @param gxValue WO: GValue raised to the XValue power, mod p. * GXValue will be the same * size as the modulus p from DHKeyObject. * @param event_p RW: On input, if null the call is synchronous * and no event is returned. The operation * is complete when the call returns. If * non-null, then the call is asynchronous; * an event is returned that can be used to * determine when the operation completes. * * @return * ret - returns N8_STATUS_OK if successful or Error value. * * @par Errors: * N8_INVALID_OBJECT - context request object is NULL<BR> * N8_INVALID_KEY - The DHKeyObject is not a valid key * object * for this operation. * * @par Assumptions: **********************************************************************/ N8_Status_t N8_DHCompute(N8_DH_KeyObject_t *key_p, N8_Buffer_t *gValue_p, N8_Buffer_t *xValue_p, N8_Buffer_t *gxValue_p, N8_Event_t *event_p) { N8_Status_t ret = N8_STATUS_OK; API_Request_t *req_p = NULL; unsigned int nBytes; N8_Buffer_t *g_p; N8_Buffer_t *x_p; N8_Buffer_t *res_p; uint32_t g_a; uint32_t x_a; uint32_t res_a; unsigned int g_len; unsigned int x_len; unsigned int res_len; N8_Boolean_t useShortCommandBlock = N8_FALSE; do { ret = N8_preamble(); CHECK_RETURN(ret); CHECK_OBJECT(key_p, ret); CHECK_OBJECT(xValue_p, ret); CHECK_OBJECT(gxValue_p, ret); CHECK_STRUCTURE(key_p->structureID, N8_DH_STRUCT_ID, ret); /* compute the lengths of all of the parameters as a convenience */ g_len = key_p->modulusLength; x_len = key_p->modulusLength; res_len = key_p->modulusLength; nBytes = (NEXT_WORD_SIZE(x_len) + NEXT_WORD_SIZE(res_len)); /* gValue_p is allowed to be NULL. if so, use the g from the key object. */ if (gValue_p == NULL) { useShortCommandBlock = N8_TRUE; /* allocate user-space buffer */ ret = createPKRequestBuffer(&req_p, key_p->unitID, N8_CB_COMPUTE_G_XMODP_NUMCMDS_SHORT, resultHandlerGeneric, nBytes); } else { nBytes += NEXT_WORD_SIZE(g_len); /* allocate user-space buffer */ ret = createPKRequestBuffer(&req_p, key_p->unitID, N8_CB_COMPUTE_G_XMODP_NUMCMDS_LONG, resultHandlerGeneric, nBytes); } CHECK_RETURN(ret); /* set up the addressing for the pointers */ x_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset); x_a = req_p->qr.physicalAddress + req_p->dataoffset; res_p = x_p + NEXT_WORD_SIZE(x_len); res_a = x_a + NEXT_WORD_SIZE(x_len); memcpy(x_p, xValue_p, x_len); req_p->copyBackSize = x_len; req_p->copyBackFrom_p = res_p; req_p->copyBackTo_p = gxValue_p; if (useShortCommandBlock == N8_TRUE) { ret = cb_computeGXmodp_short(req_p, x_a, key_p->p_a, key_p->cp_a, key_p->gRmodP_a, res_a, key_p->modulusLength, req_p->PK_CommandBlock_ptr); } else { /* gValue_p is not NULL, copy the user-space */ /* data into our kernel space buffers */ g_p = res_p + NEXT_WORD_SIZE(res_len); g_a = res_a + NEXT_WORD_SIZE(res_len); memcpy(g_p, gValue_p, g_len); ret = cb_computeGXmodp_long(req_p, g_a, x_a, key_p->p_a, key_p->cp_a, key_p->RmodP_a, res_a, key_p->modulusLength, req_p->PK_CommandBlock_ptr); } CHECK_RETURN(ret); QUEUE_AND_CHECK(event_p, req_p, ret); HANDLE_EVENT(event_p, req_p, ret); } while (FALSE); DBG(("DH computed\n")); /* * Deallocate the request if we arrived from an error condition. */ if (ret != N8_STATUS_OK) { freeRequest(req_p); } return ret; } /* N8_DHCompute */
/** @ingroup dh * @brief Initializes the specified DHKeyObject so that it can be used * in Diffie-Hellman operations. The KeyMaterial object (structure) * contains the appropriate group generator g, modulus p, and modulus size. * * Description: * This call pre-computes various constant values from the supplied * parameters and initializes DHKeyObject with these values. By * pre-computing these values, Diffie-Hellman computations can be done * faster than if these constants must be computed on each operation. * Once a DHKeyObject has been initialized, it can be used repeatedly * in multiple DH operations. It does not ever need to be re-initialized, * unless the actual key value(s) change (i.e., unless the key itself * changes). * * @param key_p RW: The caller allocated DHKeyObject, initialized * by this call with the appropriate DH key * material and pre-computed DH constants * depending on the value of the KeyType parameter * @param material_p RO: Pointer to the key material to use in initializing * DHKeyObject. * * @return * ret - returns N8_STATUS_OK if successful or Error value. * * @par Errors: * N8_INVALID_OBJECT - DH key or key material object is NULL<BR> * * @par Assumptions: * None. **********************************************************************/ N8_Status_t N8_DHInitializeKey(N8_DH_KeyObject_t *key_p, N8_DH_KeyMaterial_t *material_p, N8_Event_t *event_p) { N8_Status_t ret = N8_STATUS_OK; int nBytes; API_Request_t *req_p = NULL; do { ret = N8_preamble(); CHECK_RETURN(ret); CHECK_OBJECT(key_p, ret); CHECK_OBJECT(material_p, ret); key_p->unitID = material_p->unitID; /* check the modulus size to ensure it is 1 <= ms <= 512. return * N8_INVALID_SIZE if not. */ if (material_p->modulusSize < N8_DH_MIN_MODULUS_SIZE || material_p->modulusSize > N8_DH_MAX_MODULUS_SIZE) { ret = N8_INVALID_KEY_SIZE; break; } /* Allocate space for the initialized key. we must compute 'R mod p' and 'cp' * for use in subsequent DHComputes. */ key_p->modulusLength = material_p->modulusSize; nBytes = (NEXT_WORD_SIZE(key_p->modulusLength) + /* g */ NEXT_WORD_SIZE(key_p->modulusLength) + /* p */ NEXT_WORD_SIZE(key_p->modulusLength) + /* R mod p */ NEXT_WORD_SIZE(key_p->modulusLength) + /* g R mod p */ NEXT_WORD_SIZE(PK_DH_CP_Byte_Length));/* cp */ /* Allocate a kernel buffer to hold data accessed by the NSP2000 */ key_p->kmem_p = N8_KMALLOC_PK(nBytes); CHECK_OBJECT(key_p->kmem_p, ret); memset(key_p->kmem_p->VirtualAddress, 0, nBytes); /* Compute virtual addresses within the kernel buffer */ key_p->g = (N8_Buffer_t *) key_p->kmem_p->VirtualAddress; key_p->p = key_p->g + NEXT_WORD_SIZE(key_p->modulusLength); key_p->R_mod_p = key_p->p + NEXT_WORD_SIZE(key_p->modulusLength); key_p->gR_mod_p = key_p->R_mod_p + NEXT_WORD_SIZE(key_p->modulusLength); key_p->cp = key_p->gR_mod_p + NEXT_WORD_SIZE(key_p->modulusLength); /* Compute physical addresses within the kernel buffer */ key_p->g_a = key_p->kmem_p->PhysicalAddress; key_p->p_a = key_p->g_a + NEXT_WORD_SIZE(key_p->modulusLength); key_p->RmodP_a = key_p->p_a + NEXT_WORD_SIZE(key_p->modulusLength); key_p->gRmodP_a = key_p->RmodP_a + NEXT_WORD_SIZE(key_p->modulusLength); key_p->cp_a = key_p->gRmodP_a + NEXT_WORD_SIZE(key_p->modulusLength); /* Set up the memory for p and g and copy from the key material */ memcpy(key_p->p, material_p->p, material_p->modulusSize); memcpy(key_p->g, material_p->g, material_p->modulusSize); /* Set the structure ID */ key_p->structureID = N8_DH_STRUCT_ID; /* allocate user-space command buffer */ ret = createPKRequestBuffer(&req_p, key_p->unitID, N8_CB_PRECOMPUTE_DHVALUES_NUMCMDS, NULL, 0); CHECK_RETURN(ret); ret = cb_precomputeDHValues(req_p, key_p->g_a, key_p->p_a, key_p->RmodP_a, key_p->gRmodP_a, key_p->cp_a, key_p->modulusLength, req_p->PK_CommandBlock_ptr, key_p->unitID); CHECK_RETURN(ret); QUEUE_AND_CHECK(event_p, req_p, ret); HANDLE_EVENT(event_p, req_p, ret); } while(FALSE); /* * Deallocate the request if we arrived from an error condition. */ if (ret != N8_STATUS_OK) { /* free the request */ freeRequest(req_p); /* free the key also, if it has been allocated */ if (key_p != NULL) { /* ignore the return code as we want to return the original anyway */ (void) N8_DHFreeKey(key_p); } } return ret; } /* N8_DHInitializeKey */
/** @ingroup n8_ssltls * @brief Decrypt and verify an entire SSL or TLS message. * * Decrypt an verify a SSL or TLS message. If the verification fails, it will * be noted in the return value. * * @param packetObj_p RW: Pre-initialized packet object. * @param packet_p RO: A complete, encrypted SSL or TLS packet * including the header. * @param computedMAC_p RW: Pointer to result space for the MAC * computation output. * @param verify_p: WO: Pointer to a verify flag. If the MAC's * match, the verify flag will be set to N8_TRUE. * @param result_p RW: Pointer to result space for the decrypted * result. * @param request RW: Kernel request buffer used when mode = * N8_PACKETMEMORY_REQUEST. * @param event_p RW: Asynchronous event pointer. * * @par Externals * None * * @return * Error condition if raised. * * @par Errors * N8_MALLOC_FAILED<br> * N8_INVALID_INPUT_SIZE - the value in the packet header is too large or too * small.<br> * N8_INCONSISTENT - the version number in the packet header does not * match the designation in the packet object.<br> * N8_INVALID_OBJECT - packet object is not a valid object initialized * for SSL or TLS<br> * N8_INVALID_VALUE - the value of the type field in the packet header * is not one of the legal values for SSL or TLS.<br> * * @par Assumptions * The result_p and computedMAC_p pointers refer to pre-allocated space of * sufficient size. The calling program retains responsibility for freeing this * memory. *****************************************************************************/ N8_Status_t N8_SSLTLSDecryptVerifyMemory(N8_Packet_t *packetObj_p, const N8_SSLTLSPacket_t *packet_p, N8_Buffer_t *computedMAC_p, N8_Boolean_t *verify_p, N8_SSLTLSPacket_t *result_p, N8_RequestHandle_t request, N8_Event_t *event_p) { N8_Status_t ret = N8_STATUS_OK; API_Request_t *req_p = NULL; EA_CMD_BLOCK_t *next_cb_p = NULL; N8_SSL_Post_Decrypt_Data_t *postData_p = NULL; uint16_t length; short int encLen; int nBytes; N8_Buffer_t *res_p = NULL; uint32_t res_a; N8_Buffer_t *input_p = NULL; uint32_t input_a; N8_Buffer_t *ctx_p = NULL; uint32_t ctx_a = 0; unsigned int numCommands = 0; unsigned int numCtxBytes = 0; N8_MemoryHandle_t *request_p; n8_ctxLoadFcn_t ctxLoadFcn; n8_SSLTLSFcn_t decryptFcn; do { /* ensure none of the pointers we're given are null */ CHECK_OBJECT(packetObj_p, ret); CHECK_STRUCTURE(packetObj_p->structureID, N8_PACKET_STRUCT_ID, ret); CHECK_OBJECT(packet_p, ret); #ifdef N8_MAC_COPYBACK CHECK_OBJECT(computedMAC_p, ret); #endif CHECK_OBJECT(result_p, ret); request_p = (N8_MemoryHandle_t *) request; /* Check that request_p & mode are consistent */ if (request_p == NULL) { if (packetObj_p->mode != N8_PACKETMEMORY_NONE) { /* No request_p means mode should be "none" */ ret = N8_INCONSISTENT; break; } } else if (packetObj_p->mode != N8_PACKETMEMORY_REQUEST) { /* They said they would give us a request and they didn't */ ret = N8_INCONSISTENT; break; } /* * convert the length from network order to host order */ length = ntohs(*((uint16_t *) &packet_p[SSLTLS_LENGTH_OFFSET])); /* verify the length is not greater than the max */ if (length > N8_SSLTLS_MAX_DATA_SIZE_DECRYPT) { ret = N8_INVALID_INPUT_SIZE; break; } numCommands = packetObj_p->decCommands; if (packetObj_p->contextLoadNeeded == N8_TRUE) { numCommands += packetObj_p->ctxLoadCmds; numCtxBytes = NEXT_WORD_SIZE(sizeof(EA_ARC4_CTX)); } encLen = N8_ComputeEncryptedLength(length, packetObj_p->hashPacket.hashSize, packetObj_p->packetCipher); /* kernel space is needed for the data portion of the incoming packet plus * the hash and padding. the exact amount is needed for the return * packet. */ /* Note that if the in packet is NULL, we don't check the out packet */ if (request_p == NULL) { nBytes = NEXT_WORD_SIZE(length) * 2 + numCtxBytes; /* create an API request buffer */ ret = createEARequestBuffer(&req_p, packetObj_p->unitID, numCommands, resultHandlerSSLTLSDecrypt, nBytes); CHECK_RETURN(ret); /* User has not provided any buffers */ res_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset); res_a = req_p->qr.physicalAddress + req_p->dataoffset; input_p = res_p + NEXT_WORD_SIZE(length); input_a = res_a + NEXT_WORD_SIZE(length); ctx_p = input_p + NEXT_WORD_SIZE(encLen); ctx_a = input_a + NEXT_WORD_SIZE(encLen); } else { /* User has provided a request packet, which must contain enough space for the input and output packets. The user may reuse the input pointer for the output. */ /* The user has given us a request structure. We just need to initialize it. */ req_p = (API_Request_t *) request_p->VirtualAddress; initializeEARequestBuffer(req_p, request_p, packetObj_p->unitID, numCommands, resultHandlerSSLTLSDecrypt, N8_TRUE); /* Initialize input_p and input_a to the beginning of data area in the request */ input_p = (N8_Buffer_t *)((unsigned long) packet_p + SSLTLS_DATA_OFFSET); input_a = N8_VirtToPhys(input_p); res_p = result_p + SSLTLS_DATA_OFFSET; res_a = N8_VirtToPhys(res_p); /* If we are loading context memory, we load it at the last N8_CTX_BYTES before the data section */ if (numCtxBytes > 0) { ctx_p = (N8_Buffer_t *)((unsigned long) req_p + sizeof(API_Request_t) + N8_COMMAND_BLOCK_BYTES); ctx_a = N8_VirtToPhys(ctx_p); } } next_cb_p = req_p->EA_CommandBlock_ptr; /* generate the command blocks necessary to load the context, if required */ if (packetObj_p->contextLoadNeeded == N8_TRUE) { /* Generate the command blocks for the Context Load */ ctxLoadFcn = (n8_ctxLoadFcn_t)packetObj_p->ctxLoadFcn; ret = ctxLoadFcn(req_p, req_p->EA_CommandBlock_ptr, packetObj_p, &packetObj_p->cipherInfo, packetObj_p->packetHashAlgorithm, ctx_p, ctx_a, &next_cb_p); CHECK_RETURN(ret); packetObj_p->contextLoadNeeded = N8_FALSE; } /* copy the data portion of the incoming packet into the input kernel * buffer */ if (request_p == NULL) { memcpy(input_p, &packet_p[SSLTLS_DATA_OFFSET], length); } /* use the post processing structure in the API Request */ postData_p = (N8_SSL_Post_Decrypt_Data_t *)&req_p->postProcessBuffer; /* now check the length */ if (length < packetObj_p->minLength) { ret = N8_INVALID_INPUT_SIZE; break; } /* if des, ensure the length is a multiple of N8_DES_BLOCK_MULTIPLE */ if ((packetObj_p->packetCipher == N8_CIPHER_DES) && ((length % N8_DES_BLOCK_MULTIPLE) != 0)) { ret = N8_INVALID_INPUT_SIZE; break; } /* set up the copy back for the result packet. we only copy back the data * portion which we get from the kernel buffer. */ req_p->copyBackTo_p = &result_p[SSLTLS_DATA_OFFSET]; req_p->copyBackFrom_p = res_p; /* the length the decrypted data is not known until after the operation is * run. we will calculate it in the resultHandler. set the copyBackSize * to zero as a safe thing to do.*/ req_p->copyBackSize = 0; if (packetObj_p->contextHandle.inUse == N8_FALSE) { /* This sets up the offset for the start of the copy back of the IV. This case can only occur if the cipher is DES, not ARC4 */ memcpy(&postData_p->nextIV, &(packet_p[5 - N8_DES_KEY_LENGTH + length]), N8_DES_KEY_LENGTH); } /* set up the post processing data */ postData_p->macLength = packetObj_p->macLength; postData_p->computedMAC_p = computedMAC_p; postData_p->packetObj_p = packetObj_p; postData_p->verify_p = verify_p; postData_p->encryptedLength = length; if (request_p == NULL) { postData_p->copyData = N8_TRUE; } else { postData_p->copyData = N8_FALSE; } postData_p->resultPacket_p = result_p; /* tell the Queue Manager to copy back the command block results */ req_p->copyBackCommandBlock = N8_TRUE; req_p->postProcessingData_p = (void *) postData_p; /* Generate the command blocks for the Decrypt */ decryptFcn = (n8_SSLTLSFcn_t)packetObj_p->SSLTLScmdFcn; ret = decryptFcn(next_cb_p, packetObj_p, packet_p, input_a, res_a, packetObj_p->decOpCode); CHECK_RETURN(ret); /* set up the return packet * again, recall we cannot set the length in the result packet now and * will have to do it in the result handler. */ memcpy(&result_p[SSLTLS_TYPE_OFFSET], &packet_p[SSLTLS_TYPE_OFFSET], sizeof(uint8_t) + sizeof(uint16_t)); QUEUE_AND_CHECK(event_p, req_p, ret); HANDLE_EVENT(event_p, req_p, ret); } while (FALSE); /* clean up if necessary. note that if there is no error condition, the post * data and request will be de-allocated in the result handler. */ if (ret != N8_STATUS_OK) { freeRequest(req_p); } return ret; } /* N8_SSLTLSDecryptVerify */
/** @ingroup n8_ssltls * @brief Encrypt/Authenticate an SSL or TLS message * * An entire SSL or TLS record is encrypted/authenticated. * * @param packetObj_p RW: Pointer to a packet object which was * previously initialized for SSL or TLS * @param packet_p RO: Pointer to packet * @param result_p RW: Pointer to pre-allocated buffer where the * results will be stored. * @param request RW: Kernel request buffer used when mode = * N8_PACKETMEMORY_REQUEST. * @param event_p RW: Asynchronous event pointer. * * @par Externals * None * * @return * Error condition if raised. * * @par Errors * None * * @par Assumptions * None *****************************************************************************/ N8_Status_t N8_SSLTLSEncryptAuthenticateMemory(N8_Packet_t *packetObj_p, const N8_SSLTLSPacket_t *packet_p, N8_SSLTLSPacket_t *result_p, N8_RequestHandle_t request, N8_Event_t *event_p) { N8_Status_t ret = N8_STATUS_OK; API_Request_t *req_p = NULL; EA_CMD_BLOCK_t *next_cb_p = NULL; uint16_t length; short int encLen; short int packetLen; N8_Buffer_t *res_p = NULL; uint32_t res_a; N8_Buffer_t *input_p = NULL; uint32_t input_a; N8_Buffer_t *ctx_p = NULL; uint32_t ctx_a = 0; int nBytes; unsigned int numCommands = 0; unsigned int numCtxBytes = 0; N8_MemoryHandle_t *request_p; n8_ctxLoadFcn_t ctxLoadFcn; n8_SSLTLSFcn_t encryptFcn; do { /* verify the pointers passed in are not null */ CHECK_OBJECT(packetObj_p, ret); CHECK_STRUCTURE(packetObj_p->structureID, N8_PACKET_STRUCT_ID, ret); CHECK_OBJECT(packet_p, ret); CHECK_OBJECT(result_p, ret); request_p = (N8_MemoryHandle_t *) request; /* Check that request_p & mode are consistent */ if (request_p == NULL) { if (packetObj_p->mode != N8_PACKETMEMORY_NONE) { /* No request_p means mode should be "none" */ ret = N8_INCONSISTENT; break; } } else if (packetObj_p->mode != N8_PACKETMEMORY_REQUEST) { /* They said they would give us a request and they didn't */ ret = N8_INCONSISTENT; break; } /* * convert the length from network order to host order */ length = SSLTLS_EXTRACT_LENGTH(packet_p); /* check to see the data length is within range * [0..N8_SSLTLS_MAX_DATA_SIZE_ENCRYPT] */ if (length > N8_SSLTLS_MAX_DATA_SIZE_ENCRYPT) { ret = N8_INVALID_INPUT_SIZE; break; } numCommands = packetObj_p->encCommands; if (packetObj_p->contextLoadNeeded == N8_TRUE) { numCommands += packetObj_p->ctxLoadCmds; numCtxBytes = NEXT_WORD_SIZE(sizeof(EA_ARC4_CTX)); } /* create a kernel memory structure for temporarily storing the results */ /* compute the lengths for the result packet */ encLen = N8_ComputeEncryptedLength(length, packetObj_p->hashPacket.hashSize, packetObj_p->packetCipher); packetLen = encLen + SSLTLS_HEADER_LEN; /* compute the total number of bytes in kernel space we need to allocate. * note we round up to the next word boundary. */ /* Note that if the in packet is NULL, we don't check the out packet */ if (request_p == NULL) { nBytes = (NEXT_WORD_SIZE(length) + /* input */ NEXT_WORD_SIZE(encLen) + /* output */ numCtxBytes); /* size of context, if needed */ /* create an API request buffer */ ret = createEARequestBuffer(&req_p, packetObj_p->unitID, numCommands, resultHandlerSSLTLSEncrypt, nBytes); CHECK_RETURN(ret); /* User has not provided a request buffer */ res_p = (N8_Buffer_t *) ((int)req_p + req_p->dataoffset); res_a = req_p->qr.physicalAddress + req_p->dataoffset; input_p = res_p + NEXT_WORD_SIZE(length); input_a = res_a + NEXT_WORD_SIZE(length); ctx_p = input_p + NEXT_WORD_SIZE(encLen); ctx_a = input_a + NEXT_WORD_SIZE(encLen); } else { /* The user has given us a request structure. We just need to initialize it. */ req_p = (API_Request_t *) request_p->VirtualAddress; initializeEARequestBuffer(req_p, request_p, packetObj_p->unitID, numCommands, resultHandlerSSLTLSEncrypt, N8_TRUE); /* User has provided a request packet, which must contain enough space for the input and output packets. The user may reuse the input pointer for the output. */ input_p = (N8_Buffer_t *)((unsigned long) packet_p + SSLTLS_DATA_OFFSET); input_a = N8_VirtToPhys(input_p); res_p = (N8_Buffer_t *)((unsigned long) result_p + SSLTLS_DATA_OFFSET); res_a = N8_VirtToPhys(res_p); /* If we are loading context memory, we load it at the last N8_CTX_BYTES before the data section */ if (numCtxBytes > 0) { ctx_p = (N8_Buffer_t *)((unsigned long) req_p + sizeof(API_Request_t) + N8_COMMAND_BLOCK_BYTES); ctx_a = N8_VirtToPhys(ctx_p); } } next_cb_p = req_p->EA_CommandBlock_ptr; /* generate the command blocks necessary to load the context, if required */ if (packetObj_p->contextLoadNeeded == N8_TRUE) { /* Generate the command blocks for the Context Load */ ctxLoadFcn = (n8_ctxLoadFcn_t)packetObj_p->ctxLoadFcn; ret = ctxLoadFcn(req_p, next_cb_p, packetObj_p, &packetObj_p->cipherInfo, packetObj_p->packetHashAlgorithm, ctx_p, ctx_a, &next_cb_p); CHECK_RETURN(ret); packetObj_p->contextLoadNeeded = N8_FALSE; } req_p->copyBackFrom_p = res_p; req_p->postProcessingData_p = (void *) packetObj_p; /* This sets up the offset for the start of the copy back of the IV */ req_p->postProcessBuffer[0] = encLen - N8_DES_KEY_LENGTH; if (request_p == NULL) { memcpy(input_p, &packet_p[SSLTLS_DATA_OFFSET], length); req_p->copyBackTo_p = &result_p[SSLTLS_DATA_OFFSET]; req_p->copyBackSize = encLen; } else { req_p->copyBackSize = 0; } /* Generate the command blocks for the Encrypt */ encryptFcn = (n8_SSLTLSFcn_t)packetObj_p->SSLTLScmdFcn; ret = encryptFcn(next_cb_p, packetObj_p, packet_p, input_a, res_a, packetObj_p->encOpCode); CHECK_RETURN(ret); /* set up the return packet. note that this can be done before the * command is executed as it is only constant header information. */ memcpy(&result_p[SSLTLS_TYPE_OFFSET], &packet_p[SSLTLS_TYPE_OFFSET], sizeof(uint8_t) + sizeof(uint16_t)); SSLTLS_SET_LENGTH(result_p, encLen); QUEUE_AND_CHECK(event_p, req_p, ret); HANDLE_EVENT(event_p, req_p, ret); } while (FALSE); /* clean up if necessary. note that if there is no error condition, the * request will be de-allocated in the result handler. */ if (ret != N8_STATUS_OK) { freeRequest(req_p); } return ret; } /* N8_SSLEncryptAuthenticateMemory */