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 */
Example #2
0
/** @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 */