Security_Hks_under huks moduleRkc.c Code Commentary Part VI

Keywords: security

An overview of this article

This is followed by:

After explaining the generation of keys, masking keys, and recovery of key memory, this article will continue with hks_The last part of the rkc.c code about initialization.

Code Framework

hks_rkc.c
│ └── hks_rkc_chk_init_para
│ └── hks_rkc_init_ksf
│ └── hks_rkc_init
│ └── hks_rkc_destroy
│ └── hks_rkc_chk_kek_para
│ └── hks_rkc_get_kek

Code Details

1. hks_rkc_chk_init_para

  • Function function: check initialization parameters
    root key component - check initialization parameter

  • Parameter description: Initialization parameters
    parameter:
    init_para - [in] - initialization parameter.

  • Return value: success or error code
    return value:
    success or error code

Detailed code and comments are as follows:

static int32_t hks_rkc_chk_init_para(const struct hks_rkc_init_para *init_para)
{
    //This function is only used as the check function hks_Rkc_Parameters of init()
    /* This function is only used for the parameter check of hks_rkc_init() */
    //Check the storage type of the root key component
    if ((init_para->storage_type != HKS_RKC_STORAGE_FILE_SYS) &&
        (init_para->storage_type != HKS_RKC_STORAGE_FLASH)) {
        log_error("invalid para,storage_type=%u", init_para->storage_type);
        return HKS_ERROR_INVALID_ARGUMENT;
    }
    //Check the number of iterations for the derived root master key
    if ((init_para->rmk_iter == 0) ||
        (init_para->rmk_iter > HKS_RKC_RMK_ITER_MAX)) {
        log_error("invalid para,rmk_iter=%u", init_para->rmk_iter);
        return HKS_ERROR_INVALID_ARGUMENT;
    }
    //Check if the hash algorithm used by the derived root master key is SHA256
    if (init_para->rmk_hash_alg != HKS_RKC_RMK_HMAC_SHA256) {
        log_error("invalid para,rmk_hash_alg=%u",
            init_para->rmk_hash_alg);
        return HKS_ERROR_INVALID_ARGUMENT;
    }
    //Check the number of keystore files
    if ((init_para->ksf_attr.num == 0) ||
        (init_para->ksf_attr.num > HKS_RKC_KSF_NUM)) {
        log_error("invalid para,num=%u", init_para->ksf_attr.num);
        return HKS_ERROR_INVALID_ARGUMENT;
    }

    return HKS_STATUS_OK;
}

2. hks_rkc_init_ksf

  • Function function: Initialize keystore file
    root key component - initialize

  • Parameter Description: Key Information Existence
    parameter:
    is_key_info_exist - [in] - is key info exist.

  • Return value: success or error code
    return value:
    success or error code

Detailed code and comments are as follows:

static int32_t hks_rkc_init_ksf(int32_t is_key_info_exist)
{
    //Load the root key component data from the keystore file and call the function hks_rkc_load_ksf
    /* load the root key component data from keystore file. */
    int32_t rc = hks_rkc_load_ksf(NULL);//Load keystore file

    //If the keystore file fails to load and no key exists, try to recreate it and call the function hks_rkc_create_ksf
    /*
     * if the keystore file is failed to load and no key is exist,
     * try to recreate it.
     */
    if ((rc != HKS_STATUS_OK) && (is_key_info_exist == HKS_BOOL_FALSE))
        rc = hks_rkc_create_ksf();//Create Key Library File

    return rc;
}

3. hks_rkc_init

  • Functional functions: Initialization (integration)
    root key component - initialize

  • Parameter description: Initialization parameters, key information existence
    parameter:
    init_para - [in] - initialization parameter.
    is_key_info_exist - [in] - is key info exist.

  • Return value: success or error code
    return value:
    success or error code

Detailed code and comments are as follows:

