security_huks模块下hks_rkc.c代码评注第二部分
本篇综述
本篇是hks_rkc.c代码评注的第二部分,在security_huks模块下hks_rkc.c代码评注第一部分的基础上,进一步讲解在hks_rkc.c中从密钥库文件缓冲区提取部分信息以及读取全部信息的方法。
本篇代码架构
hks_rkc.c
├── extract
│ └── hks_rkc_extract_ksf_file_flag
│ └── hks_rkc_extract_ksf_hash
│ └── hks_rkc_extract_ksf_rk
│ └── hks_rkc_extract_ksf_mk
│ └── hks_rkc_extract_ksf_buf
├── read
│ └── hks_rkc_read_ksf
│ └── hks_rkc_read_all_ksf
关键信息提取
本部分共有5个重要的函数,都是关于根密钥组件的密钥库文件关键信息的提取,需要特别强调的一点是:信息提取源在ksf_buf中即密钥库文件缓冲区中。与填入的操作相对应,填入是将ksf_data中的数据填写到ksf_buf中,提取是从ksf_buf从提取信息到ksf_data 或其他定义的变量中。
1.hks_rkc_extract_ksf_file_flag
-
函数功能:从ksf的缓冲区中提取ksf文件标记
root key component - extract ksf file flag from keystore file buffer -
参数说明:密钥库文件缓冲区、密钥库文件缓冲区大小、密钥库文件偏移量大小
parameter:
ksf_buf - [in] - the buffer of keystore file.
ksf_buf_len - [out] - the length of keystore file buffer.
ksf_buf_offset - [in,out] - the offset of keystore file buffer. -
返回值:成功或错误代码
return value:
success or error code
代码如下:
static int32_t hks_rkc_extract_ksf_file_flag(const uint8_t *ksf_buf,
uint32_t ksf_buf_len, uint32_t *ksf_buf_offset)
{
//先定义并初始化文件标志位00000000
uint8_t file_flag[HKS_RKC_KSF_FLAG_LEN] = {0};
//调用函数hks_u8_buf_2_u8_array函数,提取文件标志,提取内容存取在file_flag中
/* Extract file flag. */
int32_t rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len,
ksf_buf_offset,
file_flag, HKS_RKC_KSF_FLAG_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//检查密钥库文件标志
/* Check file flag. */
if (memcmp(file_flag, g_hks_rkc_ksf_flag, HKS_RKC_KSF_FLAG_LEN)) {
log_error("ksf file flag is invalid");
return HKS_ERROR_READ_FILE_FAIL;
}
return HKS_STATUS_OK;
}
2.hks_rkc_extract_ksf_hash
-
函数功能:从密钥库文件缓冲区提取散列字段
root key component - extract hash field from keystore file buffer -
参数说明:密钥库文件缓冲区、密钥库文件缓冲区大小、密钥库文件偏移量大小
parameter:
ksf_buf - [in] - the buffer of keystore file.
ksf_buf_len - [out] - the length of keystore file buffer.
ksf_buf_offset - [in,out] - the offset of keystore file buffer. -
返回值:成功或错误代码
return value:
success or error code
代码如下:
static int32_t hks_rkc_extract_ksf_hash(uint8_t *ksf_buf, uint32_t ksf_buf_len,
uint32_t *ksf_buf_offset)
{
//密钥库文件缓冲区中散列字段、hash散列结果的初始化
uint8_t ksf_hash[HKS_RKC_HASH_LEN] = {0};
uint8_t hash_result[HKS_RKC_HASH_LEN] = {0};
struct hks_blob hash_src = { 0, NULL, 0 };
struct hks_blob hash = { 0, NULL, 0 };
/* 利用SHA256计算hash散列值
* calculate SHA256
* skip file flag, begin with version, end with reserve field.
*/
//hash源和hash结果的数据开始位置的设置和数据大小的设置
hash_src.data = ksf_buf + HKS_RKC_KSF_FLAG_LEN;
hash_src.size = *ksf_buf_offset - HKS_RKC_KSF_FLAG_LEN;
hash.data = hash_result;
hash.size = HKS_RKC_HASH_LEN;
//调用hks_calc_sha256算法求取hash散列结果
int32_t rc = hks_calc_sha256(&hash_src, HKS_RKC_KSF_HASH_SRC_NUM,
&hash);
if (rc != HKS_STATUS_OK)
return rc;
//从ksf缓冲区中提取ksf_hash的结果
/* Extract hash from ksf buffer */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_hash, HKS_RKC_HASH_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//检查提取结果与hash_result是否一致
/* Check hash result. */
if (memcmp(hash_result, ksf_hash, HKS_RKC_HASH_LEN)) {
log_error("ksf hash result is invalid");
return HKS_ERROR_INVALID_KEY_FILE;
}
return HKS_STATUS_OK;
}
3.hks_rkc_extract_ksf_rk
-
函数功能:从密钥库文件缓冲区中提取根密钥数据放入ksf_data中
root key component - extract root key data from keystore file buffer -
传入参数:密钥库文件缓冲区、密钥库文件缓冲区大小、密钥库文件偏移量大小、密钥库文件数据结构体变量
parameter:
ksf_buf - [in] - the buffer of keystore file.
ksf_buf_len - [in] - the buffer length of keystore file.
ksf_buf_offset - [in,out] - the buffer offset of keystore file.
ksf_data - [out] - the data of keystore file. -
返回值:成功或错误代码
return value:
success or error code
代码如下:
static int32_t hks_rkc_extract_ksf_rk(const uint8_t *ksf_buf,
uint32_t ksf_buf_len, uint32_t *ksf_buf_offset,
struct hks_rkc_ksf_data *ksf_data)
{
//提取根密钥版本号
/* Extract version. */
int32_t rc = hks_u8_buf_2_u16(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->version));
if (rc != HKS_STATUS_OK)
return rc;
//提取根密钥创建时间
/* Extract rk_creat_time */
rc = hks_u8_buf_2_time(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->rk_created_time));
if (rc != HKS_STATUS_OK)
return rc;
//提取根密钥过期时间
/* Extract rk_expired_time */
rc = hks_u8_buf_2_time(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->rk_expired_time));
if (rc != HKS_STATUS_OK)
return rc;
//提取第一个材料
/* Extract the first material */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->rk_material1, HKS_RKC_MATERIAL_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//提取第二个材料
/* Extract the second material */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->rk_material2, HKS_RKC_MATERIAL_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//提取派生根主密钥(键)的迭代次数
/* Extract iterator number */
rc = hks_u8_buf_2_u32(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->rmk_iter));
if (rc != HKS_STATUS_OK)
return rc;
//提取派生根主密钥的椒盐化参数
/* Extract salt */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->rmk_salt, HKS_RKC_SALT_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//提取派生根主密钥(键)使用的hash算法信息
/* Extract hash algorithm */
rc = hks_u8_buf_2_u32(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->rmk_hash_alg));
if (rc != HKS_STATUS_OK)
return rc;
//提取根密钥保留数据
/* Extract reserve field */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->rk_rsv, sizeof(ksf_data->rk_rsv));
if (rc != HKS_STATUS_OK)
return rc;
return rc;
}
4.hks_rkc_extract_ksf_mk
-
从密钥库文件缓冲区中提取主密钥数据放入ksf_data中
root key component - extract master key data from keystore file buffer -
参数说明:密钥库文件缓冲区、密钥库文件缓冲区大小、密钥库文件偏移量大小、密钥库文件数据结构体变量
parameter:
ksf_buf - [in] - the buffer of keystore file.
ksf_buf_len - [in] - the buffer length of keystore file.
ksf_buf_offset - [in,out] - the buffer offset of keystore file.
ksf_data - [out] - the data of keystore file. -
返回值:成功或错误代码
return value:
success or error code
代码如下:
static int32_t hks_rkc_extract_ksf_mk(const uint8_t *ksf_buf,
uint32_t ksf_buf_len, uint32_t *ksf_buf_offset,
struct hks_rkc_ksf_data *ksf_data)
{
//提取主密钥创建时间
/* Extract mk_created_time */
int32_t rc = hks_u8_buf_2_time(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->mk_created_time));
if (rc != HKS_STATUS_OK)
return rc;
//提取主密钥过期时间
/* Fill mk_expired_time */
rc = hks_u8_buf_2_time(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->mk_expired_time));
if (rc != HKS_STATUS_OK)
return rc;
//提取主密钥使用的加密算法
/* Fill encrption algorithm */
rc = hks_u8_buf_2_u32(ksf_buf, ksf_buf_len, ksf_buf_offset,
&(ksf_data->mk_encrypt_alg));
if (rc != HKS_STATUS_OK)
return rc;
//提取主密钥的IV
/* Fill IV */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->mk_iv, HKS_RKC_MK_IV_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//提取主密钥的密文
/* Fill ciphertext */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->mk_ciphertext, HKS_RKC_MK_CIPHERTEXT_LEN);
if (rc != HKS_STATUS_OK)
return rc;
//提取主密钥保留数据
/* Fill reserve field */
rc = hks_u8_buf_2_u8_array(ksf_buf, ksf_buf_len, ksf_buf_offset,
ksf_data->mk_rsv, sizeof(ksf_data->mk_rsv));
if (rc != HKS_STATUS_OK)
return rc;
return rc;
}
5. hks_rkc_extract_ksf_buf
-
函数功能:利用函数的调用从密钥库文件缓冲区中提取数据写入ksf_data中(功能封装)
root key component - extract data from keystore file buffer -
参数说明:密钥库文件缓冲区、密钥库文件缓冲区大小、密钥库文件数据结构体变量
parameter:
ksf_buf - [in] - the buffer of keystore file.
ksf_buf_len - [in] - the buffer length of keystore file.
ksf_data - [out] - the data of keystore file. -
返回值:成功或错误代码
return value:
success or error code
代码如下:
static int32_t hks_rkc_extract_ksf_buf(uint8_t *ksf_buf, uint32_t ksf_buf_len,
struct hks_rkc_ksf_data *ksf_data)
{
uint32_t ksf_buf_offset = 0;
//函数封装,提取密钥库文件标志
/* Extract file flag. */
int32_t rc = hks_rkc_extract_ksf_file_flag(ksf_buf, ksf_buf_len,
&ksf_buf_offset);
if (rc != HKS_STATUS_OK)
return rc;
//函数封装,提取根密钥数据
/* Extract root key data */
rc = hks_rkc_extract_ksf_rk(ksf_buf, ksf_buf_len, &ksf_buf_offset,
ksf_data);
if (rc != HKS_STATUS_OK)
return rc;
//函数封装,提取主密钥数据
/* Extract master key data */
rc = hks_rkc_extract_ksf_mk(ksf_buf, ksf_buf_len, &ksf_buf_offset,
ksf_data);
if (rc != HKS_STATUS_OK)
return rc;
//函数封装,提取hash散列数据
/* Extract hash */
rc = hks_rkc_extract_ksf_hash(ksf_buf, ksf_buf_len, &ksf_buf_offset);
if (rc != HKS_STATUS_OK)
return rc;
return HKS_STATUS_OK;
}
读取密钥库文件
与从密钥库文件中提取信息、填充信息到缓冲区不同,读取密钥库文件的输入参数关键在ksf_name即密钥库文件名(地址)上,读取操作需要先把信息填充到缓冲区上,再通过提取缓冲区上的信息写入ksf_data中,因此读取是两步操作的结合。
1.hks_rkc_read_ksf
-
函数功能:读取密钥库文件信息, 将在地址ksf_name下读到的密钥库文件信息写入ksf_data下
root key component - read keystore file -
参数说明:密钥库文件名、密钥库文件数据结构体变量
parameter:
ksf_name - [in] - keystore filename.
ksf_data - [out] - the data of keystore file. -
返回值:成功或错误代码
return value:
success or error code
需要注意的是文件大小的检查、缓冲区空间的开辟、信息的循环读取、以及密钥读取缓冲区空间的清理与释放,代码及详细注释如下:
static int32_t hks_rkc_read_ksf(const char *ksf_name,
struct hks_rkc_ksf_data *ksf_data)
{
uint32_t file_size = 0;
//用file_size记录文件存储大小
int32_t rc = hks_file_size(ksf_name, &file_size);
//检查是否成功获取文件大小
if (rc != HKS_STATUS_OK) {
log_error("get ksf file size fail,name=%s,rc=%d", ksf_name, rc);
return HKS_ERROR_INVALID_KEY_FILE;
}
//检查文件大小,正常情况下的文件大小一定比预定义缓冲区最大空间要大
/* check the file size. */
if (file_size < HKS_RKC_KSF_BUF_LEN) {
log_error("file size is invalid,name=%s,size=%u",
ksf_name, file_size);
return HKS_ERROR_INVALID_KEY_FILE;
}
//申请密钥库文件缓冲区
uint8_t *ksf_buf = (uint8_t *)HKS_MALLOC(HKS_RKC_KSF_BUF_LEN);
if (ksf_buf == NULL) {
log_error("malloc ksf buffer fail");
return HKS_ERROR_MALLOC_FAIL;
}
//在使用前清理密钥库缓冲区数据
/* Clear buffer data before using it. */
(void)memset_s(ksf_buf, HKS_RKC_KSF_BUF_LEN, 0, HKS_RKC_KSF_BUF_LEN);
//不断循环进行读写操作
do {
int32_t ksf_real_len = 0;
//读取文件信息,将ksf_name地址下的信息读入ksf_buf中并且在ksf_real_len中记录读取到文件的真实长度
rc = hks_file_read(ksf_name, HKS_FILE_OFFSET_BASE, ksf_buf,
HKS_RKC_KSF_BUF_LEN, &ksf_real_len);
if (rc != HKS_STATUS_OK) {
log_error("read ksf file fail,name=%s,rc=%d",
ksf_name, rc);
break;
}
if (ksf_real_len != HKS_RKC_KSF_BUF_LEN) {
log_error("real length is invalid,name=%s,real_len=%d",
ksf_name, ksf_real_len);
rc = HKS_ERROR_INVALID_KEY_FILE;
break;
}
//调用函数hks_rkc_extract_ksf_buf,将ksf_buf中的数据提取出来写入ksf_data中
rc = hks_rkc_extract_ksf_buf(ksf_buf, ksf_real_len, ksf_data);
if (rc != HKS_STATUS_OK) {
log_error("extract ksf file fail,name=%s,rc=%d",
ksf_name, rc);
break;
}
} while (0);
//根密钥数据在使用完后需要被清理
/* the data of root key should be cleared after use */
(void)memset_s(ksf_buf, HKS_RKC_KSF_BUF_LEN, 0, HKS_RKC_KSF_BUF_LEN);//将ksf_buf中的数据清0,接着释放ksf_buf的空间
hks_free_ptr(ksf_buf);
//检查上面一系列操作的状态
if (rc != HKS_STATUS_OK)
return HKS_ERROR_INVALID_KEY_FILE;
return HKS_STATUS_OK;
}
2.hks_rkc_read_all_ksf
在读取单个密钥库文件信息的基础上,本函数将介绍读取所有密钥库文件的操作方法。
-
函数功能:读取所有的密钥库文件
root key component - read all keystore files. -
参数说明:所有密钥库文件状态、所有密钥库文件数据、第一个有效数据、第一个有效数据的索引
parameter:
all_ksf_rc - [out] - all reture code.
all_ksf_data - [out] - all data.
valid_ksf_data - [out] - the first valid data.
valid_ksf_index - [out] - the index of first valid data. -
返回值:成功或错误代码
return value:
success or error code
需要注意的是在外层加入一个关于密钥库文件数的循环,详细代码及注释如下:
static int32_t hks_rkc_read_all_ksf(int32_t *all_ksf_rc,
struct hks_rkc_ksf_data *all_ksf_data,
struct hks_rkc_ksf_data **valid_ksf_data, uint32_t *valid_ksf_index)
{
//检查根密钥组件密钥库文件数是否超过预定义的密钥库文件最大个数
if (g_hks_rkc_cfg.ksf_attr.num > HKS_RKC_KSF_NUM) {
log_error("invalid ksf num=%u", g_hks_rkc_cfg.ksf_attr.num);
return HKS_ERROR_INTERNAL_UNKOWN;
}
//定义根密钥组件密钥库文件数
uint32_t i = 0;
/* Read all ksf */
for (; i < g_hks_rkc_cfg.ksf_attr.num; ++i) {
if (g_hks_rkc_cfg.ksf_attr.name[i] == NULL)
continue;
//依次读取根密钥组件的密钥库文件内容,将其写入all_ksf_data[]数组中,并记录读取状态到all_ksf_rc[]数组中
all_ksf_rc[i] = hks_rkc_read_ksf(g_hks_rkc_cfg.ksf_attr.name[i],
&(all_ksf_data[i]));
if (all_ksf_rc[i] != HKS_STATUS_OK)
continue;
//记录第一组有效数据的地址位置,并且记录其索引
if (*valid_ksf_data == NULL) {
/* the first valid ksf is found, save flag and index. */
*valid_ksf_data = &(all_ksf_data[i]); //赋值法
*valid_ksf_index = i;
}
}
//返回函数成功执行状态
return HKS_STATUS_OK;
}
本篇小结
本篇主要讲解了从密钥库文件缓冲区提取部分信息以及读取全部信息的方法,下面我们将继续更新有关hks_rkc.c代码评注的第三部分和第四部分,敬请期待!