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

11  * top-level directory.
16 #include "qemu/main-loop.h"
19 #include "qemu/error-report.h"
22 #include "hw/virtio/virtio-crypto.h"
23 #include "hw/qdev-properties.h"
24 #include "standard-headers/linux/virtio_ids.h"
25 #include "system/cryptodev-vhost.h"
39 switch (sreq->info.op_code) { in virtio_crypto_free_create_session_req()
41 g_free(sreq->info.u.sym_sess_info.cipher_key); in virtio_crypto_free_create_session_req()
42 g_free(sreq->info.u.sym_sess_info.auth_key); in virtio_crypto_free_create_session_req()
46 g_free(sreq->info.u.asym_sess_info.key); in virtio_crypto_free_create_session_req()
57 error_report("Unknown opcode: %u", sreq->info.op_code); in virtio_crypto_free_create_session_req()
81 info->cipher_alg = ldl_le_p(&cipher_para->algo); in virtio_crypto_cipher_session_helper()
82 info->key_len = ldl_le_p(&cipher_para->keylen); in virtio_crypto_cipher_session_helper()
83 info->direction = ldl_le_p(&cipher_para->op); in virtio_crypto_cipher_session_helper()
84 DPRINTF("cipher_alg=%" PRIu32 ", info->direction=%" PRIu32 "\n", in virtio_crypto_cipher_session_helper()
85 info->cipher_alg, info->direction); in virtio_crypto_cipher_session_helper()
87 if (info->key_len > vcrypto->conf.max_cipher_key_len) { in virtio_crypto_cipher_session_helper()
88 error_report("virtio-crypto length of cipher key is too big: %u", in virtio_crypto_cipher_session_helper()
89 info->key_len); in virtio_crypto_cipher_session_helper()
90 return -VIRTIO_CRYPTO_ERR; in virtio_crypto_cipher_session_helper()
93 if (info->key_len > 0) { in virtio_crypto_cipher_session_helper()
95 DPRINTF("keylen=%" PRIu32 "\n", info->key_len); in virtio_crypto_cipher_session_helper()
97 info->cipher_key = g_malloc(info->key_len); in virtio_crypto_cipher_session_helper()
98 s = iov_to_buf(*iov, num, 0, info->cipher_key, info->key_len); in virtio_crypto_cipher_session_helper()
99 if (unlikely(s != info->key_len)) { in virtio_crypto_cipher_session_helper()
100 virtio_error(vdev, "virtio-crypto cipher key incorrect"); in virtio_crypto_cipher_session_helper()
101 return -EFAULT; in virtio_crypto_cipher_session_helper()
103 iov_discard_front(iov, &num, info->key_len); in virtio_crypto_cipher_session_helper()
119 CryptoDevBackendSymSessionInfo *sym_info = &sreq->info.u.sym_sess_info; in virtio_crypto_create_sym_session()
124 op_type = ldl_le_p(&sess_req->op_type); in virtio_crypto_create_sym_session()
125 sreq->info.op_code = opcode; in virtio_crypto_create_sym_session()
127 sym_info = &sreq->info.u.sym_sess_info; in virtio_crypto_create_sym_session()
128 sym_info->op_type = op_type; in virtio_crypto_create_sym_session()
132 &sess_req->u.cipher.para, in virtio_crypto_create_sym_session()
141 &sess_req->u.chain.para.cipher_param, in virtio_crypto_create_sym_session()
147 sym_info->alg_chain_order = ldl_le_p( in virtio_crypto_create_sym_session()
148 &sess_req->u.chain.para.alg_chain_order); in virtio_crypto_create_sym_session()
149 sym_info->add_len = ldl_le_p(&sess_req->u.chain.para.aad_len); in virtio_crypto_create_sym_session()
150 sym_info->hash_mode = ldl_le_p(&sess_req->u.chain.para.hash_mode); in virtio_crypto_create_sym_session()
151 if (sym_info->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) { in virtio_crypto_create_sym_session()
152 sym_info->hash_alg = in virtio_crypto_create_sym_session()
153 ldl_le_p(&sess_req->u.chain.para.u.mac_param.algo); in virtio_crypto_create_sym_session()
154 sym_info->auth_key_len = ldl_le_p( in virtio_crypto_create_sym_session()
155 &sess_req->u.chain.para.u.mac_param.auth_key_len); in virtio_crypto_create_sym_session()
156 sym_info->hash_result_len = ldl_le_p( in virtio_crypto_create_sym_session()
157 &sess_req->u.chain.para.u.mac_param.hash_result_len); in virtio_crypto_create_sym_session()
158 if (sym_info->auth_key_len > vcrypto->conf.max_auth_key_len) { in virtio_crypto_create_sym_session()
159 error_report("virtio-crypto length of auth key is too big: %u", in virtio_crypto_create_sym_session()
160 sym_info->auth_key_len); in virtio_crypto_create_sym_session()
161 return -VIRTIO_CRYPTO_ERR; in virtio_crypto_create_sym_session()
164 if (sym_info->auth_key_len > 0) { in virtio_crypto_create_sym_session()
165 sym_info->auth_key = g_malloc(sym_info->auth_key_len); in virtio_crypto_create_sym_session()
166 s = iov_to_buf(iov, out_num, 0, sym_info->auth_key, in virtio_crypto_create_sym_session()
167 sym_info->auth_key_len); in virtio_crypto_create_sym_session()
168 if (unlikely(s != sym_info->auth_key_len)) { in virtio_crypto_create_sym_session()
170 "virtio-crypto authenticated key incorrect"); in virtio_crypto_create_sym_session()
171 return -EFAULT; in virtio_crypto_create_sym_session()
173 iov_discard_front(&iov, &out_num, sym_info->auth_key_len); in virtio_crypto_create_sym_session()
175 } else if (sym_info->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN) { in virtio_crypto_create_sym_session()
176 sym_info->hash_alg = ldl_le_p( in virtio_crypto_create_sym_session()
177 &sess_req->u.chain.para.u.hash_param.algo); in virtio_crypto_create_sym_session()
178 sym_info->hash_result_len = ldl_le_p( in virtio_crypto_create_sym_session()
179 &sess_req->u.chain.para.u.hash_param.hash_result_len); in virtio_crypto_create_sym_session()
183 return -VIRTIO_CRYPTO_NOTSUPP; in virtio_crypto_create_sym_session()
188 return -VIRTIO_CRYPTO_NOTSUPP; in virtio_crypto_create_sym_session()
192 return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info, in virtio_crypto_create_sym_session()
193 queue_index, sreq->cb, sreq); in virtio_crypto_create_sym_session()
204 CryptoDevBackendAsymSessionInfo *asym_info = &sreq->info.u.asym_sess_info; in virtio_crypto_create_asym_session()
208 sreq->info.op_code = opcode; in virtio_crypto_create_asym_session()
209 algo = ldl_le_p(&sess_req->para.algo); in virtio_crypto_create_asym_session()
210 keytype = ldl_le_p(&sess_req->para.keytype); in virtio_crypto_create_asym_session()
211 keylen = ldl_le_p(&sess_req->para.keylen); in virtio_crypto_create_asym_session()
216 return -VIRTIO_CRYPTO_NOTSUPP; in virtio_crypto_create_asym_session()
220 asym_info->key = g_malloc(keylen); in virtio_crypto_create_asym_session()
221 if (iov_to_buf(iov, out_num, 0, asym_info->key, keylen) != keylen) { in virtio_crypto_create_asym_session()
222 virtio_error(vdev, "virtio-crypto asym key incorrect"); in virtio_crypto_create_asym_session()
223 return -EFAULT; in virtio_crypto_create_asym_session()
228 asym_info = &sreq->info.u.asym_sess_info; in virtio_crypto_create_asym_session()
229 asym_info->algo = algo; in virtio_crypto_create_asym_session()
230 asym_info->keytype = keytype; in virtio_crypto_create_asym_session()
231 asym_info->keylen = keylen; in virtio_crypto_create_asym_session()
232 switch (asym_info->algo) { in virtio_crypto_create_asym_session()
234 asym_info->u.rsa.padding_algo = in virtio_crypto_create_asym_session()
235 ldl_le_p(&sess_req->para.u.rsa.padding_algo); in virtio_crypto_create_asym_session()
236 asym_info->u.rsa.hash_algo = in virtio_crypto_create_asym_session()
237 ldl_le_p(&sess_req->para.u.rsa.hash_algo); in virtio_crypto_create_asym_session()
243 return -VIRTIO_CRYPTO_ERR; in virtio_crypto_create_asym_session()
247 return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info, in virtio_crypto_create_asym_session()
248 queue_index, sreq->cb, sreq); in virtio_crypto_create_asym_session()
259 session_id = ldq_le_p(&close_sess_req->session_id); in virtio_crypto_handle_close_session()
263 vcrypto->cryptodev, session_id, queue_id, sreq->cb, sreq); in virtio_crypto_handle_close_session()
269 VirtQueue *vq = sreq->vq; in virtio_crypto_create_session_completion()
270 VirtQueueElement *elem = sreq->elem; in virtio_crypto_create_session_completion()
271 VirtIODevice *vdev = sreq->vdev; in virtio_crypto_create_session_completion()
273 struct iovec *in_iov = elem->in_sg; in virtio_crypto_create_session_completion()
274 unsigned in_num = elem->in_num; in virtio_crypto_create_session_completion()
279 if (ret == -EFAULT) { in virtio_crypto_create_session_completion()
282 } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { in virtio_crypto_create_session_completion()
284 } else if (ret == -VIRTIO_CRYPTO_KEY_REJECTED) { in virtio_crypto_create_session_completion()
290 stq_le_p(&input.session_id, sreq->info.session_id); in virtio_crypto_create_session_completion()
296 virtio_error(vdev, "virtio-crypto input incorrect"); in virtio_crypto_create_session_completion()
311 VirtQueue *vq = sreq->vq; in virtio_crypto_destroy_session_completion()
312 VirtQueueElement *elem = sreq->elem; in virtio_crypto_destroy_session_completion()
313 VirtIODevice *vdev = sreq->vdev; in virtio_crypto_destroy_session_completion()
314 struct iovec *in_iov = elem->in_sg; in virtio_crypto_destroy_session_completion()
315 unsigned in_num = elem->in_num; in virtio_crypto_destroy_session_completion()
326 virtio_error(vdev, "virtio-crypto status incorrect"); in virtio_crypto_destroy_session_completion()
361 if (elem->out_num < 1 || elem->in_num < 1) { in virtio_crypto_handle_ctrl()
362 virtio_error(vdev, "virtio-crypto ctrl missing headers"); in virtio_crypto_handle_ctrl()
368 out_num = elem->out_num; in virtio_crypto_handle_ctrl()
369 out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num); in virtio_crypto_handle_ctrl()
372 in_num = elem->in_num; in virtio_crypto_handle_ctrl()
373 in_iov = elem->in_sg; in virtio_crypto_handle_ctrl()
377 virtio_error(vdev, "virtio-crypto request ctrl_hdr too short"); in virtio_crypto_handle_ctrl()
388 sreq->vdev = vdev; in virtio_crypto_handle_ctrl()
389 sreq->vq = vq; in virtio_crypto_handle_ctrl()
390 sreq->elem = elem; in virtio_crypto_handle_ctrl()
394 sreq->cb = virtio_crypto_create_session_completion; in virtio_crypto_handle_ctrl()
406 sreq->cb = virtio_crypto_create_session_completion; in virtio_crypto_handle_ctrl()
422 sreq->cb = virtio_crypto_destroy_session_completion; in virtio_crypto_handle_ctrl()
436 error_report("virtio-crypto unsupported ctrl opcode: %d", opcode); in virtio_crypto_handle_ctrl()
440 virtio_error(vdev, "virtio-crypto input incorrect"); in virtio_crypto_handle_ctrl()
458 req->vcrypto = vcrypto; in virtio_crypto_init_request()
459 req->vq = vq; in virtio_crypto_init_request()
460 req->in = NULL; in virtio_crypto_init_request()
461 req->in_iov = NULL; in virtio_crypto_init_request()
462 req->in_num = 0; in virtio_crypto_init_request()
463 req->in_len = 0; in virtio_crypto_init_request()
464 req->flags = QCRYPTODEV_BACKEND_ALGO_TYPE__MAX; in virtio_crypto_init_request()
465 memset(&req->op_info, 0x00, sizeof(req->op_info)); in virtio_crypto_init_request()
474 if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_SYM) { in virtio_crypto_free_request()
476 CryptoDevBackendSymOpInfo *op_info = req->op_info.u.sym_op_info; in virtio_crypto_free_request()
479 max_len = op_info->iv_len + in virtio_crypto_free_request()
480 op_info->aad_len + in virtio_crypto_free_request()
481 op_info->src_len + in virtio_crypto_free_request()
482 op_info->dst_len + in virtio_crypto_free_request()
483 op_info->digest_result_len; in virtio_crypto_free_request()
489 } else if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) { in virtio_crypto_free_request()
490 CryptoDevBackendAsymOpInfo *op_info = req->op_info.u.asym_op_info; in virtio_crypto_free_request()
492 g_free(op_info->src); in virtio_crypto_free_request()
493 g_free(op_info->dst); in virtio_crypto_free_request()
499 g_free(req->in_iov); in virtio_crypto_free_request()
510 struct iovec *in_iov = req->in_iov; in virtio_crypto_sym_input_data_helper()
516 len = sym_op_info->src_len; in virtio_crypto_sym_input_data_helper()
518 s = iov_from_buf(in_iov, req->in_num, 0, sym_op_info->dst, len); in virtio_crypto_sym_input_data_helper()
520 virtio_error(vdev, "virtio-crypto dest data incorrect"); in virtio_crypto_sym_input_data_helper()
524 iov_discard_front(&in_iov, &req->in_num, len); in virtio_crypto_sym_input_data_helper()
526 if (sym_op_info->op_type == in virtio_crypto_sym_input_data_helper()
529 s = iov_from_buf(in_iov, req->in_num, 0, in virtio_crypto_sym_input_data_helper()
530 sym_op_info->digest_result, in virtio_crypto_sym_input_data_helper()
531 sym_op_info->digest_result_len); in virtio_crypto_sym_input_data_helper()
532 if (s != sym_op_info->digest_result_len) { in virtio_crypto_sym_input_data_helper()
533 virtio_error(vdev, "virtio-crypto digest result incorrect"); in virtio_crypto_sym_input_data_helper()
544 struct iovec *in_iov = req->in_iov; in virtio_crypto_akcipher_input_data_helper()
550 len = asym_op_info->dst_len; in virtio_crypto_akcipher_input_data_helper()
555 s = iov_from_buf(in_iov, req->in_num, 0, asym_op_info->dst, len); in virtio_crypto_akcipher_input_data_helper()
557 virtio_error(vdev, "virtio-crypto asym dest data incorrect"); in virtio_crypto_akcipher_input_data_helper()
561 iov_discard_front(&in_iov, &req->in_num, len); in virtio_crypto_akcipher_input_data_helper()
564 req->in_len = sizeof(struct virtio_crypto_inhdr) + asym_op_info->dst_len; in virtio_crypto_akcipher_input_data_helper()
570 VirtIOCrypto *vcrypto = req->vcrypto; in virtio_crypto_req_complete()
572 uint8_t status = -ret; in virtio_crypto_req_complete()
574 if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_SYM) { in virtio_crypto_req_complete()
576 req->op_info.u.sym_op_info); in virtio_crypto_req_complete()
577 } else if (req->flags == QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM) { in virtio_crypto_req_complete()
579 req->op_info.u.asym_op_info); in virtio_crypto_req_complete()
581 stb_p(&req->in->status, status); in virtio_crypto_req_complete()
582 virtqueue_push(req->vq, &req->elem, req->in_len); in virtio_crypto_req_complete()
583 virtio_notify(vdev, req->vq); in virtio_crypto_req_complete()
617 iv_len = ldl_le_p(&cipher_para->iv_len); in virtio_crypto_sym_op_helper()
618 src_len = ldl_le_p(&cipher_para->src_data_len); in virtio_crypto_sym_op_helper()
619 dst_len = ldl_le_p(&cipher_para->dst_data_len); in virtio_crypto_sym_op_helper()
621 iv_len = ldl_le_p(&alg_chain_para->iv_len); in virtio_crypto_sym_op_helper()
622 src_len = ldl_le_p(&alg_chain_para->src_data_len); in virtio_crypto_sym_op_helper()
623 dst_len = ldl_le_p(&alg_chain_para->dst_data_len); in virtio_crypto_sym_op_helper()
625 aad_len = ldl_le_p(&alg_chain_para->aad_len); in virtio_crypto_sym_op_helper()
626 hash_result_len = ldl_le_p(&alg_chain_para->hash_result_len); in virtio_crypto_sym_op_helper()
628 &alg_chain_para->hash_start_src_offset); in virtio_crypto_sym_op_helper()
630 &alg_chain_para->cipher_start_src_offset); in virtio_crypto_sym_op_helper()
631 len_to_cipher = ldl_le_p(&alg_chain_para->len_to_cipher); in virtio_crypto_sym_op_helper()
632 len_to_hash = ldl_le_p(&alg_chain_para->len_to_hash); in virtio_crypto_sym_op_helper()
643 if (unlikely(max_len > vcrypto->conf.max_size)) { in virtio_crypto_sym_op_helper()
644 virtio_error(vdev, "virtio-crypto too big length"); in virtio_crypto_sym_op_helper()
649 op_info->iv_len = iv_len; in virtio_crypto_sym_op_helper()
650 op_info->src_len = src_len; in virtio_crypto_sym_op_helper()
651 op_info->dst_len = dst_len; in virtio_crypto_sym_op_helper()
652 op_info->aad_len = aad_len; in virtio_crypto_sym_op_helper()
653 op_info->digest_result_len = hash_result_len; in virtio_crypto_sym_op_helper()
654 op_info->hash_start_src_offset = hash_start_src_offset; in virtio_crypto_sym_op_helper()
655 op_info->len_to_hash = len_to_hash; in virtio_crypto_sym_op_helper()
656 op_info->cipher_start_src_offset = cipher_start_src_offset; in virtio_crypto_sym_op_helper()
657 op_info->len_to_cipher = len_to_cipher; in virtio_crypto_sym_op_helper()
659 if (op_info->iv_len > 0) { in virtio_crypto_sym_op_helper()
660 DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len); in virtio_crypto_sym_op_helper()
661 op_info->iv = op_info->data + curr_size; in virtio_crypto_sym_op_helper()
663 s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len); in virtio_crypto_sym_op_helper()
664 if (unlikely(s != op_info->iv_len)) { in virtio_crypto_sym_op_helper()
665 virtio_error(vdev, "virtio-crypto iv incorrect"); in virtio_crypto_sym_op_helper()
668 iov_discard_front(&iov, &out_num, op_info->iv_len); in virtio_crypto_sym_op_helper()
669 curr_size += op_info->iv_len; in virtio_crypto_sym_op_helper()
673 if (op_info->aad_len > 0) { in virtio_crypto_sym_op_helper()
674 DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len); in virtio_crypto_sym_op_helper()
675 op_info->aad_data = op_info->data + curr_size; in virtio_crypto_sym_op_helper()
677 s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len); in virtio_crypto_sym_op_helper()
678 if (unlikely(s != op_info->aad_len)) { in virtio_crypto_sym_op_helper()
679 virtio_error(vdev, "virtio-crypto additional auth data incorrect"); in virtio_crypto_sym_op_helper()
682 iov_discard_front(&iov, &out_num, op_info->aad_len); in virtio_crypto_sym_op_helper()
684 curr_size += op_info->aad_len; in virtio_crypto_sym_op_helper()
688 if (op_info->src_len > 0) { in virtio_crypto_sym_op_helper()
689 DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len); in virtio_crypto_sym_op_helper()
690 op_info->src = op_info->data + curr_size; in virtio_crypto_sym_op_helper()
692 s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len); in virtio_crypto_sym_op_helper()
693 if (unlikely(s != op_info->src_len)) { in virtio_crypto_sym_op_helper()
694 virtio_error(vdev, "virtio-crypto source data incorrect"); in virtio_crypto_sym_op_helper()
697 iov_discard_front(&iov, &out_num, op_info->src_len); in virtio_crypto_sym_op_helper()
699 curr_size += op_info->src_len; in virtio_crypto_sym_op_helper()
703 op_info->dst = op_info->data + curr_size; in virtio_crypto_sym_op_helper()
704 curr_size += op_info->dst_len; in virtio_crypto_sym_op_helper()
706 DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len); in virtio_crypto_sym_op_helper()
711 op_info->digest_result = op_info->data + curr_size; in virtio_crypto_sym_op_helper()
731 op_type = ldl_le_p(&req->op_type); in virtio_crypto_handle_sym_req()
733 sym_op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para, in virtio_crypto_handle_sym_req()
736 return -EFAULT; in virtio_crypto_handle_sym_req()
740 &req->u.chain.para, in virtio_crypto_handle_sym_req()
743 return -EFAULT; in virtio_crypto_handle_sym_req()
747 error_report("virtio-crypto unsupported cipher type"); in virtio_crypto_handle_sym_req()
748 return -VIRTIO_CRYPTO_NOTSUPP; in virtio_crypto_handle_sym_req()
751 sym_op_info->op_type = op_type; in virtio_crypto_handle_sym_req()
752 op_info->u.sym_op_info = sym_op_info; in virtio_crypto_handle_sym_req()
772 src_len = ldl_le_p(&req->para.src_data_len); in virtio_crypto_handle_asym_req()
773 dst_len = ldl_le_p(&req->para.dst_data_len); in virtio_crypto_handle_asym_req()
779 virtio_error(vdev, "virtio-crypto asym src data incorrect" in virtio_crypto_handle_asym_req()
790 if (op_info->op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) { in virtio_crypto_handle_asym_req()
793 virtio_error(vdev, "virtio-crypto asym dst data incorrect" in virtio_crypto_handle_asym_req()
802 asym_op_info->src_len = src_len; in virtio_crypto_handle_asym_req()
803 asym_op_info->dst_len = dst_len; in virtio_crypto_handle_asym_req()
804 asym_op_info->src = src; in virtio_crypto_handle_asym_req()
805 asym_op_info->dst = dst; in virtio_crypto_handle_asym_req()
806 op_info->u.asym_op_info = asym_op_info; in virtio_crypto_handle_asym_req()
815 return -EFAULT; in virtio_crypto_handle_asym_req()
821 VirtIOCrypto *vcrypto = request->vcrypto; in virtio_crypto_handle_request()
823 VirtQueueElement *elem = &request->elem; in virtio_crypto_handle_request()
824 int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq)); in virtio_crypto_handle_request()
834 CryptoDevBackendOpInfo *op_info = &request->op_info; in virtio_crypto_handle_request()
836 if (elem->out_num < 1 || elem->in_num < 1) { in virtio_crypto_handle_request()
837 virtio_error(vdev, "virtio-crypto dataq missing headers"); in virtio_crypto_handle_request()
838 return -1; in virtio_crypto_handle_request()
841 out_num = elem->out_num; in virtio_crypto_handle_request()
842 out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num); in virtio_crypto_handle_request()
845 in_num = elem->in_num; in virtio_crypto_handle_request()
846 in_iov_copy = g_memdup2(elem->in_sg, sizeof(in_iov[0]) * in_num); in virtio_crypto_handle_request()
851 virtio_error(vdev, "virtio-crypto request outhdr too short"); in virtio_crypto_handle_request()
852 return -1; in virtio_crypto_handle_request()
856 if (in_iov[in_num - 1].iov_len < in virtio_crypto_handle_request()
858 virtio_error(vdev, "virtio-crypto request inhdr too short"); in virtio_crypto_handle_request()
859 return -1; in virtio_crypto_handle_request()
862 request->in_len = iov_size(in_iov, in_num); in virtio_crypto_handle_request()
863 request->in = (void *)in_iov[in_num - 1].iov_base in virtio_crypto_handle_request()
864 + in_iov[in_num - 1].iov_len in virtio_crypto_handle_request()
865 - sizeof(struct virtio_crypto_inhdr); in virtio_crypto_handle_request()
872 request->in_num = in_num; in virtio_crypto_handle_request()
873 request->in_iov = in_iov; in virtio_crypto_handle_request()
878 op_info->session_id = ldq_le_p(&req.header.session_id); in virtio_crypto_handle_request()
879 op_info->op_code = opcode; in virtio_crypto_handle_request()
880 op_info->queue_index = queue_index; in virtio_crypto_handle_request()
881 op_info->cb = virtio_crypto_req_complete; in virtio_crypto_handle_request()
882 op_info->opaque = request; in virtio_crypto_handle_request()
887 op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALGO_TYPE_SYM; in virtio_crypto_handle_request()
897 op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM; in virtio_crypto_handle_request()
904 if (ret == -EFAULT) { in virtio_crypto_handle_request()
905 return -1; in virtio_crypto_handle_request()
906 } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { in virtio_crypto_handle_request()
907 virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); in virtio_crypto_handle_request()
909 ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev, in virtio_crypto_handle_request()
922 error_report("virtio-crypto unsupported dataq opcode: %u", in virtio_crypto_handle_request()
924 virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); in virtio_crypto_handle_request()
937 virtqueue_detach_element(req->vq, &req->elem, 0); in virtio_crypto_handle_dataq()
947 VirtIOCrypto *vcrypto = q->vcrypto; in virtio_crypto_dataq_bh()
951 if (!vdev->vm_running) { in virtio_crypto_dataq_bh()
956 if (unlikely(!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))) { in virtio_crypto_dataq_bh()
961 virtio_crypto_handle_dataq(vdev, q->dataq); in virtio_crypto_dataq_bh()
962 virtio_queue_set_notification(q->dataq, 1); in virtio_crypto_dataq_bh()
965 if (virtio_queue_empty(q->dataq)) { in virtio_crypto_dataq_bh()
969 virtio_queue_set_notification(q->dataq, 0); in virtio_crypto_dataq_bh()
978 &vcrypto->vqs[virtio_crypto_vq2q(virtio_get_queue_index(vq))]; in virtio_crypto_handle_dataq_bh()
981 if (!vdev->vm_running) { in virtio_crypto_handle_dataq_bh()
985 qemu_bh_schedule(q->dataq_bh); in virtio_crypto_handle_dataq_bh()
999 vcrypto->curr_queues = 1; in virtio_crypto_reset()
1000 if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { in virtio_crypto_reset()
1001 vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; in virtio_crypto_reset()
1003 vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; in virtio_crypto_reset()
1034 vcrypto->conf.crypto_services = virtio_crypto_init_services( in virtio_crypto_init_config()
1035 vcrypto->conf.cryptodev->conf.crypto_services); in virtio_crypto_init_config()
1036 vcrypto->conf.cipher_algo_l = in virtio_crypto_init_config()
1037 vcrypto->conf.cryptodev->conf.cipher_algo_l; in virtio_crypto_init_config()
1038 vcrypto->conf.cipher_algo_h = in virtio_crypto_init_config()
1039 vcrypto->conf.cryptodev->conf.cipher_algo_h; in virtio_crypto_init_config()
1040 vcrypto->conf.hash_algo = vcrypto->conf.cryptodev->conf.hash_algo; in virtio_crypto_init_config()
1041 vcrypto->conf.mac_algo_l = vcrypto->conf.cryptodev->conf.mac_algo_l; in virtio_crypto_init_config()
1042 vcrypto->conf.mac_algo_h = vcrypto->conf.cryptodev->conf.mac_algo_h; in virtio_crypto_init_config()
1043 vcrypto->conf.aead_algo = vcrypto->conf.cryptodev->conf.aead_algo; in virtio_crypto_init_config()
1044 vcrypto->conf.akcipher_algo = vcrypto->conf.cryptodev->conf.akcipher_algo; in virtio_crypto_init_config()
1045 vcrypto->conf.max_cipher_key_len = in virtio_crypto_init_config()
1046 vcrypto->conf.cryptodev->conf.max_cipher_key_len; in virtio_crypto_init_config()
1047 vcrypto->conf.max_auth_key_len = in virtio_crypto_init_config()
1048 vcrypto->conf.cryptodev->conf.max_auth_key_len; in virtio_crypto_init_config()
1049 vcrypto->conf.max_size = vcrypto->conf.cryptodev->conf.max_size; in virtio_crypto_init_config()
1058 vcrypto->cryptodev = vcrypto->conf.cryptodev; in virtio_crypto_device_realize()
1059 if (vcrypto->cryptodev == NULL) { in virtio_crypto_device_realize()
1062 } else if (cryptodev_backend_is_used(vcrypto->cryptodev)) { in virtio_crypto_device_realize()
1064 object_get_canonical_path_component(OBJECT(vcrypto->conf.cryptodev))); in virtio_crypto_device_realize()
1068 vcrypto->max_queues = MAX(vcrypto->cryptodev->conf.peers.queues, 1); in virtio_crypto_device_realize()
1069 if (vcrypto->max_queues + 1 > VIRTIO_QUEUE_MAX) { in virtio_crypto_device_realize()
1072 vcrypto->max_queues, VIRTIO_QUEUE_MAX); in virtio_crypto_device_realize()
1076 virtio_init(vdev, VIRTIO_ID_CRYPTO, vcrypto->config_size); in virtio_crypto_device_realize()
1077 vcrypto->curr_queues = 1; in virtio_crypto_device_realize()
1078 vcrypto->vqs = g_new0(VirtIOCryptoQueue, vcrypto->max_queues); in virtio_crypto_device_realize()
1079 for (i = 0; i < vcrypto->max_queues; i++) { in virtio_crypto_device_realize()
1080 vcrypto->vqs[i].dataq = in virtio_crypto_device_realize()
1082 vcrypto->vqs[i].dataq_bh = in virtio_crypto_device_realize()
1084 &vcrypto->vqs[i]); in virtio_crypto_device_realize()
1085 vcrypto->vqs[i].vcrypto = vcrypto; in virtio_crypto_device_realize()
1088 vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl); in virtio_crypto_device_realize()
1089 if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { in virtio_crypto_device_realize()
1090 vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; in virtio_crypto_device_realize()
1092 vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; in virtio_crypto_device_realize()
1096 cryptodev_backend_set_used(vcrypto->cryptodev, true); in virtio_crypto_device_realize()
1106 max_queues = vcrypto->multiqueue ? vcrypto->max_queues : 1; in virtio_crypto_device_unrealize()
1108 virtio_delete_queue(vcrypto->vqs[i].dataq); in virtio_crypto_device_unrealize()
1109 q = &vcrypto->vqs[i]; in virtio_crypto_device_unrealize()
1110 qemu_bh_delete(q->dataq_bh); in virtio_crypto_device_unrealize()
1113 g_free(vcrypto->vqs); in virtio_crypto_device_unrealize()
1114 virtio_delete_queue(vcrypto->ctrl_vq); in virtio_crypto_device_unrealize()
1117 cryptodev_backend_set_used(vcrypto->cryptodev, false); in virtio_crypto_device_unrealize()
1121 .name = "virtio-crypto",
1142 * Virtio-crypto device conforms to VIRTIO 1.0 which is always LE, in virtio_crypto_get_config()
1145 stl_le_p(&crypto_cfg.status, c->status); in virtio_crypto_get_config()
1146 stl_le_p(&crypto_cfg.max_dataqueues, c->max_queues); in virtio_crypto_get_config()
1147 stl_le_p(&crypto_cfg.crypto_services, c->conf.crypto_services); in virtio_crypto_get_config()
1148 stl_le_p(&crypto_cfg.cipher_algo_l, c->conf.cipher_algo_l); in virtio_crypto_get_config()
1149 stl_le_p(&crypto_cfg.cipher_algo_h, c->conf.cipher_algo_h); in virtio_crypto_get_config()
1150 stl_le_p(&crypto_cfg.hash_algo, c->conf.hash_algo); in virtio_crypto_get_config()
1151 stl_le_p(&crypto_cfg.mac_algo_l, c->conf.mac_algo_l); in virtio_crypto_get_config()
1152 stl_le_p(&crypto_cfg.mac_algo_h, c->conf.mac_algo_h); in virtio_crypto_get_config()
1153 stl_le_p(&crypto_cfg.aead_algo, c->conf.aead_algo); in virtio_crypto_get_config()
1154 stl_le_p(&crypto_cfg.max_cipher_key_len, c->conf.max_cipher_key_len); in virtio_crypto_get_config()
1155 stl_le_p(&crypto_cfg.max_auth_key_len, c->conf.max_auth_key_len); in virtio_crypto_get_config()
1156 stq_le_p(&crypto_cfg.max_size, c->conf.max_size); in virtio_crypto_get_config()
1157 stl_le_p(&crypto_cfg.akcipher_algo, c->conf.akcipher_algo); in virtio_crypto_get_config()
1159 memcpy(config, &crypto_cfg, c->config_size); in virtio_crypto_get_config()
1166 (c->status & VIRTIO_CRYPTO_S_HW_READY) && vdev->vm_running; in virtio_crypto_started()
1172 int queues = c->multiqueue ? c->max_queues : 1; in virtio_crypto_vhost_status()
1173 CryptoDevBackend *b = c->cryptodev; in virtio_crypto_vhost_status()
1174 CryptoDevBackendClient *cc = b->conf.peers.ccs[0]; in virtio_crypto_vhost_status()
1180 if ((virtio_crypto_started(c, status)) == !!c->vhost_started) { in virtio_crypto_vhost_status()
1184 if (!c->vhost_started) { in virtio_crypto_vhost_status()
1187 c->vhost_started = 1; in virtio_crypto_vhost_status()
1191 "falling back on userspace virtio", -r); in virtio_crypto_vhost_status()
1192 c->vhost_started = 0; in virtio_crypto_vhost_status()
1196 c->vhost_started = 0; in virtio_crypto_vhost_status()
1214 assert(vcrypto->vhost_started); in virtio_crypto_guest_notifier_mask()
1217 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 in virtio_crypto_guest_notifier_mask()
1233 assert(vcrypto->vhost_started); in virtio_crypto_guest_notifier_pending()
1236 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 in virtio_crypto_guest_notifier_pending()
1254 b = vcrypto->cryptodev; in virtio_crypto_get_vhost()
1259 cc = b->conf.peers.ccs[0]; in virtio_crypto_get_vhost()
1265 return &vhost_crypto->dev; in virtio_crypto_get_vhost()
1274 dc->vmsd = &vmstate_virtio_crypto; in virtio_crypto_class_init()
1275 set_bit(DEVICE_CATEGORY_MISC, dc->categories); in virtio_crypto_class_init()
1276 vdc->realize = virtio_crypto_device_realize; in virtio_crypto_class_init()
1277 vdc->unrealize = virtio_crypto_device_unrealize; in virtio_crypto_class_init()
1278 vdc->get_config = virtio_crypto_get_config; in virtio_crypto_class_init()
1279 vdc->get_features = virtio_crypto_get_features; in virtio_crypto_class_init()
1280 vdc->reset = virtio_crypto_reset; in virtio_crypto_class_init()
1281 vdc->set_status = virtio_crypto_set_status; in virtio_crypto_class_init()
1282 vdc->guest_notifier_mask = virtio_crypto_guest_notifier_mask; in virtio_crypto_class_init()
1283 vdc->guest_notifier_pending = virtio_crypto_guest_notifier_pending; in virtio_crypto_class_init()
1284 vdc->get_vhost = virtio_crypto_get_vhost; in virtio_crypto_class_init()
1295 vcrypto->config_size = sizeof(struct virtio_crypto_config); in virtio_crypto_instance_init()