1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hks_adapter.h"
17 
18 #include <stddef.h>
19 
20 #include "securec.h"
21 #include "hks_api.h"
22 #include "hks_type.h"
23 #include "hks_param.h"
24 
25 #include "device_security_defines.h"
26 #include "utils_log.h"
27 #include "utils_mem.h"
28 #include "utils_tlv.h"
29 
30 #define MAX_ENTRY 8
31 #define TYPE_NONCE 0x200
32 #define TYPE_CERT_BASE 0x100
33 #define TYPE_CERT_END (TYPE_CERT_BASE + MAX_ENTRY)
34 #define LIST_MAX_SIZE 10240
35 
36 // need free
FillHksParamSet(struct HksParamSet ** paramSet,struct HksParam * param,int32_t paramNums)37 int32_t FillHksParamSet(struct HksParamSet **paramSet, struct HksParam *param, int32_t paramNums)
38 {
39     if (param == NULL) {
40         SECURITY_LOG_ERROR("param is null");
41         return ERR_INVALID_PARA;
42     }
43     int32_t ret = HksInitParamSet(paramSet);
44     if (ret != HKS_SUCCESS) {
45         SECURITY_LOG_ERROR("HksInitParamSet failed, hks ret = %{public}d", ret);
46         return ERR_INVALID_PARA;
47     }
48     ret = HksAddParams(*paramSet, param, paramNums);
49     if (ret != HKS_SUCCESS) {
50         SECURITY_LOG_ERROR("HksAddParams failed, hks ret = %{public}d", ret);
51         HksFreeParamSet(paramSet);
52         return ERR_INVALID_PARA;
53     }
54     ret = HksBuildParamSet(paramSet);
55     if (ret != HKS_SUCCESS) {
56         SECURITY_LOG_ERROR("HksBuildParamSet failed, hks ret = %{public}d", ret);
57         HksFreeParamSet(paramSet);
58         return ERR_INVALID_PARA;
59     }
60     return SUCCESS;
61 }
62 
HksGenerateKeyAdapter(const struct HksBlob * keyAlias)63 int32_t HksGenerateKeyAdapter(const struct HksBlob *keyAlias)
64 {
65     if (keyAlias == NULL) {
66         SECURITY_LOG_ERROR("keyAlias is null");
67         return ERR_INVALID_PARA;
68     }
69     struct HksParam tmpParams[] = {
70         {.tag = HKS_TAG_KEY_STORAGE_FLAG, .uint32Param = HKS_STORAGE_PERSISTENT},
71         {.tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_RSA},
72         {.tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_RSA_KEY_SIZE_2048},
73         {.tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_VERIFY},
74         {.tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256},
75         {.tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_PSS},
76         {.tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT},
77         {.tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_ECB},
78         {.tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
79     };
80     struct HksParamSet *paramSet = NULL;
81     if (FillHksParamSet(&paramSet, tmpParams, sizeof(tmpParams) / sizeof(tmpParams[0])) != SUCCESS) {
82         SECURITY_LOG_ERROR("FillHksParamSet failed");
83         return ERR_HUKS_ERR;
84     }
85     int32_t ret = HksGenerateKey(keyAlias, paramSet, NULL);
86     if (ret != HKS_SUCCESS) {
87         SECURITY_LOG_ERROR("HksGenerateKey failed, hks ret = %{public}d", ret);
88         HksFreeParamSet(&paramSet);
89         return ERR_HUKS_ERR;
90     }
91     HksFreeParamSet(&paramSet);
92     return SUCCESS;
93 }
94 
95 // need free
ConstructHksCertChain(struct HksCertChain ** certChain,const struct HksCertChainInitParams * certChainParam)96 int32_t ConstructHksCertChain(struct HksCertChain **certChain, const struct HksCertChainInitParams *certChainParam)
97 {
98     if (certChainParam == NULL || certChainParam->certChainExist == false ||
99         certChainParam->certCountValid == false || certChainParam->certDataExist == false) {
100         return ERR_INVALID_PARA;
101     }
102 
103     *certChain = (struct HksCertChain *)MALLOC(sizeof(struct HksCertChain));
104     if (*certChain == NULL) {
105         return ERR_NO_MEMORY;
106     }
107     (*certChain)->certsCount = CERT_CHAIN_CERT_NUM;
108     (*certChain)->certs = (struct HksBlob *)MALLOC(sizeof(struct HksBlob) * ((*certChain)->certsCount));
109     if ((*certChain)->certs == NULL) {
110         FREE(*certChain);
111         *certChain = NULL;
112         return ERR_NO_MEMORY;
113     }
114     for (uint32_t i = 0; i < (*certChain)->certsCount; i++) {
115         (*certChain)->certs[i].size = 0;
116         (*certChain)->certs[i].data = NULL;
117     }
118     for (uint32_t i = 0; i < (*certChain)->certsCount; i++) {
119         (*certChain)->certs[i].size = certChainParam->certDataSize;
120         (*certChain)->certs[i].data = (uint8_t *)MALLOC((*certChain)->certs[i].size);
121         if ((*certChain)->certs[i].data == NULL) {
122             DestroyHksCertChain(*certChain);
123             *certChain = NULL;
124             return ERR_NO_MEMORY;
125         }
126         (void)memset_s((*certChain)->certs[i].data, certChainParam->certDataSize, 0, certChainParam->certDataSize);
127     }
128     return SUCCESS;
129 }
130 
DestroyHksCertChain(struct HksCertChain * certChain)131 void DestroyHksCertChain(struct HksCertChain *certChain)
132 {
133     if (certChain == NULL || certChain->certs == NULL || certChain->certsCount <= 0) {
134         return;
135     }
136     for (uint32_t i = 0; i < certChain->certsCount; i++) {
137         if (certChain->certs[i].data != NULL) {
138             FREE(certChain->certs[i].data);
139             certChain->certs[i].data = NULL;
140         }
141     }
142     FREE(certChain->certs);
143     certChain->certs = NULL;
144     FREE(certChain);
145 }
146 
147 // need free
HksCertChainToBuffer(const struct HksCertChain * hksCertChain,uint8_t ** data,uint32_t * dataLen)148 int32_t HksCertChainToBuffer(const struct HksCertChain *hksCertChain, uint8_t **data, uint32_t *dataLen)
149 {
150     if (hksCertChain == NULL) {
151         return ERR_INVALID_PARA;
152     }
153 
154     TlvCommon tlvs[MAX_ENTRY];
155     (void)memset_s(&tlvs[0], sizeof(tlvs), 0, sizeof(tlvs));
156     uint32_t tlvCnt = 0;
157     for (uint32_t i = 0; i < hksCertChain->certsCount; i++) {
158         tlvs[tlvCnt].tag = TYPE_CERT_BASE + 1;
159         tlvs[tlvCnt].len = hksCertChain->certs[i].size;
160         tlvs[tlvCnt].value = hksCertChain->certs[i].data;
161         tlvCnt++;
162     }
163 
164     uint8_t *out = MALLOC(LIST_MAX_SIZE);
165     if (out == NULL) {
166         return ERR_NO_MEMORY;
167     }
168     (void)memset_s(out, LIST_MAX_SIZE, 0, LIST_MAX_SIZE);
169     if (Serialize(tlvs, tlvCnt, out, LIST_MAX_SIZE, dataLen) != TLV_OK) {
170         FREE(out);
171         return ERR_NO_MEMORY;
172     }
173     *data = out;
174     return SUCCESS;
175 }
176 
177 // point to exist memory, no need free but can not change data
BufferToHksCertChain(const uint8_t * data,uint32_t dataLen,struct HksCertChain * hksCertChain)178 int32_t BufferToHksCertChain(const uint8_t *data, uint32_t dataLen, struct HksCertChain *hksCertChain)
179 {
180     if (data == NULL || dataLen == 0) {
181         return ERR_INVALID_PARA;
182     }
183     TlvCommon tlvs[MAX_ENTRY];
184     (void)memset_s(&tlvs[0], sizeof(tlvs), 0, sizeof(tlvs));
185 
186     uint32_t cnt = 0;
187     uint32_t ret = Deserialize(data, dataLen, &tlvs[0], MAX_ENTRY, &cnt);
188     if (ret != TLV_OK || cnt == 0 || cnt > MAX_ENTRY) {
189         return ERR_INVALID_PARA;
190     }
191     uint32_t certCnt = 0;
192     for (uint32_t i = 0; i < cnt; i++) {
193         if ((tlvs[i].tag >= TYPE_CERT_BASE) && (tlvs[i].tag <= TYPE_CERT_END)) {
194             hksCertChain->certs[certCnt].data = tlvs[i].value;
195             hksCertChain->certs[certCnt].size = tlvs[i].len;
196             certCnt++;
197         }
198     }
199     hksCertChain->certsCount = certCnt;
200     return SUCCESS;
201 }