本篇主要分析hks_mbedtls_ecdh.c代码
一、背景知识
ecdh算法理论介绍
二、代码分析将ecc公钥材料转换为ctx格式 参数解释:
- nativekey:用来存放本地密钥信息
- pubKey:存放一组公钥信息
- ctx:用来存放最后转换的结果
static int32_t EccKeyMaterialToCtx(const struct HksBlob *nativeKey,
const struct HksBlob *pubKey, mbedtls_ecdh_context *ctx)
{
int32_t ret = HksEccKeyMaterialToPub(pubKey, &(ctx->Qp));
//转换公钥
if (ret != HKS_SUCCESS) {
HKS_LOG_E("Ecc keyMaterial to public key failed! ret = 0x%X", ret);
return ret;
}
ret = HksEccKeyMaterialToPri(nativeKey, &(ctx->d));
//转换私钥
if (ret != HKS_SUCCESS) {
HKS_LOG_E("Ecc keyMaterial to private key failed! ret = 0x%X", ret);
}
return ret;
}
ecdh算法实现 参数解释:
- nativekey:本地密钥组
- pubkey:传入公钥
- spec:密钥规范
- shareKey:存放最后计算得到的密钥
int32_t HksMbedtlsEcdh(const struct HksBlob *nativeKey,
const struct HksBlob *pubKey, const struct HksKeySpec *spec, struct HksBlob *sharedKey)
{
int32_t ret = EccKeyCheck(pubKey);
//先对传入的公钥参数进行检查
if (ret != HKS_SUCCESS) {
return ret;
}
mbedtls_ecp_group_id mbedtlsCurveNist = MBEDTLS_ECP_DP_NONE;
ret = HksMbedtlsEccGetKeyCurveNist((struct KeyMaterialEcc *)(nativeKey->data), &mbedtlsCurveNist);
//获取本地密钥的曲线nist信息
if (ret != HKS_SUCCESS) {
return ret;
}
mbedtls_ctr_drbg_context ctrDrbg;
mbedtls_entropy_context entropy;
ret = HksCtrDrbgSeed(&ctrDrbg, &entropy);
//初始化随机数等相关变量,生成随机数
if (ret != HKS_SUCCESS) {
return ret;
}
mbedtls_ecdh_context ctx;
mbedtls_ecdh_init(&ctx);
do {
ret = mbedtls_ecp_group_load(&(ctx.grp), mbedtlsCurveNist);
//调用ecp_group_load来执行参数的加载
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls ecdh load group failed! mbedtls ret = 0x%X", ret);
break;
}
ret = EccKeyMaterialToCtx(nativeKey, pubKey, &ctx);
//将本地密钥和公钥转换为ctx格式
if (ret != HKS_SUCCESS) {
break;
}
ret = mbedtls_ecdh_compute_shared(&(ctx.grp), &(ctx.z), &(ctx.Qp), &(ctx.d), mbedtls_ctr_drbg_random, &ctrDrbg);
//执行ecdh算法当中的密钥交换,并计算共享密钥
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls ecdh shared key failed! mbedtls ret = 0x%X", ret);
break;
}
const uint32_t keyByteLen = spec->keyLen / HKS_BITS_PER_BYTE;
ret = mbedtls_mpi_write_binary(&(ctx.z), sharedKey->data, keyByteLen);
//将分享后的密钥写进shareKey,写入长度keyByteLen
if (ret != HKS_MBEDTLS_SUCCESS) {
HKS_LOG_E("Mbedtls ecdh mpi write to sharedKey failed! mbedtls ret = 0x%X", ret);
(void)memset_s(sharedKey->data, sharedKey->size, 0, sharedKey->size);
//初始化定义的用来分享交换密钥的内存空间
break;
}
sharedKey->size = keyByteLen;
//将计算得到的共享密钥长度置为keyByteLen
} while (0);
mbedtls_ecdh_free(&ctx);
mbedtls_ctr_drbg_free(&ctrDrbg);
mbedtls_entropy_free(&entropy);
//释放相关空间内存
return ret;
}