Exemplo n.º 1
0
/** @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 */
Exemplo n.º 2
0
/** @ingroup cb_dsa
 * @brief  Creates the command blocks to perform DSA verify operation
 *
 *                   1) Compute e = e1 mod q
 *                   2) Compute invs = s^1 mod q
 *                   3) Compute u1 = invs * e mod q
 *                   4) Compute u2 = invs * r mod q
 *                   5) Compute v1 = g^u1 mod p
 *                   6) Compute w = y^u2 mod p
 *                   7) Compute v3 = v1 * w mod p
 *                   8) Compute v = v3 mod q
 *
 *
 *                         Big Number Cache slot allocation
 *
 *               1       2       3       4       5       6       7       8
 *   -------------------------------------------------------------------------
 *   step 1)     q               e1
 *               .                       e
 *   step 2)     .               s
 *               .      invs
 *   step 3)     .       .               u1
 *   step 4)     .       .       r       .
 *               .       .       u2      .
 *   step 5)     .      p[0]     .       .     2^128
 *               .      p[0]^-1  .       .       .
 *               .     -p[0]^-1  .       .       .
 *               .       .       .       .       p                       g
 *               .       .       .       .       .             Rmodp     .
 *               .       .       .       .       .    gRmodp             .
 *               .       .       .       .       .              v1        
 *   step 6)     .       .       .               .     Rmodp     .       y
 *               .       .       .               .    yRmodp     .
 *               .       .       .               .               .       w  
 *   step 7)     .                               .              v3
 *   step 8)     v
 *
 *
 *
 *  @param req_p        RW:  Pointer to command
 *                           blocks.  
 *  @param key          RO:  The previously initialized DSAKeyObject
 *                           containing the DSA key
 *                           materials to be used.
 *  @param q_a          RO:  Physical address of q value.
 *  @param cp_a         RO:  Physical address of computed cp.
 *  @param gR_mod_p_a   RO:  Physical address of computed gRmodp.
 *  @param p_a          RO:  Physical address of p value.
 *  @param publicKey_a  RO:  Physical address of public key.
 *  @param mh_a         RO:  Physical address of hash.
 *  @param r_a          RO:  Physical address of r value.
 *  @param s_a          RO:  Physical address of s value.
 *  @param res_a        WO:  Physical address of result.
 *
 * @return 
 *    ret - returns N8_STATUS_OK if successful or Error value.
 *
 * @par Errors
 *          N8_INVALID_OBJECT   -   command block pointer is NULL<BR>
 *          N8_MALLOC_FAILED    -   memory allocation failed<BR>
 *
 * @par Assumptions
 *    None.<br>
 *****************************************************************************/
