core_service+hks_auth源码解读
1.知识总结
WrapKey
密钥封装:在keyType中我们可以看到这样一类密钥,其实这类密钥就是为了对密钥进行保护而进行的封装,比如密钥存储在不安全的存储设备或者在网络中传输时。
使用密钥封装模式来保证密钥的保密防篡改
这里简单介绍密钥封装的三种方法,后续会结合鸿蒙安全模块的代码对其中用到的方法进行解读
- KW :基于AES的密钥封装但不使用填充
- KWP:基于AES的密钥封装并使用填充
- TKW:基于TDES的密钥封装但不适用填充
2.总体概述
该部分的代码主要与用户需求检查和密钥获取相关
通过函数的调用将私钥和公钥进行封装加密,当然还有一种密钥封装形式为wrapKey,在知识总结中耶简单提过,都是为了密钥在传输过程中的安全性考虑而设计的
3.代码解读
3.1hks_auth.c
- 定义了一个结构体HksAuthPolicy用于存储不同的PolicyTag
- 定义了静态变量一系列功能服务policy-tag的宏定义,为后面进行遍历检查提供tag
3.AuthPolicy
根据HksAuthPolicy结构体中的policyCnt进行循环,通过其中的policyTag获取两个tag然后调用HksGetParam分别得到authParam和requestParam然后进行类型匹配和非空检查
3.2hks_core_service.c
安全模块的核心服务模块
3.2.1GetGenType
函数功能:根据tag从paramSet中获取keyGenTypeParam然后switch-case根据其值对*genType赋值
3.2.2CheckAgreeKeyIn
函数功能:检查传入的key中的公钥私钥的size是否合适
3.2.3GetAgreeBaseKey
函数功能:获取keyIn中被加密的密钥并将其信息存入keyOut中
这里由于存在两个bool参数来控制是否加密和是否为公钥,所以理论上可以获取四种状态的密钥
函数实现:首先对参数进行检查---->根据是否为公钥进行数据的扩充和内存拷贝---->然后根据是否为明文选择数据的处理方式,是明文则不需要解密直接赋值,是密文则调用HksGenerateKeyNode进行解密得到原来的密钥---->再通过HksGetRawKey获取其中的信息存入keyOut
//获取加密后的密钥中的原始密钥
//由于存在两个标志所以理论上可以获取四种密钥
//加密或未加密的公钥或私钥
int32_t GetAgreeBaseKey(const bool isPubKey, const bool isPlainPubKey, const struct HksBlob *keyIn,
struct HksBlob *keyOut)
{ //根据所给的两个bool判断参数对keyIn和keyOut进行size更新
struct Hks25519KeyPair *keyPair = (struct Hks25519KeyPair *)(keyIn->data);
uint32_t size = isPubKey ? keyPair->publicBufferSize : keyPair->privateBufferSize;
uint8_t *buffer = (uint8_t *)HksMalloc(size);
if (buffer == NULL) {
HKS_LOG_E("malloc failed");
return HKS_ERROR_MALLOC_FAIL;
}
uint8_t *tmp = isPubKey ? (keyIn->data + sizeof(*keyPair)) :
(keyIn->data + sizeof(*keyPair) + keyPair->publicBufferSize);
if (memcpy_s(buffer, size, tmp, size) != EOK) {
HKS_LOG_E("memcpy failed");
HKS_FREE_PTR(buffer);
return HKS_ERROR_BAD_STATE;
}
if (isPlainPubKey) { /* public key is plain key, only copy */
keyOut->data = buffer;
keyOut->size = size;
return HKS_SUCCESS;
}
struct HksBlob tempKey = { size, buffer };
//将转换后的keyNode存入HksKeyNode
struct HksKeyNode *keyNode = HksGenerateKeyNode(&tempKey);
HKS_FREE_PTR(buffer);
if (keyNode == NULL) {
HKS_LOG_E("generating keynode with agree key failed");
return HKS_ERROR_BAD_STATE;
}
//获取rawKey
int32_t ret = HksGetRawKey(keyNode->paramSet, keyOut);
if (ret != HKS_SUCCESS) {
HKS_LOG_E("get raw key during key agreement failed!");
}
HksFreeKeyNode(&keyNode);
return ret;
}
后面两个函数就是封装该内核函数进行公钥和私钥的解密和获取
3.2.4GenAgreeKey
函数功能:将输入的公钥和密钥进行封装加密为可以传输的agreedKey
3.2.5GenKeyByAgree
函数功能:从keyIn中获取公钥私钥进行加密封装为shareKey
函数实现:通过调用上述提供的功能函数从KeyIn中解析出公钥私钥再调用GenAgreeKey进行加密封装
剩余的函数将在下一篇进行讲解