Logo Search packages:      
Sourcecode: linux version File versions

static fsl_shw_return_t wrap ( fsl_shw_uco_t user_ctx,
fsl_shw_sko_t key_info,
uint8_t *  black_key 
) [static]

Perform wrapping of a black key from a RED slot

Parameters:
user_ctx A user context from fsl_shw_register_user().
[in,out] key_info The information about the key to be which will be wrapped... key length, slot info, etc.
black_key Place to store encrypted key
Returns:
A return code of type fsl_shw_return_t.

Definition at line 414 of file fsl_shw_wrap.c.

References fsl_shw_sko_t::algorithm, create_icv_calc(), DESC_IN_KEY, DESC_KEY_OUT, fsl_shw_sko_t::flags, FSL_CTR_MOD_128, FSL_HASH_ALG_SHA256, FSL_KEY_ALG_AES, FSL_KEY_ALG_HMAC, FSL_RETURN_OK_S, fsl_shw_sko_set_key_length, FSL_SKO_KEY_SW_KEY, FSL_SYM_MODE_CTR, fsl_shw_sko_t::handle, fsl_shw_sko_t::key_length, fsl_shw_sko_t::keystore, keystore_slot_alloc(), keystore_slot_dealloc(), keystore_slot_encrypt(), keystore_slot_load(), LOG_DIAG, fsl_shw_uco_t::mem_util, sah_Append_Desc(), sah_Append_Link(), sah_Create_Key_Link(), SAH_HDR_MDHA_SET_MODE_HASH, SAH_HDR_RNG_GENERATE, SAH_HDR_SKHA_ENC_DEC, SAH_HDR_SKHA_SET_MODE_IV_KEY, sah_insert_mdha_algorithm, sah_insert_skha_algorithm, sah_insert_skha_mode, sah_insert_skha_modulus, SAH_USES_LINK_DATA, and fsl_shw_sko_t::userid.

Referenced by fsl_shw_extract_key().

