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 sreq->info.op_code = opcode; 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 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_ALGO_TYPE__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_ALGO_TYPE_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_ALGO_TYPE_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_ALGO_TYPE_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_ALGO_TYPE_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 if (unlikely(src_len != dst_len)) { 638 virtio_error(vdev, "sym request src len is different from dst len"); 639 return NULL; 640 } 641 642 max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len; 643 if (unlikely(max_len > vcrypto->conf.max_size)) { 644 virtio_error(vdev, "virtio-crypto too big length"); 645 return NULL; 646 } 647 648 op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len); 649 op_info->iv_len = iv_len; 650 op_info->src_len = src_len; 651 op_info->dst_len = dst_len; 652 op_info->aad_len = aad_len; 653 op_info->digest_result_len = hash_result_len; 654 op_info->hash_start_src_offset = hash_start_src_offset; 655 op_info->len_to_hash = len_to_hash; 656 op_info->cipher_start_src_offset = cipher_start_src_offset; 657 op_info->len_to_cipher = len_to_cipher; 658 /* Handle the initialization vector */ 659 if (op_info->iv_len > 0) { 660 DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len); 661 op_info->iv = op_info->data + curr_size; 662 663 s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len); 664 if (unlikely(s != op_info->iv_len)) { 665 virtio_error(vdev, "virtio-crypto iv incorrect"); 666 goto err; 667 } 668 iov_discard_front(&iov, &out_num, op_info->iv_len); 669 curr_size += op_info->iv_len; 670 } 671 672 /* Handle additional authentication data if exists */ 673 if (op_info->aad_len > 0) { 674 DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len); 675 op_info->aad_data = op_info->data + curr_size; 676 677 s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len); 678 if (unlikely(s != op_info->aad_len)) { 679 virtio_error(vdev, "virtio-crypto additional auth data incorrect"); 680 goto err; 681 } 682 iov_discard_front(&iov, &out_num, op_info->aad_len); 683 684 curr_size += op_info->aad_len; 685 } 686 687 /* Handle the source data */ 688 if (op_info->src_len > 0) { 689 DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len); 690 op_info->src = op_info->data + curr_size; 691 692 s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len); 693 if (unlikely(s != op_info->src_len)) { 694 virtio_error(vdev, "virtio-crypto source data incorrect"); 695 goto err; 696 } 697 iov_discard_front(&iov, &out_num, op_info->src_len); 698 699 curr_size += op_info->src_len; 700 } 701 702 /* Handle the destination data */ 703 op_info->dst = op_info->data + curr_size; 704 curr_size += op_info->dst_len; 705 706 DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len); 707 708 /* Handle the hash digest result */ 709 if (hash_result_len > 0) { 710 DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len); 711 op_info->digest_result = op_info->data + curr_size; 712 } 713 714 return op_info; 715 716 err: 717 g_free(op_info); 718 return NULL; 719 } 720 721 static int 722 virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto, 723 struct virtio_crypto_sym_data_req *req, 724 CryptoDevBackendOpInfo *op_info, 725 struct iovec *iov, unsigned int out_num) 726 { 727 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 728 CryptoDevBackendSymOpInfo *sym_op_info; 729 uint32_t op_type; 730 731 op_type = ldl_le_p(&req->op_type); 732 if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) { 733 sym_op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para, 734 NULL, iov, out_num); 735 if (!sym_op_info) { 736 return -EFAULT; 737 } 738 } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) { 739 sym_op_info = virtio_crypto_sym_op_helper(vdev, NULL, 740 &req->u.chain.para, 741 iov, out_num); 742 if (!sym_op_info) { 743 return -EFAULT; 744 } 745 } else { 746 /* VIRTIO_CRYPTO_SYM_OP_NONE */ 747 error_report("virtio-crypto unsupported cipher type"); 748 return -VIRTIO_CRYPTO_NOTSUPP; 749 } 750 751 sym_op_info->op_type = op_type; 752 op_info->u.sym_op_info = sym_op_info; 753 754 return 0; 755 } 756 757 static int 758 virtio_crypto_handle_asym_req(VirtIOCrypto *vcrypto, 759 struct virtio_crypto_akcipher_data_req *req, 760 CryptoDevBackendOpInfo *op_info, 761 struct iovec *iov, unsigned int out_num) 762 { 763 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 764 CryptoDevBackendAsymOpInfo *asym_op_info; 765 uint32_t src_len; 766 uint32_t dst_len; 767 uint32_t len; 768 uint8_t *src = NULL; 769 uint8_t *dst = NULL; 770 771 asym_op_info = g_new0(CryptoDevBackendAsymOpInfo, 1); 772 src_len = ldl_le_p(&req->para.src_data_len); 773 dst_len = ldl_le_p(&req->para.dst_data_len); 774 775 if (src_len > 0) { 776 src = g_malloc0(src_len); 777 len = iov_to_buf(iov, out_num, 0, src, src_len); 778 if (unlikely(len != src_len)) { 779 virtio_error(vdev, "virtio-crypto asym src data incorrect" 780 "expected %u, actual %u", src_len, len); 781 goto err; 782 } 783 784 iov_discard_front(&iov, &out_num, src_len); 785 } 786 787 if (dst_len > 0) { 788 dst = g_malloc0(dst_len); 789 790 if (op_info->op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) { 791 len = iov_to_buf(iov, out_num, 0, dst, dst_len); 792 if (unlikely(len != dst_len)) { 793 virtio_error(vdev, "virtio-crypto asym dst data incorrect" 794 "expected %u, actual %u", dst_len, len); 795 goto err; 796 } 797 798 iov_discard_front(&iov, &out_num, dst_len); 799 } 800 } 801 802 asym_op_info->src_len = src_len; 803 asym_op_info->dst_len = dst_len; 804 asym_op_info->src = src; 805 asym_op_info->dst = dst; 806 op_info->u.asym_op_info = asym_op_info; 807 808 return 0; 809 810 err: 811 g_free(asym_op_info); 812 g_free(src); 813 g_free(dst); 814 815 return -EFAULT; 816 } 817 818 static int 819 virtio_crypto_handle_request(VirtIOCryptoReq *request) 820 { 821 VirtIOCrypto *vcrypto = request->vcrypto; 822 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 823 VirtQueueElement *elem = &request->elem; 824 int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq)); 825 struct virtio_crypto_op_data_req req; 826 int ret; 827 g_autofree struct iovec *in_iov_copy = NULL; 828 g_autofree struct iovec *out_iov_copy = NULL; 829 struct iovec *in_iov; 830 struct iovec *out_iov; 831 unsigned in_num; 832 unsigned out_num; 833 uint32_t opcode; 834 CryptoDevBackendOpInfo *op_info = &request->op_info; 835 836 if (elem->out_num < 1 || elem->in_num < 1) { 837 virtio_error(vdev, "virtio-crypto dataq missing headers"); 838 return -1; 839 } 840 841 out_num = elem->out_num; 842 out_iov_copy = g_memdup2(elem->out_sg, sizeof(out_iov[0]) * out_num); 843 out_iov = out_iov_copy; 844 845 in_num = elem->in_num; 846 in_iov_copy = g_memdup2(elem->in_sg, sizeof(in_iov[0]) * in_num); 847 in_iov = in_iov_copy; 848 849 if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req)) 850 != sizeof(req))) { 851 virtio_error(vdev, "virtio-crypto request outhdr too short"); 852 return -1; 853 } 854 iov_discard_front(&out_iov, &out_num, sizeof(req)); 855 856 if (in_iov[in_num - 1].iov_len < 857 sizeof(struct virtio_crypto_inhdr)) { 858 virtio_error(vdev, "virtio-crypto request inhdr too short"); 859 return -1; 860 } 861 /* We always touch the last byte, so just see how big in_iov is. */ 862 request->in_len = iov_size(in_iov, in_num); 863 request->in = (void *)in_iov[in_num - 1].iov_base 864 + in_iov[in_num - 1].iov_len 865 - sizeof(struct virtio_crypto_inhdr); 866 iov_discard_back(in_iov, &in_num, sizeof(struct virtio_crypto_inhdr)); 867 868 /* 869 * The length of operation result, including dest_data 870 * and digest_result if exists. 871 */ 872 request->in_num = in_num; 873 request->in_iov = in_iov; 874 /* now, we free the in_iov_copy inside virtio_crypto_free_request */ 875 in_iov_copy = NULL; 876 877 opcode = ldl_le_p(&req.header.opcode); 878 op_info->session_id = ldq_le_p(&req.header.session_id); 879 op_info->op_code = opcode; 880 op_info->queue_index = queue_index; 881 op_info->cb = virtio_crypto_req_complete; 882 op_info->opaque = request; 883 884 switch (opcode) { 885 case VIRTIO_CRYPTO_CIPHER_ENCRYPT: 886 case VIRTIO_CRYPTO_CIPHER_DECRYPT: 887 op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALGO_TYPE_SYM; 888 ret = virtio_crypto_handle_sym_req(vcrypto, 889 &req.u.sym_req, op_info, 890 out_iov, out_num); 891 goto check_result; 892 893 case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT: 894 case VIRTIO_CRYPTO_AKCIPHER_DECRYPT: 895 case VIRTIO_CRYPTO_AKCIPHER_SIGN: 896 case VIRTIO_CRYPTO_AKCIPHER_VERIFY: 897 op_info->algtype = request->flags = QCRYPTODEV_BACKEND_ALGO_TYPE_ASYM; 898 ret = virtio_crypto_handle_asym_req(vcrypto, 899 &req.u.akcipher_req, op_info, 900 out_iov, out_num); 901 902 check_result: 903 /* Serious errors, need to reset virtio crypto device */ 904 if (ret == -EFAULT) { 905 return -1; 906 } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) { 907 virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); 908 } else { 909 ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev, 910 op_info); 911 if (ret < 0) { 912 virtio_crypto_req_complete(request, ret); 913 } 914 } 915 break; 916 917 case VIRTIO_CRYPTO_HASH: 918 case VIRTIO_CRYPTO_MAC: 919 case VIRTIO_CRYPTO_AEAD_ENCRYPT: 920 case VIRTIO_CRYPTO_AEAD_DECRYPT: 921 default: 922 error_report("virtio-crypto unsupported dataq opcode: %u", 923 opcode); 924 virtio_crypto_req_complete(request, -VIRTIO_CRYPTO_NOTSUPP); 925 } 926 927 return 0; 928 } 929 930 static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq) 931 { 932 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 933 VirtIOCryptoReq *req; 934 935 while ((req = virtio_crypto_get_request(vcrypto, vq))) { 936 if (virtio_crypto_handle_request(req) < 0) { 937 virtqueue_detach_element(req->vq, &req->elem, 0); 938 virtio_crypto_free_request(req); 939 break; 940 } 941 } 942 } 943 944 static void virtio_crypto_dataq_bh(void *opaque) 945 { 946 VirtIOCryptoQueue *q = opaque; 947 VirtIOCrypto *vcrypto = q->vcrypto; 948 VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto); 949 950 /* This happens when device was stopped but BH wasn't. */ 951 if (!vdev->vm_running) { 952 return; 953 } 954 955 /* Just in case the driver is not ready on more */ 956 if (unlikely(!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))) { 957 return; 958 } 959 960 for (;;) { 961 virtio_crypto_handle_dataq(vdev, q->dataq); 962 virtio_queue_set_notification(q->dataq, 1); 963 964 /* Are we done or did the guest add more buffers? */ 965 if (virtio_queue_empty(q->dataq)) { 966 break; 967 } 968 969 virtio_queue_set_notification(q->dataq, 0); 970 } 971 } 972 973 static void 974 virtio_crypto_handle_dataq_bh(VirtIODevice *vdev, VirtQueue *vq) 975 { 976 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 977 VirtIOCryptoQueue *q = 978 &vcrypto->vqs[virtio_crypto_vq2q(virtio_get_queue_index(vq))]; 979 980 /* This happens when device was stopped but VCPU wasn't. */ 981 if (!vdev->vm_running) { 982 return; 983 } 984 virtio_queue_set_notification(vq, 0); 985 qemu_bh_schedule(q->dataq_bh); 986 } 987 988 static uint64_t virtio_crypto_get_features(VirtIODevice *vdev, 989 uint64_t features, 990 Error **errp) 991 { 992 return features; 993 } 994 995 static void virtio_crypto_reset(VirtIODevice *vdev) 996 { 997 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 998 /* multiqueue is disabled by default */ 999 vcrypto->curr_queues = 1; 1000 if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { 1001 vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; 1002 } else { 1003 vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; 1004 } 1005 } 1006 1007 static uint32_t virtio_crypto_init_services(uint32_t qservices) 1008 { 1009 uint32_t vservices = 0; 1010 1011 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_CIPHER)) { 1012 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_CIPHER); 1013 } 1014 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_HASH)) { 1015 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_HASH); 1016 } 1017 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_MAC)) { 1018 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_MAC); 1019 } 1020 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_AEAD)) { 1021 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_AEAD); 1022 } 1023 if (qservices & (1 << QCRYPTODEV_BACKEND_SERVICE_TYPE_AKCIPHER)) { 1024 vservices |= (1 << VIRTIO_CRYPTO_SERVICE_AKCIPHER); 1025 } 1026 1027 return vservices; 1028 } 1029 1030 static void virtio_crypto_init_config(VirtIODevice *vdev) 1031 { 1032 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1033 1034 vcrypto->conf.crypto_services = virtio_crypto_init_services( 1035 vcrypto->conf.cryptodev->conf.crypto_services); 1036 vcrypto->conf.cipher_algo_l = 1037 vcrypto->conf.cryptodev->conf.cipher_algo_l; 1038 vcrypto->conf.cipher_algo_h = 1039 vcrypto->conf.cryptodev->conf.cipher_algo_h; 1040 vcrypto->conf.hash_algo = vcrypto->conf.cryptodev->conf.hash_algo; 1041 vcrypto->conf.mac_algo_l = vcrypto->conf.cryptodev->conf.mac_algo_l; 1042 vcrypto->conf.mac_algo_h = vcrypto->conf.cryptodev->conf.mac_algo_h; 1043 vcrypto->conf.aead_algo = vcrypto->conf.cryptodev->conf.aead_algo; 1044 vcrypto->conf.akcipher_algo = vcrypto->conf.cryptodev->conf.akcipher_algo; 1045 vcrypto->conf.max_cipher_key_len = 1046 vcrypto->conf.cryptodev->conf.max_cipher_key_len; 1047 vcrypto->conf.max_auth_key_len = 1048 vcrypto->conf.cryptodev->conf.max_auth_key_len; 1049 vcrypto->conf.max_size = vcrypto->conf.cryptodev->conf.max_size; 1050 } 1051 1052 static void virtio_crypto_device_realize(DeviceState *dev, Error **errp) 1053 { 1054 VirtIODevice *vdev = VIRTIO_DEVICE(dev); 1055 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev); 1056 int i; 1057 1058 vcrypto->cryptodev = vcrypto->conf.cryptodev; 1059 if (vcrypto->cryptodev == NULL) { 1060 error_setg(errp, "'cryptodev' parameter expects a valid object"); 1061 return; 1062 } else if (cryptodev_backend_is_used(vcrypto->cryptodev)) { 1063 error_setg(errp, "can't use already used cryptodev backend: %s", 1064 object_get_canonical_path_component(OBJECT(vcrypto->conf.cryptodev))); 1065 return; 1066 } 1067 1068 vcrypto->max_queues = MAX(vcrypto->cryptodev->conf.peers.queues, 1); 1069 if (vcrypto->max_queues + 1 > VIRTIO_QUEUE_MAX) { 1070 error_setg(errp, "Invalid number of queues (= %" PRIu32 "), " 1071 "must be a positive integer less than %d.", 1072 vcrypto->max_queues, VIRTIO_QUEUE_MAX); 1073 return; 1074 } 1075 1076 virtio_init(vdev, VIRTIO_ID_CRYPTO, vcrypto->config_size); 1077 vcrypto->curr_queues = 1; 1078 vcrypto->vqs = g_new0(VirtIOCryptoQueue, vcrypto->max_queues); 1079 for (i = 0; i < vcrypto->max_queues; i++) { 1080 vcrypto->vqs[i].dataq = 1081 virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh); 1082 vcrypto->vqs[i].dataq_bh = 1083 virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh, 1084 &vcrypto->vqs[i]); 1085 vcrypto->vqs[i].vcrypto = vcrypto; 1086 } 1087 1088 vcrypto->ctrl_vq = virtio_add_queue(vdev, 1024, virtio_crypto_handle_ctrl); 1089 if (!cryptodev_backend_is_ready(vcrypto->cryptodev)) { 1090 vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY; 1091 } else { 1092 vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY; 1093 } 1094 1095 virtio_crypto_init_config(vdev); 1096 cryptodev_backend_set_used(vcrypto->cryptodev, true); 1097 } 1098 1099 static void virtio_crypto_device_unrealize(DeviceState *dev) 1100 { 1101 VirtIODevice *vdev = VIRTIO_DEVICE(dev); 1102 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev); 1103 VirtIOCryptoQueue *q; 1104 int i, max_queues; 1105 1106 max_queues = vcrypto->multiqueue ? vcrypto->max_queues : 1; 1107 for (i = 0; i < max_queues; i++) { 1108 virtio_delete_queue(vcrypto->vqs[i].dataq); 1109 q = &vcrypto->vqs[i]; 1110 qemu_bh_delete(q->dataq_bh); 1111 } 1112 1113 g_free(vcrypto->vqs); 1114 virtio_delete_queue(vcrypto->ctrl_vq); 1115 1116 virtio_cleanup(vdev); 1117 cryptodev_backend_set_used(vcrypto->cryptodev, false); 1118 } 1119 1120 static const VMStateDescription vmstate_virtio_crypto = { 1121 .name = "virtio-crypto", 1122 .unmigratable = 1, 1123 .minimum_version_id = VIRTIO_CRYPTO_VM_VERSION, 1124 .version_id = VIRTIO_CRYPTO_VM_VERSION, 1125 .fields = (const VMStateField[]) { 1126 VMSTATE_VIRTIO_DEVICE, 1127 VMSTATE_END_OF_LIST() 1128 }, 1129 }; 1130 1131 static Property virtio_crypto_properties[] = { 1132 DEFINE_PROP_LINK("cryptodev", VirtIOCrypto, conf.cryptodev, 1133 TYPE_CRYPTODEV_BACKEND, CryptoDevBackend *), 1134 DEFINE_PROP_END_OF_LIST(), 1135 }; 1136 1137 static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config) 1138 { 1139 VirtIOCrypto *c = VIRTIO_CRYPTO(vdev); 1140 struct virtio_crypto_config crypto_cfg = {}; 1141 1142 /* 1143 * Virtio-crypto device conforms to VIRTIO 1.0 which is always LE, 1144 * so we can use LE accessors directly. 1145 */ 1146 stl_le_p(&crypto_cfg.status, c->status); 1147 stl_le_p(&crypto_cfg.max_dataqueues, c->max_queues); 1148 stl_le_p(&crypto_cfg.crypto_services, c->conf.crypto_services); 1149 stl_le_p(&crypto_cfg.cipher_algo_l, c->conf.cipher_algo_l); 1150 stl_le_p(&crypto_cfg.cipher_algo_h, c->conf.cipher_algo_h); 1151 stl_le_p(&crypto_cfg.hash_algo, c->conf.hash_algo); 1152 stl_le_p(&crypto_cfg.mac_algo_l, c->conf.mac_algo_l); 1153 stl_le_p(&crypto_cfg.mac_algo_h, c->conf.mac_algo_h); 1154 stl_le_p(&crypto_cfg.aead_algo, c->conf.aead_algo); 1155 stl_le_p(&crypto_cfg.max_cipher_key_len, c->conf.max_cipher_key_len); 1156 stl_le_p(&crypto_cfg.max_auth_key_len, c->conf.max_auth_key_len); 1157 stq_le_p(&crypto_cfg.max_size, c->conf.max_size); 1158 stl_le_p(&crypto_cfg.akcipher_algo, c->conf.akcipher_algo); 1159 1160 memcpy(config, &crypto_cfg, c->config_size); 1161 } 1162 1163 static bool virtio_crypto_started(VirtIOCrypto *c, uint8_t status) 1164 { 1165 VirtIODevice *vdev = VIRTIO_DEVICE(c); 1166 return (status & VIRTIO_CONFIG_S_DRIVER_OK) && 1167 (c->status & VIRTIO_CRYPTO_S_HW_READY) && vdev->vm_running; 1168 } 1169 1170 static void virtio_crypto_vhost_status(VirtIOCrypto *c, uint8_t status) 1171 { 1172 VirtIODevice *vdev = VIRTIO_DEVICE(c); 1173 int queues = c->multiqueue ? c->max_queues : 1; 1174 CryptoDevBackend *b = c->cryptodev; 1175 CryptoDevBackendClient *cc = b->conf.peers.ccs[0]; 1176 1177 if (!cryptodev_get_vhost(cc, b, 0)) { 1178 return; 1179 } 1180 1181 if ((virtio_crypto_started(c, status)) == !!c->vhost_started) { 1182 return; 1183 } 1184 1185 if (!c->vhost_started) { 1186 int r; 1187 1188 c->vhost_started = 1; 1189 r = cryptodev_vhost_start(vdev, queues); 1190 if (r < 0) { 1191 error_report("unable to start vhost crypto: %d: " 1192 "falling back on userspace virtio", -r); 1193 c->vhost_started = 0; 1194 } 1195 } else { 1196 cryptodev_vhost_stop(vdev, queues); 1197 c->vhost_started = 0; 1198 } 1199 } 1200 1201 static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) 1202 { 1203 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1204 1205 virtio_crypto_vhost_status(vcrypto, status); 1206 } 1207 1208 static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, 1209 bool mask) 1210 { 1211 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1212 int queue = virtio_crypto_vq2q(idx); 1213 1214 assert(vcrypto->vhost_started); 1215 1216 /* 1217 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 1218 * as the macro of configure interrupt's IDX, If this driver does not 1219 * support, the function will return 1220 */ 1221 1222 if (idx == VIRTIO_CONFIG_IRQ_IDX) { 1223 return; 1224 } 1225 cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); 1226 } 1227 1228 static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int idx) 1229 { 1230 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1231 int queue = virtio_crypto_vq2q(idx); 1232 1233 assert(vcrypto->vhost_started); 1234 1235 /* 1236 * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1 1237 * as the macro of configure interrupt's IDX, If this driver does not 1238 * support, the function will return 1239 */ 1240 1241 if (idx == VIRTIO_CONFIG_IRQ_IDX) { 1242 return false; 1243 } 1244 return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); 1245 } 1246 1247 static struct vhost_dev *virtio_crypto_get_vhost(VirtIODevice *vdev) 1248 { 1249 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); 1250 CryptoDevBackend *b; 1251 CryptoDevBackendClient *cc; 1252 CryptoDevBackendVhost *vhost_crypto; 1253 1254 b = vcrypto->cryptodev; 1255 if (!b) { 1256 return NULL; 1257 } 1258 1259 cc = b->conf.peers.ccs[0]; 1260 vhost_crypto = cryptodev_get_vhost(cc, b, 0); 1261 if (!vhost_crypto) { 1262 return NULL; 1263 } 1264 1265 return &vhost_crypto->dev; 1266 } 1267 1268 static void virtio_crypto_class_init(ObjectClass *klass, void *data) 1269 { 1270 DeviceClass *dc = DEVICE_CLASS(klass); 1271 VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); 1272 1273 device_class_set_props(dc, virtio_crypto_properties); 1274 dc->vmsd = &vmstate_virtio_crypto; 1275 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 1276 vdc->realize = virtio_crypto_device_realize; 1277 vdc->unrealize = virtio_crypto_device_unrealize; 1278 vdc->get_config = virtio_crypto_get_config; 1279 vdc->get_features = virtio_crypto_get_features; 1280 vdc->reset = virtio_crypto_reset; 1281 vdc->set_status = virtio_crypto_set_status; 1282 vdc->guest_notifier_mask = virtio_crypto_guest_notifier_mask; 1283 vdc->guest_notifier_pending = virtio_crypto_guest_notifier_pending; 1284 vdc->get_vhost = virtio_crypto_get_vhost; 1285 } 1286 1287 static void virtio_crypto_instance_init(Object *obj) 1288 { 1289 VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj); 1290 1291 /* 1292 * The default config_size is sizeof(struct virtio_crypto_config). 1293 * Can be overridden with virtio_crypto_set_config_size. 1294 */ 1295 vcrypto->config_size = sizeof(struct virtio_crypto_config); 1296 } 1297 1298 static const TypeInfo virtio_crypto_info = { 1299 .name = TYPE_VIRTIO_CRYPTO, 1300 .parent = TYPE_VIRTIO_DEVICE, 1301 .instance_size = sizeof(VirtIOCrypto), 1302 .instance_init = virtio_crypto_instance_init, 1303 .class_init = virtio_crypto_class_init, 1304 }; 1305 1306 static void virtio_register_types(void) 1307 { 1308 type_register_static(&virtio_crypto_info); 1309 } 1310 1311 type_init(virtio_register_types) 1312