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