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(¶mSet);
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(¶mSet);
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(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, NULL, 0, 0);
358 if (ret != HKS_SUCCESS) {
359 return HuksErrorTransfer(ret);
360 }
361
362 ret = HksFinish(handle, paramSet, &inData, &outData);
363 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
384 if (ret != HKS_SUCCESS) {
385 LOGE("[FATAL]HUKS rename key alias failed. error=%{public}d", ret);
386 }
387 return HuksErrorTransfer(ret);
388 }