1 /* 2 * Virtio crypto Support 3 * 4 * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. 5 * 6 * Authors: 7 * Gonglei <arei.gonglei@huawei.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or 10 * (at your option) any later version. See the COPYING file in the 11 * top-level directory. 12 */ 13 14 #include "qemu/osdep.h" 15 #include "qemu/iov.h" 16 #include "qemu/main-loop.h" 17 #include "qemu/module.h" 18 #include "qapi/error.h" 19 #include "qemu/error-report.h" 20 21 #include "hw/virtio/virtio.h" 22 #include "hw/virtio/virtio-crypto.h" 23 #include "hw/qdev-properties.h" 24 #include "standard-headers/linux/virtio_ids.h" 25 #include "sysemu/cryptodev-vhost.h" 26 27 #define VIRTIO_CRYPTO_VM_VERSION 1 28 29 typedef struct VirtIOCryptoSessionReq { 30 VirtIODevice *vdev; 31 VirtQueue *vq; 32 VirtQueueElement *elem; 33 CryptoDevBackendSessionInfo info; 34 CryptoDevCompletionFunc cb; 35 } VirtIOCryptoSessionReq; 36 37 static void virtio_crypto_free_create_session_req(VirtIOCryptoSessionReq *sreq) 38 { 39 switch (sreq->info.op_code) { 40 case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION: 41 g_free(sreq->info.u.sym_sess_info.cipher_key); 42 g_free(sreq->info.u.sym_sess_info.auth_key); 43 break; 44 45 case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION: 46 g_free(sreq->info.u.asym_sess_info.key); 47 break; 48 49 case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION: 50 case VIRTIO_CRYPTO_HASH_DESTROY_SESSION: 51 case VIRTIO_CRYPTO_MAC_DESTROY_SESSION: 52 case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION: 53 case VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION: 54 break; 55 56 default: 57 error_report("Unknown opcode: %u", sreq->info.op_code); 58 } 59 g_free(sreq); 60 } 61 62 /* 63 * Transfer virtqueue index to crypto queue index. 64 * The control virtqueue is after the data virtqueues 65 * so the input value doesn't need to be adjusted 66 */ 67 static inline int virtio_crypto_vq2q(int queue_index) 68 { 69 return queue_index; 70 } 71 72 static int 73 virtio_crypto_cipher_session_helper(VirtIODevice *vdev, 74 CryptoDevBackendSymSessionInfo *info, 75 struct virtio_crypto_cipher_session_para *cipher_para, 76 struct iovec **iov, unsigned int *out_num) 77 { 78 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 79 unsigned int num = *out_num; 80 81 info->cipher_alg = ldl_le_p(&cipher_para->algo); 82 info->key_len = ldl_le_p(&cipher_para->keylen); 83 info->direction = ldl_le_p(&cipher_para->op); 84 DPRINTF("cipher_alg=%" PRIu32 ", info->direction=%" PRIu32 "\n", 85 info->cipher_alg, info->direction); 86 87 if (info->key_len > vcrypto->conf.max_cipher_key_len) { 88 error_report("virtio-crypto length of cipher key is too big: %u", 89 info->key_len); 90 return -VIRTIO_CRYPTO_ERR; 91 } 92 /* Get cipher key */ 93 if (info->key_len > 0) { 94 size_t s; 95 DPRINTF("keylen=%" PRIu32 "\n", info->key_len); 96 97 info->cipher_key = g_malloc(info->key_len); 98 s = iov_to_buf(*iov, num, 0, info->cipher_key, info->key_len); 99 if (unlikely(s != info->key_len)) { 100 virtio_error(vdev, "virtio-crypto cipher key incorrect"); 101 return -EFAULT; 102 } 103 iov_discard_front(iov, &num, info->key_len); 104 *out_num = num; 105 } 106 107 return 0; 108 } 109 110 static int 111 virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto, 112 struct virtio_crypto_sym_create_session_req *sess_req, 113 uint32_t queue_id, 114 uint32_t opcode, 115 struct iovec *iov, unsigned int out_num, 116 VirtIOCryptoSessionReq *sreq) 117 { 118 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 119 CryptoDevBackendSymSessionInfo *sym_info = &sreq->info.u.sym_sess_info; 120 int queue_index; 121 uint32_t op_type; 122 int ret; 123 124 op_type = ldl_le_p(&sess_req->op_type); 125 sreq->info.op_code = opcode; 126 127 sym_info = &sreq->info.u.sym_sess_info; 128 sym_info->op_type = op_type; 129 130 if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) { 131 ret = virtio_crypto_cipher_session_helper(vdev, sym_info, 132 &sess_req->u.cipher.para, 133 &iov, &out_num); 134 if (ret < 0) { 135 return ret; 136 } 137 } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) { 138 size_t s; 139 /* cipher part */ 140 ret = virtio_crypto_cipher_session_helper(vdev, sym_info, 141 &sess_req->u.chain.para.cipher_param, 142 &iov, &out_num); 143 if (ret < 0) { 144 return ret; 145 } 146 /* hash part */ 147 sym_info->alg_chain_order = ldl_le_p( 148 &sess_req->u.chain.para.alg_chain_order); 149 sym_info->add_len = ldl_le_p(&sess_req->u.chain.para.aad_len); 150 sym_info->hash_mode = ldl_le_p(&sess_req->u.chain.para.hash_mode); 151 if (sym_info->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) { 152 sym_info->hash_alg = 153 ldl_le_p(&sess_req->u.chain.para.u.mac_param.algo); 154 sym_info->auth_key_len = ldl_le_p( 155 &sess_req->u.chain.para.u.mac_param.auth_key_len); 156 sym_info->hash_result_len = ldl_le_p( 157 &sess_req->u.chain.para.u.mac_param.hash_result_len); 158 if (sym_info->auth_key_len > vcrypto->conf.max_auth_key_len) { 159 error_report("virtio-crypto length of auth key is too big: %u", 160 sym_info->auth_key_len); 161 return -VIRTIO_CRYPTO_ERR; 162 } 163 /* get auth key */ 164 if (sym_info->auth_key_len > 0) { 165 sym_info->auth_key = g_malloc(sym_info->auth_key_len); 166 s = iov_to_buf(iov, out_num, 0, sym_info->auth_key, 167 sym_info->auth_key_len); 168 if (unlikely(s != sym_info->auth_key_len)) { 169 virtio_error(vdev, 170 "virtio-crypto authenticated key incorrect"); 171 return -EFAULT; 172 } 173 iov_discard_front(&iov, &out_num, sym_info->auth_key_len); 174 } 175 } else if (sym_info->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN) { 176 sym_info->hash_alg = ldl_le_p( 177 &sess_req->u.chain.para.u.hash_param.algo); 178 sym_info->hash_result_len = ldl_le_p( 179 &sess_req->u.chain.para.u.hash_param.hash_result_len); 180 } else { 181 /* VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */ 182 error_report("unsupported hash mode"); 183 return -VIRTIO_CRYPTO_NOTSUPP; 184 } 185 } else { 186 /* VIRTIO_CRYPTO_SYM_OP_NONE */ 187 error_report("unsupported cipher op_type: VIRTIO_CRYPTO_SYM_OP_NONE"); 188 return -VIRTIO_CRYPTO_NOTSUPP; 189 } 190 191 queue_index = virtio_crypto_vq2q(queue_id); 192 return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info, 193 queue_index, sreq->cb, sreq); 194 } 195 196 static int 197 virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto, 198 struct virtio_crypto_akcipher_create_session_req *sess_req, 199 uint32_t queue_id, uint32_t opcode, 200 struct iovec *iov, unsigned int out_num, 201 VirtIOCryptoSessionReq *sreq) 202 { 203 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 204 CryptoDevBackendAsymSessionInfo *asym_info = &sreq->info.u.asym_sess_info; 205 int queue_index; 206 uint32_t algo, keytype, keylen; 207 208 algo = ldl_le_p(&sess_req->para.algo); 209 keytype = ldl_le_p(&sess_req->para.keytype); 210 keylen = ldl_le_p(&sess_req->para.keylen); 211 212 if ((keytype != VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC) 213 && (keytype != VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE)) { 214 error_report("unsupported asym keytype: %d", keytype); 215 return -VIRTIO_CRYPTO_NOTSUPP; 216 } 217 218 if (keylen) { 219 asym_info->key = g_malloc(keylen); 220 if (iov_to_buf(iov, out_num, 0, asym_info->key, keylen) != keylen) { 221 virtio_error(vdev, "virtio-crypto asym key incorrect"); 222 return -EFAULT; 223 } 224 iov_discard_front(&iov, &out_num, keylen); 225 } 226 227 sreq->info.op_code = opcode; 228 asym_info = &sreq->info.u.asym_sess_info; 229 asym_info->algo = algo; 230 asym_info->keytype = keytype; 231 asym_info->keylen = keylen; 232 switch (asym_info->algo) { 233 case VIRTIO_CRYPTO_AKCIPHER_RSA: 234 asym_info->u.rsa.padding_algo = 235 ldl_le_p(&sess_req->para.u.rsa.padding_algo); 236 asym_info->u.rsa.hash_algo = 237 ldl_le_p(&sess_req->para.u.rsa.hash_algo); 238 break; 239 240 /* TODO DSA&ECDSA handling */ 241 242 default: 243 return -VIRTIO_CRYPTO_ERR; 244 } 245 246 queue_index = virtio_crypto_vq2q(queue_id); 247 return cryptodev_backend_create_session(vcrypto->cryptodev, &sreq->info, 248 queue_index, sreq->cb, sreq); 249 } 250 251 static int 252 virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto, 253 struct virtio_crypto_destroy_session_req *close_sess_req, 254 uint32_t queue_id, 255 VirtIOCryptoSessionReq *sreq) 256 { 257 uint64_t session_id; 258 259 session_id = ldq_le_p(&close_sess_req->session_id); 260 DPRINTF("close session, id=%" PRIu64 "\n", session_id); 261 262 return cryptodev_backend_close_session( 263 vcrypto->cryptodev, session_id, queue_id, sreq->cb, sreq); 264 } 265 266 static void virtio_crypto_create_session_completion(void *opaque, int ret) 267 { 268 VirtIOCryptoSessionReq *sreq = (VirtIOCryptoSessionReq *)opaque; 269 VirtQueue *vq = sreq->vq; 270 VirtQueueElement *elem = sreq->elem; 271 VirtIODevice *vdev = sreq->vdev; 272 struct virtio_crypto_session_input input; 273 struct iovec *in_iov = elem->in_sg; 274 unsigned in_num = elem->in_num; 275 size_t s; 276 277 memset(&input, 0, sizeof(input)); 278 /* Serious errors, need to reset virtio crypto device */ 279 if (ret == -EFAULT) { 280 virtqueue_detach_element(vq, elem, 0); 281 goto out; 282 } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { 283 stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP); 284 } else if (ret == -VIRTIO_CRYPTO_KEY_REJECTED) { 285 stl_le_p(&input.status, VIRTIO_CRYPTO_KEY_REJECTED); 286 } else if (ret != VIRTIO_CRYPTO_OK) { 287 stl_le_p(&input.status, VIRTIO_CRYPTO_ERR); 288 } else { 289 /* Set the session id */ 290 stq_le_p(&input.session_id, sreq->info.session_id); 291 stl_le_p(&input.status, VIRTIO_CRYPTO_OK); 292 } 293 294 s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input)); 295 if (unlikely(s != sizeof(input))) { 296 virtio_error(vdev, "virtio-crypto input incorrect"); 297 virtqueue_detach_element(vq, elem, 0); 298 goto out; 299 } 300 virtqueue_push(vq, elem, sizeof(input)); 301 virtio_notify(vdev, vq); 302 303 out: 304 g_free(elem); 305 virtio_crypto_free_create_session_req(sreq); 306 } 307 308 static void virtio_crypto_destroy_session_completion(void *opaque, int ret) 309 { 310 VirtIOCryptoSessionReq *sreq = (VirtIOCryptoSessionReq *)opaque; 311 VirtQueue *vq = sreq->vq; 312 VirtQueueElement *elem = sreq->elem; 313 VirtIODevice *vdev = sreq->vdev; 314 struct iovec *in_iov = elem->in_sg; 315 unsigned in_num = elem->in_num; 316 uint8_t status; 317 size_t s; 318 319 if (ret < 0) { 320 status = VIRTIO_CRYPTO_ERR; 321 } else { 322 status = VIRTIO_CRYPTO_OK; 323 } 324 s = iov_from_buf(in_iov, in_num, 0, &status, sizeof(status)); 325 if (unlikely(s != sizeof(status))) { 326 virtio_error(vdev, "virtio-crypto status incorrect"); 327 virtqueue_detach_element(vq, elem, 0); 328 goto out; 329 } 330 virtqueue_push(vq, elem, sizeof(status)); 331 virtio_notify(vdev, vq); 332 333 out: 334 g_free(elem); 335 g_free(sreq); 336 } 337 338 static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) 339 { 340 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 341 struct virtio_crypto_op_ctrl_req ctrl; 342 VirtQueueElement *elem; 343 VirtIOCryptoSessionReq *sreq; 344 unsigned out_num; 345 unsigned in_num; 346 uint32_t queue_id; 347 uint32_t opcode; 348 struct virtio_crypto_session_input input; 349 size_t s; 350 int ret; 351 struct iovec *out_iov; 352 struct iovec *in_iov; 353 354 for (;;) { 355 g_autofree struct iovec *out_iov_copy = NULL; 356 357 elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); 358 if (!elem) { 359 break; 360 } 361 if (elem->out_num < 1 || elem->in_num < 1) { 362 virtio_error(vdev, "virtio-crypto ctrl missing headers"); 363 virtqueue_detach_element(vq, elem, 0); 364 g_free(elem); 365 break; 366 } 367 368 out_num = elem->out_num; 369 out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num); 370 out_iov = out_iov_copy; 371 372 in_num = elem->in_num; 373 in_iov = elem->in_sg; 374 375 if (unlikely(iov_to_buf(out_iov, out_num, 0, &ctrl, sizeof(ctrl)) 376 != sizeof(ctrl))) { 377 virtio_error(vdev, "virtio-crypto request ctrl_hdr too short"); 378 virtqueue_detach_element(vq, elem, 0); 379 g_free(elem); 380 break; 381 } 382 iov_discard_front(&out_iov, &out_num, sizeof(ctrl)); 383 384 opcode = ldl_le_p(&ctrl.header.opcode); 385 queue_id = ldl_le_p(&ctrl.header.queue_id); 386 387 sreq = g_new0(VirtIOCryptoSessionReq, 1); 388 sreq->vdev = vdev; 389 sreq->vq = vq; 390 sreq->elem = elem; 391 392 switch (opcode) { 393 case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION: 394 sreq->cb = virtio_crypto_create_session_completion; 395 ret = virtio_crypto_create_sym_session(vcrypto, 396 &ctrl.u.sym_create_session, 397 queue_id, opcode, 398 out_iov, out_num, 399 sreq); 400 if (ret < 0) { 401 virtio_crypto_create_session_completion(sreq, ret); 402 } 403 break; 404 405 case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION: 406 sreq->cb = virtio_crypto_create_session_completion; 407 ret = virtio_crypto_create_asym_session(vcrypto, 408 &ctrl.u.akcipher_create_session, 409 queue_id, opcode, 410 out_iov, out_num, 411 sreq); 412 if (ret < 0) { 413 virtio_crypto_create_session_completion(sreq, ret); 414 } 415 break; 416 417 case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION: 418 case VIRTIO_CRYPTO_HASH_DESTROY_SESSION: 419 case VIRTIO_CRYPTO_MAC_DESTROY_SESSION: 420 case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION: 421 case VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION: 422 sreq->cb = virtio_crypto_destroy_session_completion; 423 ret = virtio_crypto_handle_close_session(vcrypto, 424 &ctrl.u.destroy_session, queue_id, 425 sreq); 426 if (ret < 0) { 427 virtio_crypto_destroy_session_completion(sreq, ret); 428 } 429 break; 430 431 case VIRTIO_CRYPTO_HASH_CREATE_SESSION: 432 case VIRTIO_CRYPTO_MAC_CREATE_SESSION: 433 case VIRTIO_CRYPTO_AEAD_CREATE_SESSION: 434 default: 435 memset(&input, 0, sizeof(input)); 436 error_report("virtio-crypto unsupported ctrl opcode: %d", opcode); 437 stl_le_p(&input.status, VIRTIO_CRYPTO_NOTSUPP); 438 s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input)); 439 if (unlikely(s != sizeof(input))) { 440 virtio_error(vdev, "virtio-crypto input incorrect"); 441 virtqueue_detach_element(vq, elem, 0); 442 } else { 443 virtqueue_push(vq, elem, sizeof(input)); 444 virtio_notify(vdev, vq); 445 } 446 g_free(sreq); 447 g_free(elem); 448 449 break; 450 } /* end switch case */ 451 452 } /* end for loop */ 453 } 454 455 static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue *vq, 456 VirtIOCryptoReq *req) 457 { 458 req->vcrypto = vcrypto; 459 req->vq = vq; 460 req->in = NULL; 461 req->in_iov = NULL; 462 req->in_num = 0; 463 req->in_len = 0; 464 req->flags = QCRYPTODEV_BACKEND_ALG__MAX; 465 memset(&req->op_info, 0x00, sizeof(req->op_info)); 466 } 467 468 static void virtio_crypto_free_request(VirtIOCryptoReq *req) 469 { 470 if (!req) { 471 return; 472 } 473 474 if (req->flags == QCRYPTODEV_BACKEND_ALG_SYM) { 475 size_t max_len; 476 CryptoDevBackendSymOpInfo *op_info = req->op_info.u.sym_op_info; 477 478 if (op_info) { 479 max_len = op_info->iv_len + 480 op_info->aad_len + 481 op_info->src_len + 482 op_info->dst_len + 483 op_info->digest_result_len; 484 485 /* Zeroize and free request data structure */ 486 memset(op_info, 0, sizeof(*op_info) + max_len); 487 g_free(op_info); 488 } 489 } else if (req->flags == QCRYPTODEV_BACKEND_ALG_ASYM) { 490 CryptoDevBackendAsymOpInfo *op_info = req->op_info.u.asym_op_info; 491 if (op_info) { 492 g_free(op_info->src); 493 g_free(op_info->dst); 494 memset(op_info, 0, sizeof(*op_info)); 495 g_free(op_info); 496 } 497 } 498 499 g_free(req->in_iov); 500 g_free(req); 501 } 502 503 static void 504 virtio_crypto_sym_input_data_helper(VirtIODevice *vdev, 505 VirtIOCryptoReq *req, 506 uint32_t status, 507 CryptoDevBackendSymOpInfo *sym_op_info) 508 { 509 size_t s, len; 510 struct iovec *in_iov = req->in_iov; 511 512 if (status != VIRTIO_CRYPTO_OK) { 513 return; 514 } 515 516 len = sym_op_info->src_len; 517 /* Save the cipher result */ 518 s = iov_from_buf(in_iov, req->in_num, 0, sym_op_info->dst, len); 519 if (s != len) { 520 virtio_error(vdev, "virtio-crypto dest data incorrect"); 521 return; 522 } 523 524 iov_discard_front(&in_iov, &req->in_num, len); 525 526 if (sym_op_info->op_type == 527 VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) { 528 /* Save the digest result */ 529 s = iov_from_buf(in_iov, req->in_num, 0, 530 sym_op_info->digest_result, 531 sym_op_info->digest_result_len); 532 if (s != sym_op_info->digest_result_len) { 533 virtio_error(vdev, "virtio-crypto digest result incorrect"); 534 } 535 } 536 } 537 538 static void 539 virtio_crypto_akcipher_input_data_helper(VirtIODevice *vdev, 540 VirtIOCryptoReq *req, int32_t status, 541 CryptoDevBackendAsymOpInfo *asym_op_info) 542 { 543 size_t s, len; 544 struct iovec *in_iov = req->in_iov; 545 546 if (status != VIRTIO_CRYPTO_OK) { 547 return; 548 } 549 550 len = asym_op_info->dst_len; 551 if (!len) { 552 return; 553 } 554 555 s = iov_from_buf(in_iov, req->in_num, 0, asym_op_info->dst, len); 556 if (s != len) { 557 virtio_error(vdev, "virtio-crypto asym dest data incorrect"); 558 return; 559 } 560 561 iov_discard_front(&in_iov, &req->in_num, len); 562 563 /* For akcipher, dst_len may be changed after operation */ 564 req->in_len = sizeof(struct virtio_crypto_inhdr) + asym_op_info->dst_len; 565 } 566 567 static void virtio_crypto_req_complete(void *opaque, int ret) 568 { 569 VirtIOCryptoReq *req = (VirtIOCryptoReq *)opaque; 570 VirtIOCrypto *vcrypto = req->vcrypto; 571 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 572 uint8_t status = -ret; 573 574 if (req->flags == QCRYPTODEV_BACKEND_ALG_SYM) { 575 virtio_crypto_sym_input_data_helper(vdev, req, status, 576 req->op_info.u.sym_op_info); 577 } else if (req->flags == QCRYPTODEV_BACKEND_ALG_ASYM) { 578 virtio_crypto_akcipher_input_data_helper(vdev, req, status, 579 req->op_info.u.asym_op_info); 580 } 581 stb_p(&req->in->status, status); 582 virtqueue_push(req->vq, &req->elem, req->in_len); 583 virtio_notify(vdev, req->vq); 584 virtio_crypto_free_request(req); 585 } 586 587 static VirtIOCryptoReq * 588 virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq) 589 { 590 VirtIOCryptoReq *req = virtqueue_pop(vq, sizeof(VirtIOCryptoReq)); 591 592 if (req) { 593 virtio_crypto_init_request(s, vq, req); 594 } 595 return req; 596 } 597 598 static CryptoDevBackendSymOpInfo * 599 virtio_crypto_sym_op_helper(VirtIODevice *vdev, 600 struct virtio_crypto_cipher_para *cipher_para, 601 struct virtio_crypto_alg_chain_data_para *alg_chain_para, 602 struct iovec *iov, unsigned int out_num) 603 { 604 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 605 CryptoDevBackendSymOpInfo *op_info; 606 uint32_t src_len = 0, dst_len = 0; 607 uint32_t iv_len = 0; 608 uint32_t aad_len = 0, hash_result_len = 0; 609 uint32_t hash_start_src_offset = 0, len_to_hash = 0; 610 uint32_t cipher_start_src_offset = 0, len_to_cipher = 0; 611 612 uint64_t max_len, curr_size = 0; 613 size_t s; 614 615 /* Plain cipher */ 616 if (cipher_para) { 617 iv_len = ldl_le_p(&cipher_para->iv_len); 618 src_len = ldl_le_p(&cipher_para->src_data_len); 619 dst_len = ldl_le_p(&cipher_para->dst_data_len); 620 } else if (alg_chain_para) { /* Algorithm chain */ 621 iv_len = ldl_le_p(&alg_chain_para->iv_len); 622 src_len = ldl_le_p(&alg_chain_para->src_data_len); 623 dst_len = ldl_le_p(&alg_chain_para->dst_data_len); 624 625 aad_len = ldl_le_p(&alg_chain_para->aad_len); 626 hash_result_len = ldl_le_p(&alg_chain_para->hash_result_len); 627 hash_start_src_offset = ldl_le_p( 628 &alg_chain_para->hash_start_src_offset); 629 cipher_start_src_offset = ldl_le_p( 630 &alg_chain_para->cipher_start_src_offset); 631 len_to_cipher = ldl_le_p(&alg_chain_para->len_to_cipher); 632 len_to_hash = ldl_le_p(&alg_chain_para->len_to_hash); 633 } else { 634 return NULL; 635 } 636 637 max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len; 638 if (unlikely(max_len > vcrypto->conf.max_size)) { 639 virtio_error(vdev, "virtio-crypto too big length"); 640 return NULL; 641 } 642 643 op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len); 644 op_info->iv_len = iv_len; 645 op_info->src_len = src_len; 646 op_info->dst_len = dst_len; 647 op_info->aad_len = aad_len; 648 op_info->digest_result_len = hash_result_len; 649 op_info->hash_start_src_offset = hash_start_src_offset; 650 op_info->len_to_hash = len_to_hash; 651 op_info->cipher_start_src_offset = cipher_start_src_offset; 652 op_info->len_to_cipher = len_to_cipher; 653 /* Handle the initilization vector */ 654 if (op_info->iv_len > 0) { 655 DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len); 656 op_info->iv = op_info->data + curr_size; 657 658 s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len); 659 if (unlikely(s != op_info->iv_len)) { 660 virtio_error(vdev, "virtio-crypto iv incorrect"); 661 goto err; 662 } 663 iov_discard_front(&iov, &out_num, op_info->iv_len); 664 curr_size += op_info->iv_len; 665 } 666 667 /* Handle additional authentication data if exists */ 668 if (op_info->aad_len > 0) { 669 DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len); 670 op_info->aad_data = op_info->data + curr_size; 671 672 s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len); 673 if (unlikely(s != op_info->aad_len)) { 674 virtio_error(vdev, "virtio-crypto additional auth data incorrect"); 675 goto err; 676 } 677 iov_discard_front(&iov, &out_num, op_info->aad_len); 678 679 curr_size += op_info->aad_len; 680 } 681 682 /* Handle the source data */ 683 if (op_info->src_len > 0) { 684 DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len); 685 op_info->src = op_info->data + curr_size; 686 687 s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len); 688 if (unlikely(s != op_info->src_len)) { 689 virtio_error(vdev, "virtio-crypto source data incorrect"); 690 goto err; 691 } 692 iov_discard_front(&iov, &out_num, op_info->src_len); 693 694 curr_size += op_info->src_len; 695 } 696 697 /* Handle the destination data */ 698 op_info->dst = op_info->data + curr_size; 699 curr_size += op_info->dst_len; 700 701 DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len); 702 703 /* Handle the hash digest result */ 704 if (hash_result_len > 0) { 705 DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len); 706 op_info->digest_result = op_info->data + curr_size; 707 } 708 709 return op_info; 710 711 err: 712 g_free(op_info); 713 return NULL; 714 } 715 716 static int 717 virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto, 718 struct virtio_crypto_sym_data_req *req, 719 CryptoDevBackendOpInfo *op_info, 720 struct iovec *iov, unsigned int out_num) 721 { 722 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 723 CryptoDevBackendSymOpInfo *sym_op_info; 724 uint32_t op_type; 725 726 op_type = ldl_le_p(&req->op_type); 727 if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) { 728 sym_op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para, 729 NULL, iov, out_num); 730 if (!sym_op_info) { 731 return -EFAULT; 732 } 733 } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) { 734 sym_op_info = virtio_crypto_sym_op_helper(vdev, NULL, 735 &req->u.chain.para, 736 iov, out_num); 737 if (!sym_op_info) { 738 return -EFAULT; 739 } 740 } else { 741 /* VIRTIO_CRYPTO_SYM_OP_NONE */ 742 error_report("virtio-crypto unsupported cipher type"); 743 return -VIRTIO_CRYPTO_NOTSUPP; 744 } 745 746 sym_op_info->op_type = op_type; 747 op_info->u.sym_op_info = sym_op_info; 748 749 return 0; 750 } 751 752 static int 753 virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto, 754 struct virtio_crypto_akcipher_data_req *req, 755 CryptoDevBackendOpInfo *op_info, 756 struct iovec *iov, unsigned int out_num) 757 { 758 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 759 CryptoDevBackendAsymOpInfo *asym_op_info; 760 uint32_t src_len; 761 uint32_t dst_len; 762 uint32_t len; 763 uint8_t *src = NULL; 764 uint8_t *dst = NULL; 765 766 asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1); 767 src_len = ldl_le_p(&req->para.src_data_len); 768 dst_len = ldl_le_p(&req->para.dst_data_len); 769 770 if (src_len > 0) { 771 src = g_malloc0(src_len); 772 len = iov_to_buf(iov, out_num, 0, src, src_len); 773 if (unlikely(len != src_len)) { 774 virtio_error(vdev, "virtio-crypto asym src data incorrect" 775 "expected %u, actual %u", src_len, len); 776 goto err; 777 } 778 779 iov_discard_front(&iov, &out_num, src_len); 780 } 781 782 if (dst_len > 0) { 783 dst = g_malloc0(dst_len); 784 785 if (op_info->op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) { 786 len = iov_to_buf(iov, out_num, 0, dst, dst_len); 787 if (unlikely(len != dst_len)) { 788 virtio_error(vdev, "virtio-crypto asym dst data incorrect" 789 "expected %u, actual %u", dst_len, len); 790 goto err; 791 } 792 793 iov_discard_front(&iov, &out_num, dst_len); 794 } 795 } 796 797 asym_op_info->src_len = src_len; 798 asym_op_info->dst_len = dst_len; 799 asym_op_info->src = src; 800 asym_op_info->dst = dst; 801 op_info->u.asym_op_info = asym_op_info; 802 803 return 0; 804 805 err: 806 g_free(asym_op_info); 807 g_free(src); 808 g_free(dst); 809 810 return -EFAULT; 811 } 812 813 static int 814 virtio_crypto_handle_request(VirtIOCryptoReq *request) 815 { 816 VirtIOCrypto *vcrypto = request->vcrypto; 817 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 818 VirtQueueElement *elem = &request->elem; 819 int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq)); 820 struct virtio_crypto_op_data_req req; 821 int ret; 822 g_autofree struct iovec *in_iov_copy = NULL; 823 g_autofree struct iovec *out_iov_copy = NULL; 824 struct iovec *in_iov; 825 struct iovec *out_iov; 826 unsigned in_num; 827 unsigned out_num; 828 uint32_t opcode; 829 CryptoDevBackendOpInfo *op_info = &request->op_info; 830 831 if (elem->out_num < 1 || elem->in_num < 1) { 832 virtio_error(vdev, "virtio-crypto dataq missing headers"); 833 return -1; 834 } 835 836 out_num = elem->out_num; 837 out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num); 838 out_iov = out_iov_copy; 839 840 in_num = elem->in_num; 841 in_iov_copy = g_memdup2(elem->in_sg, sizeof(in_iov[0]) * in_num); 842 in_iov = in_iov_copy; 843 844 if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req)) 845 != sizeof(req))) { 846 virtio_error(vdev, "virtio-crypto request outhdr too short"); 847 return -1; 848 } 849 iov_discard_front(&out_iov, &out_num, sizeof(req)); 850 851 if (in_iov[in_num - 1].iov_len < 852 sizeof(struct virtio_crypto_inhdr)) { 853 virtio_error(vdev, "virtio-crypto request inhdr too short"); 854 return -1; 855 } 856 /* We always touch the last byte, so just see how big in_iov is. */ 857 request->in_len = iov_size(in_iov, in_num); 858 request->in = (void *)in_iov[in_num - 1].iov_base 859 + in_iov[in_num - 1].iov_len 860 - sizeof(struct virtio_crypto_inhdr); 861 iov_discard_back(in_iov, &in_num, sizeof(struct virtio_crypto_inhdr)); 862 863 /* 864 * The length of operation result, including dest_data 865 * and digest_result if exists. 866 */ 867 request->in_num = in_num; 868 request->in_iov = in_iov; 869 /* now, we free the in_iov_copy inside virtio_crypto_free_request */ 870 in_iov_copy = NULL; 871 872 opcode = ldl_le_p(&req.header.opcode); 873 op_info->session_id = ldq_le_p(&req.header.session_id); 874 op_info->op_code = opcode; 875 op_info->queue_index = queue_index; 876 op_info->cb = virtio_crypto_req_complete; 877 op_info->opaque = request; 878 879 switch (opcode) { 880 case VIRTIO_CRYPTO_CIPHER_ENCRYPT: 881 case VIRTIO_CRYPTO_CIPHER_DECRYPT: 882 op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALG_SYM; 883 ret = virtio_crypto_handle_sym_req(vcrypto, 884 &req.u.sym_req, op_info, 885 out_iov, out_num); 886 goto check_result; 887 888 case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT: 889 case VIRTIO_CRYPTO_AKCIPHER_DECRYPT: 890 case VIRTIO_CRYPTO_AKCIPHER_SIGN: 891 case VIRTIO_CRYPTO_AKCIPHER_VERIFY: 892 op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALG_ASYM; 893 ret = virtio_crypto_handle_asym_req(vcrypto, 894 &req.u.akcipher_req, op_info, 895 out_iov, out_num); 896 897 check_result: 898 /* Serious errors, need to reset virtio crypto device */ 899 if (ret == -EFAULT) { 900 return -1; 901 } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { 902 virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); 903 } else { 904 ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev, 905 op_info); 906 if (ret < 0) { 907 virtio_crypto_req_complete(request, ret); 908 } 909 } 910 break; 911 912 case VIRTIO_CRYPTO_HASH: 913 case VIRTIO_CRYPTO_MAC: 914 case VIRTIO_CRYPTO_AEAD_ENCRYPT: 915 case VIRTIO_CRYPTO_AEAD_DECRYPT: 916 default: 917 error_report("virtio-crypto unsupported dataq opcode: %u", 918 opcode); 919 virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); 920 } 921 922 return 0; 923 } 924 925 static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq) 926 { 927 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 928 VirtIOCryptoReq *req; 929 930 while ((req = virtio_crypto_get_request(vcrypto, vq))) { 931 if (virtio_crypto_handle_request(req) < 0) { 932 virtqueue_detach_element(req->vq, &req->elem, 0); 933 virtio_crypto_free_request(req); 934 break; 935 } 936 } 937 } 938 939 static void virtio_crypto_dataq_bh(void *opaque) 940 { 941 VirtIOCryptoQueue *q = opaque; 942 VirtIOCrypto *vcrypto = q->vcrypto; 943 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 944 945 /* This happens when device was stopped but BH wasn't. */ 946 if (!vdev->vm_running) { 947 return; 948 } 949 950 /* Just in case the driver is not ready on more */ 951 if (unlikely(!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))) { 952 return; 953 } 954 955 for (;;) { 956 virtio_crypto_handle_dataq(vdev, q->dataq); 957 virtio_queue_set_notification(q->dataq, 1); 958 959 /* Are we done or did the guest add more buffers? */ 960 if (virtio_queue_empty(q->dataq)) { 961 break; 962 } 963 964 virtio_queue_set_notification(q->dataq, 0); 965 } 966 } 967 968 static void 969 virtio_crypto_handle_dataq_bh(VirtIODevice *vdev, VirtQueue *vq) 970 { 971 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 972 VirtIOCryptoQueue *q = 973 &vcrypto->vqs[virtio_crypto_vq2q(virtio_get_queue_index(vq))]; 974 975 /* This happens when device was stopped but VCPU wasn't. */ 976 if (!vdev->vm_running) { 977 return; 978 } 979 virtio_queue_set_notification(vq, 0); 980 qemu_bh_schedule(q->dataq_bh); 981 } 982 983 static uint64_t virtio_crypto_get_features(VirtIODevice *vdev, 984 uint64_t features, 985 Error **errp) 986 { 987 return features; 988 } 989 990 static void virtio_crypto_reset(VirtIODevice *vdev) 991 { 992 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 993 /* multiqueue is disabled by default */ 994 vcrypto->curr_queues = 1; 995 if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { 996 vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; 997 } else { 998 vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; 999 } 1000 } 1001 1002 static uint32_t virtio_crypto_init_services(uint32_t qservices) 1003 { 1004 uint32_t vservices = 0; 1005 1006 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_CIPHER)) { 1007 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_CIPHER); 1008 } 1009 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_HASH)) { 1010 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_HASH); 1011 } 1012 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_MAC)) { 1013 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_MAC); 1014 } 1015 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_AEAD)) { 1016 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_AEAD); 1017 } 1018 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_AKCIPHER)) { 1019 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_AKCIPHER); 1020 } 1021 1022 return vservices; 1023 } 1024 1025 static void virtio_crypto_init_config(VirtIODevice *vdev) 1026 { 1027 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1028 1029 vcrypto->conf.crypto_services = virtio_crypto_init_services( 1030 vcrypto->conf.cryptodev->conf.crypto_services); 1031 vcrypto->conf.cipher_algo_l = 1032 vcrypto->conf.cryptodev->conf.cipher_algo_l; 1033 vcrypto->conf.cipher_algo_h = 1034 vcrypto->conf.cryptodev->conf.cipher_algo_h; 1035 vcrypto->conf.hash_algo = vcrypto->conf.cryptodev->conf.hash_algo; 1036 vcrypto->conf.mac_algo_l = vcrypto->conf.cryptodev->conf.mac_algo_l; 1037 vcrypto->conf.mac_algo_h = vcrypto->conf.cryptodev->conf.mac_algo_h; 1038 vcrypto->conf.aead_algo = vcrypto->conf.cryptodev->conf.aead_algo; 1039 vcrypto->conf.akcipher_algo = vcrypto->conf.cryptodev->conf.akcipher_algo; 1040 vcrypto->conf.max_cipher_key_len = 1041 vcrypto->conf.cryptodev->conf.max_cipher_key_len; 1042 vcrypto->conf.max_auth_key_len = 1043 vcrypto->conf.cryptodev->conf.max_auth_key_len; 1044 vcrypto->conf.max_size = vcrypto->conf.cryptodev->conf.max_size; 1045 } 1046 1047 static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) 1048 { 1049 VirtIODevice *vdev = VIRTIO_DEVICE(dev); 1050 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev); 1051 int i; 1052 1053 vcrypto->cryptodev = vcrypto->conf.cryptodev; 1054 if (vcrypto->cryptodev == NULL) { 1055 error_setg(errp, "'cryptodev' parameter expects a valid object"); 1056 return; 1057 } else if (cryptodev_backend_is_used(vcrypto->cryptodev)) { 1058 error_setg(errp, "can't use already used cryptodev backend: %s", 1059 object_get_canonical_path_component(OBJECT(vcrypto->conf.cryptodev))); 1060 return; 1061 } 1062 1063 vcrypto->max_queues = MAX(vcrypto->cryptodev->conf.peers.queues, 1); 1064 if (vcrypto->max_queues + 1 > VIRTIO_QUEUE_MAX) { 1065 error_setg(errp, "Invalid number of queues (= %" PRIu32 "), " 1066 "must be a positive integer less than %d.", 1067 vcrypto->max_queues, VIRTIO_QUEUE_MAX); 1068 return; 1069 } 1070 1071 virtio_init(vdev, VIRTIO_ID_CRYPTO, vcrypto->config_size); 1072 vcrypto->curr_queues = 1; 1073 vcrypto->vqs = g_new0(VirtIOCryptoQueue, vcrypto->max_queues); 1074 for (i = 0; i < vcrypto->max_queues; i++) { 1075 vcrypto->vqs[i].dataq = 1076 virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); 1077 vcrypto->vqs[i].dataq_bh = 1078 qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i], 1079 &dev->mem_reentrancy_guard); 1080 vcrypto->vqs[i].vcrypto = vcrypto; 1081 } 1082 1083 vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl); 1084 if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { 1085 vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; 1086 } else { 1087 vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; 1088 } 1089 1090 virtio_crypto_init_config(vdev); 1091 cryptodev_backend_set_used(vcrypto->cryptodev, true); 1092 } 1093 1094 static void virtio_crypto_device_unrealize(DeviceState *dev) 1095 { 1096 VirtIODevice *vdev = VIRTIO_DEVICE(dev); 1097 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev); 1098 VirtIOCryptoQueue *q; 1099 int i, max_queues; 1100 1101 max_queues = vcrypto->multiqueue ? vcrypto->max_queues : 1; 1102 for (i = 0; i < max_queues; i++) { 1103 virtio_delete_queue(vcrypto->vqs[i].dataq); 1104 q = &vcrypto->vqs[i]; 1105 qemu_bh_delete(q->dataq_bh); 1106 } 1107 1108 g_free(vcrypto->vqs); 1109 virtio_delete_queue(vcrypto->ctrl_vq); 1110 1111 virtio_cleanup(vdev); 1112 cryptodev_backend_set_used(vcrypto->cryptodev, false); 1113 } 1114 1115 static const VMStateDescription vmstate_virtio_crypto = { 1116 .name = "virtio-crypto", 1117 .unmigratable = 1, 1118 .minimum_version_id = VIRTIO_CRYPTO_VM_VERSION, 1119 .version_id = VIRTIO_CRYPTO_VM_VERSION, 1120 .fields = (VMStateField[]) { 1121 VMSTATE_VIRTIO_DEVICE, 1122 VMSTATE_END_OF_LIST() 1123 }, 1124 }; 1125 1126 static Property virtio_crypto_properties[] = { 1127 DEFINE_PROP_LINK("cryptodev", VirtIOCrypto, conf.cryptodev, 1128 TYPE_CRYPTODEV_BACKEND, CryptoDevBackend *), 1129 DEFINE_PROP_END_OF_LIST(), 1130 }; 1131 1132 static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config) 1133 { 1134 VirtIOCrypto *c = VIRTIO_CRYPTO(vdev); 1135 struct virtio_crypto_config crypto_cfg = {}; 1136 1137 /* 1138 * Virtio-crypto device conforms to VIRTIO 1.0 which is always LE, 1139 * so we can use LE accessors directly. 1140 */ 1141 stl_le_p(&crypto_cfg.status, c->status); 1142 stl_le_p(&crypto_cfg.max_dataqueues, c->max_queues); 1143 stl_le_p(&crypto_cfg.crypto_services, c->conf.crypto_services); 1144 stl_le_p(&crypto_cfg.cipher_algo_l, c->conf.cipher_algo_l); 1145 stl_le_p(&crypto_cfg.cipher_algo_h, c->conf.cipher_algo_h); 1146 stl_le_p(&crypto_cfg.hash_algo, c->conf.hash_algo); 1147 stl_le_p(&crypto_cfg.mac_algo_l, c->conf.mac_algo_l); 1148 stl_le_p(&crypto_cfg.mac_algo_h, c->conf.mac_algo_h); 1149 stl_le_p(&crypto_cfg.aead_algo, c->conf.aead_algo); 1150 stl_le_p(&crypto_cfg.max_cipher_key_len, c->conf.max_cipher_key_len); 1151 stl_le_p(&crypto_cfg.max_auth_key_len, c->conf.max_auth_key_len); 1152 stq_le_p(&crypto_cfg.max_size, c->conf.max_size); 1153 stl_le_p(&crypto_cfg.akcipher_algo, c->conf.akcipher_algo); 1154 1155 memcpy(config, &crypto_cfg, c->config_size); 1156 } 1157 1158 static bool virtio_crypto_started(VirtIOCrypto *c, uint8_t status) 1159 { 1160 VirtIODevice *vdev = VIRTIO_DEVICE(c); 1161 return (status & VIRTIO_CONFIG_S_DRIVER_OK) && 1162 (c->status & VIRTIO_CRYPTO_S_HW_READY) && vdev->vm_running; 1163 } 1164 1165 static void virtio_crypto_vhost_status(VirtIOCrypto *c, uint8_t status) 1166 { 1167 VirtIODevice *vdev = VIRTIO_DEVICE(c); 1168 int queues = c->multiqueue ? c->max_queues : 1; 1169 CryptoDevBackend *b = c->cryptodev; 1170 CryptoDevBackendClient *cc = b->conf.peers.ccs[0]; 1171 1172 if (!cryptodev_get_vhost(cc, b, 0)) { 1173 return; 1174 } 1175 1176 if ((virtio_crypto_started(c, status)) == !!c->vhost_started) { 1177 return; 1178 } 1179 1180 if (!c->vhost_started) { 1181 int r; 1182 1183 c->vhost_started = 1; 1184 r = cryptodev_vhost_start(vdev, queues); 1185 if (r < 0) { 1186 error_report("unable to start vhost crypto: %d: " 1187 "falling back on userspace virtio", -r); 1188 c->vhost_started = 0; 1189 } 1190 } else { 1191 cryptodev_vhost_stop(vdev, queues); 1192 c->vhost_started = 0; 1193 } 1194 } 1195 1196 static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) 1197 { 1198 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1199 1200 virtio_crypto_vhost_status(vcrypto, status); 1201 } 1202 1203 static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, 1204 bool mask) 1205 { 1206 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1207 int queue = virtio_crypto_vq2q(idx); 1208 1209 assert(vcrypto->vhost_started); 1210 1211 /* 1212 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 1213 * as the Marco of configure interrupt's IDX, If this driver does not 1214 * support, the function will return 1215 */ 1216 1217 if (idx == VIRTIO_CONFIG_IRQ_IDX) { 1218 return; 1219 } 1220 cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); 1221 } 1222 1223 static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) 1224 { 1225 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1226 int queue = virtio_crypto_vq2q(idx); 1227 1228 assert(vcrypto->vhost_started); 1229 1230 /* 1231 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 1232 * as the Marco of configure interrupt's IDX, If this driver does not 1233 * support, the function will return 1234 */ 1235 1236 if (idx == VIRTIO_CONFIG_IRQ_IDX) { 1237 return false; 1238 } 1239 return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); 1240 } 1241 1242 static struct vhost_dev *virtio_crypto_get_vhost(VirtIODevice *vdev) 1243 { 1244 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1245 CryptoDevBackend *b = vcrypto->cryptodev; 1246 CryptoDevBackendClient *cc = b->conf.peers.ccs[0]; 1247 CryptoDevBackendVhost *vhost_crypto = cryptodev_get_vhost(cc, b, 0); 1248 return &vhost_crypto->dev; 1249 } 1250 1251 static void virtio_crypto_class_init(ObjectClass *klass, void *data) 1252 { 1253 DeviceClass *dc = DEVICE_CLASS(klass); 1254 VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); 1255 1256 device_class_set_props(dc, virtio_crypto_properties); 1257 dc->vmsd = &vmstate_virtio_crypto; 1258 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 1259 vdc->realize = virtio_crypto_device_realize; 1260 vdc->unrealize = virtio_crypto_device_unrealize; 1261 vdc->get_config = virtio_crypto_get_config; 1262 vdc->get_features = virtio_crypto_get_features; 1263 vdc->reset = virtio_crypto_reset; 1264 vdc->set_status = virtio_crypto_set_status; 1265 vdc->guest_notifier_mask = virtio_crypto_guest_notifier_mask; 1266 vdc->guest_notifier_pending = virtio_crypto_guest_notifier_pending; 1267 vdc->get_vhost = virtio_crypto_get_vhost; 1268 } 1269 1270 static void virtio_crypto_instance_init(Object *obj) 1271 { 1272 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj); 1273 1274 /* 1275 * The default config_size is sizeof(struct virtio_crypto_config). 1276 * Can be overriden with virtio_crypto_set_config_size. 1277 */ 1278 vcrypto->config_size = sizeof(struct virtio_crypto_config); 1279 } 1280 1281 static const TypeInfo virtio_crypto_info = { 1282 .name = TYPE_VIRTIO_CRYPTO, 1283 .parent = TYPE_VIRTIO_DEVICE, 1284 .instance_size = sizeof(VirtIOCrypto), 1285 .instance_init = virtio_crypto_instance_init, 1286 .class_init = virtio_crypto_class_init, 1287 }; 1288 1289 static void virtio_register_types(void) 1290 { 1291 type_register_static(&virtio_crypto_info); 1292 } 1293 1294 type_init(virtio_register_types) 1295