• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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