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