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