• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&current_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, &current_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);