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