• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <stdint.h>
17 
18 #include "hks_api.h"
19 #include "hks_param.h"
20 
21 #include "asset_log.h"
22 #include "asset_type.h"
23 #include "huks_wrapper.h"
24 
AccessibilityToHksAuthStorageLevel(enum Accessibility accessibility)25 static enum HksAuthStorageLevel AccessibilityToHksAuthStorageLevel(enum Accessibility accessibility)
26 {
27     switch (accessibility) {
28         case DEVICE_POWERED_ON:
29             return HKS_AUTH_STORAGE_LEVEL_DE;
30         case DEVICE_FIRST_UNLOCKED:
31             return HKS_AUTH_STORAGE_LEVEL_CE;
32         default:
33             return HKS_AUTH_STORAGE_LEVEL_ECE;
34     }
35 }
36 
HuksErrorTransfer(int32_t ret)37 static int32_t HuksErrorTransfer(int32_t ret)
38 {
39     switch (ret) {
40         case HKS_SUCCESS:
41             return ASSET_SUCCESS;
42         case HKS_ERROR_NO_PERMISSION:
43         case HKS_ERROR_DEVICE_PASSWORD_UNSET:
44             return ASSET_STATUS_MISMATCH;
45         case HKS_ERROR_NOT_EXIST:
46             return ASSET_NOT_FOUND;
47         case HKS_ERROR_KEY_AUTH_FAILED:
48         case HKS_ERROR_KEY_AUTH_VERIFY_FAILED:
49         case HKS_ERROR_CHECK_GET_AUTH_TOKEN_FAILED:
50         case HKS_ERROR_INVALID_AUTH_TOKEN:
51         case HKS_ERROR_KEY_AUTH_TIME_OUT:
52             return ASSET_ACCESS_DENIED;
53         case HKS_ERROR_CRYPTO_ENGINE_ERROR:
54             return ASSET_DATA_CORRUPTED;
55         default:
56             return ASSET_CRYPTO_ERROR;
57     }
58 }
59 
AddSpecificUserIdParams(struct HksParamSet * paramSet,int32_t userId)60 static int32_t AddSpecificUserIdParams(struct HksParamSet *paramSet, int32_t userId)
61 {
62     struct HksParam specificUserIdParams[] = {
63         { .tag = HKS_TAG_SPECIFIC_USER_ID, .int32Param = userId },
64     };
65     return HksAddParams(paramSet, specificUserIdParams, ARRAY_SIZE(specificUserIdParams));
66 }
67 
BuildParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramCount,int32_t userId)68 static int32_t BuildParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount,
69     int32_t userId)
70 {
71     int32_t ret = HksInitParamSet(paramSet);
72     if (ret != HKS_SUCCESS) {
73         LOGE("[FATAL]HUKS init param set failed. error=%{public}d", ret);
74         return ret;
75     }
76 
77     if (paramCount != 0) {
78         ret = HksAddParams(*paramSet, params, paramCount);
79         if (ret != HKS_SUCCESS) {
80             LOGE("[FATAL]HUKS add params failed. error=%{public}d", ret);
81             HksFreeParamSet(paramSet);
82             return ret;
83         }
84 
85         if (userId > ASSET_ROOT_USER_UPPERBOUND) {
86             ret = AddSpecificUserIdParams(*paramSet, userId);
87             if (ret != HKS_SUCCESS) {
88                 LOGE("[FATAL]HUKS add specific userId failed. error=%{public}d", ret);
89                 HksFreeParamSet(paramSet);
90                 return ret;
91             }
92         }
93     }
94 
95     ret = HksBuildParamSet(paramSet);
96     if (ret != HKS_SUCCESS) {
97         LOGE("[FATAL]HUKS build param set failed. error=%{public}d", ret);
98         HksFreeParamSet(paramSet);
99     }
100     return ret;
101 }
102 
AddCommonGenParams(struct HksParamSet * paramSet,const struct KeyId * keyId)103 static int32_t AddCommonGenParams(struct HksParamSet *paramSet, const struct KeyId *keyId)
104 {
105     struct HksParam commonParams[] = {
106         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
107         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
108         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
109         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
110         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
111         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
112         { .tag = HKS_TAG_IS_ALLOWED_DATA_WRAP, .boolParam = true },
113     };
114     return HksAddParams(paramSet, commonParams, ARRAY_SIZE(commonParams));
115 }
116 
AddAuthGenParams(struct HksParamSet * paramSet)117 static int32_t AddAuthGenParams(struct HksParamSet *paramSet)
118 {
119     struct HksParam authParams[] = {
120         { .tag = HKS_TAG_KEY_AUTH_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
121         { .tag = HKS_TAG_KEY_AUTH_ACCESS_TYPE, .uint32Param = HKS_AUTH_ACCESS_ALWAYS_VALID },
122         { .tag = HKS_TAG_BATCH_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
123         { .tag = HKS_TAG_CHALLENGE_TYPE, .uint32Param = HKS_CHALLENGE_TYPE_NORMAL },
124         { .tag = HKS_TAG_USER_AUTH_TYPE, .uint32Param =
125             HKS_USER_AUTH_TYPE_FINGERPRINT | HKS_USER_AUTH_TYPE_FACE | HKS_USER_AUTH_TYPE_PIN }
126     };
127     return HksAddParams(paramSet, authParams, ARRAY_SIZE(authParams));
128 }
129 
GenerateKey(const struct KeyId * keyId,bool needAuth,bool requirePasswordSet)130 int32_t GenerateKey(const struct KeyId *keyId, bool needAuth, bool requirePasswordSet)
131 {
132     struct HksParamSet *paramSet = NULL;
133     int32_t ret = HKS_SUCCESS;
134     do {
135         ret = HksInitParamSet(&paramSet);
136         if (ret != HKS_SUCCESS) {
137             LOGE("[FATAL]HUKS init param set failed. error=%{public}d", ret);
138             break;
139         }
140 
141         ret = AddCommonGenParams(paramSet, keyId);
142         if (ret != HKS_SUCCESS) {
143             LOGE("[FATAL]HUKS add common params failed. error=%{public}d", ret);
144             break;
145         }
146 
147         if (keyId->userId > ASSET_ROOT_USER_UPPERBOUND) {
148             ret = AddSpecificUserIdParams(paramSet, keyId->userId);
149             if (ret != HKS_SUCCESS) {
150                 LOGE("[FATAL]HUKS add specific userId failed. error=%{public}d", ret);
151                 break;
152             }
153         }
154 
155         if (needAuth) {
156             ret = AddAuthGenParams(paramSet);
157             if (ret != HKS_SUCCESS) {
158                 LOGE("[FATAL]HUKS add auth params failed. error=%{public}d", ret);
159                 break;
160             }
161         }
162 
163         if (requirePasswordSet) {
164             struct HksParam tempParam = { .tag = HKS_TAG_IS_DEVICE_PASSWORD_SET, .boolParam = true };
165             ret = HksAddParams(paramSet, &tempParam, 1); // 1: add one param to paramSet
166             if (ret != HKS_SUCCESS) {
167                 LOGE("[FATAL]HUKS add requirePasswordSet param failed. error=%{public}d", ret);
168                 break;
169             }
170         }
171 
172         ret = HksBuildParamSet(&paramSet);
173         if (ret != HKS_SUCCESS) {
174             LOGE("[FATAL]HUKS build param set failed. error=%{public}d", ret);
175             break;
176         }
177 
178         ret = HksGenerateKey(&keyId->alias, paramSet, NULL);
179         if (ret != HKS_SUCCESS) {
180             LOGE("[FATAL]HUKS generate key failed. error=%{public}d", ret);
181         }
182     } while (0);
183 
184     HksFreeParamSet(&paramSet);
185     return HuksErrorTransfer(ret);
186 }
187 
DeleteKey(const struct KeyId * keyId)188 int32_t DeleteKey(const struct KeyId *keyId)
189 {
190     struct HksParam params[] = {
191         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
192     };
193     struct HksParamSet *paramSet = NULL;
194     int32_t ret = BuildParamSet(&paramSet, params, ARRAY_SIZE(params), keyId->userId);
195     if (ret != HKS_SUCCESS) {
196         return HuksErrorTransfer(ret);
197     }
198 
199     ret = HksDeleteKey(&keyId->alias, paramSet);
200     HksFreeParamSet(&paramSet);
201     return HuksErrorTransfer(ret);
202 }
203 
IsKeyExist(const struct KeyId * keyId)204 int32_t IsKeyExist(const struct KeyId *keyId)
205 {
206     struct HksParam params[] = {
207         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
208     };
209     struct HksParamSet *paramSet = NULL;
210     int32_t ret = BuildParamSet(&paramSet, params, ARRAY_SIZE(params), keyId->userId);
211     if (ret != HKS_SUCCESS) {
212         return HuksErrorTransfer(ret);
213     }
214 
215     ret = HksKeyExist(&keyId->alias, paramSet);
216     HksFreeParamSet(&paramSet);
217     return HuksErrorTransfer(ret);
218 }
219 
EncryptData(const struct KeyId * keyId,const struct HksBlob * aad,const struct HksBlob * inData,struct HksBlob * outData)220 int32_t EncryptData(const struct KeyId *keyId, const struct HksBlob *aad, const struct HksBlob *inData,
221     struct HksBlob *outData)
222 {
223     struct HksParam encryptParams[] = {
224         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
225         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
226         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
227         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
228         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
229         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = *aad },
230         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
231     };
232     struct HksParamSet *encryptParamSet = NULL;
233     int32_t ret = BuildParamSet(&encryptParamSet, encryptParams, ARRAY_SIZE(encryptParams), keyId->userId);
234     if (ret != HKS_SUCCESS) {
235         return HuksErrorTransfer(ret);
236     }
237 
238     uint8_t handle[sizeof(uint64_t)] = { 0 };
239     struct HksBlob handleBlob = { sizeof(uint64_t), handle };
240     ret = HksInit(&keyId->alias, encryptParamSet, &handleBlob, NULL);
241     if (ret != HKS_SUCCESS) {
242         LOGE("[FATAL]HUKS encrypt init failed. error=%{public}d", ret);
243         HksFreeParamSet(&encryptParamSet);
244         return HuksErrorTransfer(ret);
245     }
246 
247     ret = HksFinish(&handleBlob, encryptParamSet, inData, outData);
248     HksFreeParamSet(&encryptParamSet);
249     if (ret != HKS_SUCCESS) {
250         LOGE("[FATAL]HUKS encrypt finish failed. error=%{public}d", ret);
251     }
252     return HuksErrorTransfer(ret);
253 }
254 
DecryptData(const struct KeyId * keyId,const struct HksBlob * aad,const struct HksBlob * inData,struct HksBlob * outData)255 int32_t DecryptData(const struct KeyId *keyId, const struct HksBlob *aad, const struct HksBlob *inData,
256     struct HksBlob *outData)
257 {
258     struct HksBlob cipher = { inData->size - NONCE_SIZE - TAG_SIZE, inData->data };
259     struct HksBlob tag = { TAG_SIZE, inData->data + (inData->size - NONCE_SIZE - TAG_SIZE) };
260     struct HksBlob nonce = { NONCE_SIZE, inData->data + (inData->size - NONCE_SIZE) };
261 
262     struct HksParamSet *decryptParamSet = NULL;
263     struct HksParam decryptParams[] = {
264         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
265         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
266         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
267         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
268         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
269         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = *aad },
270         { .tag = HKS_TAG_NONCE, .blob = nonce },
271         { .tag = HKS_TAG_AE_TAG, .blob = tag },
272         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
273     };
274 
275     int32_t ret = BuildParamSet(&decryptParamSet, decryptParams, ARRAY_SIZE(decryptParams), keyId->userId);
276     if (ret != HKS_SUCCESS) {
277         return HuksErrorTransfer(ret);
278     }
279 
280     uint8_t handle[sizeof(uint64_t)] = { 0 };
281     struct HksBlob handleBlob = { sizeof(uint64_t), handle };
282     ret = HksInit(&keyId->alias, decryptParamSet, &handleBlob, NULL);
283     if (ret != HKS_SUCCESS) {
284         LOGE("[FATAL]HUKS decrypt init failed. error=%{public}d", ret);
285         HksFreeParamSet(&decryptParamSet);
286         return HuksErrorTransfer(ret);
287     }
288 
289     ret = HksFinish(&handleBlob, decryptParamSet, &cipher, outData);
290     HksFreeParamSet(&decryptParamSet);
291     if (ret != HKS_SUCCESS) {
292         LOGE("[FATAL]HUKS decrypt finish failed. error=%{public}d", ret);
293     }
294     return HuksErrorTransfer(ret);
295 }
296 
InitKey(const struct KeyId * keyId,uint32_t validTime,struct HksBlob * challenge,struct HksBlob * handle)297 int32_t InitKey(const struct KeyId *keyId, uint32_t validTime, struct HksBlob *challenge, struct HksBlob *handle)
298 {
299     struct HksParam initParams[] = {
300         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES},
301         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
302         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
303         { .tag = HKS_TAG_IS_BATCH_OPERATION, .boolParam = true },
304         { .tag = HKS_TAG_BATCH_OPERATION_TIMEOUT, .uint32Param = validTime },
305         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
306     };
307     struct HksParamSet *paramSet = NULL;
308     int32_t ret = BuildParamSet(&paramSet, initParams, ARRAY_SIZE(initParams), keyId->userId);
309     if (ret != HKS_SUCCESS) {
310         return HuksErrorTransfer(ret);
311     }
312 
313     ret = HksInit(&keyId->alias, paramSet, handle, challenge);
314     HksFreeParamSet(&paramSet);
315     if (ret != HKS_SUCCESS) {
316         LOGE("[FATAL]HUKS batch decrypt init failed. error=%{public}d", ret);
317     }
318     return HuksErrorTransfer(ret);
319 }
320 
ExecCrypt(const struct HksBlob * handle,const struct HksBlob * aad,const struct HksBlob * authToken,const struct HksBlob * inData,struct HksBlob * outData)321 int32_t ExecCrypt(const struct HksBlob *handle, const struct HksBlob *aad, const struct HksBlob *authToken,
322     const struct HksBlob *inData, struct HksBlob *outData)
323 {
324     struct HksBlob tag = { TAG_SIZE, inData->data + (inData->size - NONCE_SIZE - TAG_SIZE) };
325     struct HksBlob nonce = { NONCE_SIZE, inData->data + (inData->size - NONCE_SIZE) };
326 
327     struct HksParam updateParams[] = {
328         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
329         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
330         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
331         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
332         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
333         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { .size = aad->size, .data = aad->data } },
334         { .tag = HKS_TAG_NONCE, .blob = nonce },
335         { .tag = HKS_TAG_AE_TAG, .blob = tag },
336         { .tag = HKS_TAG_AUTH_TOKEN, .blob = *authToken },
337     };
338 
339     struct HksParamSet *paramSet = NULL;
340     int32_t ret = BuildParamSet(&paramSet, updateParams, ARRAY_SIZE(updateParams), 0);
341     if (ret != HKS_SUCCESS) {
342         return HuksErrorTransfer(ret);
343     }
344 
345     struct HksBlob cipher = { inData->size - NONCE_SIZE - TAG_SIZE, inData->data };
346     ret = HksUpdate(handle, paramSet, &cipher, outData);
347     HksFreeParamSet(&paramSet);
348     if (ret != HKS_SUCCESS) {
349         LOGE("[FATAL]HUKS batch decrypt update failed. error=%{public}d", ret);
350     }
351     return HuksErrorTransfer(ret);
352 }
353 
Drop(const struct HksBlob * handle)354 int32_t Drop(const struct HksBlob *handle)
355 {
356     struct HksBlob inData = { 0, NULL };
357     struct HksBlob outData = { 0, NULL };
358 
359     struct HksParamSet *paramSet = NULL;
360     int32_t ret = BuildParamSet(&paramSet, NULL, 0, 0);
361     if (ret != HKS_SUCCESS) {
362         return HuksErrorTransfer(ret);
363     }
364 
365     ret = HksFinish(handle, paramSet, &inData, &outData);
366     HksFreeParamSet(&paramSet);
367     if (ret != HKS_SUCCESS) {
368         LOGE("[FATAL]HUKS batch decrypt finish failed. error=%{public}d", ret);
369     }
370     return HuksErrorTransfer(ret);
371 }
372 
RenameKeyAlias(const struct KeyId * keyId,const struct HksBlob * newKeyAlias)373 int32_t RenameKeyAlias(const struct KeyId *keyId, const struct HksBlob *newKeyAlias)
374 {
375     struct HksParam params[] = {
376         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = AccessibilityToHksAuthStorageLevel(keyId->accessibility) },
377         { .tag = HKS_TAG_IS_COPY_NEW_KEY, .boolParam = true },
378     };
379     struct HksParamSet *paramSet = NULL;
380     int32_t ret = BuildParamSet(&paramSet, params, ARRAY_SIZE(params), keyId->userId);
381     if (ret != HKS_SUCCESS) {
382         return HuksErrorTransfer(ret);
383     }
384 
385     ret = HksRenameKeyAlias(&keyId->alias, paramSet, newKeyAlias);
386     HksFreeParamSet(&paramSet);
387     if (ret != HKS_SUCCESS) {
388         LOGE("[FATAL]HUKS rename key alias failed. error=%{public}d", ret);
389     }
390     return HuksErrorTransfer(ret);
391 }