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