N8_Status_t n8_SKSsetStatus(N8_SKSKeyHandle_t *keyHandle_p, unsigned int status) { int i; unsigned int alloc_units_to_free = 0; unsigned int num_sks_words; unsigned int sks_alloc_unit_offset = 0; NspInstance_t *NSPinstance_p; N8_Status_t ret = N8_STATUS_OK; if ((keyHandle_p->unitID < 0) || (keyHandle_p->unitID >= NSPcount_g)) { DBG(("Invalid unit: %d\n", keyHandle_p->unitID)); return N8_INVALID_VALUE; } /* assign the right control struct for the target HW */ NSPinstance_p = &NSPDeviceTable_g[keyHandle_p->unitID]; ret = n8_ComputeKeyLength(keyHandle_p->key_type, keyHandle_p->key_length, &num_sks_words); if (ret != N8_STATUS_OK) { return ret; } /* given the number SKS words, compute the number of allocation units */ alloc_units_to_free = CEIL(num_sks_words, SKS_WORDS_PER_ALLOC_UNIT); /* given the offset in words, find the first allocation unit */ sks_alloc_unit_offset = keyHandle_p->sks_offset / SKS_WORDS_PER_ALLOC_UNIT; if (ret != N8_STATUS_OK) { return ret; } N8_AtomicLock(NSPinstance_p->SKSSem); for (i = 0; i < alloc_units_to_free; i++) { NSPinstance_p->SKS_map[sks_alloc_unit_offset + i] = status; } N8_AtomicUnlock(NSPinstance_p->SKSSem); return ret; } /* n8_SKSsetStatus */
/** @ingroup n8_sks_daemon * @brief Sets the status of the SKS allocation units spanning an SKS key * * @param keyHandle_p RO: key handle * @param status RO: free or in use * @param alloc_map RW: SKS allocation descriptor table * * @par Externals: * None. * * @return * A text description of all of the return codes of the function. * * @par Errors: * return status of SKS_ComputeKeyLength call * * @par Locks: * None. * * @par Assumptions: *****************************************************************************/ static N8_Status_t n8_setStatus(N8_SKSKeyHandle_t *keyHandle_p, unsigned int status, N8_Buffer_t *alloc_map) { int i; unsigned int alloc_units_to_free; unsigned int num_sks_words; unsigned int sks_alloc_unit_offset; N8_Status_t ret; ret = n8_ComputeKeyLength(keyHandle_p->key_type, keyHandle_p->key_length, &num_sks_words); if (ret != N8_STATUS_OK) { DBG(("n8_setStatus: n8_ComputeKeyLength returned an error\n")); return ret; } DBG(("num_sks_words:\t%d\n",num_sks_words)); /* given the number SKS words, compute the number of allocation units */ alloc_units_to_free = CEIL(num_sks_words, SKS_WORDS_PER_ALLOC_UNIT); DBG(("alloc_units_to_free;\t%d\n",alloc_units_to_free)); /* given the offset in words, find the first allocation unit */ sks_alloc_unit_offset = keyHandle_p->sks_offset / SKS_WORDS_PER_ALLOC_UNIT; DBG(("sks_alloc_unit_offset:\t%d\n",sks_alloc_unit_offset)); for (i = 0; i < alloc_units_to_free; i++) { alloc_map[sks_alloc_unit_offset + i] = status; } return ret; } /* n8_setStatus */
N8_Status_t n8_SKSAllocate(N8_SKSKeyHandle_t* keyHandle_p) { unsigned int i; unsigned int free_blocks_start_index = 0; unsigned int free_blocks = 0; unsigned int best_fit_index = 0; unsigned int best_fit_blocks = 0; unsigned int SKS_words_needed = 0; unsigned int SKS_allocation_units_needed = 0; NspInstance_t *NSPinstance_p; N8_Boolean_t sks_hole_found = N8_FALSE; uint32_t keyLength = keyHandle_p->key_length; N8_SKSKeyType_t keyType = keyHandle_p->key_type; int targetSKS = (int) keyHandle_p->unitID; N8_Status_t ret = N8_STATUS_OK; DBG(("N8_Allocate: \n")); if ((targetSKS < 0) || (targetSKS >= NSPcount_g)) { DBG(("Invalid unit: %d\n", targetSKS)); return N8_INVALID_VALUE; } /* assign the right control struct for the target HW */ NSPinstance_p = &NSPDeviceTable_g[targetSKS]; DBG(("SKS WORDS %d\n", SKS_RSA_DATA_LENGTH(keyLength))); if ((ret = n8_ComputeKeyLength(keyType, keyLength, &SKS_words_needed)) != N8_STATUS_OK) { DBG(("Could not compute SKS key length: %d\n", ret)); return ret; } DBG(( "Total of %d words needed in the SKS (%d) PROM for key length %d.\n", SKS_words_needed, targetSKS, keyLength)); SKS_allocation_units_needed = CEIL(SKS_words_needed, SKS_WORDS_PER_ALLOC_UNIT); DBG(( "Total of %d allocation units needed in the SKS (%d) PROM.\n", SKS_allocation_units_needed, targetSKS)); DBG(( "Looking for free blocks in descriptor %d.\n", targetSKS)); best_fit_blocks = SKS_ALLOC_UNITS_PER_PROM; best_fit_index = 0; /* Entering critical section */ N8_AtomicLock(NSPinstance_p->SKSSem); /* Find the best fit for this block of words. */ sks_hole_found = N8_FALSE; i = SKS_PROM_MIN_OFFSET; while (i < SKS_ALLOC_UNITS_PER_PROM) { if (NSPinstance_p->SKS_map[i] == SKS_FREE) { DBG(("Found a free block at SKS allocation unit offset %d.\n", i)); free_blocks_start_index = i; i++; while ((i < SKS_ALLOC_UNITS_PER_PROM) && ((NSPinstance_p->SKS_map[i]) == SKS_FREE)) { i++; } free_blocks = i - free_blocks_start_index; DBG(("Number of free allocation blocks is %d.\n", free_blocks)); /* If the number of free blocks to allocate is larger than the * needed number of blocks (in groups of SKS_WORDS_PER_ALLOC_UNIT) * then we can allocate this block. */ if (free_blocks >= SKS_allocation_units_needed) { DBG(("Number of free blocks (%d) >= to needed blocks (%d).\n", free_blocks, SKS_allocation_units_needed)); sks_hole_found = N8_TRUE; /* See if this is the smallest fit. */ if (free_blocks <= best_fit_blocks) { best_fit_index = free_blocks_start_index; best_fit_blocks = free_blocks; } } else { /* block is too small */ DBG(("Number of free blocks (%d) < to needed blocks (%d).\n", free_blocks, SKS_allocation_units_needed)); } } i++; } /* while i < SKS_ALLOC_UNITS_PER_PROM */ if (sks_hole_found == N8_TRUE) { DBG(( "Allocating %d blocks out of %d free allocation blocks to key.\n", SKS_allocation_units_needed, free_blocks)); /* Mark the blocks, in alloc unit sizes, as in use. */ for (i = best_fit_index; i < best_fit_index + SKS_allocation_units_needed; i++) { DBG(("Allocating block %d.\n", i)); NSPinstance_p->SKS_map[i] = SKS_INUSE; } /* for */ /* Set the key offset. */ keyHandle_p->sks_offset = best_fit_index * SKS_WORDS_PER_ALLOC_UNIT; DBG(("New key handle offset will be :%d\n", keyHandle_p->sks_offset)); } else { /* No space found! */ DBG(( "Unable to find enough free space in SKS to allocate for key.\n")); ret = N8_NO_MORE_RESOURCE; } /* Leaving critical section. */ N8_AtomicUnlock(NSPinstance_p->SKSSem); return ret; } /* n8_SKSAllocate */