int32_t hks_rkc_init(const struct hks_rkc_init_para *init_para,
    int32_t is_key_info_exist)
{
    //Define root key component initialization parameter structure pointer init_para_inner, and assign
    const struct hks_rkc_init_para *init_para_inner = init_para;

    //Check if the incoming parameter is empty
    if (init_para_inner == NULL)
        init_para_inner = &g_hks_rkc_def_init_para;

    //Check initialization parameters
    int32_t rc = hks_rkc_chk_init_para(init_para_inner);

    if (rc != HKS_STATUS_OK)
        return rc;

    //Check the configuration state of the root key component
    if (g_hks_rkc_cfg.state != HKS_RKC_STATE_INIT)
        return HKS_STATUS_OK;

    //Write log information and assign root key component configuration information
    log_info("RKC init:begin, is_key_info_exist=%d", is_key_info_exist);
    do {
        g_hks_rkc_cfg.state = HKS_RKC_STATE_ON_INIT;
        g_hks_rkc_cfg.version = init_para_inner->version;
        g_hks_rkc_cfg.storage_type = init_para_inner->storage_type;
        g_hks_rkc_cfg.rmk_iter = init_para_inner->rmk_iter;
        g_hks_rkc_cfg.rmk_hash_alg = init_para_inner->rmk_hash_alg;
        g_hks_rkc_cfg.mk_encrypt_alg = init_para_inner->mk_encrypt_alg;
        g_hks_rkc_cfg.kek_hash_alg = init_para_inner->kek_hash_alg;
        g_hks_rkc_cfg.kek_iter = init_para_inner->kek_iter;

        //Initialize properties of keystore file
        /* Initialize the attribute of keystore file */
        rc = hks_rkc_init_ksf_attr(&(init_para_inner->ksf_attr));
        if (rc != HKS_STATUS_OK)
            break;

        //Initialization Entropy
        /* Initialize entropy */
        rc = hks_rkc_init_entropy(init_para_inner->entropy,
            init_para_inner->entropy_len);
        if (rc != HKS_STATUS_OK)
            break;

        //Initialize the root key component of the keystore file
        /* Initialize the keystore file of root key component. */
        rc = hks_rkc_init_ksf(is_key_info_exist);
        if (rc != HKS_STATUS_OK)
            break;

        g_hks_rkc_cfg.state = HKS_RKC_STATE_RUNNING;
        log_info("root key component init success");
    } while (0);

    //Destroy memory space to ensure key security
    if (rc != HKS_STATUS_OK) {
        g_hks_rkc_cfg.state = HKS_RKC_STATE_FAIL;
        hks_rkc_destroy();
    }
    log_info("RKC init:end,rc=%d", rc);

    return rc;
}

4. hks_rkc_destroy

  • Function function: Destroy work
    root key component - destory

  • No Passage
    parameter: none

  • No return value
    return value: none

Detailed code and comments are as follows:

void hks_rkc_destroy(void)
{
    //Change root key component configuration state to deleted state
    g_hks_rkc_cfg.state = HKS_RKC_STATE_ON_DEL;

    uint32_t i = 0;

    //Securely delete part of keystore file property name
    for (; i < HKS_RKC_KSF_NUM; ++i)
        hks_file_del_s(g_hks_rkc_cfg.ksf_attr.name[i]);

    //Clear memory space
    hks_rkc_clear_mem();
}

5. hks_rkc_clear_mem

  • Function function: Clean up memory
    root key component - clear memory

  • No Passage
    parameter: none

  • No return value
    return value: none

Detailed code and comments are as follows:

void hks_rkc_clear_mem(void)
{
    uint32_t i = 0;

    //Release of all keystore file spaces requested
    for (; i < HKS_RKC_KSF_NUM; ++i)
        hks_free_ptr(g_hks_rkc_cfg.ksf_attr.name[i]);

    //Release of Entropy
    hks_free_ptr(g_hks_rkc_cfg.entropy);

    //Zero information in the configuration of the root component
    (void)memset_s(&g_hks_rkc_cfg, sizeof(g_hks_rkc_cfg), 0,
        sizeof(g_hks_rkc_cfg));

    //Zero master key memory space information for root key component
    (void)memset_s(&g_hks_rkc_mk, sizeof(g_hks_rkc_mk), 0,
        sizeof(g_hks_rkc_mk));
}