{
      SAH_SF_DCLS;
      unsigned slots_allocated = 0; /* boolean */
      fsl_shw_sko_t T_key_info;     /* for holding T */
      fsl_shw_sko_t KEK_key_info;   /* for holding KEK */
      unsigned original_key_length = key_info->key_length;
      unsigned rounded_key_length;
      sah_Link *link1;
      sah_Link *link2;

      black_key[LENGTH_OFFSET] = key_info->key_length;
      black_key[ALGORITHM_OFFSET] = key_info->algorithm;

      memcpy(&T_key_info, key_info, sizeof(T_key_info));
      fsl_shw_sko_set_key_length(&T_key_info, T_LENGTH);
      T_key_info.algorithm = FSL_KEY_ALG_HMAC;

      memcpy(&KEK_key_info, &T_key_info, sizeof(KEK_key_info));
      KEK_key_info.algorithm = FSL_KEY_ALG_AES;

      if (key_info->keystore == NULL) {
            /* Key goes in system keystore */
            ret = do_system_keystore_slot_alloc(user_ctx,
                        T_LENGTH, key_info->userid,
                      &T_key_info.handle);
      
      } else {
            /* Key goes in user keystore */
            ret = keystore_slot_alloc(key_info->keystore,
                          T_LENGTH,
                          key_info->userid, &T_key_info.handle);
      }
      if (ret != FSL_RETURN_OK_S) {
            goto out;
      }

      if (key_info->keystore == NULL) {
            /* Key goes in system keystore */
            ret = do_system_keystore_slot_alloc(user_ctx,
                        KEK_LENGTH, key_info->userid,
                        &KEK_key_info.handle);
            
      } else {
            /* Key goes in user keystore */
            ret = keystore_slot_alloc(key_info->keystore,
                    KEK_LENGTH,  key_info->userid, 
                    &KEK_key_info.handle);
      }

      if (ret != FSL_RETURN_OK_S) {
#ifdef DIAG_SECURITY_FUNC
            LOG_DIAG("do_scc_slot_alloc() failed");
#endif
            if (key_info->keystore == NULL) {
                  /* Key goes in system keystore */
                  (void)do_system_keystore_slot_dealloc(user_ctx,
                        key_info->userid, T_key_info.handle);
      
            } else {
                  /* Key goes in user keystore */
                  (void)keystore_slot_dealloc(key_info->keystore,
                              key_info->userid, T_key_info.handle);
            }
      } else {
            slots_allocated = 1;
      }

      /* Set up to compute everything except T' ... */
#ifndef DO_REPEATABLE_WRAP
      /* Compute T = RND() */
      header = SAH_HDR_RNG_GENERATE;      /* Desc. #18 */
      DESC_KEY_OUT(header, &T_key_info, 0, NULL);
#else
      if (key_info->keystore == NULL) {
            /* Key goes in system keystore */
            ret = do_system_keystore_slot_load(user_ctx,
                     T_key_info.userid,
                     T_key_info.handle, T_block,
                     T_key_info.key_length);
      } else {
            /* Key goes in user keystore */
            ret = keystore_slot_load(key_info->keystore,
                         T_key_info.userid,
                         T_key_info.handle,
                         T_block, T_key_info.key_length);
      }

      if (ret != FSL_RETURN_OK_S) {
            goto out;
      }
#endif

      /* Compute KEK = SHA256(T | Ownerid) */
      header = (SAH_HDR_MDHA_SET_MODE_HASH      /* #8 */
              ^ sah_insert_mdha_init
              ^ sah_insert_mdha_algorithm[FSL_HASH_ALG_SHA256]
              ^ sah_insert_mdha_pdata);
      /* Input - Start with T */
      ret = sah_Create_Key_Link(user_ctx->mem_util, &link1, &T_key_info);
      if (ret != FSL_RETURN_OK_S) {
            goto out;
      }
      /* Still input - append ownerid */
      ret = sah_Append_Link(user_ctx->mem_util, link1,
                        (void *)&key_info->userid,
                        sizeof(key_info->userid), SAH_USES_LINK_DATA);
      if (ret != FSL_RETURN_OK_S) {
            goto out;
      }
      /* Output - KEK goes into RED slot */
      ret = sah_Create_Key_Link(user_ctx->mem_util, &link2, &KEK_key_info);
      if (ret != FSL_RETURN_OK_S) {
            goto out;
      }
      /* Put the Hash calculation into the chain. */
      ret = sah_Append_Desc(user_ctx->mem_util, &desc_chain,
                        header, link1, link2);
      if (ret != FSL_RETURN_OK_S) {
            goto out;
      }
#if defined(NEED_CTR_WORKAROUND)
      rounded_key_length = ROUND_LENGTH(original_key_length);
      key_info->key_length = rounded_key_length;
#else
      rounded_key_length = original_key_length;
#endif
      /* Compute KEY' = AES-encrypt(KEK, KEY) */
      header = (SAH_HDR_SKHA_SET_MODE_IV_KEY    /* #1 */
              ^ sah_insert_skha_mode[FSL_SYM_MODE_CTR]
              ^ sah_insert_skha_algorithm[FSL_KEY_ALG_AES]
              ^ sah_insert_skha_modulus[FSL_CTR_MOD_128]);
      /* Set up KEK as key to use */
      DESC_IN_KEY(header, 0, NULL, &KEK_key_info);
      header = SAH_HDR_SKHA_ENC_DEC;
      DESC_KEY_OUT(header, key_info,
                 key_info->key_length, black_key + KEY_PRIME_OFFSET);

      /* Set up flags info */
      black_key[FLAGS_OFFSET] = 0;
      if (key_info->flags & FSL_SKO_KEY_SW_KEY) {
            black_key[FLAGS_OFFSET] |= FLAGS_SW_KEY;
      }

      /* Compute and store ICV into Black Key */
      ret = create_icv_calc(user_ctx, &desc_chain, &T_key_info,
                        black_key, original_key_length,
                        black_key + ICV_OFFSET);
      if (ret != FSL_RETURN_OK_S) {
#ifdef DIAG_SECURITY_FUNC
            LOG_DIAG("Creation of sah_Key_Link failed due to bad key"
                   " flag!\n");
#endif                        /*DIAG_SECURITY_FUNC */
            goto out;
      }

      /* Now get Sahara to do the work. */
#ifdef DIAG_SECURITY_FUNC
      LOG_DIAG("Encrypting key with KEK");
#endif
      SAH_SF_EXECUTE();
      if (ret != FSL_RETURN_OK_S) {
#ifdef DIAG_SECURITY_FUNC
            LOG_DIAG("sah_Descriptor_Chain_Execute() failed");
#endif
            goto out;
      }

      /* Compute T' = SLID_encrypt(T); Result goes to Black Key */
      if (key_info->keystore == NULL) {
            /* Key goes in system keystore */
            ret = do_system_keystore_slot_encrypt(user_ctx,
                              T_key_info.userid,  T_key_info.handle,
                              T_LENGTH, black_key + T_PRIME_OFFSET);
      } else {
            /* Key goes in user keystore */
            ret = keystore_slot_encrypt(user_ctx,
                                  key_info->keystore,
                                  T_key_info.userid,
                                  T_key_info.handle,
                                  T_LENGTH,
                                  black_key + T_PRIME_OFFSET);
      }

      if (ret != FSL_RETURN_OK_S) {
#ifdef DIAG_SECURITY_FUNC
            LOG_DIAG("do_scc_slot_encrypt() failed");
#endif
            goto out;
      }

      out:
      key_info->key_length = original_key_length;

      SAH_SF_DESC_CLEAN();
      if (slots_allocated) {
            if (key_info->keystore == NULL) {
                  /* Key goes in system keystore */
                  (void)do_system_keystore_slot_dealloc(user_ctx,
                                                key_info->userid,
                                                T_key_info.
                                                handle);
                  (void)do_system_keystore_slot_dealloc(user_ctx,
                                                key_info->userid,
                                                KEK_key_info.
                                                handle);
            } else {
                  /* Key goes in user keystore */
                  (void)keystore_slot_dealloc(key_info->keystore,
                                        key_info->userid,
                            T_key_info.handle);
                  (void)keystore_slot_dealloc(key_info->keystore,
                            key_info->userid,
                            KEK_key_info.handle);
          }
      }     

      return ret;
}                       /* wrap */


Generated by  Doxygen 1.6.0   Back to index