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