Lines Matching +full:- +full:- +full:-

28 #include "qemu/main-loop.h"
30 #include "qemu/error-report.h"
34 #include "standard-headers/linux/virtio_crypto.h"
43 #define TYPE_CRYPTODEV_BACKEND_LKCF "cryptodev-backend-lkcf"
47 #define INVALID_KEY_ID -1
53 * Here the key is uploaded to the thread-keyring of worker thread, at least
54 * util linux-6.0:
55 * 1. process keyring seems to behave unexpectedly if main-thread does not
59 * 3. it can reduce the load of the main-loop because the key passed by the
116 eventfd_read(lkcf->eventfd, &nevent); in cryptodev_lkcf_handle_response()
118 qemu_mutex_lock(&lkcf->rsp_mutex); in cryptodev_lkcf_handle_response()
119 QSIMPLEQ_PREPEND(&responses, &lkcf->responses); in cryptodev_lkcf_handle_response()
120 qemu_mutex_unlock(&lkcf->rsp_mutex); in cryptodev_lkcf_handle_response()
123 if (task->cb) { in cryptodev_lkcf_handle_response()
124 task->cb(task->opaque, task->status); in cryptodev_lkcf_handle_response()
136 if (opts->alg != QCRYPTO_AK_CIPHER_ALGO_RSA) { in cryptodev_lkcf_set_op_desc()
137 error_setg(errp, "Unsupported alg: %u", opts->alg); in cryptodev_lkcf_set_op_desc()
138 return -1; in cryptodev_lkcf_set_op_desc()
141 rsa_opt = &opts->u.rsa; in cryptodev_lkcf_set_op_desc()
142 if (rsa_opt->padding_alg == QCRYPTO_RSA_PADDING_ALGO_PKCS1) { in cryptodev_lkcf_set_op_desc()
144 QCryptoRSAPaddingAlgo_str(rsa_opt->padding_alg), in cryptodev_lkcf_set_op_desc()
145 QCryptoHashAlgo_str(rsa_opt->hash_alg)); in cryptodev_lkcf_set_op_desc()
149 QCryptoRSAPaddingAlgo_str(rsa_opt->padding_alg)); in cryptodev_lkcf_set_op_desc()
160 opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_PKCS1; in cryptodev_lkcf_set_rsa_opt()
164 opt->hash_alg = QCRYPTO_HASH_ALGO_MD5; in cryptodev_lkcf_set_rsa_opt()
168 opt->hash_alg = QCRYPTO_HASH_ALGO_SHA1; in cryptodev_lkcf_set_rsa_opt()
172 opt->hash_alg = QCRYPTO_HASH_ALGO_SHA256; in cryptodev_lkcf_set_rsa_opt()
176 opt->hash_alg = QCRYPTO_HASH_ALGO_SHA512; in cryptodev_lkcf_set_rsa_opt()
181 return -1; in cryptodev_lkcf_set_rsa_opt()
187 opt->padding_alg = QCRYPTO_RSA_PADDING_ALGO_RAW; in cryptodev_lkcf_set_rsa_opt()
192 return -1; in cryptodev_lkcf_set_rsa_opt()
200 if (lkcf->sess[i] == NULL) { in cryptodev_lkcf_get_unused_session_index()
204 return -1; in cryptodev_lkcf_get_unused_session_index()
210 int queues = backend->conf.peers.queues, i; in cryptodev_lkcf_init()
217 "Only support one queue in cryptodev-builtin backend"); in cryptodev_lkcf_init()
220 lkcf->eventfd = eventfd(0, 0); in cryptodev_lkcf_init()
221 if (lkcf->eventfd < 0) { in cryptodev_lkcf_init()
227 cc->info_str = g_strdup_printf("cryptodev-lkcf0"); in cryptodev_lkcf_init()
228 cc->queue_index = 0; in cryptodev_lkcf_init()
229 cc->type = QCRYPTODEV_BACKEND_TYPE_LKCF; in cryptodev_lkcf_init()
230 backend->conf.peers.ccs[0] = cc; in cryptodev_lkcf_init()
232 backend->conf.crypto_services = in cryptodev_lkcf_init()
234 backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA; in cryptodev_lkcf_init()
235 lkcf->running = true; in cryptodev_lkcf_init()
237 QSIMPLEQ_INIT(&lkcf->requests); in cryptodev_lkcf_init()
238 QSIMPLEQ_INIT(&lkcf->responses); in cryptodev_lkcf_init()
239 qemu_mutex_init(&lkcf->mutex); in cryptodev_lkcf_init()
240 qemu_mutex_init(&lkcf->rsp_mutex); in cryptodev_lkcf_init()
241 qemu_cond_init(&lkcf->cond); in cryptodev_lkcf_init()
243 qemu_thread_create(&lkcf->worker_threads[i], "lkcf-worker", in cryptodev_lkcf_init()
247 lkcf->eventfd, cryptodev_lkcf_handle_response, NULL, lkcf); in cryptodev_lkcf_init()
255 int queues = backend->conf.peers.queues; in cryptodev_lkcf_cleanup()
259 qemu_mutex_lock(&lkcf->mutex); in cryptodev_lkcf_cleanup()
260 lkcf->running = false; in cryptodev_lkcf_cleanup()
261 qemu_mutex_unlock(&lkcf->mutex); in cryptodev_lkcf_cleanup()
262 qemu_cond_broadcast(&lkcf->cond); in cryptodev_lkcf_cleanup()
264 close(lkcf->eventfd); in cryptodev_lkcf_cleanup()
266 qemu_thread_join(&lkcf->worker_threads[i]); in cryptodev_lkcf_cleanup()
269 QSIMPLEQ_FOREACH_SAFE(task, &lkcf->requests, queue, next) { in cryptodev_lkcf_cleanup()
270 if (task->cb) { in cryptodev_lkcf_cleanup()
271 task->cb(task->opaque, task->status); in cryptodev_lkcf_cleanup()
276 QSIMPLEQ_FOREACH_SAFE(task, &lkcf->responses, queue, next) { in cryptodev_lkcf_cleanup()
277 if (task->cb) { in cryptodev_lkcf_cleanup()
278 task->cb(task->opaque, task->status); in cryptodev_lkcf_cleanup()
283 qemu_mutex_destroy(&lkcf->mutex); in cryptodev_lkcf_cleanup()
284 qemu_cond_destroy(&lkcf->cond); in cryptodev_lkcf_cleanup()
285 qemu_mutex_destroy(&lkcf->rsp_mutex); in cryptodev_lkcf_cleanup()
288 if (lkcf->sess[i] != NULL) { in cryptodev_lkcf_cleanup()
294 cc = backend->conf.peers.ccs[i]; in cryptodev_lkcf_cleanup()
297 backend->conf.peers.ccs[i] = NULL; in cryptodev_lkcf_cleanup()
306 CryptoDevBackendLKCFSession *session = task->sess; in cryptodev_lkcf_execute_task()
309 int ret, status, op_code = task->op_info->op_code; in cryptodev_lkcf_execute_task()
323 * thread-pool. in cryptodev_lkcf_execute_task()
325 if (session->keytype == QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE) { in cryptodev_lkcf_execute_task()
326 if (qcrypto_akcipher_export_p8info(&session->akcipher_opts, in cryptodev_lkcf_execute_task()
327 session->key, session->keylen, in cryptodev_lkcf_execute_task()
330 cryptodev_lkcf_set_op_desc(&session->akcipher_opts, op_desc, in cryptodev_lkcf_execute_task()
333 status = -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_execute_task()
336 key_id = add_key(KCTL_KEY_TYPE_PKEY, "lkcf-backend-priv-key", in cryptodev_lkcf_execute_task()
342 if (!qcrypto_akcipher_supports(&session->akcipher_opts)) { in cryptodev_lkcf_execute_task()
343 status = -VIRTIO_CRYPTO_NOTSUPP; in cryptodev_lkcf_execute_task()
346 akcipher = qcrypto_akcipher_new(&session->akcipher_opts, in cryptodev_lkcf_execute_task()
347 session->keytype, in cryptodev_lkcf_execute_task()
348 session->key, session->keylen, in cryptodev_lkcf_execute_task()
352 status = -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_execute_task()
357 asym_op_info = task->op_info->u.asym_op_info; in cryptodev_lkcf_execute_task()
362 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
363 asym_op_info->dst, asym_op_info->dst_len); in cryptodev_lkcf_execute_task()
366 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
367 asym_op_info->dst, asym_op_info->dst_len, &local_error); in cryptodev_lkcf_execute_task()
374 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
375 asym_op_info->dst, asym_op_info->dst_len); in cryptodev_lkcf_execute_task()
378 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
379 asym_op_info->dst, asym_op_info->dst_len, &local_error); in cryptodev_lkcf_execute_task()
386 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
387 asym_op_info->dst, asym_op_info->dst_len); in cryptodev_lkcf_execute_task()
390 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
391 asym_op_info->dst, asym_op_info->dst_len, &local_error); in cryptodev_lkcf_execute_task()
398 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
399 asym_op_info->dst, asym_op_info->dst_len); in cryptodev_lkcf_execute_task()
402 asym_op_info->src, asym_op_info->src_len, in cryptodev_lkcf_execute_task()
403 asym_op_info->dst, asym_op_info->dst_len, &local_error); in cryptodev_lkcf_execute_task()
409 status = -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_execute_task()
422 -VIRTIO_CRYPTO_KEY_REJECTED : -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_execute_task()
425 asym_op_info->dst_len = ret; in cryptodev_lkcf_execute_task()
432 task->status = status; in cryptodev_lkcf_execute_task()
434 qemu_mutex_lock(&task->lkcf->rsp_mutex); in cryptodev_lkcf_execute_task()
435 if (QSIMPLEQ_EMPTY(&task->lkcf->responses)) { in cryptodev_lkcf_execute_task()
438 QSIMPLEQ_INSERT_TAIL(&task->lkcf->responses, task, queue); in cryptodev_lkcf_execute_task()
439 qemu_mutex_unlock(&task->lkcf->rsp_mutex); in cryptodev_lkcf_execute_task()
442 eventfd_write(task->lkcf->eventfd, 1); in cryptodev_lkcf_execute_task()
453 qemu_mutex_lock(&backend->mutex); in cryptodev_lkcf_worker()
454 while (backend->running && QSIMPLEQ_EMPTY(&backend->requests)) { in cryptodev_lkcf_worker()
455 qemu_cond_wait(&backend->cond, &backend->mutex); in cryptodev_lkcf_worker()
457 if (backend->running) { in cryptodev_lkcf_worker()
458 task = QSIMPLEQ_FIRST(&backend->requests); in cryptodev_lkcf_worker()
459 QSIMPLEQ_REMOVE_HEAD(&backend->requests, queue); in cryptodev_lkcf_worker()
461 qemu_mutex_unlock(&backend->mutex); in cryptodev_lkcf_worker()
480 QCryptodevBackendAlgoType algtype = op_info->algtype; in cryptodev_lkcf_operation()
483 if (op_info->session_id >= MAX_SESSIONS || in cryptodev_lkcf_operation()
484 lkcf->sess[op_info->session_id] == NULL) { in cryptodev_lkcf_operation()
486 op_info->session_id); in cryptodev_lkcf_operation()
487 return -VIRTIO_CRYPTO_INVSESS; in cryptodev_lkcf_operation()
490 sess = lkcf->sess[op_info->session_id]; in cryptodev_lkcf_operation()
493 return -VIRTIO_CRYPTO_NOTSUPP; in cryptodev_lkcf_operation()
497 task->op_info = op_info; in cryptodev_lkcf_operation()
498 task->cb = op_info->cb; in cryptodev_lkcf_operation()
499 task->opaque = op_info->opaque; in cryptodev_lkcf_operation()
500 task->sess = sess; in cryptodev_lkcf_operation()
501 task->lkcf = lkcf; in cryptodev_lkcf_operation()
502 task->status = -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_operation()
504 qemu_mutex_lock(&lkcf->mutex); in cryptodev_lkcf_operation()
505 QSIMPLEQ_INSERT_TAIL(&lkcf->requests, task, queue); in cryptodev_lkcf_operation()
506 qemu_mutex_unlock(&lkcf->mutex); in cryptodev_lkcf_operation()
507 qemu_cond_signal(&lkcf->cond); in cryptodev_lkcf_operation()
522 switch (sess_info->algo) { in cryptodev_lkcf_create_asym_session()
524 sess->akcipher_opts.alg = QCRYPTO_AK_CIPHER_ALGO_RSA; in cryptodev_lkcf_create_asym_session()
526 sess_info->u.rsa.padding_algo, sess_info->u.rsa.hash_algo, in cryptodev_lkcf_create_asym_session()
527 &sess->akcipher_opts.u.rsa, &local_error) != 0) { in cryptodev_lkcf_create_asym_session()
529 return -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_create_asym_session()
534 error_report("Unsupported asym alg %u", sess_info->algo); in cryptodev_lkcf_create_asym_session()
535 return -VIRTIO_CRYPTO_NOTSUPP; in cryptodev_lkcf_create_asym_session()
538 switch (sess_info->keytype) { in cryptodev_lkcf_create_asym_session()
540 sess->keytype = QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC; in cryptodev_lkcf_create_asym_session()
544 sess->keytype = QCRYPTO_AK_CIPHER_KEY_TYPE_PRIVATE; in cryptodev_lkcf_create_asym_session()
548 error_report("Unknown akcipher keytype: %u", sess_info->keytype); in cryptodev_lkcf_create_asym_session()
549 return -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_create_asym_session()
556 return -VIRTIO_CRYPTO_ERR; in cryptodev_lkcf_create_asym_session()
559 sess->keylen = sess_info->keylen; in cryptodev_lkcf_create_asym_session()
560 sess->key = g_malloc(sess_info->keylen); in cryptodev_lkcf_create_asym_session()
561 memcpy(sess->key, sess_info->key, sess_info->keylen); in cryptodev_lkcf_create_asym_session()
563 lkcf->sess[index] = g_steal_pointer(&sess); in cryptodev_lkcf_create_asym_session()
581 switch (sess_info->op_code) { in cryptodev_lkcf_create_session()
583 asym_sess_info = &sess_info->u.asym_sess_info; in cryptodev_lkcf_create_session()
585 lkcf, asym_sess_info, &sess_info->session_id); in cryptodev_lkcf_create_session()
589 ret = -VIRTIO_CRYPTO_NOTSUPP; in cryptodev_lkcf_create_session()
591 sess_info->op_code); in cryptodev_lkcf_create_session()
609 assert(session_id < MAX_SESSIONS && lkcf->sess[session_id]); in cryptodev_lkcf_close_session()
610 session = lkcf->sess[session_id]; in cryptodev_lkcf_close_session()
611 lkcf->sess[session_id] = NULL; in cryptodev_lkcf_close_session()
613 g_free(session->key); in cryptodev_lkcf_close_session()
626 bc->init = cryptodev_lkcf_init; in cryptodev_lkcf_class_init()
627 bc->cleanup = cryptodev_lkcf_cleanup; in cryptodev_lkcf_class_init()
628 bc->create_session = cryptodev_lkcf_create_session; in cryptodev_lkcf_class_init()
629 bc->close_session = cryptodev_lkcf_close_session; in cryptodev_lkcf_class_init()
630 bc->do_op = cryptodev_lkcf_operation; in cryptodev_lkcf_class_init()