6. hks_rkc_chk_kek_para

  • Function function: Check parameters of key encryption key
    root key component - check the parameter of key-encrypting key

  • Parameter Description: Salinized Value, Key Encryption Key
    parameter:
    salt - [in] - salt,
    kek - [in] - key-encrypting key,

  • Return value: success or failure code
    return value:
    success or error code

Detailed code and comments are as follows:

static int32_t hks_rkc_chk_kek_para(const struct hks_blob *salt,
    const struct hks_blob *kek)
{
    //Check if salinization value is empty
    if (salt == NULL) {
        log_error("invalid salt");
        return HKS_ERROR_NULL_POINTER;
    }
    //Check for data within salinization values
    if (salt->data == NULL) {
        log_error("invalid salt data");
        return HKS_ERROR_NULL_POINTER;
    }
    //Check for compliance with salinization values
    if ((salt->size > HKS_RKC_KEK_SALT_LEN_MAX) ||
        (salt->size < HKS_RKC_KEK_SALT_LEN_MIN)) {
        log_error("invalid salt size=%u", salt->size);
        return HKS_ERROR_INVALID_ARGUMENT;
    }

    //Check if the key encryption key is empty
    if (kek == NULL) {
        log_error("invalid kek");
        return HKS_ERROR_NULL_POINTER;
    }
    //Check if the key encryption key has data
    if (kek->data == NULL) {
        log_error("invalid kek data");
        return HKS_ERROR_NULL_POINTER;
    }
    //Check key encryption key size compliance
    if (kek->size != HKS_RKC_KEK_LEN) {
        log_error("invalid kek size=%u", kek->size);
        return HKS_ERROR_INVALID_ARGUMENT;
    }

    return HKS_STATUS_OK;
}

7. hks_rkc_get_kek

  • Function function: Get key encryption key
    root key component - get the key-encrypting key

  • Parameter description: Salinization value (input), Key encryption key (output)
    parameter:
    salt - [in] - salt,
    kek - [out] - key-encrypting key, it must be cleared by caller after use.

  • Return value: success or error code
    return value:
    success or error code

Detailed code and comments are as follows:

int32_t hks_rkc_get_kek(const struct hks_blob *salt, struct hks_blob *kek)
{
    //Check if the master key is valid
    if (g_hks_rkc_mk.is_valid == HKS_BOOL_FALSE) {
        log_error("mk is valid");
        return HKS_ERROR_INVALID_KEY_FILE;
    }

    //Check key encryption key parameters
    int32_t rc = hks_rkc_chk_kek_para(salt, kek);

    if (rc != HKS_STATUS_OK)
        return rc;

    //Define master key structure
    struct hks_blob mk;

    //Initialization of master key
    rc = hks_blob_init(&mk, sizeof(uint8_t), HKS_RKC_MK_LEN,
        HKS_BLOB_TYPE_KEY);
    if (rc != HKS_STATUS_OK)
        return rc;

    //Define and initialize the master key mask and the master key with the master key mask
    struct hks_blob mk_mask = { HKS_BLOB_TYPE_KEY, g_hks_rkc_cfg.mk_mask, HKS_RKC_MK_LEN };
    struct hks_blob mk_with_mask = { HKS_BLOB_TYPE_KEY, g_hks_rkc_mk.mk_with_mask, HKS_RKC_MK_LEN };

    //Mask movement, using XOR to set mk_with_mask and mk_The mask XOR result is stored in the master key MK
    /* remove mask */
    hks_xor(&mk_with_mask, &mk_mask, &mk);

    //Using pbkdf2_hmac algorithm to obtain derived key
    /* derive kek with PBKDF2-HMAC */
    rc = hks_rkc_pbkdf2_hmac(g_hks_rkc_cfg.kek_hash_alg, &mk, salt,
        g_hks_rkc_cfg.kek_iter, kek);

    //Destroy master key memory space
    hks_blob_destroy(&mk);

    return rc;
}

This summary

All the algorithms, definitions and operation-related functions of root key components have been explained. Welcome to read and comment!

Posted by Niko on Fri, 03 Sep 2021 13:37:17 -0700