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 "external_interface_adapter.h"
17
18 #include <stddef.h>
19 #include <string.h>
20
21 #include "device_auth.h"
22 #include "device_auth_defines.h"
23 #include "hks_adapter.h"
24 #include "hks_api.h"
25 #include "hks_param.h"
26 #include "hks_type.h"
27 #include "securec.h"
28
29 #include "device_security_defines.h"
30 #include "utils_json.h"
31 #include "utils_log.h"
32 #include "utils_mem.h"
33
34 #define DEVICE_AUTH_INPUT_PARAM_STRING_LENGTH 512
35 #define DSLM_CERT_CHAIN_BASE_LENGTH 4096
36
37 #define DSLM_INFO_MAX_LEN_UDID 68
38 #define DSLM_INFO_MAX_LEN_SERIAL 68
39 #define DSLM_INFO_MAX_LEN_VERSION 128
40 #define DSLM_INFO_MAX_LEN_CRED 2048
41 #define DSLM_INFO_MAX_LEN_NONCE 2048
42
43 #define EMPTY_PK_INFO "[]"
44 #define DEFAULT_PK_INFO "[{\"groupId\" : \"0\",\"publicKey\" : \"0\"}]"
45
46 static int32_t GenerateFuncParamJson(bool isSelfPk, const char *udidStr, char *dest, uint32_t destMax);
47
GetPkInfoListStr(bool isSelf,const char * udidStr,char ** pkInfoList)48 int32_t GetPkInfoListStr(bool isSelf, const char *udidStr, char **pkInfoList)
49 {
50 SECURITY_LOG_INFO("start");
51
52 char paramJson[DEVICE_AUTH_INPUT_PARAM_STRING_LENGTH] = {0};
53 char *returnInfoList = NULL;
54 uint32_t returnInfoNum = 0;
55
56 int32_t ret = GenerateFuncParamJson(isSelf, udidStr, paramJson, DEVICE_AUTH_INPUT_PARAM_STRING_LENGTH);
57 if (ret != SUCCESS) {
58 SECURITY_LOG_ERROR("GenerateFuncParamJson failed");
59 return ret;
60 }
61
62 const DeviceGroupManager *interface = GetGmInstance();
63 if (interface == NULL) {
64 SECURITY_LOG_ERROR("GetGmInstance null");
65 return ERR_CALL_EXTERNAL_FUNC;
66 }
67 ret = interface->getPkInfoList(ANY_OS_ACCOUNT, "dslm_service", paramJson, &returnInfoList, &returnInfoNum);
68 if (ret == HC_ERR_ONLY_ACCOUNT_RELATED) {
69 SECURITY_LOG_INFO("device auth cred situation");
70 ret = SUCCESS;
71 }
72 if (ret != SUCCESS) {
73 SECURITY_LOG_INFO("getPkInfoList failed, ret = %{public}d", ret);
74 return ERR_CALL_EXTERNAL_FUNC;
75 }
76
77 char *pkInfoBuff = returnInfoList;
78 if (pkInfoBuff == NULL || strcmp(pkInfoBuff, EMPTY_PK_INFO) == 0) {
79 SECURITY_LOG_INFO("current pkInfoList is %s", pkInfoBuff == NULL ? "null" : "empty");
80 pkInfoBuff = DEFAULT_PK_INFO;
81 }
82
83 do {
84 char *output = (char *)MALLOC(strlen(pkInfoBuff) + 1);
85 if (output == NULL) {
86 SECURITY_LOG_ERROR("malloc error");
87 ret = ERR_MEMORY_ERR;
88 break;
89 }
90
91 if (strcpy_s(output, strlen(pkInfoBuff) + 1, pkInfoBuff) != EOK) {
92 SECURITY_LOG_ERROR("strcpy_s error");
93 ret = ERR_MEMORY_ERR;
94 FREE(output);
95 break;
96 }
97 *pkInfoList = output;
98 ret = SUCCESS;
99 } while (0);
100
101 if (returnInfoList != NULL) {
102 interface->destroyInfo(&returnInfoList);
103 }
104 return ret;
105 }
106
DslmCredAttestAdapter(struct DslmInfoInCertChain * info,uint8_t ** certChain,uint32_t * certChainLen)107 int32_t DslmCredAttestAdapter(struct DslmInfoInCertChain *info, uint8_t **certChain, uint32_t *certChainLen)
108 {
109 SECURITY_LOG_INFO("start");
110
111 const char alias[] = "dslm_key";
112 struct HksBlob keyAlias = {sizeof(alias), (uint8_t *)alias};
113
114 if (HksGenerateKeyAdapter(&keyAlias) != SUCCESS) {
115 SECURITY_LOG_ERROR("HksGenerateKeyAdapter failed");
116 return ERR_HUKS_ERR;
117 }
118 struct HksParam inputData[] = {
119 {.tag = HKS_TAG_ATTESTATION_CHALLENGE, .blob = {strlen(info->nonceStr) + 1, (uint8_t *)info->nonceStr}},
120 {.tag = HKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO, .blob = {strlen(info->credStr) + 1, (uint8_t *)info->credStr}},
121 {.tag = HKS_TAG_ATTESTATION_ID_UDID, .blob = {strlen(info->udidStr) + 1, (uint8_t *)info->udidStr}},
122 {.tag = HKS_TAG_ATTESTATION_ID_ALIAS, .blob = keyAlias},
123 };
124
125 struct HksParamSet *inputParam = NULL;
126 uint32_t certChainMaxLen = strlen(info->credStr) + strlen(info->nonceStr) + DSLM_CERT_CHAIN_BASE_LENGTH;
127 struct HksCertChain *hksCertChain = NULL;
128 const struct HksCertChainInitParams certParam = {true, true, true, certChainMaxLen};
129
130 int32_t ret = ConstructHksCertChain(&hksCertChain, &certParam);
131 if (ret != SUCCESS) {
132 SECURITY_LOG_ERROR("ConstructHksCertChain failed, ret = %{public}d ", ret);
133 return ret;
134 }
135 if (FillHksParamSet(&inputParam, inputData, sizeof(inputData) / sizeof(inputData[0])) != SUCCESS) {
136 SECURITY_LOG_ERROR("FillHksParamSet failed");
137 DestroyHksCertChain(hksCertChain);
138 return ERR_CALL_EXTERNAL_FUNC;
139 }
140 ret = HksAttestKey(&keyAlias, inputParam, hksCertChain);
141 if (ret != HKS_SUCCESS) {
142 SECURITY_LOG_ERROR("HksAttestKey failed, ret = %{public}d ", ret);
143 HksFreeParamSet(&inputParam);
144 DestroyHksCertChain(hksCertChain);
145 return ERR_CALL_EXTERNAL_FUNC;
146 }
147 ret = HksCertChainToBuffer(hksCertChain, certChain, certChainLen);
148 if (ret != SUCCESS) {
149 SECURITY_LOG_ERROR("HksCertChainToHksBlob failed");
150 HksFreeParamSet(&inputParam);
151 DestroyHksCertChain(hksCertChain);
152 FREE(*certChain);
153 *certChain = NULL;
154 return ret;
155 }
156 HksFreeParamSet(&inputParam);
157 DestroyHksCertChain(hksCertChain);
158 SECURITY_LOG_DEBUG("success, certChainLen = %{public}d ", *certChainLen);
159 return SUCCESS;
160 }
161
ValidateCertChainAdapter(const uint8_t * data,uint32_t dataLen,struct DslmInfoInCertChain * resultInfo)162 int32_t ValidateCertChainAdapter(const uint8_t *data, uint32_t dataLen, struct DslmInfoInCertChain *resultInfo)
163 {
164 SECURITY_LOG_INFO("start");
165
166 char nonceStr[DSLM_INFO_MAX_LEN_NONCE] = {0};
167 char credStr[DSLM_INFO_MAX_LEN_CRED] = {0};
168 char udidStr[DSLM_INFO_MAX_LEN_UDID] = {0};
169 struct HksParam outputData[] = {
170 {.tag = HKS_TAG_ATTESTATION_CHALLENGE, .blob = {DSLM_INFO_MAX_LEN_NONCE, (uint8_t *)nonceStr}},
171 {.tag = HKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO, .blob = {DSLM_INFO_MAX_LEN_CRED, (uint8_t *)credStr}},
172 {.tag = HKS_TAG_ATTESTATION_ID_UDID, .blob = {DSLM_INFO_MAX_LEN_UDID, (uint8_t *)udidStr}},
173 };
174 struct HksParamSet *outputParam = NULL;
175 struct HksBlob certBlob[CERT_CHAIN_CERT_NUM] = {{0}};
176 struct HksCertChain hksCertChain = {&certBlob[0], CERT_CHAIN_CERT_NUM};
177
178 if (BufferToHksCertChain(data, dataLen, &hksCertChain) != SUCCESS) {
179 SECURITY_LOG_ERROR("BufferToHksCertChain failed");
180 return ERR_CALL_EXTERNAL_FUNC;
181 }
182 if (FillHksParamSet(&outputParam, outputData, sizeof(outputData) / sizeof(outputData[0])) != SUCCESS) {
183 SECURITY_LOG_ERROR("FillHksParamSet failed");
184 return ERR_CALL_EXTERNAL_FUNC;
185 }
186 if (HksValidateCertChain(&hksCertChain, outputParam) != HKS_SUCCESS) {
187 SECURITY_LOG_ERROR("HksValidateCertChain failed");
188 HksFreeParamSet(&outputParam);
189 return ERR_CALL_EXTERNAL_FUNC;
190 }
191 uint32_t cnt = 0;
192 struct HksBlob *blob = &outputParam->params[cnt].blob;
193 if (memcpy_s(resultInfo->nonceStr, DSLM_INFO_MAX_LEN_NONCE, blob->data, blob->size) != EOK) {
194 HksFreeParamSet(&outputParam);
195 return ERR_MEMORY_ERR;
196 }
197 blob = &outputParam->params[++cnt].blob;
198 if (memcpy_s(resultInfo->credStr, DSLM_INFO_MAX_LEN_CRED, blob->data, blob->size) != EOK) {
199 HksFreeParamSet(&outputParam);
200 return ERR_MEMORY_ERR;
201 }
202 blob = &outputParam->params[++cnt].blob;
203 if (memcpy_s(resultInfo->udidStr, DSLM_INFO_MAX_LEN_UDID, blob->data, blob->size) != EOK) {
204 HksFreeParamSet(&outputParam);
205 return ERR_MEMORY_ERR;
206 }
207
208 SECURITY_LOG_INFO("success");
209 HksFreeParamSet(&outputParam);
210 return SUCCESS;
211 }
212
HksAttestIsReadyAdapter(void)213 int32_t HksAttestIsReadyAdapter(void)
214 {
215 #ifdef L2_STANDARD
216 if (HcmIsDeviceKeyExist(NULL) != HKS_SUCCESS) {
217 SECURITY_LOG_ERROR("Hks attest not ready");
218 return ERR_CALL_EXTERNAL_FUNC;
219 }
220 return SUCCESS;
221 #else
222 return ERR_DEFAULT;
223 #endif
224 }
225
GenerateFuncParamJson(bool isSelfPk,const char * udidStr,char * dest,uint32_t destMax)226 static int32_t GenerateFuncParamJson(bool isSelfPk, const char *udidStr, char *dest, uint32_t destMax)
227 {
228 DslmJsonHandle json = DslmCreateJson(NULL);
229 if (json == NULL) {
230 return ERR_INVALID_PARA;
231 }
232
233 DslmAddFieldBoolToJson(json, "isSelfPk", isSelfPk);
234 DslmAddFieldStringToJson(json, "udid", udidStr);
235
236 char *paramsJsonBuffer = DslmConvertJsonToString(json);
237 if (paramsJsonBuffer == NULL) {
238 DslmDestroyJson(json);
239 return ERR_MEMORY_ERR;
240 }
241 DslmDestroyJson(json);
242 if (strcpy_s(dest, destMax, paramsJsonBuffer) != EOK) {
243 FREE(paramsJsonBuffer);
244 paramsJsonBuffer = NULL;
245 return ERR_MEMORY_ERR;
246 }
247 FREE(paramsJsonBuffer);
248 paramsJsonBuffer = NULL;
249 return SUCCESS;
250 }
251
InitDslmInfoInCertChain(struct DslmInfoInCertChain * saveInfo)252 int32_t InitDslmInfoInCertChain(struct DslmInfoInCertChain *saveInfo)
253 {
254 if (saveInfo == NULL) {
255 return ERR_INVALID_PARA;
256 }
257 saveInfo->nonceStr = (char *)MALLOC(DSLM_INFO_MAX_LEN_NONCE);
258 if (saveInfo->nonceStr == NULL) {
259 return ERR_NO_MEMORY;
260 }
261 saveInfo->credStr = (char *)MALLOC(DSLM_INFO_MAX_LEN_CRED);
262 if (saveInfo->credStr == NULL) {
263 FREE(saveInfo->nonceStr);
264 saveInfo->nonceStr = NULL;
265 return ERR_NO_MEMORY;
266 }
267 saveInfo->udidStr = (char *)MALLOC(DSLM_INFO_MAX_LEN_UDID);
268 if (saveInfo->udidStr == NULL) {
269 FREE(saveInfo->nonceStr);
270 saveInfo->nonceStr = NULL;
271 FREE(saveInfo->credStr);
272 saveInfo->credStr = NULL;
273 return ERR_NO_MEMORY;
274 }
275 return SUCCESS;
276 }
277
DestroyDslmInfoInCertChain(struct DslmInfoInCertChain * saveInfo)278 void DestroyDslmInfoInCertChain(struct DslmInfoInCertChain *saveInfo)
279 {
280 if (saveInfo == NULL) {
281 return;
282 }
283 if (saveInfo->nonceStr != NULL) {
284 FREE(saveInfo->nonceStr);
285 saveInfo->nonceStr = NULL;
286 }
287 if (saveInfo->credStr != NULL) {
288 FREE(saveInfo->credStr);
289 saveInfo->credStr = NULL;
290 }
291 if (saveInfo->udidStr != NULL) {
292 FREE(saveInfo->udidStr);
293 saveInfo->udidStr = NULL;
294 }
295 (void)memset_s(saveInfo, sizeof(struct DslmInfoInCertChain), 0, sizeof(struct DslmInfoInCertChain));
296 }
297