コード例 #1
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
/** @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 */
コード例 #2
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
/*****************************************************************************
 * 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 */
コード例 #3
0
/** @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 */
コード例 #4
0
/** @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 */
コード例 #5
0
/** @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 */
コード例 #6
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
/** @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 */
コード例 #7
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
/** @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 */
コード例 #8
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
/** @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 */
コード例 #9
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
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 */
コード例 #10
0
ファイル: n8_sks.c プロジェクト: eyberg/rumpkernel-netbsd-src
/** @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 */
コード例 #11
0
/** @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 */
コード例 #12
0
ファイル: n8_system.c プロジェクト: Tommmster/netbsd-avr32
/** @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 */