1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 * Description: key manager kernel API function implementation.
15 *
16 * Create: 2023-05-26
17 */
18
19 #include "kapi_km.h"
20 #include "kapi_inner.h"
21
22 #include "crypto_common_def.h"
23 #include "crypto_common_macro.h"
24 #include "crypto_drv_common.h"
25 #include "drv_klad.h"
26 #include "drv_keyslot.h"
27
28 #define handle_2_id(handle) (((handle)) & 0xffff)
29
30 typedef struct {
31 crypto_owner owner;
32 td_bool is_open;
33 td_handle keyslot_handle;
34 crypto_keyslot_type type;
35 } crypto_kapi_keyslot_ctx;
36
37 typedef struct {
38 crypto_owner owner;
39 td_handle drv_klad_handle;
40 td_handle drv_keyslot_handle;
41 crypto_klad_dest klad_type;
42 crypto_klad_attr klad_attr;
43 crypto_klad_session_key session_key;
44 td_handle keyslot_handle;
45 unsigned int is_open : 1;
46 unsigned int is_attached : 1;
47 unsigned int is_set_attr : 1;
48 unsigned int is_set_session_key : 1;
49 } crypto_kapi_klad_ctx;
50
51 crypto_mutex g_klad_mutex;
52 crypto_mutex g_keyslot_mutex;
53
54 #define CRYPTO_MCIPHER_KEYSLOT_NUM 8
55 #define CRYPTO_HMAC_KEYSLOT_NUM 2
56 #define CRYPTO_KLAD_VIRT_NUM 4
57
58 static crypto_kapi_keyslot_ctx g_keyslot_symc_ctx_list[CRYPTO_MCIPHER_KEYSLOT_NUM] = {0};
59 static crypto_kapi_keyslot_ctx g_keyslot_hmac_ctx_list[CRYPTO_HMAC_KEYSLOT_NUM] = {0};
60
61 static crypto_kapi_klad_ctx g_klad_ctx_list[CRYPTO_KLAD_VIRT_NUM] = {0};
62
63 #define kapi_klad_mutex_lock() crypto_mutex_lock(&g_klad_mutex)
64
65 #define kapi_klad_mutex_unlock() crypto_mutex_unlock(&g_klad_mutex)
66
67 #define kapi_keyslot_mutex_lock() crypto_mutex_lock(&g_keyslot_mutex)
68
69 #define kapi_keyslot_mutex_unlock() crypto_mutex_unlock(&g_keyslot_mutex)
70
71 #define km_compat_errno(err_code) KAPI_COMPAT_ERRNO(ERROR_MODULE_KM, err_code)
72 #define km_null_ptr_chk(ptr) \
73 crypto_chk_return((ptr) == TD_NULL, km_compat_errno(ERROR_PARAM_IS_NULL), #ptr" is NULL\n")
74
kapi_km_env_init(td_void)75 td_s32 kapi_km_env_init(td_void)
76 {
77 td_s32 ret;
78
79 ret = crypto_mutex_init(&g_klad_mutex);
80 crypto_chk_return(ret != TD_SUCCESS, ret, "crypto_mutex_init failed, ret is 0x%x\n", ret);
81
82 ret = crypto_mutex_init(&g_keyslot_mutex);
83 crypto_chk_goto(ret != TD_SUCCESS, klad_mutex_destroy_exit, "crypto_mutex_init failed, ret is 0x%x\n", ret);
84
85 ret = drv_keyslot_init();
86 crypto_chk_goto(ret != TD_SUCCESS, keyslot_mutex_destroy_exit, "drv_keyslot_init failed, ret is 0x%x\n", ret);
87
88 return TD_SUCCESS;
89
90 keyslot_mutex_destroy_exit:
91 crypto_mutex_destroy(&g_keyslot_mutex);
92 klad_mutex_destroy_exit:
93 crypto_mutex_destroy(&g_klad_mutex);
94 return TD_FAILURE;
95 }
96
kapi_km_env_deinit(td_void)97 td_s32 kapi_km_env_deinit(td_void)
98 {
99 crypto_mutex_destroy(&g_keyslot_mutex);
100 crypto_mutex_destroy(&g_klad_mutex);
101
102 (td_void)memset_s(g_keyslot_symc_ctx_list, sizeof(g_keyslot_symc_ctx_list), 0, sizeof(g_keyslot_symc_ctx_list));
103 (td_void)memset_s(g_keyslot_hmac_ctx_list, sizeof(g_keyslot_hmac_ctx_list), 0, sizeof(g_keyslot_hmac_ctx_list));
104
105 (td_void)drv_keyslot_deinit();
106
107 (td_void)memset_s(g_klad_ctx_list, sizeof(g_klad_ctx_list), 0, sizeof(g_klad_ctx_list));
108
109 return TD_SUCCESS;
110 }
111
kapi_km_deinit(td_void)112 td_s32 kapi_km_deinit(td_void)
113 {
114 td_s32 i;
115 crypto_owner owner;
116 crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL;
117 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
118
119 crypto_get_owner(&owner);
120 /* mcipher keyslot. */
121 for (i = 0; i < CRYPTO_MCIPHER_KEYSLOT_NUM; i++) {
122 keyslot_ctx = &g_keyslot_symc_ctx_list[i];
123 if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) == 0) {
124 (td_void)drv_keyslot_destroy(keyslot_ctx->keyslot_handle);
125 (td_void)memset_s(keyslot_ctx, sizeof(crypto_kapi_keyslot_ctx), 0, sizeof(crypto_kapi_keyslot_ctx));
126 }
127 }
128 /* hmac keyslot. */
129 for (i = 0; i < CRYPTO_HMAC_KEYSLOT_NUM; i++) {
130 keyslot_ctx = &g_keyslot_hmac_ctx_list[i];
131 if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) == 0) {
132 (td_void)drv_keyslot_destroy(keyslot_ctx->keyslot_handle);
133 (td_void)memset_s(keyslot_ctx, sizeof(crypto_kapi_keyslot_ctx), 0, sizeof(crypto_kapi_keyslot_ctx));
134 }
135 }
136
137 /* klad. */
138 for (i = 0; i < CRYPTO_HMAC_KEYSLOT_NUM; i++) {
139 klad_ctx = &g_klad_ctx_list[i];
140 if (memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) == 0) {
141 (td_void)memset_s(klad_ctx, sizeof(crypto_kapi_klad_ctx), 0, sizeof(crypto_kapi_klad_ctx));
142 }
143 }
144
145 return TD_SUCCESS;
146 }
147
inner_keyslot_handle_chk(td_handle keyslot_handle)148 static td_s32 inner_keyslot_handle_chk(td_handle keyslot_handle)
149 {
150 td_u32 idx = 0;
151 if (crypto_keyslot_get_module_id(keyslot_handle) != KAPI_KEYSLOT_MODULE_ID) {
152 crypto_log_err("invliad module id\n");
153 return km_compat_errno(ERROR_INVALID_HANDLE);
154 }
155 idx = crypto_keyslot_get_idx(keyslot_handle);
156 if (crypto_keyslot_is_hmac(keyslot_handle) == TD_TRUE) {
157 crypto_chk_return(idx >= CRYPTO_HMAC_KEYSLOT_NUM, km_compat_errno(ERROR_INVALID_HANDLE),
158 "idx overflow for hmac keyslot\n");
159 } else if (crypto_keyslot_is_mcipher(keyslot_handle) == TD_TRUE) {
160 crypto_chk_return(idx >= CRYPTO_MCIPHER_KEYSLOT_NUM, km_compat_errno(ERROR_INVALID_HANDLE),
161 "idx overflow for mcipher keyslot\n");
162 } else {
163 crypto_log_err("invalid keyslot_type, keyslot_handle is 0x%x\n", keyslot_handle);
164 return km_compat_errno(ERROR_INVALID_HANDLE);
165 }
166 return TD_SUCCESS;
167 }
168
inner_keyslot_get_ctx(td_handle keyslot_handle)169 static crypto_kapi_keyslot_ctx *inner_keyslot_get_ctx(td_handle keyslot_handle)
170 {
171 td_s32 ret;
172 td_u32 idx = 0;
173 crypto_kapi_keyslot_ctx *ctx = TD_NULL;
174
175 ret = inner_keyslot_handle_chk(keyslot_handle);
176 crypto_chk_return(ret != TD_SUCCESS, TD_NULL, "inner_keyslot_handle_chk failed\n");
177
178 idx = crypto_keyslot_get_idx(keyslot_handle);
179 if (crypto_keyslot_is_mcipher(keyslot_handle)) {
180 ctx = &g_keyslot_symc_ctx_list[idx];
181 } else {
182 ctx = &g_keyslot_hmac_ctx_list[idx];
183 }
184 return ctx;
185 }
186
inner_klad_handle_chk(td_handle klad_handle)187 static td_s32 inner_klad_handle_chk(td_handle klad_handle)
188 {
189 td_u32 idx = 0;
190 if (kapi_get_module_id(klad_handle) != KAPI_KLAD_MODULE_ID) {
191 crypto_log_err("invalid module id\n");
192 return km_compat_errno(ERROR_INVALID_HANDLE);
193 }
194 idx = kapi_get_ctx_idx(klad_handle);
195 crypto_chk_return(idx >= CRYPTO_KLAD_VIRT_NUM, km_compat_errno(ERROR_INVALID_HANDLE),
196 "idx overflow for klad\n");
197
198 return TD_SUCCESS;
199 }
200
201 #define HASH_BLOCK_SIZE_64BYTE 64
202 #define HASH_BLOCK_SIZE_128BYTE 128
inner_hmac_clear_key_size_check(crypto_klad_hmac_type hmac_type,td_u32 key_length)203 static td_bool inner_hmac_clear_key_size_check(crypto_klad_hmac_type hmac_type, td_u32 key_length)
204 {
205 td_u32 block_size = 0;
206
207 switch (hmac_type) {
208 case CRYPTO_KLAD_HMAC_TYPE_SHA1:
209 case CRYPTO_KLAD_HMAC_TYPE_SHA224:
210 case CRYPTO_KLAD_HMAC_TYPE_SHA256:
211 case CRYPTO_KLAD_HMAC_TYPE_SM3:
212 block_size = HASH_BLOCK_SIZE_64BYTE;
213 break;
214 case CRYPTO_KLAD_HMAC_TYPE_SHA384:
215 case CRYPTO_KLAD_HMAC_TYPE_SHA512:
216 block_size = HASH_BLOCK_SIZE_128BYTE;
217 break;
218 default:
219 crypto_log_err("Invalid Hmac Mode!\n");
220 return TD_FALSE;
221 }
222
223 if (key_length > block_size) {
224 return TD_FALSE;
225 }
226
227 return TD_TRUE;
228 }
229
230 /* Keyslot. Long-term occupation by default */
kapi_keyslot_create(td_handle * kapi_keyslot_handle,crypto_keyslot_type keyslot_type)231 td_s32 kapi_keyslot_create(td_handle *kapi_keyslot_handle, crypto_keyslot_type keyslot_type)
232 {
233 td_u32 idx;
234 td_s32 ret = TD_SUCCESS;
235 td_handle keyslot_handle = 0;
236 crypto_kapi_keyslot_ctx *ctx_list = TD_NULL;
237 crypto_kapi_keyslot_ctx *current_ctx = TD_NULL;
238 td_u32 is_hmac = 0;
239
240 km_null_ptr_chk(kapi_keyslot_handle);
241 if (keyslot_type == (crypto_keyslot_type)CRYPTO_KEYSLOT_TYPE_MCIPHER) {
242 ctx_list = g_keyslot_symc_ctx_list;
243 } else if (keyslot_type == (crypto_keyslot_type)CRYPTO_KEYSLOT_TYPE_HMAC) {
244 ctx_list = g_keyslot_hmac_ctx_list;
245 is_hmac = 1;
246 } else {
247 crypto_log_err("invalid keyslot_type\n");
248 return km_compat_errno(ERROR_INVALID_PARAM);
249 }
250
251 kapi_keyslot_mutex_lock();
252
253 ret = drv_keyslot_create(&keyslot_handle, keyslot_type);
254 crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_keyslot_create failed, ret is 0x%x\n", ret);
255 idx = handle_2_id(keyslot_handle);
256
257 current_ctx = &ctx_list[idx];
258 current_ctx->keyslot_handle = keyslot_handle;
259 current_ctx->type = keyslot_type;
260 current_ctx->is_open = TD_TRUE;
261 crypto_get_owner(¤t_ctx->owner);
262
263 *kapi_keyslot_handle = crypto_keyslot_compat_handle(is_hmac, idx);
264
265 exit_unlock:
266 kapi_keyslot_mutex_unlock();
267 return ret;
268 }
269 CRYPTO_EXPORT_SYMBOL(kapi_keyslot_create);
270
kapi_keyslot_destroy(td_handle kapi_keyslot_handle)271 td_s32 kapi_keyslot_destroy(td_handle kapi_keyslot_handle)
272 {
273 td_s32 ret = TD_SUCCESS;
274 crypto_owner owner;
275 crypto_kapi_keyslot_ctx *current_ctx = TD_NULL;
276
277 current_ctx = inner_keyslot_get_ctx(kapi_keyslot_handle);
278 crypto_chk_return(current_ctx == TD_NULL, km_compat_errno(ERROR_INVALID_HANDLE), "inner_keyslot_get_ctx failed\n");
279
280 kapi_keyslot_mutex_lock();
281 if (current_ctx->is_open == TD_FALSE) {
282 ret = TD_SUCCESS;
283 goto exit_unlock;
284 }
285
286 crypto_get_owner(&owner);
287 if (memcmp(&owner, ¤t_ctx->owner, sizeof(crypto_owner)) != 0) {
288 crypto_log_err("invalid process\n");
289 ret = km_compat_errno(ERROR_INVALID_PROCESS);
290 goto exit_unlock;
291 }
292
293 ret = drv_keyslot_destroy(current_ctx->keyslot_handle);
294 crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_keyslot_destroy failed, ret is 0x%x\n", ret);
295
296 (td_void)memset_s(current_ctx, sizeof(crypto_kapi_keyslot_ctx), 0, sizeof(crypto_kapi_keyslot_ctx));
297
298 exit_unlock:
299 kapi_keyslot_mutex_unlock();
300
301 return ret;
302 }
303 CRYPTO_EXPORT_SYMBOL(kapi_keyslot_destroy);
304
305 /* Klad. Short-term occupation by default */
kapi_klad_create(td_handle * kapi_klad_handle)306 td_s32 kapi_klad_create(td_handle *kapi_klad_handle)
307 {
308 td_u32 i;
309 td_s32 ret = TD_SUCCESS;
310 crypto_kapi_klad_ctx *ctx = TD_NULL;
311
312 km_null_ptr_chk(kapi_klad_handle);
313
314 kapi_klad_mutex_lock();
315 for (i = 0; i < CRYPTO_KLAD_VIRT_NUM; i++) {
316 if (g_klad_ctx_list[i].is_open == TD_FALSE) {
317 ctx = &g_klad_ctx_list[i];
318 break;
319 }
320 }
321 if (ctx == TD_NULL) {
322 crypto_log_err("all klad contexts are busy\n");
323 ret = km_compat_errno(ERROR_CHN_BUSY);
324 goto exit_unlock;
325 }
326
327 crypto_get_owner(&ctx->owner);
328 ctx->is_open = TD_TRUE;
329 *kapi_klad_handle = synthesize_kapi_handle(KAPI_KLAD_MODULE_ID, i);
330
331 exit_unlock:
332 kapi_klad_mutex_unlock();
333 return ret;
334 }
335 CRYPTO_EXPORT_SYMBOL(kapi_klad_create);
336
kapi_klad_destroy(td_handle kapi_klad_handle)337 td_s32 kapi_klad_destroy(td_handle kapi_klad_handle)
338 {
339 td_s32 ret = TD_SUCCESS;
340 td_u32 idx = 0;
341 crypto_kapi_klad_ctx *ctx = TD_NULL;
342 crypto_owner owner;
343
344 ret = inner_klad_handle_chk(kapi_klad_handle);
345 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
346
347 idx = kapi_get_ctx_idx(kapi_klad_handle);
348 ctx = &g_klad_ctx_list[idx];
349 if (ctx->is_open == TD_FALSE) {
350 return TD_SUCCESS;
351 }
352 kapi_klad_mutex_lock();
353
354 crypto_get_owner(&owner);
355 if (memcmp(&owner, &ctx->owner, sizeof(crypto_owner)) != 0) {
356 crypto_log_err("invalid process\n");
357 ret = km_compat_errno(ERROR_INVALID_PROCESS);
358 goto exit_unlock;
359 }
360
361 (td_void)memset_s(ctx, sizeof(crypto_kapi_klad_ctx), 0, sizeof(crypto_kapi_klad_ctx));
362
363 exit_unlock:
364 kapi_klad_mutex_unlock();
365 return ret;
366 }
367 CRYPTO_EXPORT_SYMBOL(kapi_klad_destroy);
368
kapi_klad_attach(td_handle kapi_klad_handle,crypto_klad_dest klad_type,td_handle kapi_keyslot_handle)369 td_s32 kapi_klad_attach(td_handle kapi_klad_handle, crypto_klad_dest klad_type,
370 td_handle kapi_keyslot_handle)
371 {
372 td_s32 ret = TD_SUCCESS;
373 td_u32 idx = 0;
374 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
375 crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL;
376 crypto_owner owner;
377 crypto_get_owner(&owner);
378
379 crypto_chk_return (klad_type >= CRYPTO_KLAD_DEST_MAX, km_compat_errno(ERROR_INVALID_PARAM),
380 "Invalid klad_dest_type\n");
381
382 ret = inner_klad_handle_chk(kapi_klad_handle);
383 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
384
385 idx = kapi_get_ctx_idx(kapi_klad_handle);
386 klad_ctx = &g_klad_ctx_list[idx];
387
388 kapi_klad_mutex_lock();
389 crypto_chk_goto_with_ret(ret, klad_ctx->is_open == TD_FALSE, exit_unlock,
390 km_compat_errno(ERROR_CTX_CLOSED), "call klad_create first\n");
391 crypto_chk_goto_with_ret(ret, memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock,
392 km_compat_errno(ERROR_INVALID_PROCESS), "invalid process\n");
393
394 if (klad_type != CRYPTO_KLAD_DEST_NPU) {
395 keyslot_ctx = inner_keyslot_get_ctx(kapi_keyslot_handle);
396 crypto_chk_goto_with_ret(ret, keyslot_ctx == TD_NULL, exit_unlock, km_compat_errno(ERROR_INVALID_HANDLE),
397 "inner_keyslot_get_ctx failed\n");
398 crypto_chk_goto_with_ret(ret, keyslot_ctx->is_open == TD_FALSE, exit_unlock, km_compat_errno(ERROR_CTX_CLOSED),
399 "call keyslot_create first\n");
400 if (memcmp(&owner, &keyslot_ctx->owner, sizeof(crypto_owner)) != 0) {
401 crypto_log_err("invalid process\n");
402 ret = km_compat_errno(ERROR_INVALID_PROCESS);
403 goto exit_unlock;
404 }
405 klad_ctx->keyslot_handle = keyslot_ctx->keyslot_handle;
406 } else {
407 klad_ctx->keyslot_handle = kapi_keyslot_handle;
408 }
409
410 klad_ctx->is_attached = TD_TRUE;
411 klad_ctx->klad_type = klad_type;
412
413 exit_unlock:
414 kapi_klad_mutex_unlock();
415 return ret;
416 }
417 CRYPTO_EXPORT_SYMBOL(kapi_klad_attach);
418
kapi_klad_detach(td_handle kapi_klad_handle,crypto_klad_dest klad_type,td_handle kapi_keyslot_handle)419 td_s32 kapi_klad_detach(td_handle kapi_klad_handle, crypto_klad_dest klad_type,
420 td_handle kapi_keyslot_handle)
421 {
422 td_s32 ret = TD_SUCCESS;
423 td_u32 idx = 0;
424 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
425 crypto_kapi_keyslot_ctx *keyslot_ctx = TD_NULL;
426 crypto_owner owner;
427
428 crypto_chk_return (klad_type >= CRYPTO_KLAD_DEST_MAX, km_compat_errno(ERROR_INVALID_PARAM),
429 "Invalid klad_dest_type\n");
430
431 ret = inner_klad_handle_chk(kapi_klad_handle);
432 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
433
434 crypto_get_owner(&owner);
435 idx = kapi_get_ctx_idx(kapi_klad_handle);
436 klad_ctx = &g_klad_ctx_list[idx];
437 kapi_klad_mutex_lock();
438
439 crypto_chk_goto_with_ret(ret, memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock,
440 km_compat_errno(ERROR_INVALID_PROCESS), "invalid process\n");
441 crypto_chk_goto_with_ret(ret, klad_ctx->is_open == TD_FALSE, exit_unlock, km_compat_errno(ERROR_CTX_CLOSED),
442 "call klad_create first\n");
443 crypto_chk_goto_with_ret(ret, klad_ctx->is_attached == TD_FALSE, exit_unlock, km_compat_errno(ERROR_NOT_ATTACHED),
444 "call klad_attach first\n");
445
446 crypto_chk_goto_with_ret(ret, klad_ctx->klad_type != (crypto_klad_dest)klad_type, exit_unlock,
447 km_compat_errno(ERROR_INVALID_PARAM), "invalid klad_type\n");
448 if (klad_type != CRYPTO_KLAD_DEST_NPU) {
449 keyslot_ctx = inner_keyslot_get_ctx(kapi_keyslot_handle);
450 crypto_chk_goto_with_ret(ret, keyslot_ctx == TD_NULL, exit_unlock, km_compat_errno(ERROR_INVALID_HANDLE),
451 "inner_keyslot_get_ctx failed\n");
452 crypto_chk_goto_with_ret(ret, keyslot_ctx->keyslot_handle != klad_ctx->keyslot_handle, exit_unlock,
453 km_compat_errno(ERROR_INVALID_HANDLE), "invalid keyslot_handle\n");
454 } else {
455 crypto_chk_goto_with_ret(ret, klad_ctx->keyslot_handle != kapi_keyslot_handle, exit_unlock,
456 km_compat_errno(ERROR_INVALID_HANDLE), "invalid npu keyslot_handle\n");
457 }
458
459 klad_ctx->is_attached = TD_FALSE;
460 klad_ctx->keyslot_handle = 0;
461 klad_ctx->klad_type = 0;
462
463 exit_unlock:
464 kapi_klad_mutex_unlock();
465 return ret;
466 }
467 CRYPTO_EXPORT_SYMBOL(kapi_klad_detach);
468
kapi_klad_set_attr(td_handle kapi_klad_handle,const crypto_klad_attr * attr)469 td_s32 kapi_klad_set_attr(td_handle kapi_klad_handle, const crypto_klad_attr *attr)
470 {
471 td_s32 ret = TD_SUCCESS;
472 td_u32 idx = 0;
473 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
474 crypto_owner owner;
475
476 km_null_ptr_chk(attr);
477 crypto_chk_return(attr->key_sec_cfg.key_sec >= CRYPTO_KLAD_SEC_MAX, km_compat_errno(ERROR_INVALID_PARAM),
478 "crypto_klad_attr.key_sec_cfg.key_sec >= CRYPTO_KLAD_SEC_MAX\n");
479 crypto_chk_return(attr->key_cfg.engine >= CRYPTO_KLAD_ENGINE_MAX, km_compat_errno(ERROR_INVALID_PARAM),
480 "crypto_klad_attr.key_cfg.engine >= CRYPTO_KLAD_ENGINE_MAX\n");
481
482 ret = inner_klad_handle_chk(kapi_klad_handle);
483 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
484
485 crypto_get_owner(&owner);
486 idx = kapi_get_ctx_idx(kapi_klad_handle);
487 klad_ctx = &g_klad_ctx_list[idx];
488 kapi_klad_mutex_lock();
489
490 crypto_chk_goto_with_ret(ret, memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock,
491 km_compat_errno(ERROR_INVALID_PROCESS), "invalid process\n");
492 crypto_chk_goto_with_ret(ret, klad_ctx->is_open == TD_FALSE, exit_unlock,
493 km_compat_errno(ERROR_CTX_CLOSED), "call klad_create first\n");
494
495 ret = memcpy_s(&klad_ctx->klad_attr, sizeof(crypto_klad_attr), attr, sizeof(crypto_klad_attr));
496 crypto_chk_goto_with_ret(ret, ret != EOK, exit_unlock, km_compat_errno(ERROR_MEMCPY_S), "memcpy_s failed\n");
497
498 klad_ctx->is_set_attr = TD_TRUE;
499
500 exit_unlock:
501 kapi_klad_mutex_unlock();
502 return ret;
503 }
504 CRYPTO_EXPORT_SYMBOL(kapi_klad_set_attr);
505
kapi_klad_get_attr(td_handle kapi_klad_handle,crypto_klad_attr * attr)506 td_s32 kapi_klad_get_attr(td_handle kapi_klad_handle, crypto_klad_attr *attr)
507 {
508 td_s32 ret = TD_SUCCESS;
509 td_u32 idx = 0;
510 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
511 crypto_owner owner;
512
513 km_null_ptr_chk(attr);
514 ret = inner_klad_handle_chk(kapi_klad_handle);
515 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
516
517 crypto_get_owner(&owner);
518 idx = kapi_get_ctx_idx(kapi_klad_handle);
519 klad_ctx = &g_klad_ctx_list[idx];
520 kapi_klad_mutex_lock();
521
522 crypto_chk_goto_with_ret(ret, memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock,
523 km_compat_errno(ERROR_INVALID_PROCESS), "invalid process\n");
524 crypto_chk_goto_with_ret(ret, klad_ctx->is_open == TD_FALSE, exit_unlock,
525 km_compat_errno(ERROR_CTX_CLOSED), "call klad_create first\n");
526 crypto_chk_goto_with_ret(ret, klad_ctx->is_set_attr == TD_FALSE, exit_unlock,
527 km_compat_errno(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n");
528
529 ret = memcpy_s(attr, sizeof(crypto_klad_attr), &klad_ctx->klad_attr, sizeof(crypto_klad_attr));
530 crypto_chk_goto_with_ret(ret, ret != EOK, exit_unlock, km_compat_errno(ERROR_MEMCPY_S), "memcpy_s failed\n");
531
532 exit_unlock:
533 kapi_klad_mutex_unlock();
534 return ret;
535 }
536 CRYPTO_EXPORT_SYMBOL(kapi_klad_get_attr);
537
kapi_klad_set_clear_key(td_handle kapi_klad_handle,const crypto_klad_clear_key * key)538 td_s32 kapi_klad_set_clear_key(td_handle kapi_klad_handle, const crypto_klad_clear_key *key)
539 {
540 td_s32 ret = TD_SUCCESS;
541 td_u32 idx = 0;
542 td_handle hard_klad_handle;
543 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
544 crypto_owner owner;
545 crypto_klad_clear_key clear_key;
546
547 km_null_ptr_chk(key);
548 crypto_chk_return(key->key_parity >= CRYPTO_KLAD_KEY_PARITY_MAX, km_compat_errno(ERROR_INVALID_PARAM),
549 "klad_clear_key.key_parity >= CRYPTO_KLAD_KEY_PARITY_MAX\n");
550
551 clear_key.key = key->key;
552 clear_key.key_parity = key->key_parity;
553 clear_key.key_length = key->key_length;
554 clear_key.hmac_type = key->hmac_type;
555
556 ret = inner_klad_handle_chk(kapi_klad_handle);
557 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
558
559 crypto_get_owner(&owner);
560 idx = kapi_get_ctx_idx(kapi_klad_handle);
561 klad_ctx = &g_klad_ctx_list[idx];
562 kapi_klad_mutex_lock();
563
564 crypto_chk_goto_with_ret(ret, memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock,
565 km_compat_errno(ERROR_INVALID_PROCESS), "invalid process\n");
566 crypto_chk_goto_with_ret(ret, klad_ctx->is_open == TD_FALSE, exit_unlock,
567 km_compat_errno(ERROR_CTX_CLOSED), "call klad_create first\n");
568 crypto_chk_goto_with_ret(ret, klad_ctx->is_attached == TD_FALSE, exit_unlock,
569 km_compat_errno(ERROR_NOT_ATTACHED), "call klad_attach first\n");
570 crypto_chk_goto_with_ret(ret, klad_ctx->is_set_attr == TD_FALSE, exit_unlock,
571 km_compat_errno(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n");
572
573 crypto_chk_goto_with_ret(ret, (klad_ctx->klad_type == CRYPTO_KLAD_DEST_HMAC) &&
574 (inner_hmac_clear_key_size_check(clear_key.hmac_type, clear_key.key_length) == TD_FALSE), exit_unlock,
575 km_compat_errno(ERROR_INVALID_PARAM), "invalid key_size, please do hash first\n");
576
577 ret = drv_klad_create(&hard_klad_handle);
578 crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_klad_create failed, ret is 0x%x\n", ret);
579
580 ret = drv_klad_set_attr(hard_klad_handle, &klad_ctx->klad_attr);
581 crypto_chk_goto(ret != TD_SUCCESS, exit_destroy, "drv_klad_set_attr failed, ret is 0x%x\n", ret);
582
583 ret = drv_klad_attach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle);
584 crypto_chk_goto(ret != TD_SUCCESS, exit_destroy, "drv_klad_attach failed, ret is 0x%x\n", ret);
585
586 ret = drv_klad_set_clear_key(hard_klad_handle, &clear_key);
587 crypto_chk_goto(ret != TD_SUCCESS, exit_detach, "drv_klad_set_clear_key failed, ret is 0x%x\n", ret);
588
589 exit_detach:
590 drv_klad_detach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle);
591 exit_destroy:
592 drv_klad_destroy(hard_klad_handle);
593 exit_unlock:
594 kapi_klad_mutex_unlock();
595 return ret;
596 }
597 CRYPTO_EXPORT_SYMBOL(kapi_klad_set_clear_key);
598
599 #define CRYPTO_EFFECTIVE_KEY_SALT_LENGTH_MAX 28
kapi_klad_set_effective_key(td_handle kapi_klad_handle,const crypto_klad_effective_key * effective_key)600 td_s32 kapi_klad_set_effective_key(td_handle kapi_klad_handle, const crypto_klad_effective_key *effective_key)
601 {
602 td_s32 ret = TD_SUCCESS;
603 td_u32 idx = 0;
604 crypto_kapi_klad_ctx *klad_ctx = TD_NULL;
605 crypto_owner owner;
606 td_handle hard_klad_handle = 0;
607
608 km_null_ptr_chk(effective_key);
609 km_null_ptr_chk(effective_key->salt);
610 crypto_chk_return(effective_key->salt_length > CRYPTO_EFFECTIVE_KEY_SALT_LENGTH_MAX,
611 km_compat_errno(ERROR_INVALID_PARAM), "effective_key.kdf_hard_alg >= CRYPTO_KDF_HARD_ALG_MAX\n");
612 crypto_chk_return(effective_key->kdf_hard_alg >= CRYPTO_KDF_HARD_ALG_MAX, km_compat_errno(ERROR_INVALID_PARAM),
613 "effective_key.kdf_hard_alg >= CRYPTO_KDF_HARD_ALG_MAX\n");
614 crypto_chk_return(effective_key->key_size != CRYPTO_KLAD_KEY_SIZE_128BIT &&
615 effective_key->key_size != CRYPTO_KLAD_KEY_SIZE_192BIT &&
616 effective_key->key_size != CRYPTO_KLAD_KEY_SIZE_256BIT,
617 km_compat_errno(ERROR_INVALID_PARAM), "Content key's size is invalid\n");
618
619 ret = inner_klad_handle_chk(kapi_klad_handle);
620 crypto_chk_return(ret != TD_SUCCESS, ret, "inner_klad_handle_chk failed\n");
621
622 crypto_get_owner(&owner);
623 idx = kapi_get_ctx_idx(kapi_klad_handle);
624 klad_ctx = &g_klad_ctx_list[idx];
625 kapi_klad_mutex_lock();
626
627 crypto_chk_goto_with_ret(ret, memcmp(&owner, &klad_ctx->owner, sizeof(crypto_owner)) != 0, exit_unlock,
628 km_compat_errno(ERROR_INVALID_PROCESS), "invalid process\n");
629 crypto_chk_goto_with_ret(ret, klad_ctx->is_open == TD_FALSE, exit_unlock,
630 km_compat_errno(ERROR_CTX_CLOSED), "call klad_create first\n");
631 crypto_chk_goto_with_ret(ret, klad_ctx->is_attached == TD_FALSE, exit_unlock,
632 km_compat_errno(ERROR_NOT_ATTACHED), "call klad_attach first\n");
633 crypto_chk_goto_with_ret(ret, klad_ctx->is_set_attr == TD_FALSE, exit_unlock,
634 km_compat_errno(ERROR_NOT_SET_CONFIG), "call klad_set_attr first\n");
635 crypto_chk_goto_with_ret(ret, klad_ctx->klad_attr.klad_cfg.rootkey_type == CRYPTO_KDF_HARD_KEY_TYPE_ODRK1 &&
636 effective_key->key_size != CRYPTO_KLAD_KEY_SIZE_128BIT, exit_unlock,
637 km_compat_errno(ERROR_INVALID_PARAM), "ODRK1 only support 128 key_size\n");
638
639 ret = drv_klad_create(&hard_klad_handle);
640 crypto_chk_goto(ret != TD_SUCCESS, exit_unlock, "drv_klad_create failed, ret is 0x%x\n", ret);
641
642 ret = drv_klad_set_attr(hard_klad_handle, (crypto_klad_attr *)&klad_ctx->klad_attr);
643 crypto_chk_goto(ret != TD_SUCCESS, destroy_exit, "drv_klad_set_attr failed, ret is 0x%x\n", ret);
644
645 ret = drv_klad_attach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle);
646 crypto_chk_goto(ret != TD_SUCCESS, destroy_exit, "drv_klad_attach failed, ret is 0x%x\n", ret);
647
648 ret = drv_klad_set_effective_key(hard_klad_handle, effective_key);
649 crypto_chk_goto(ret != TD_SUCCESS, detach_exit, "drv_klad_set_session_key failed, ret is 0x%x\n", ret);
650 detach_exit:
651 drv_klad_detach(hard_klad_handle, klad_ctx->klad_type, klad_ctx->keyslot_handle);
652 destroy_exit:
653 drv_klad_destroy(hard_klad_handle);
654 exit_unlock:
655 kapi_klad_mutex_unlock();
656 return ret;
657 }
658 CRYPTO_EXPORT_SYMBOL(kapi_klad_set_effective_key);
659
kapi_kdf_update(crypto_kdf_otp_key otp_key,crypto_kdf_update_alg alg)660 td_s32 kapi_kdf_update(crypto_kdf_otp_key otp_key, crypto_kdf_update_alg alg)
661 {
662 td_s32 ret = TD_SUCCESS;
663
664 crypto_chk_return(otp_key >= CRYPTO_KDF_OTP_KEY_MAX,
665 km_compat_errno(ERROR_INVALID_PARAM), "kdf_otp_key >= CRYPTO_KDF_OTP_KEY_MAX\n");
666 crypto_chk_return(alg >= CRYPTO_KDF_UPDATE_ALG_MAX,
667 km_compat_errno(ERROR_INVALID_PARAM), "update_alg >= CRYPTO_KDF_UPDATE_ALG_MAX\n");
668
669 kapi_klad_mutex_lock();
670 ret = drv_kdf_update(otp_key, alg);
671 crypto_chk_goto(ret != TD_SUCCESS, unlock_exit, "drv_kdf_update failed, ret is 0x%x\n", ret);
672
673 unlock_exit:
674 kapi_klad_mutex_unlock();
675 return ret;
676 }
677 CRYPTO_EXPORT_SYMBOL(kapi_kdf_update);