/** @ingroup n8_sks * @brief Obliterates all data within an SKS PROM. * * Attempts to de-allocate, then erase the all key entries in an SKS PROM. * THIS SHOULD NEVER BE INVOKED EXCEPT TO CLEAR ALL KEYS IN A GIVEN PROM. * THIS IS AN IRREVERSIBLE ACTION. * * @param targetSKS RW: A int, the target SKS PROM. * * @par Externals: * None * * @return * N8_STATUS_OK indicates the key de-allocation and erase successfully * completed. * N8_UNEXPECTED_ERROR indicates an error erasing the SKS key entry or that * the API was not or could not be initialized. * *****************************************************************************/ N8_Status_t N8_SKSReset(N8_Unit_t targetSKS) { int i; N8_Status_t ret = N8_STATUS_OK; N8_Unit_t firstSKS, lastSKS; int numberSKS; DBG(("N8_SKSReset: entering...\n")); ret = N8_preamble(); if (ret != N8_STATUS_OK) { return ret; } /* get the number of units */ numberSKS = n8_getNumUnits(); if (targetSKS == N8_ANY_UNIT) { firstSKS = 0; lastSKS = numberSKS-1; } else if (targetSKS >= 0 && targetSKS < numberSKS) { firstSKS = lastSKS = targetSKS; } else { ret = N8_INVALID_VALUE; return ret; } /* loop over the SKS units to be reset. it will either be all or just the * targetSKS. */ for (i = firstSKS; i <= lastSKS; i++) { ret = n8_SKSResetUnit(i); if (ret != N8_STATUS_OK) { return ret; } /* request N8 userspace daemon to remove * all the key handle files on the host * file system that are under the specified * execution unit */ ret = n8_daemon_sks_reset(i); if (ret != N8_STATUS_OK) { DBG(("Error resetting SKS files: %d\n", ret)); return N8_FILE_ERROR; } } DBG(("N8_SKSReset: leaving...\n")); return ret; } /* N8_SKSReset */
/***************************************************************************** * N8_SKSVerifyRSA *****************************************************************************/ N8_Status_t N8_SKSVerifyRSA(N8_SKSKeyHandle_t* keyHandle_p, N8_Buffer_t* input_p, N8_Buffer_t* result_p) { N8_RSAKeyObject_t privateKey; N8_Buffer_t* decryptBuffer_p; N8_Status_t ret; DBG(("Verify RSA Key.\n")); ret = N8_preamble(); if (ret != N8_STATUS_OK) { return ret; } /* Set the material to NULL as we are using the SKS. */ ret = N8_RSAInitializeKey(&privateKey, N8_PRIVATE_SKS, NULL, NULL); if (ret != N8_STATUS_OK) { DBG(("Could not initialize RSA private key from SKS. (%s)\n", N8_Status_t_text(ret))); return ret; } decryptBuffer_p = (N8_Buffer_t *) N8_UMALLOC(privateKey.privateKeyLength); if (decryptBuffer_p == NULL) { DBG(("Could not allocate %i bytes for decrypt buffer.\n", privateKey.privateKeyLength)); return N8_MALLOC_FAILED; } ret = N8_RSADecrypt(&privateKey, input_p, privateKey.privateKeyLength, decryptBuffer_p, NULL); if (ret != N8_STATUS_OK) { DBG(("Could not complete RSA decrypt using SKS private key. (%s)\n", N8_Status_t_text(ret))); return ret; } /* Compare the buffers. If they are different, then indicate this in the return code. */ if (memcmp(result_p, decryptBuffer_p, privateKey.privateKeyLength) != 0) { DBG(("Message buffers are not the same. " "RSA Decrypt failed or SKS private key material is not valid.\n")); return N8_VERIFICATION_FAILED; } DBG(("RSA Decrypt good: SKS private key is valid.\n")); return N8_STATUS_OK; } /* N8_SKSVerifyRSA */
/** @ingroup dh * @brief Free an initialized Diffie-Hellman key object * * At initialization, the key object has several components allocated. This * method will release those resources. This method should be called when the * key is no longer used. It is the user's responsibility to avoid memory leaks * by invoking this method. * * @param key_p RW: Pointer to key object to be freed. * * @par Externals * None * * @return * Status: N8_STATUS_OK -- no errors<br> * N8_INVALID_KEY -- the key passed was not a valid key. * * @par Errors * No errors are reported except as noted above. * * @par Assumptions * None *****************************************************************************/ N8_Status_t N8_DHFreeKey(N8_DH_KeyObject_t *key_p) { N8_Status_t ret = N8_STATUS_OK; do { ret = N8_preamble(); CHECK_RETURN(ret); if ((key_p == NULL) || (key_p->structureID != N8_DH_STRUCT_ID)) { ret = N8_INVALID_KEY; break; } if (key_p->kmem_p != NULL) { N8_KFREE(key_p->kmem_p); key_p->kmem_p = NULL; } key_p->structureID = 0; } while (FALSE); return ret; } /* N8_DHFreeKey */
/** @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_sks * @brief De-allocates and erases a private key entry to an SKS PROM. * * Attempts to de-allocate, then erase the key into an SKS PROM. * * @param keyHandle_p RW: A N8_SKSKeyHandle_t pointer. * * @par Externals: * None * * @return * N8_STATUS_OK indicates the key de-allocation and erase successfully * completed. * N8_UNEXPECTED_ERROR indicates an error erasing the SKS key entry or that * the API was not or could not be initialized. * * @par Assumptions: * That the key handle pointer is valid. *****************************************************************************/ N8_Status_t N8_SKSFree(N8_SKSKeyHandle_t* keyHandle_p) { int words_to_free; char* key_type; int i; uint32_t zero = 0x0; N8_Status_t ret; char fullFileName[1024]; DBG(("SKS Free\n")); ret = N8_preamble(); if (ret != N8_STATUS_OK) { return ret; } if (keyHandle_p == NULL) { ret = N8_INVALID_KEY; return ret; } #ifdef N8DEBUG n8_printSKSKeyHandle(keyHandle_p); #endif if ((keyHandle_p->key_type) == N8_RSA_VERSION_1_KEY) { words_to_free = SKS_RSA_DATA_LENGTH(keyHandle_p->key_length); key_type = "RSA"; } else if (keyHandle_p->key_type == N8_DSA_VERSION_1_KEY) { words_to_free = SKS_DSA_DATA_LENGTH(keyHandle_p->key_length); key_type = "DSA"; } else { DBG(("Unknown key type.\n")); return N8_INVALID_KEY; } DBG(("Zeroing out the key in the SKS PROM.\n")); /* Grab the offset and begin deleting data! */ for (i = keyHandle_p->sks_offset; (i < keyHandle_p->sks_offset+words_to_free) && (i < SKS_PROM_MAX_OFFSET); i++) { ret = n8_SKSWrite(keyHandle_p->unitID, &zero, 1, i, FALSE); if (ret != N8_STATUS_OK) { DBG(("Error writing to SKS in N8_SKSFree. (%s)\n", N8_Status_t_text(ret))); return ret; } } n8_SKSsetStatus(keyHandle_p, SKS_FREE); sprintf(fullFileName, "%s%d/%s", SKS_KEY_NODE_PATH, keyHandle_p->unitID, keyHandle_p->entry_name); /* request N8 userspace daemon to delete the specfied file */ n8_daemon_sks_delete(fullFileName); return N8_STATUS_OK; } /* N8_SKSFree */
/** @ingroup n8_sks * @brief Allocate and write a private DSA key entry to an SKS PROM. * * Attempts to allocate, then write the key into an SKS PROM. * * @param keyMaterial_p RW: A N8_DSAKeyMaterial_t pointer. * @param keyEntryName_p RW: A char pointer, the name of the sks entry. * * @par Externals: * None * * @return * N8_STATUS_OK indicates the key allocation and write successfully * completed. * N8_UNEXPECTED_ERROR indicates an error writing the key handle or that * the API was not or could not be initialized. * * @par Assumptions: * That the DSA key material pointer is valid. *****************************************************************************/ N8_Status_t N8_SKSAllocateDSA(N8_DSAKeyMaterial_t *keyMaterial_p, const N8_Buffer_t *keyEntryName_p) { N8_DSAKeyObject_t key; N8_Buffer_t* param; unsigned int keyLength; uint32_t targetSKS = 0, sksOffset = 0; N8_Status_t ret; N8_SKSKeyHandle_t *sks_key_p; do { ret = N8_preamble(); CHECK_RETURN(ret); CHECK_OBJECT(keyMaterial_p, ret); CHECK_OBJECT(keyMaterial_p->privateKey.value_p, ret); CHECK_OBJECT(keyEntryName_p, ret); if (strlen(keyEntryName_p) >= N8_SKS_ENTRY_NAME_MAX_LENGTH) { ret = N8_INVALID_OBJECT; break; } if ((keyMaterial_p->p.lengthBytes == 0) || (keyMaterial_p->q.lengthBytes == 0)) { ret = N8_INVALID_KEY_SIZE; break; } ret = n8_DSAValidateKey(keyMaterial_p, N8_PRIVATE); CHECK_RETURN(ret); sks_key_p = &keyMaterial_p->SKSKeyHandle; ret = n8_verifyUnitID(keyMaterial_p->unitID, sks_key_p); CHECK_RETURN(ret); /* The key length field of the key handle is always in BNC digits. */ sks_key_p->key_length = BYTES_TO_PKDIGITS(keyMaterial_p->p.lengthBytes); /* check to see if an entry of this name already exists and free * it if so. */ ret = n8_checkAndFreeEntry(keyEntryName_p, keyMaterial_p->SKSKeyHandle.unitID); CHECK_RETURN(ret); ret = N8_DSAInitializeKey(&key, N8_PRIVATE, keyMaterial_p, NULL); CHECK_RETURN(ret); keyLength = sks_key_p->key_length; targetSKS = sks_key_p->unitID; sks_key_p->key_type = N8_DSA_VERSION_1_KEY; /* allocate an sks. */ ret = n8_SKSAllocate(sks_key_p); CHECK_RETURN(ret); /* attempt to write the key information to the mapping files */ strcpy(sks_key_p->entry_name, keyEntryName_p); /* request N8 userspace daemon to write out a key handle file */ ret = n8_daemon_sks_write(sks_key_p, keyEntryName_p); if (ret != N8_STATUS_OK) { /* the write to the key handle failed. * we need to unallocate the space * and return a failure. */ n8_SKSsetStatus(sks_key_p, SKS_FREE); break; } sksOffset = sks_key_p->sks_offset; /* Write the data into the SKS PROM. */ DBG(("Writing key data into SKS.\n")); /* The DSA parameter block to be stored the DSA has the following structure: * p sks_offset key_length digits * g*R mod p sks_offset + 4 * key_length key_length digits * q sks_offset + 8 * key_length 2 digits * x sks_offset + 8*kl + 8 2 digits * p sks_offset + 8*kl + 16 1 digit */ /* Write the p value into the SKS. */ DBG(("Writing p param into SKS.\n")); param = key.paramBlock + PK_DSA_P_Param_Offset; ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_DSA_P_LENGTH(sks_key_p->key_length), sksOffset + SKS_DSA_P_OFFSET(sks_key_p->key_length), FALSE); CHECK_RETURN(ret); /* Write the gR mod p value into the SKS. */ DBG(("Writing gR mod p param into SKS.\n")); param = key.paramBlock + PK_DSA_GR_MOD_P_Param_Offset(sks_key_p->key_length); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_DSA_GRMODP_LENGTH(sks_key_p->key_length), sksOffset + SKS_DSA_GRMODP_OFFSET(sks_key_p->key_length), FALSE); CHECK_RETURN(ret); /* Write the q value into the SKS. */ DBG(("Writing q param into SKS.\n")); param = key.paramBlock + PK_DSA_Q_Param_Offset(sks_key_p->key_length); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_DSA_Q_LENGTH(sks_key_p->key_length), sksOffset + SKS_DSA_Q_OFFSET(sks_key_p->key_length), FALSE); CHECK_RETURN(ret); /* Write the x value (private key) into the SKS. */ DBG(("Writing x (private key) param into SKS.\n")); param = key.paramBlock + PK_DSA_X_Param_Offset(sks_key_p->key_length); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_DSA_X_LENGTH(sks_key_p->key_length), sksOffset + SKS_DSA_X_OFFSET(sks_key_p->key_length), FALSE); CHECK_RETURN(ret); /* Write the cp value into the SKS. */ DBG(("Writing cp into SKS.\n")); param = key.paramBlock + PK_DSA_CP_Param_Offset(sks_key_p->key_length); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_DSA_CP_LENGTH(sks_key_p->key_length), sksOffset + SKS_DSA_CP_OFFSET(sks_key_p->key_length), FALSE); CHECK_RETURN(ret); } while (FALSE); if (key.structureID == N8_DSA_STRUCT_ID) { N8_Status_t freeRet; freeRet = N8_DSAFreeKey(&key); /* if we terminated the processing loop with an error, let's report that * error to the calling function rather than have it masked by the return * from free key. */ if (ret == N8_STATUS_OK) { ret = freeRet; } } return ret; } /* N8_SKSAllocateDSA */
/** @ingroup n8_sks * @brief Allocate and write a private RSA key entry to an SKS PROM. * * Attempts to allocate, then write the key into an SKS PROM. * * @param keyMaterial_p RW: A N8_RSAKeyMaterial_t pointer. * @param keyEntryName_p RW: A char pointer, the name of the sks entry. * * @par Externals: * None * * @return * N8_STATUS_OK indicates the key allocation and write successfully completed. * N8_UNEXPECTED_ERROR indicates an error writing the key handle or that * the API was not or could not be initialized. * * @par Assumptions: * That the RSA key material pointer is valid. *****************************************************************************/ N8_Status_t N8_SKSAllocateRSA(N8_RSAKeyMaterial_t *keyMaterial_p, const N8_Buffer_t *keyEntryName_p) { N8_RSAKeyObject_t key; N8_Buffer_t* param; uint32_t sksOffset = 0, targetSKS = 0, keyLength = 0; N8_Status_t ret = N8_STATUS_OK; N8_SKSKeyHandle_t *sks_key_p; do { ret = N8_preamble(); CHECK_RETURN(ret); CHECK_OBJECT(keyMaterial_p, ret); CHECK_OBJECT(keyMaterial_p->privateKey.value_p, ret); CHECK_OBJECT(keyEntryName_p, ret); if (strlen(keyEntryName_p) >= N8_SKS_ENTRY_NAME_MAX_LENGTH) { ret = N8_INVALID_OBJECT; break; } if ((keyMaterial_p->p.lengthBytes == 0) || (keyMaterial_p->q.lengthBytes == 0)) { ret = N8_INVALID_KEY_SIZE; break; } sks_key_p = &keyMaterial_p->SKSKeyHandle; ret = n8_verifyUnitID(keyMaterial_p->unitID, sks_key_p); CHECK_RETURN(ret); /* Check requirements for p and q lengths. */ /* len(p) == len(q) */ if (keyMaterial_p->q.lengthBytes != keyMaterial_p->p.lengthBytes) { DBG(("P and Q RSA key material parameters not of same length!\n")); ret = N8_INVALID_KEY_SIZE; break; } /* len(p) == len(q) == 1/2 len(private key). note we don't perform the * division in the test as integer division would round down. */ if ((keyMaterial_p->q.lengthBytes * 2) != keyMaterial_p->privateKey.lengthBytes) { DBG(("P and Q RSA key material parameter length not half of " "private key length!\n")); ret = N8_INVALID_KEY_SIZE; break; } /* public key length mod 32 == 0 or 17-31 */ if (keyMaterial_p->privateKey.lengthBytes % 32 != 0 && keyMaterial_p->privateKey.lengthBytes % 32 <= 16) { DBG(("Private key length %% 32 is not in the valid range of 0 or 17-31.\n")); ret = N8_INVALID_KEY_SIZE; break; } /* check to see if an entry of this name already exists and free * it if so. */ ret = n8_checkAndFreeEntry(keyEntryName_p, keyMaterial_p->SKSKeyHandle.unitID); CHECK_RETURN(ret); ret = N8_RSAInitializeKey(&key, N8_PRIVATE_CRT, keyMaterial_p, NULL); CHECK_RETURN(ret); keyLength = keyMaterial_p->privateKey.lengthBytes; targetSKS = sks_key_p->unitID; sks_key_p->key_type = N8_RSA_VERSION_1_KEY; /* The key length field of the key handle is always in BNC digits. */ sks_key_p->key_length = BYTES_TO_PKDIGITS(keyLength); DBG(("Key Length in bytes: %d\n", keyLength)); DBG(("Key length in digits: %d\n", sks_key_p->key_length)); ret = n8_SKSAllocate(sks_key_p); CHECK_RETURN(ret); /* attempt to write the key information to the mapping files */ strcpy(sks_key_p->entry_name, keyEntryName_p); /* request N8 userspace daemon to write out a key handle file */ ret = n8_daemon_sks_write(sks_key_p, keyEntryName_p); if (ret != N8_STATUS_OK) { /* the write to the key handle failed. * we need to unallocate the space * and return a failure. */ DBG(("n8_daemon_sks_write returned error\n")); n8_SKSsetStatus(sks_key_p, SKS_FREE); break; } sksOffset = sks_key_p->sks_offset; /* Write the data into the SKS PROM. */ DBG(("Writing key data into SKS.\n")); /* Write the p value into the SKS. */ DBG(("Writing p param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_P_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_P_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_P_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the p value into the SKS. */ DBG(("Writing q param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_Q_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_Q_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_Q_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the dp value into the SKS. */ DBG(("Writing dp param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_DP_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_DP_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_DP_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the dq value into the SKS. */ DBG(("Writing dq param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_DQ_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_DQ_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_DQ_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the R mod p value into the SKS. */ DBG(("Writing R mod p param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_R_MOD_P_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_RMODP_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_RMODP_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the R mod q value into the SKS. */ DBG(("Writing R mod q param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_R_MOD_Q_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_RMODQ_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_RMODQ_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the n value into the SKS. */ DBG(("Writing n param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_N_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_N_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_N_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the pInv value into the SKS. */ DBG(("Writing pInv param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_U_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_PINV_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_PINV_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the cp value into the SKS. */ DBG(("Writing cp param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_CP_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_CP_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_CP_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); CHECK_RETURN(ret); /* Write the cq value into the SKS. */ DBG(("Writing cq param into SKS.\n")); param = (N8_Buffer_t*) key.kmem_p->VirtualAddress + PK_RSA_CQ_Param_Byte_Offset(&key); ret = n8_SKSWrite(targetSKS, (uint32_t*) param, SKS_RSA_CQ_LENGTH(sks_key_p->key_length), sksOffset + SKS_RSA_CQ_OFFSET(sks_key_p->key_length), FALSE); DBG(("Return from write: %s\n", N8_Status_t_text(ret))); } while (FALSE); if (key.structureID == N8_RSA_STRUCT_ID) { N8_Status_t freeRet; freeRet = N8_RSAFreeKey(&key); /* if we terminated the processing loop with an error, let's report that * error to the calling function rather than have it masked by the return * from free key. */ if (ret == N8_STATUS_OK) { ret = freeRet; } } return ret; } /* N8_SKSAllocateRSA */
N8_Status_t N8_SKSVerifyDSA(N8_SKSKeyHandle_t* keyHandle_p, N8_Buffer_t* inputHash_p, N8_Buffer_t* resultRValue_p, N8_Buffer_t* resultSValue_p) { N8_DSAKeyObject_t privateKey; N8_Buffer_t* signRValueBuffer_p, *signSValueBuffer_p; N8_Status_t ret; DBG(("Verify DSA Key.\n")); ret = N8_preamble(); if (ret != N8_STATUS_OK) { return ret; } /* Set the material to NULL as we are using the SKS. */ ret = N8_DSAInitializeKey(&privateKey, N8_PRIVATE_SKS, NULL, NULL); if (ret != N8_STATUS_OK) { DBG(("Could not initialize DSA private key from SKS. (%s)\n", N8_Status_t_text(ret))); return ret; } /* !!!!!! Is there a #define for the S and R value byte lengths?!?!?!! */ if ((signRValueBuffer_p = (N8_Buffer_t *) N8_UMALLOC(20)) != 0) { DBG(("Could not allocate %i bytes for DSA sign R value buffer.\n", privateKey.modulusLength)); return N8_MALLOC_FAILED; } if ((signSValueBuffer_p = (N8_Buffer_t *) N8_UMALLOC(20)) != 0) { DBG(("Could not allocate %i bytes for DSA sign S value buffer.\n", privateKey.modulusLength)); return N8_MALLOC_FAILED; } ret = N8_DSASign(&privateKey, inputHash_p, signRValueBuffer_p, signSValueBuffer_p, NULL); if (ret != N8_STATUS_OK) { DBG(("Could not complete DSA sign using SKS private key. (%s)\n", N8_Status_t_text(ret))); return ret; } /* Compare the buffers. If they are different, then indicate this in the return code. */ if (memcmp(resultRValue_p, signRValueBuffer_p, 20) != 0) { DBG(("Result R value buffers are not the same. " "DSA Sign failed or SKS private key material is not valid.\n")); return N8_VERIFICATION_FAILED; } if (memcmp(resultSValue_p, signSValueBuffer_p, 20) != 0) { DBG(("Result S value buffers are not the same. " "DSA Sign failed or SKS private key material is not valid.\n")); return N8_VERIFICATION_FAILED; } DBG(("DSA Sign good: SKS private key is valid.\n")); return N8_STATUS_OK; } /* N8_SKSVerifyDSA */
/** @ingroup n8_sks * @brief Reads a key handle data from a named key entry for an SKS PROM. * * @param systemKeyNode RW: A char pointer, the named key entry. * @param keyHandle_p WO: A N8_SKSKeyHandle_t pointer. * * @par Externals: * SKS_initialized_g RW: A boolean value that indicates whether the SKS * admin interface API has been initialized. * @return * N8_STATUS_OK indicates the key read successfully completed. * N8_UNEXPECTED_ERROR indicates an error reading the SKS key entry or that * the API was not or could not be initialized. * *****************************************************************************/ N8_Status_t N8_SKSGetKeyHandle(const N8_Buffer_t* keyEntryName, N8_SKSKeyHandle_t* keyHandle_p) { N8_Status_t ret = N8_STATUS_OK; char fullFileName[1024]; int numberSKS; int i; int found; DBG(("Get KeyHandle : \n")); ret = N8_preamble(); if (ret != N8_STATUS_OK) { return ret; } if ((keyEntryName == NULL) || (keyHandle_p == NULL)) { return N8_INVALID_OBJECT; } /* get the number of units */ numberSKS = n8_getNumUnits(); /* check to see if we can have a buffer overrun. the +4 is for the trailing * '/' and for the size of the unitID -- assuming the number of units is no * more than 999. */ if ((strlen(SKS_KEY_NODE_PATH) + strlen(keyEntryName) + 4) >= sizeof(fullFileName)) { return N8_UNEXPECTED_ERROR; } found = -1; for (i = 0; i < numberSKS; i++) { sprintf(fullFileName, "%s%d/%s", SKS_KEY_NODE_PATH, i, keyEntryName); /* request N8 userspace daemon to read from the specfied key * handle file */ ret = n8_daemon_sks_read(keyHandle_p, fullFileName); if (ret == N8_STATUS_OK) { found = i; /* n8_daemon_sks_read does not set the entry name */ strcpy(keyHandle_p->entry_name, keyEntryName); #if N8_SKS_ROUND_ROBIN keyHandle_p->unitID = N8_ANY_UNIT; #endif /* N8_SKS_ROUND_ROBIN */ break; } } if (found == -1) { ret = N8_INVALID_KEY; } return ret; } /* N8_SKSGetKeyHandle */
/** @ingroup n8_packet * @brief Initializes (makes ready for use in packet operations) the packet object. * * Typically a packet object will be initialized at the beginning of an SSL, * TLS, or IPSec session with the cipher and hash information particular to * that session. The packet object can then be used in all subsequent packet * operations until the session is terminated. Note however that if a new key * is negotiated during the session, then the packet object must be re-initialized * with the new key material. * * @param packetObject_p WO: The packet object to be initialized with the * specified information.<BR> * @param contextHandle_p RO: A valid context index as returned by * N8_AllocateContext, if Cipher = ARC4. * Optional, if Cipher = DES.<BR> * @param protocol RO: One of the values SSL, TLS, or IPSec. * Denotes the protocol that PacketObject should * be initialized for.<BR> * @param cipher RO: If Protocol = SSL or TLS, one of the values ARC4 * or DES. * If Protocol = IPSec, then Cipher must be DES. * Specifies the cipher algorithm to use, and hence the * type and format of the information in * CipherInfo_p.<BR> * @param cipherInfo_p RO: The specific information to be used in the * initialization of the cipher algorithm. Its * contents depend on the value of ContextType, as * specified above.<BR> * @param hashAlgorithm RO: One of the values MD5, SHA-1, HMAC-MD5, HMAC-SHA-1, * HMAC-MD5-96 or HMAC-SHA-1-96 denoting the hash * algorithm to be used. * @param mode RO: One of the values from N8_PacketMemoryMode_t * * * @return * packetObject_p - initialized packet object. * ret - returns N8_STATUS_OK if successful or Error value. * * @par Errors: * N8_INVALID_PROTOCOL - The value of Protocol is not one of the legal * values SSL, TSL or IPSec.<BR> * N8_INVALID_OBJECT - packet object is zero, couldn't write to unspecified * address<BR> * N8_INVALID_CIPHER - The value of Cipher is not one of the legal values * ARC4 or DES.<BR> * N8_INVALID_HASH - The value of HashAlgorithm is not one of the legal * values MD5, SHA-1, HMAC-MD5, HMAC-SHA-1, HMAC-MD5-96 * or HMAC-SHA-1-96<BR> * N8_INVALID_VALUE - The value of ContextIndex is not a valid context * index, or ContextIndex is null but a context index * is required because ARC4 is specified.<BR> * N8_UNALLOCATED_CONTEXT - ContextIndex denotes a context memory index that * has not been allocated by N8_AllocateContext.<BR> * N8_INVALID_KEY_SIZE - The size of the key specified in CipherInfo_p is * outside the valid range for the encryption algorithm * specified in Cipher, or the size of an HMAC key * specified in CipherInfo_p is outside the valid range * for the hash algorithm specified in HashAlgorithm.<BR> * N8_INCONSISTENT - The information in CipherInfo_p and/or its type is * different than or inconsistent with the type * specified by Cipher or HashAlgorithm, or the * combination of values specified by Protocol, Cipher, * and HashAlgorithm is invalid (for example, SSL is * specified with HMAC-MD5, or IPSec is specified with * ARC4).<BR> * N8_MALLOC_FAILED - memory allocation failed * N8_UNIMPLEMENTED_FUNCTION - not supported protocol configuration requested * N8_HARDWARE_ERROR - couldn't write to context memory * * * @par Assumptions: * The context entry specified in this call should not be in use with any * other current encrypt object or packet object. This condition is not * checked for; incorrect / indeterminate results and / or errors are likely * in this situation.<BR> * If a new key is negotiated during the session, then the packet object must * be re-initialized with the new key material.<BR> *****************************************************************************/ N8_Status_t N8_PacketInitializeMemory(N8_Packet_t *packetObject_p, const N8_ContextHandle_t *contextHandle_p, const N8_Protocol_t protocol, const N8_Cipher_t cipher, const N8_CipherInfo_t *cipherInfo_p, const N8_HashAlgorithm_t hashAlgorithm, const N8_PacketMemoryMode_t mode, N8_Event_t *event_p) { API_Request_t *req_p = NULL; N8_Status_t ret = N8_STATUS_OK; /* the return status: OK or ERROR */ int protocolConfiguration = 0; int i; key_cblock_t key1, key2, key3; /* Keys to be checked */ N8_Buffer_t *ctx_p = NULL; uint32_t ctx_a; /* physical address of context for * post-computation processing */ N8_Boolean_t unitValid; DBG(("N8_PacketInitializeMemory\n")); do { ret = N8_preamble(); CHECK_RETURN(ret); /* verify packet object */ CHECK_OBJECT(packetObject_p, ret); /* verify cipher object */ CHECK_OBJECT(cipherInfo_p, ret); /* Check mode paramter & Init the mode to the user value */ if (mode != N8_PACKETMEMORY_REQUEST && mode != N8_PACKETMEMORY_NONE) { ret = N8_INVALID_ENUM; break; } packetObject_p->mode = mode; if (contextHandle_p != NULL) { DBG(("N8_PacketInitialize using context\n")); /* Make sure the context struct is valid */ CHECK_STRUCTURE(contextHandle_p->structureID, N8_CONTEXT_STRUCT_ID, ret); unitValid = n8_validateUnit(contextHandle_p->unitID); if (!unitValid) { ret= N8_INVALID_UNIT; break; } memcpy(&packetObject_p->contextHandle, contextHandle_p, sizeof(N8_ContextHandle_t)); packetObject_p->contextHandle.inUse = N8_TRUE; packetObject_p->unitID = contextHandle_p->unitID; } else { if (cipher == N8_CIPHER_ARC4) { /* The use of ARC4 requires a context */ ret = N8_UNALLOCATED_CONTEXT; break; } else { DBG(("N8_PacketInitialize not using context\n")); unitValid = n8_validateUnit(cipherInfo_p->unitID); if (!unitValid) { ret= N8_INVALID_UNIT; break; } packetObject_p->contextHandle.inUse = N8_FALSE; packetObject_p->contextHandle.index = 0xFFFF; packetObject_p->unitID = cipherInfo_p->unitID; } } /* copy the supplied cipher info into the packet object */ memcpy(&packetObject_p->cipherInfo, cipherInfo_p, sizeof(N8_CipherInfo_t)); /* verify cipher */ switch (cipher) { case N8_CIPHER_ARC4: /* verify key size */ if ((packetObject_p->cipherInfo.keySize < 1) || (packetObject_p->cipherInfo.keySize > ARC4_KEY_SIZE_BYTES_MAX)) { DBG(("Key size specified for ARC4 is outside the" " valid range: %d\n", packetObject_p->cipherInfo.keySize)); DBG(("N8_PacketInitialize - return Error\n")); ret = N8_INVALID_KEY_SIZE; break; } packetObject_p->ctxLoadFcn = &cb_ea_loadARC4KeyToContext; packetObject_p->ctxLoadCmds = N8_CB_EA_LOADARC4KEYTOCONTEXT_NUMCMDS; break; case N8_CIPHER_DES: /* verify key size */ if (packetObject_p->cipherInfo.keySize != DES_KEY_SIZE_BYTES) { DBG(("Key size specified for DES is outside " "the valid range: %d\n", packetObject_p->cipherInfo.keySize)); DBG(("N8_PacketInitialize - return Error\n")); ret = N8_INVALID_KEY_SIZE; break; } /* build keys for parity verification */ /* force key parity */ for (i=0 ; i < sizeof(key_cblock_t); i++) { key1[i] = packetObject_p->cipherInfo.key1[i]; key2[i] = packetObject_p->cipherInfo.key2[i]; key3[i] = packetObject_p->cipherInfo.key3[i]; } if (checkKeyParity(&key1) == FALSE) { forceParity(&key1); for (i=0 ; i < sizeof(key_cblock_t); i++) { packetObject_p->cipherInfo.key1[i] = key1[i]; } } if (checkKeyParity(&key2) == FALSE) { forceParity(&key2); for (i=0 ; i < sizeof(key_cblock_t); i++) { packetObject_p->cipherInfo.key2[i] = key2[i]; } } if (checkKeyParity(&key3) == FALSE) { forceParity(&key3); for (i=0 ; i < sizeof(key_cblock_t); i++) { packetObject_p->cipherInfo.key3[i] = key3[i]; } } /* check key1 and key2 for weakness */ if (checkKeyForWeakness(&key1) == N8_TRUE || checkKeyForWeakness(&key2) == N8_TRUE || checkKeyForWeakness(&key3) == N8_TRUE) { DBG(("Weak key\nN8_PacketInitialize - return Error\n")); ret = N8_WEAK_KEY; break; } packetObject_p->ctxLoadFcn = &cb_ea_loadDESKeyToContext; packetObject_p->ctxLoadCmds = N8_CB_EA_LOADDESKEYTOCONTEXT_NUMCMDS; break; default: /* invalid cipher */ DBG(("Invalid cipher\n")); DBG(("N8_PacketInitialize - return Error\n")); ret = N8_INVALID_CIPHER; break; } CHECK_RETURN(ret); /* create request buffer */ /* protocol in use */ packetObject_p->packetProtocol = protocol; /* encription algorithm */ packetObject_p->packetCipher = cipher; /* hash algorithm */ packetObject_p->packetHashAlgorithm = hashAlgorithm; /* verify protocol configuration */ protocolConfiguration = PROTOCOL_CIPHER_HASH(protocol, cipher, hashAlgorithm); /* after the memcpy, ensure we aren't pointing to dynamically allocated space the user set up in the cipher info. */ packetObject_p->cipherInfo.hmac_key = NULL; /* verify hash algorithm and HMAC keys if appropriate */ switch (hashAlgorithm) { case N8_MD5: case N8_SHA1: case N8_HASH_NONE: break; case N8_HMAC_SHA1: case N8_HMAC_SHA1_96: case N8_HMAC_MD5: case N8_HMAC_MD5_96: if ((packetObject_p->cipherInfo.hmacKeyLength < 0) || (packetObject_p->cipherInfo.hmacKeyLength > N8_MAX_HASH_LENGTH)) { ret = N8_INVALID_KEY_SIZE; } break; default: /* invalid hash algorithm */ DBG(("Invalid hash algorithm\n")); DBG(("N8_PacketInitialize - return Error\n")); ret = N8_INVALID_HASH; break; } CHECK_RETURN(ret); /* verify protocol */ switch (protocol) { case N8_PROTOCOL_SSL: packetObject_p->encCommands = N8_CB_EA_SSLENCRYPTAUTHENTICATE_NUMCMDS; packetObject_p->decCommands = N8_CB_EA_SSLDECRYPTVERIFY_NUMCMDS; packetObject_p->SSLTLScmdFcn = &cb_ea_SSL; break; case N8_PROTOCOL_TLS: packetObject_p->encCommands = N8_CB_EA_TLSENCRYPTAUTHENTICATE_NUMCMDS; packetObject_p->decCommands = N8_CB_EA_TLSDECRYPTVERIFY_NUMCMDS; packetObject_p->SSLTLScmdFcn = &cb_ea_TLS; break; case N8_PROTOCOL_IPSEC: if (cipher != N8_CIPHER_DES) { ret = N8_INVALID_CIPHER; } break; default: /* invalid protocol */ DBG(("Invalid protocol\n")); DBG(("N8_PacketInitialize - return Error\n")); ret = N8_INVALID_PROTOCOL; break; } CHECK_RETURN(ret); /* initialize the hash packet */ n8_setInitialIVs(&packetObject_p->hashPacket, hashAlgorithm, packetObject_p->unitID); packetObject_p->hashPacket.hashSize = N8_GetHashLength(hashAlgorithm); switch (protocolConfiguration) { case PACKET_SSL_ARC4_MD5: /* Initialize for use with MD5 encryption/decryption */ ret = n8_initializeSSL_req(&packetObject_p->cipherInfo, packetObject_p, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_SSL30_ARC4_MD5_Encrypt; packetObject_p->decOpCode = EA_Cmd_SSL30_ARC4_MD5_Decrypt; break; case PACKET_SSL_ARC4_SHA1: /* Initialize for use with ARC4 encryption/decryption */ ret = n8_initializeSSL_req(&packetObject_p->cipherInfo, packetObject_p, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_SSL30_ARC4_SHA1_Encrypt; packetObject_p->decOpCode = EA_Cmd_SSL30_ARC4_SHA1_Decrypt; break; case PACKET_SSL_DES_MD5: /* Initialize for use with DES encryption/decryption */ if (packetObject_p->contextHandle.inUse == N8_TRUE) { ret = n8_initializeSSL_req(&packetObject_p->cipherInfo, packetObject_p, &ctx_p, &ctx_a, &req_p); } packetObject_p->encOpCode = EA_Cmd_SSL30_3DES_MD5_Encrypt; packetObject_p->decOpCode = EA_Cmd_SSL30_3DES_MD5_Decrypt; break; case PACKET_SSL_DES_SHA1: /* Initialize for use with DES encryption/decryption */ if (packetObject_p->contextHandle.inUse == N8_TRUE) { ret = n8_initializeSSL_req(&packetObject_p->cipherInfo, packetObject_p, &ctx_p, &ctx_a, &req_p); } packetObject_p->encOpCode = EA_Cmd_SSL30_3DES_SHA1_Encrypt; packetObject_p->decOpCode = EA_Cmd_SSL30_3DES_SHA1_Decrypt; break; case PACKET_TLS_ARC4_HMAC_MD5: ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key, packetObject_p->cipherInfo.hmacKeyLength, &packetObject_p->hashPacket, NULL, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_TLS10_ARC4_MD5_Encrypt; packetObject_p->decOpCode = EA_Cmd_TLS10_ARC4_MD5_Decrypt; break; case PACKET_TLS_ARC4_HMAC_SHA1: ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key, packetObject_p->cipherInfo.hmacKeyLength, &packetObject_p->hashPacket, NULL, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_TLS10_ARC4_SHA1_Encrypt; packetObject_p->decOpCode = EA_Cmd_TLS10_ARC4_SHA1_Decrypt; break; case PACKET_TLS_DES_HMAC_MD5: ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key, packetObject_p->cipherInfo.hmacKeyLength, &packetObject_p->hashPacket, NULL, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_TLS10_3DES_MD5_Encrypt; packetObject_p->decOpCode = EA_Cmd_TLS10_3DES_MD5_Decrypt; break; case PACKET_TLS_DES_HMAC_SHA1: ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key, packetObject_p->cipherInfo.hmacKeyLength, &packetObject_p->hashPacket, NULL, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_TLS10_3DES_SHA1_Encrypt; packetObject_p->decOpCode = EA_Cmd_TLS10_3DES_SHA1_Decrypt; break; case PACKET_IPSEC_DES_HMAC_MD5_96: ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key, packetObject_p->cipherInfo.hmacKeyLength, &packetObject_p->hashPacket, &packetObject_p->cipherInfo, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_ESP_3DES_MD5_Encrypt; packetObject_p->decOpCode = EA_Cmd_ESP_3DES_MD5_Decrypt; break; case PACKET_IPSEC_DES_HMAC_SHA1_96: ret = n8_initializeHMAC_req(cipherInfo_p->hmac_key, packetObject_p->cipherInfo.hmacKeyLength, &packetObject_p->hashPacket, &packetObject_p->cipherInfo, &ctx_p, &ctx_a, &req_p); packetObject_p->encOpCode = EA_Cmd_ESP_3DES_SHA1_Encrypt; packetObject_p->decOpCode = EA_Cmd_ESP_3DES_SHA1_Decrypt; break; case PACKET_IPSEC_DES_HASH_NONE: packetObject_p->encOpCode = EA_Cmd_3DES_CBC_Encrypt; packetObject_p->decOpCode = EA_Cmd_ESP_3DES_SHA1_Decrypt; break; default: /* invalid protocol configuration */ DBG(("Invalid protocol configuration\n")); DBG(("N8_PacketInitialize - return Error\n")); ret = N8_INCONSISTENT; break; } CHECK_RETURN(ret); /* set up the minimum length & macLength */ switch (protocolConfiguration) { case PACKET_SSL_DES_MD5: case PACKET_TLS_DES_HMAC_MD5: packetObject_p->minLength = N8_DES_MD5_MIN_LENGTH; packetObject_p->macLength = MD5_HASH_RESULT_LENGTH; break; case PACKET_SSL_DES_SHA1: case PACKET_TLS_DES_HMAC_SHA1: packetObject_p->minLength = N8_DES_SHA1_MIN_LENGTH; packetObject_p->macLength = SHA1_HASH_RESULT_LENGTH; break; case PACKET_SSL_ARC4_MD5: case PACKET_TLS_ARC4_HMAC_MD5: packetObject_p->minLength = N8_ARC4_MD5_MIN_LENGTH; packetObject_p->macLength = MD5_HASH_RESULT_LENGTH; break; case PACKET_SSL_ARC4_SHA1: case PACKET_TLS_ARC4_HMAC_SHA1: packetObject_p->minLength = N8_ARC4_SHA1_MIN_LENGTH; packetObject_p->macLength = SHA1_HASH_RESULT_LENGTH; break; default: break; } CHECK_RETURN(ret); packetObject_p->contextLoadNeeded = packetObject_p->contextHandle.inUse; } while (FALSE); if (ret == N8_STATUS_OK) { /* set the structure pointer to the correct state */ packetObject_p->structureID = N8_PACKET_STRUCT_ID; } DBG(("N8_PacketInitialize - FINISHED\n")); return ret; } /* N8_PacketInitializeMemory */
/** @ingroup SystemInfo * @brief Allows the caller to determine the value of various NSP2000 and API * system and configuration values. * * The configuration parameter desired is determined by the value specified in * Parameter. Note that the hash units are currently being treated the same * as the EA units since the NSP2000 does not have a separate hash core. * * @param parameter RO: A constant naming the configuration value to * return. * @param value_p WO: A pointer to where to return the value(s) of the * requested system parameter. The format (type) of * what is returned depends on the value of * Parameter. * * @return * returnResult - returns N8_STATUS_OK if successful or Error value. * @par Errors * N8_INVALID_ENUM - The value of Parameter is not one of the * defined valid configuration enumerations. * N8_INVALID_OBJECT The output parameter is NULL. * @par Assumptions * None<br> *****************************************************************************/ N8_Status_t N8_GetSystemParameter(N8_Parameter_t parameter, void *value_p) { N8_Status_t ret = N8_STATUS_OK; DBG(("N8_GetSystemParameter\n")); do { ret = N8_preamble(); CHECK_RETURN(ret); /* verify value object */ CHECK_OBJECT(value_p, ret); switch (parameter) { case N8_EACOUNT: ret = setCount(value_p, N8_EA); break; case N8_EATYPE: ret = setType(value_p, N8_EA); break; case N8_PKCOUNT: ret = setCount(value_p, N8_PKP); break; case N8_PKTYPE: ret = setType(value_p, N8_PKP); break; case N8_HPCOUNT: ret = setCount(value_p, N8_EA); break; case N8_HPTYPE: ret = setType(value_p, N8_EA); break; case N8_HARDWAREVERSION: ret = setHWversion(value_p); break; case N8_HARDWAREREVISION: ret = setHWrevision(value_p); break; case N8_SOFTWAREVERSION: ret = setSWversion(value_p); break; case N8_CONTEXTMEMSIZE: ret = setContextSize(value_p); break; case N8_SKSMEMSIZE: ret = setSKSsize(value_p); break; case N8_NUMBEROFCHIPS: ret = setNumberOfChips(value_p); break; case N8_SWVERSIONTEXT: ret = setSWversionText(value_p); break; case N8_INITIALIZE_INFO: ret = setInitInfo(value_p); break; case N8_FILEDESCRIPTOR: ret = setFD(value_p); break; default: /* invalid parameter */ DBG(("Invalid parameter\n")); DBG(("N8_GetSystemParameter - return Error\n")); ret = N8_INVALID_ENUM; break; } /* switch */ }while (FALSE); DBG(("N8_GetSystemParameter - OK\n")); return ret; } /* N8_GetSystemParameter */