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