kdf算法介绍以及hks_mbedtls_kdf.c代码分析
一、算法介绍
kdf是一种密钥派生函数,全称Key Derivation Function。密钥派生函数的作用是从一个共享的秘密比特串中派生出密钥数据。在密钥协商过程中,密钥派生函数作用在密钥交换所获共享的秘密比特串上,从中产生所需的会话密钥或进一步加密的密钥数据。
函数的输入:一个比特串z,以及要获得的密钥的比特长度klen。
输出:长度为klen的密钥数据比特串。
其中一种变形形式为hkdf算法。(hmac+kdf)
参考文章:
二、代码分析
pbkdf算法的实现。传入一个比特串密钥,生成一个指定长度的密钥串存放进derivedKey。
参数详解:
- mainkey:原始的输入信息,存放输入
- derparam:存放要生成的派生密钥的参数
- info:存放信息
- derivedKey:最后派生结果的存放
//pbkdf2算法的实现
static int32_t DeriveKeyPbkdf2(const struct HksBlob *mainKey, const struct HksKeyDerivationParam *derParam,
const mbedtls_md_info_t *info, struct HksBlob *derivedKey)
{
mbedtls_md_context_t ctx;
mbedtls_md_init(&ctx);
int32_t ret;
do {
ret = mbedtls_md_setup(&ctx, info, 1); /* 1 for using HMAC */
//选择MD使用和分配内部结构
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls md setup failed! mbedtls ret = 0x%X", ret);
break;
}
ret = mbedtls_pkcs5_pbkdf2_hmac(&ctx, mainKey->data, mainKey->size, derParam->salt.data,
derParam->salt.size, derParam->iterations, derivedKey->size, derivedKey->data);
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls pbkdf2 failed! mbedtls ret = 0x%X", ret);
(void)memset_s(derivedKey->data, derivedKey->size, 0, derivedKey->size);
}
} while (0);
mbedtls_md_free(&ctx);
return ret;
}
#endif /* HKS_SUPPORT_KDF_PBKDF2 */
HKDF算法 = Hmac + KDF
HMAC是指Hash-based的MAC算法,hash函数是可选的,例如存在这些HMAC实现:
- HMAC_MD5
- HMAC_SHA1
- HMAC_SHA256
KDF算法由上面已经介绍。
函数的参数介绍:
- mainkey:原始的输入信息,存放输入
- derparam:存放要生成的派生密钥的参数
- info:存放信息
- derivedKey:最后派生结果的存放
#ifdef HKS_SUPPORT_KDF_HKDF
//hkdf算法实现
static int32_t DeriveKeyHkdf(const struct HksBlob *mainKey, const struct HksKeyDerivationParam *derParam,
const mbedtls_md_info_t *info, struct HksBlob *derivedKey)
{
int32_t ret = mbedtls_hkdf(info, derParam->salt.data, derParam->salt.size, mainKey->data, mainKey->size,
derParam->info.data, derParam->info.size, derivedKey->data, derivedKey->size);
//这是基于hmac的提取和展开键推导函数。输入由mainkey完成,将最终结果写进derivedKey
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls hkdf failed! mbedtls ret = 0x%X", ret);
(void)memset_s(derivedKey->data, derivedKey->size, 0, derivedKey->size);
}
return ret;
}
#endif /* HKS_SUPPORT_KDF_HKDF */
密钥派生函数的封装(分支结构选取)
该部分实现kdf算法和hkdf算法的封装,根据不同情况选择不同算法实现密钥的派生。
参数详解
- mainkey:原始的输入信息,存放输入
- derivationSpec:派生密钥的相关特定信息、如派生算法名称等等
- derivedKey:最后派生结果的存放
//密钥的派生
int32_t HksMbedtlsDeriveKey(const struct HksBlob *mainKey,
const struct HksKeySpec *derivationSpec, struct HksBlob *derivedKey)
{
const struct HksKeyDerivationParam *derParam = (struct HksKeyDerivationParam *)(derivationSpec->algParam);
uint32_t mbedtlsAlg;
int32_t ret = HksToMbedtlsDigestAlg(derParam->digestAlg, &mbedtlsAlg);
//将hks对应的mbedlts算法名写进mbedtlsAlg
if (ret != HKS_SUCCESS) {
return ret;
}
const mbedtls_md_info_t *info = mbedtls_md_info_from_type(mbedtlsAlg);
//获取算法md信息
if (info == NULL) {
HKS_LOG_E("Mbedtls get md info failed! mbedtls ret = 0x%X", ret);
return HKS_FAILURE;
}
switch (derivationSpec->algType) {
//根据传入的derivationSpec的算法类型,选择执行不同的算法
#ifdef HKS_SUPPORT_KDF_PBKDF2
case HKS_ALG_PBKDF2:
return DeriveKeyPbkdf2(mainKey, derParam, info, derivedKey);
#endif
#ifdef HKS_SUPPORT_KDF_HKDF
case HKS_ALG_HKDF:
return DeriveKeyHkdf(mainKey, derParam, info, derivedKey);
#endif
default:
HKS_LOG_E("Unsupport derive key alg! mode = 0x%X", derivationSpec->algType);
return HKS_ERROR_INVALID_ARGUMENT;
}
}