N8_Status_t cb_dsaVerify(API_Request_t *req_p,
                         const N8_DSAKeyObject_t *key_p,
                         uint32_t q_a, 
                         uint32_t cp_a, 
                         uint32_t gR_mod_p_a, 
                         uint32_t p_a, 
                         uint32_t publicKey_a, 
                         uint32_t mh_a,
                         uint32_t r_a,
                         uint32_t s_a,
                         uint32_t res_a,
                         PK_CMD_BLOCK_t *cmdBuf_p)
{
   PK_CMD_BLOCK_t       *math_wr_ptr = NULL;
   PK_LDST_CMD_BLOCK_t  *ldst_wr_ptr = NULL;

   uint32_t             modulusDigits;
   uint32_t             slot1, slot2, slot3, slot4; 
   uint32_t             slot5, slot6, slot7, slot8;

   N8_Status_t          ret = N8_STATUS_OK;

   do
   {
      CHECK_OBJECT(req_p, ret);
      
      modulusDigits = BYTES_TO_PKDIGITS(key_p->modulusLength);
      
      /* Initialize the slot values.  These are to address temporary 
         storage in the BNC.  Slots 1-4 hold 2-digit operands. 
         Slots 5-8 hold operands up to the key size in length. */
      slot1 = 0;                                               /* q */
      slot2 = slot1 + PK_DSA_N_BNC_Length;  /* invs */
      slot3 = slot2 + PK_DSA_N_BNC_Length;  /* e1 */
      slot4 = slot3 + PK_DSA_N_BNC_Length;  /*  */
      slot5 = slot4 + modulusDigits;
      slot6 = slot5 + modulusDigits;
      slot7 = slot6 + modulusDigits;
      slot8 = slot7 + modulusDigits;

      /*
       Compute e = e1 mod q 
       */
      /* 1) Construct a command to load q */
      /*      1       2       3       4       5       6       7       8 
              
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) cmdBuf_p;
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot1;
      ldst_wr_ptr->data_addr_ls = (unsigned int) q_a;
      ldst_wr_ptr->data_length = PK_DSA_Q_Byte_Length;


      /* 2)Construct a command to load e1 */
      /*      1       2       3       4       5       6       7       8 
              q             
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot3;
      ldst_wr_ptr->data_addr_ls = mh_a;
      ldst_wr_ptr->data_length = PK_DSA_E1_Byte_Length;

      /* 3) Construct a command for the operation e1 mod q */
      /*      1       2       3       4       5       6       7       8 
              q              e1    
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_A_Mod_M;
      math_wr_ptr->r_offset = slot4;
      math_wr_ptr->m_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot1;
      math_wr_ptr->a_length_offset = (PK_DSA_E1_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot3;
   
      /* Compute invs = s^-1 mod q */
      /* 4) Construct a command to load s */
      /*      1       2       3       4       5       6       7       8 
              q               e1   e1 mod q
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) math_wr_ptr + 1;
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot3;
      ldst_wr_ptr->data_addr_ls = s_a;
      ldst_wr_ptr->data_length = PK_DSA_S_Byte_Length;
   
      /* 5) Construct a command for the operation invs = s^-1 mod q */
      /*      1       2       3       4       5       6       7       8 
              q               s    e1 mod q
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_Inverse_A_Mod_M;
      math_wr_ptr->r_offset = slot2;
      math_wr_ptr->m_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot1;
      math_wr_ptr->a_length_offset = (PK_DSA_S_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot3;
   
      /* Compute u1 = invs * e mod q */
      /* 6) Construct a command for the operation u1 = invs * e mod q */
      /*      1       2       3       4       5       6       7       8 
              q      invs     s    e1 mod q
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (math_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_AB_Mod_M;
      math_wr_ptr->r_offset = slot4;
      math_wr_ptr->m_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot1;
      math_wr_ptr->a_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot2;
      math_wr_ptr->b_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot4;
   
      /* Compute u2 = invs * r mod q */
      /* 7) Construct a command to load r */
      /*      1       2       3       4       5       6       7       8 
              q      invs     s       u1
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (math_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot3;
      ldst_wr_ptr->data_addr_ls = r_a;
      ldst_wr_ptr->data_length = PK_DSA_R_Byte_Length;
   
      /* 8) Construct a command for the operation u2 = invs * r mod q */
      /*      1       2       3       4       5       6       7       8 
              q      invs     r       u1
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_AB_Mod_M;
      math_wr_ptr->r_offset = slot3;
      math_wr_ptr->m_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot1;
      math_wr_ptr->a_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot2;
      math_wr_ptr->b_length_offset = (PK_DSA_R_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot3;

      /* Compute v1 = g^u1 mod p */
      
      /* 9) Construct a command to load cp = -t mod 2^128 */
      /*      1       2       3       4       5       6       7       8 
              q      invs     u2      u1
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (math_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot2;
      ldst_wr_ptr->data_addr_ls = (unsigned int) cp_a;
      ldst_wr_ptr->data_length = PK_DSA_CP_Byte_Length;   
   
      /* 10) Construct a command to load g * R mod p */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot6;
      ldst_wr_ptr->data_addr_ls = gR_mod_p_a;
      ldst_wr_ptr->data_length = PK_DSA_GR_MOD_P_Byte_Length(modulusDigits);  
   
      /* 11) Construct a command to load p */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1           gR_mod_p
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot5;
      ldst_wr_ptr->data_addr_ls = (unsigned int) p_a;
      ldst_wr_ptr->data_length = PK_DSA_P_Byte_Length(modulusDigits);
   
      /* 12) Construct a command for the operation v1 = g^u1 mod p */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1      p     gR_mod_p
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_Exp_G_Mod_M;
      math_wr_ptr->r_offset = slot7;
      math_wr_ptr->m_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot5;
      math_wr_ptr->a_length_offset = (PK_DSA_GR_MOD_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot6;
      math_wr_ptr->b_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot4;
      math_wr_ptr->c_offset = slot2;

   
      /* Compute w = y^u2 mod p */
      /* 13) Construct a command to load y */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1      p     gR_mod_p  v1
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (math_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = slot8;
      ldst_wr_ptr->data_addr_ls = (unsigned int) publicKey_a;
      ldst_wr_ptr->data_length = PK_DSA_Y_Byte_Length(modulusDigits); 

      /* 14) Construct a command for the operation R mod p */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1      p     gR_mod_p  v1    publicKey
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_R_Mod_M;
      math_wr_ptr->r_offset = slot6;
      math_wr_ptr->m_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot5;
   
      /* 15) Construct a command for the operation yR mod p */
      /*      1       2       3       4       5       6      7       8 
              q      cp       u2      u1      p     R_mod_p  v1    publicKey(y)
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (math_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_AB_Mod_M;
      math_wr_ptr->r_offset = slot6;
      math_wr_ptr->m_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot5;
      math_wr_ptr->a_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot8;
      math_wr_ptr->b_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot6;
   
      /* 16) Construct a command for the operation w = y^u2 mod p */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1      p     yR_mod_p  v1    publicKey(y)
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (math_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_Exp_G_Mod_M;
      math_wr_ptr->r_offset = slot8;
      math_wr_ptr->m_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot5;
      math_wr_ptr->a_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot6;
      math_wr_ptr->b_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot3;
      math_wr_ptr->c_offset = slot2; 
   
      /* Compute v3 = v1 * w mod p */
      /* 17) Construct a command for the operation v3 = v1 * w mod p */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1      p     yR_mod_p  v1      w
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (math_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_AB_Mod_M;
      math_wr_ptr->r_offset = slot7;
      math_wr_ptr->m_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot5;
      math_wr_ptr->a_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot7;
      math_wr_ptr->b_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot8;
   
      /* Compute v = v3 mod q */
      /* 18) Construct a command for the operation v = v3 mod q */
      /*      1       2       3       4       5       6       7       8 
              q      cp       u2      u1      p     yR_mod_p  v3      w
      */
      math_wr_ptr = (PK_CMD_BLOCK_t *) (math_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_A_Mod_M;
      math_wr_ptr->r_offset = slot1;
      math_wr_ptr->m_length_offset = (PK_DSA_Q_BNC_Length << 
                                      PK_Cmd_Length_Shift) | slot1;
      math_wr_ptr->a_length_offset = (PK_DSA_P_BNC_Length(modulusDigits) << 
                                      PK_Cmd_Length_Shift) | slot7;
   
      /* 19) Construct a command to store v  */
      /*      1       2       3       4       5       6       7       8 
              v      cp       u2      u1      p     yR_mod_p  v3      w
      */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (math_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Store_R | PK_Cmd_SI_Mask;
      ldst_wr_ptr->r_offset = slot1;
      ldst_wr_ptr->data_addr_ls = res_a;
      ldst_wr_ptr->data_length = PK_DSA_Q_Byte_Length;
   

      DBG_PRINT_PK_CMD_BLOCKS("DSA verify",
                              (PK_CMD_BLOCK_t *) req_p->PK_CommandBlock_ptr,
                              N8_CB_DSA_VERIFY_NUMCMDS);
   } while (FALSE);

   return ret;

} /* cb_dsaVerify */
Exemplo n.º 3
0
/** @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 */
Exemplo n.º 4
0
/** @ingroup cb_dsa
 * @brief  Creates the command blocks to compute DSA signature
 *
 *
 *  @param req_p        RW:  Pointer to command
 *                           blocks.  
 *  @param key          RO:  The previously initialized DSAKeyObject
 *                           containing the DSA key
 *                           materials to be used.
 *  @param n_a          RO:  Physical address of random number n.
 *  @param paramBlock_a RO:  Physical address of parameters block.
 *  @param msgHash_a    RO:  Physical address of hash.
 *  @param rValue_a     RO:  Physical address of r value.
 *  @param sValue_a     RO:  Physical address of s value.
 *
 * @return 
 *    ret - returns N8_STATUS_OK if successful or Error value.
 *
 * @par Errors
 *          N8_INVALID_OBJECT   -   command block pointer is NULL<BR>
 *          N8_MALLOC_FAILED    -   memory allocation failed<BR>
 *
 * @par Assumptions
 *    None.<br>
 *****************************************************************************/
N8_Status_t cb_dsaSign(API_Request_t *req_p,
                       const N8_DSAKeyObject_t *key_p,
                       uint32_t n_a,
                       uint32_t paramBlock_a,
                       uint32_t msgHash_a,
                       uint32_t rValue_a,
                       uint32_t sValue_a,
                       PK_CMD_BLOCK_t *cmdBuf_p)
{
   PK_RSA_CMD_BLOCK_t     *math_wr_ptr = NULL;
   PK_LDST_CMD_BLOCK_t    *ldst_wr_ptr = NULL;
   uint32_t                modulusDigits;
   uint32_t                sks_word;
   N8_Status_t             ret = N8_STATUS_OK;

   do
   {
      CHECK_OBJECT(req_p, ret);
      CHECK_OBJECT(key_p, ret);

      modulusDigits = BYTES_TO_PKDIGITS(key_p->modulusLength);

      DBG(("constructing sign command blocks\n"));

      /*  1) Construct a command to load random number n */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) cmdBuf_p;
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = PK_DSA_N_BNC_Offset;
      ldst_wr_ptr->data_addr_ls = n_a;
      ldst_wr_ptr->data_length = PK_DSA_N_Byte_Length;

      /* 2) Construct a command to load hash e1 */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
      ldst_wr_ptr->r_offset = PK_DSA_E1_BNC_Offset;
      ldst_wr_ptr->data_addr_ls = msgHash_a;
      ldst_wr_ptr->data_length = PK_DSA_E1_Byte_Length;

      if (key_p->keyType == N8_PRIVATE_SKS)
      {
         /* we are using the sks.  set the sks_word variable to the correct
          * offset.  We do not need to load the DSA parameter block as it is
          * already in the SKS. */
         sks_word = key_p->SKSKeyHandle.sks_offset;
      }
      else
      {
         /* 3) Construct a command to load the DSA parameter block */
         ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
         ldst_wr_ptr->opcode_si = PK_Cmd_Load_R;
         ldst_wr_ptr->r_offset = PK_DSA_P_BNC_Offset;
         ldst_wr_ptr->data_addr_ls = paramBlock_a;
         ldst_wr_ptr->data_length = PK_DSA_Param_Byte_Length(modulusDigits);

         sks_word = PK_Cmd_N_Mask;
      }

      /* 4) Construct a command for the DSA operation */
      math_wr_ptr = (PK_RSA_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      math_wr_ptr->opcode_si = PK_Cmd_DSA_Sign_Op;
      math_wr_ptr->sks = sks_word | (modulusDigits << PK_Cmd_Key_Length_Shift);
      
      /* 5) Construct a command to store r */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (math_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Store_R;
      ldst_wr_ptr->r_offset = PK_DSA_R_BNC_Offset;
      ldst_wr_ptr->data_addr_ls = rValue_a;
      ldst_wr_ptr->data_length = PK_DSA_R_Byte_Length;

      /* 6) Construct a command to store s */
      ldst_wr_ptr = (PK_LDST_CMD_BLOCK_t *) (ldst_wr_ptr + 1);
      ldst_wr_ptr->opcode_si = PK_Cmd_Store_R | PK_Cmd_SI_Mask;
      ldst_wr_ptr->r_offset = PK_DSA_S_BNC_Offset;
      ldst_wr_ptr->data_addr_ls = sValue_a;
      ldst_wr_ptr->data_length = PK_DSA_S_Byte_Length;
      

      DBG_PRINT_PK_CMD_BLOCKS("DSA sign",
                              req_p->PK_CommandBlock_ptr,
                              N8_CB_DSA_SIGN_NUMCMDS(key_p));
   } while (FALSE);
   return ret;
}