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 {.tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE},
124 };
125
126 struct HksParamSet *inputParam = NULL;
127 uint32_t certChainMaxLen = strlen(info->credStr) + strlen(info->nonceStr) + DSLM_CERT_CHAIN_BASE_LENGTH;
128 struct HksCertChain *hksCertChain = NULL;
129 const struct HksCertChainInitParams certParam = {true, true, true, certChainMaxLen};
130
131 int32_t ret = ConstructHksCertChain(&hksCertChain, &certParam);
132 if (ret != SUCCESS) {
133 SECURITY_LOG_ERROR("ConstructHksCertChain failed, ret = %{public}d ", ret);
134 return ret;
135 }
136 if (FillHksParamSet(&inputParam, inputData, sizeof(inputData) / sizeof(inputData[0])) != SUCCESS) {
137 SECURITY_LOG_ERROR("FillHksParamSet failed");
138 DestroyHksCertChain(hksCertChain);
139 return ERR_CALL_EXTERNAL_FUNC;
140 }
141 ret = HksAttestKey(&keyAlias, inputParam, hksCertChain);
142 if (ret != HKS_SUCCESS) {
143 SECURITY_LOG_ERROR("HksAttestKey failed, ret = %{public}d ", ret);
144 HksFreeParamSet(&inputParam);
145 DestroyHksCertChain(hksCertChain);
146 return ERR_CALL_EXTERNAL_FUNC;
147 }
148 ret = HksCertChainToBuffer(hksCertChain, certChain, certChainLen);
149 if (ret != SUCCESS) {
150 SECURITY_LOG_ERROR("HksCertChainToHksBlob failed");
151 HksFreeParamSet(&inputParam);
152 DestroyHksCertChain(hksCertChain);
153 FREE(*certChain);
154 *certChain = NULL;
155 return ret;
156 }
157 HksFreeParamSet(&inputParam);
158 DestroyHksCertChain(hksCertChain);
159 SECURITY_LOG_DEBUG("success, certChainLen = %{public}d ", *certChainLen);
160 return SUCCESS;
161 }
162
ValidateCertChainAdapter(const uint8_t * data,uint32_t dataLen,struct DslmInfoInCertChain * resultInfo)163 int32_t ValidateCertChainAdapter(const uint8_t *data, uint32_t dataLen, struct DslmInfoInCertChain *resultInfo)
164 {
165 SECURITY_LOG_INFO("start");
166
167 char nonceStr[DSLM_INFO_MAX_LEN_NONCE] = {0};
168 char credStr[DSLM_INFO_MAX_LEN_CRED] = {0};
169 char udidStr[DSLM_INFO_MAX_LEN_UDID] = {0};
170 struct HksParam outputData[] = {
171 {.tag = HKS_TAG_ATTESTATION_CHALLENGE, .blob = {DSLM_INFO_MAX_LEN_NONCE, (uint8_t *)nonceStr}},
172 {.tag = HKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO, .blob = {DSLM_INFO_MAX_LEN_CRED, (uint8_t *)credStr}},
173 {.tag = HKS_TAG_ATTESTATION_ID_UDID, .blob = {DSLM_INFO_MAX_LEN_UDID, (uint8_t *)udidStr}},
174 };
175 struct HksParamSet *outputParam = NULL;
176 struct HksBlob certBlob[CERT_CHAIN_CERT_NUM] = {{0}};
177 struct HksCertChain hksCertChain = {&certBlob[0], CERT_CHAIN_CERT_NUM};
178
179 if (BufferToHksCertChain(data, dataLen, &hksCertChain) != SUCCESS) {
180 SECURITY_LOG_ERROR("BufferToHksCertChain failed");
181 return ERR_CALL_EXTERNAL_FUNC;
182 }
183 if (FillHksParamSet(&outputParam, outputData, sizeof(outputData) / sizeof(outputData[0])) != SUCCESS) {
184 SECURITY_LOG_ERROR("FillHksParamSet failed");
185 return ERR_CALL_EXTERNAL_FUNC;
186 }
187 if (HksValidateCertChain(&hksCertChain, outputParam) != HKS_SUCCESS) {
188 SECURITY_LOG_ERROR("HksValidateCertChain failed");
189 HksFreeParamSet(&outputParam);
190 return ERR_CALL_EXTERNAL_FUNC;
191 }
192 uint32_t cnt = 0;
193 struct HksBlob *blob = &outputParam->params[cnt].blob;
194 if (memcpy_s(resultInfo->nonceStr, DSLM_INFO_MAX_LEN_NONCE, blob->data, blob->size) != EOK) {
195 HksFreeParamSet(&outputParam);
196 return ERR_MEMORY_ERR;
197 }
198 blob = &outputParam->params[++cnt].blob;
199 if (memcpy_s(resultInfo->credStr, DSLM_INFO_MAX_LEN_CRED, blob->data, blob->size) != EOK) {
200 HksFreeParamSet(&outputParam);
201 return ERR_MEMORY_ERR;
202 }
203 blob = &outputParam->params[++cnt].blob;
204 if (memcpy_s(resultInfo->udidStr, DSLM_INFO_MAX_LEN_UDID, blob->data, blob->size) != EOK) {
205 HksFreeParamSet(&outputParam);
206 return ERR_MEMORY_ERR;
207 }
208
209 SECURITY_LOG_INFO("success");
210 HksFreeParamSet(&outputParam);
211 return SUCCESS;
212 }
213
HksAttestIsReadyAdapter(void)214 int32_t HksAttestIsReadyAdapter(void)
215 {
216 #ifdef L2_STANDARD
217 if (HcmIsDeviceKeyExist(NULL) != HKS_SUCCESS) {
218 SECURITY_LOG_ERROR("Hks attest not ready");
219 return ERR_CALL_EXTERNAL_FUNC;
220 }
221 return SUCCESS;
222 #else
223 return ERR_DEFAULT;
224 #endif
225 }
226
GenerateFuncParamJson(bool isSelfPk,const char * udidStr,char * dest,uint32_t destMax)227 static int32_t GenerateFuncParamJson(bool isSelfPk, const char *udidStr, char *dest, uint32_t destMax)
228 {
229 DslmJsonHandle json = DslmCreateJson(NULL);
230 if (json == NULL) {
231 return ERR_INVALID_PARA;
232 }
233
234 DslmAddFieldBoolToJson(json, "isSelfPk", isSelfPk);
235 DslmAddFieldStringToJson(json, "udid", udidStr);
236
237 char *paramsJsonBuffer = DslmConvertJsonToString(json);
238 if (paramsJsonBuffer == NULL) {
239 DslmDestroyJson(json);
240 return ERR_MEMORY_ERR;
241 }
242 DslmDestroyJson(json);
243 if (strcpy_s(dest, destMax, paramsJsonBuffer) != EOK) {
244 FREE(paramsJsonBuffer);
245 paramsJsonBuffer = NULL;
246 return ERR_MEMORY_ERR;
247 }
248 FREE(paramsJsonBuffer);
249 paramsJsonBuffer = NULL;
250 return SUCCESS;
251 }
252
InitDslmInfoInCertChain(struct DslmInfoInCertChain * saveInfo)253 int32_t InitDslmInfoInCertChain(struct DslmInfoInCertChain *saveInfo)
254 {
255 if (saveInfo == NULL) {
256 return ERR_INVALID_PARA;
257 }
258 saveInfo->nonceStr = (char *)MALLOC(DSLM_INFO_MAX_LEN_NONCE);
259 if (saveInfo->nonceStr == NULL) {
260 return ERR_NO_MEMORY;
261 }
262 saveInfo->credStr = (char *)MALLOC(DSLM_INFO_MAX_LEN_CRED);
263 if (saveInfo->credStr == NULL) {
264 FREE(saveInfo->nonceStr);
265 saveInfo->nonceStr = NULL;
266 return ERR_NO_MEMORY;
267 }
268 saveInfo->udidStr = (char *)MALLOC(DSLM_INFO_MAX_LEN_UDID);
269 if (saveInfo->udidStr == NULL) {
270 FREE(saveInfo->nonceStr);
271 saveInfo->nonceStr = NULL;
272 FREE(saveInfo->credStr);
273 saveInfo->credStr = NULL;
274 return ERR_NO_MEMORY;
275 }
276 return SUCCESS;
277 }
278
DestroyDslmInfoInCertChain(struct DslmInfoInCertChain * saveInfo)279 void DestroyDslmInfoInCertChain(struct DslmInfoInCertChain *saveInfo)
280 {
281 if (saveInfo == NULL) {
282 return;
283 }
284 if (saveInfo->nonceStr != NULL) {
285 FREE(saveInfo->nonceStr);
286 saveInfo->nonceStr = NULL;
287 }
288 if (saveInfo->credStr != NULL) {
289 FREE(saveInfo->credStr);
290 saveInfo->credStr = NULL;
291 }
292 if (saveInfo->udidStr != NULL) {
293 FREE(saveInfo->udidStr);
294 saveInfo->udidStr = NULL;
295 }
296 (void)memset_s(saveInfo, sizeof(struct DslmInfoInCertChain), 0, sizeof(struct DslmInfoInCertChain));
297 }
298