Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.5 665 lines 18 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2 /* Algorithms supported by virtio crypto device 3 * 4 * Authors: Gonglei <arei.gonglei@huawei.com> 5 * 6 * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD. 7 */ 8 9#include <linux/scatterlist.h> 10#include <crypto/algapi.h> 11#include <crypto/internal/skcipher.h> 12#include <linux/err.h> 13#include <crypto/scatterwalk.h> 14#include <linux/atomic.h> 15 16#include <uapi/linux/virtio_crypto.h> 17#include "virtio_crypto_common.h" 18 19 20struct virtio_crypto_skcipher_ctx { 21 struct crypto_engine_ctx enginectx; 22 struct virtio_crypto *vcrypto; 23 struct crypto_skcipher *tfm; 24 25 struct virtio_crypto_sym_session_info enc_sess_info; 26 struct virtio_crypto_sym_session_info dec_sess_info; 27}; 28 29struct virtio_crypto_sym_request { 30 struct virtio_crypto_request base; 31 32 /* Cipher or aead */ 33 uint32_t type; 34 struct virtio_crypto_skcipher_ctx *skcipher_ctx; 35 struct skcipher_request *skcipher_req; 36 uint8_t *iv; 37 /* Encryption? */ 38 bool encrypt; 39}; 40 41struct virtio_crypto_algo { 42 uint32_t algonum; 43 uint32_t service; 44 unsigned int active_devs; 45 struct skcipher_alg algo; 46}; 47 48/* 49 * The algs_lock protects the below global virtio_crypto_active_devs 50 * and crypto algorithms registion. 51 */ 52static DEFINE_MUTEX(algs_lock); 53static void virtio_crypto_skcipher_finalize_req( 54 struct virtio_crypto_sym_request *vc_sym_req, 55 struct skcipher_request *req, 56 int err); 57 58static void virtio_crypto_dataq_sym_callback 59 (struct virtio_crypto_request *vc_req, int len) 60{ 61 struct virtio_crypto_sym_request *vc_sym_req = 62 container_of(vc_req, struct virtio_crypto_sym_request, base); 63 struct skcipher_request *ablk_req; 64 int error; 65 66 /* Finish the encrypt or decrypt process */ 67 if (vc_sym_req->type == VIRTIO_CRYPTO_SYM_OP_CIPHER) { 68 switch (vc_req->status) { 69 case VIRTIO_CRYPTO_OK: 70 error = 0; 71 break; 72 case VIRTIO_CRYPTO_INVSESS: 73 case VIRTIO_CRYPTO_ERR: 74 error = -EINVAL; 75 break; 76 case VIRTIO_CRYPTO_BADMSG: 77 error = -EBADMSG; 78 break; 79 default: 80 error = -EIO; 81 break; 82 } 83 ablk_req = vc_sym_req->skcipher_req; 84 virtio_crypto_skcipher_finalize_req(vc_sym_req, 85 ablk_req, error); 86 } 87} 88 89static u64 virtio_crypto_alg_sg_nents_length(struct scatterlist *sg) 90{ 91 u64 total = 0; 92 93 for (total = 0; sg; sg = sg_next(sg)) 94 total += sg->length; 95 96 return total; 97} 98 99static int 100virtio_crypto_alg_validate_key(int key_len, uint32_t *alg) 101{ 102 switch (key_len) { 103 case AES_KEYSIZE_128: 104 case AES_KEYSIZE_192: 105 case AES_KEYSIZE_256: 106 *alg = VIRTIO_CRYPTO_CIPHER_AES_CBC; 107 break; 108 default: 109 return -EINVAL; 110 } 111 return 0; 112} 113 114static int virtio_crypto_alg_skcipher_init_session( 115 struct virtio_crypto_skcipher_ctx *ctx, 116 uint32_t alg, const uint8_t *key, 117 unsigned int keylen, 118 int encrypt) 119{ 120 struct scatterlist outhdr, key_sg, inhdr, *sgs[3]; 121 unsigned int tmp; 122 struct virtio_crypto *vcrypto = ctx->vcrypto; 123 int op = encrypt ? VIRTIO_CRYPTO_OP_ENCRYPT : VIRTIO_CRYPTO_OP_DECRYPT; 124 int err; 125 unsigned int num_out = 0, num_in = 0; 126 127 /* 128 * Avoid to do DMA from the stack, switch to using 129 * dynamically-allocated for the key 130 */ 131 uint8_t *cipher_key = kmemdup(key, keylen, GFP_ATOMIC); 132 133 if (!cipher_key) 134 return -ENOMEM; 135 136 spin_lock(&vcrypto->ctrl_lock); 137 /* Pad ctrl header */ 138 vcrypto->ctrl.header.opcode = 139 cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION); 140 vcrypto->ctrl.header.algo = cpu_to_le32(alg); 141 /* Set the default dataqueue id to 0 */ 142 vcrypto->ctrl.header.queue_id = 0; 143 144 vcrypto->input.status = cpu_to_le32(VIRTIO_CRYPTO_ERR); 145 /* Pad cipher's parameters */ 146 vcrypto->ctrl.u.sym_create_session.op_type = 147 cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER); 148 vcrypto->ctrl.u.sym_create_session.u.cipher.para.algo = 149 vcrypto->ctrl.header.algo; 150 vcrypto->ctrl.u.sym_create_session.u.cipher.para.keylen = 151 cpu_to_le32(keylen); 152 vcrypto->ctrl.u.sym_create_session.u.cipher.para.op = 153 cpu_to_le32(op); 154 155 sg_init_one(&outhdr, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); 156 sgs[num_out++] = &outhdr; 157 158 /* Set key */ 159 sg_init_one(&key_sg, cipher_key, keylen); 160 sgs[num_out++] = &key_sg; 161 162 /* Return status and session id back */ 163 sg_init_one(&inhdr, &vcrypto->input, sizeof(vcrypto->input)); 164 sgs[num_out + num_in++] = &inhdr; 165 166 err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, 167 num_in, vcrypto, GFP_ATOMIC); 168 if (err < 0) { 169 spin_unlock(&vcrypto->ctrl_lock); 170 kzfree(cipher_key); 171 return err; 172 } 173 virtqueue_kick(vcrypto->ctrl_vq); 174 175 /* 176 * Trapping into the hypervisor, so the request should be 177 * handled immediately. 178 */ 179 while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && 180 !virtqueue_is_broken(vcrypto->ctrl_vq)) 181 cpu_relax(); 182 183 if (le32_to_cpu(vcrypto->input.status) != VIRTIO_CRYPTO_OK) { 184 spin_unlock(&vcrypto->ctrl_lock); 185 pr_err("virtio_crypto: Create session failed status: %u\n", 186 le32_to_cpu(vcrypto->input.status)); 187 kzfree(cipher_key); 188 return -EINVAL; 189 } 190 191 if (encrypt) 192 ctx->enc_sess_info.session_id = 193 le64_to_cpu(vcrypto->input.session_id); 194 else 195 ctx->dec_sess_info.session_id = 196 le64_to_cpu(vcrypto->input.session_id); 197 198 spin_unlock(&vcrypto->ctrl_lock); 199 200 kzfree(cipher_key); 201 return 0; 202} 203 204static int virtio_crypto_alg_skcipher_close_session( 205 struct virtio_crypto_skcipher_ctx *ctx, 206 int encrypt) 207{ 208 struct scatterlist outhdr, status_sg, *sgs[2]; 209 unsigned int tmp; 210 struct virtio_crypto_destroy_session_req *destroy_session; 211 struct virtio_crypto *vcrypto = ctx->vcrypto; 212 int err; 213 unsigned int num_out = 0, num_in = 0; 214 215 spin_lock(&vcrypto->ctrl_lock); 216 vcrypto->ctrl_status.status = VIRTIO_CRYPTO_ERR; 217 /* Pad ctrl header */ 218 vcrypto->ctrl.header.opcode = 219 cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION); 220 /* Set the default virtqueue id to 0 */ 221 vcrypto->ctrl.header.queue_id = 0; 222 223 destroy_session = &vcrypto->ctrl.u.destroy_session; 224 225 if (encrypt) 226 destroy_session->session_id = 227 cpu_to_le64(ctx->enc_sess_info.session_id); 228 else 229 destroy_session->session_id = 230 cpu_to_le64(ctx->dec_sess_info.session_id); 231 232 sg_init_one(&outhdr, &vcrypto->ctrl, sizeof(vcrypto->ctrl)); 233 sgs[num_out++] = &outhdr; 234 235 /* Return status and session id back */ 236 sg_init_one(&status_sg, &vcrypto->ctrl_status.status, 237 sizeof(vcrypto->ctrl_status.status)); 238 sgs[num_out + num_in++] = &status_sg; 239 240 err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, 241 num_in, vcrypto, GFP_ATOMIC); 242 if (err < 0) { 243 spin_unlock(&vcrypto->ctrl_lock); 244 return err; 245 } 246 virtqueue_kick(vcrypto->ctrl_vq); 247 248 while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && 249 !virtqueue_is_broken(vcrypto->ctrl_vq)) 250 cpu_relax(); 251 252 if (vcrypto->ctrl_status.status != VIRTIO_CRYPTO_OK) { 253 spin_unlock(&vcrypto->ctrl_lock); 254 pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", 255 vcrypto->ctrl_status.status, 256 destroy_session->session_id); 257 258 return -EINVAL; 259 } 260 spin_unlock(&vcrypto->ctrl_lock); 261 262 return 0; 263} 264 265static int virtio_crypto_alg_skcipher_init_sessions( 266 struct virtio_crypto_skcipher_ctx *ctx, 267 const uint8_t *key, unsigned int keylen) 268{ 269 uint32_t alg; 270 int ret; 271 struct virtio_crypto *vcrypto = ctx->vcrypto; 272 273 if (keylen > vcrypto->max_cipher_key_len) { 274 pr_err("virtio_crypto: the key is too long\n"); 275 goto bad_key; 276 } 277 278 if (virtio_crypto_alg_validate_key(keylen, &alg)) 279 goto bad_key; 280 281 /* Create encryption session */ 282 ret = virtio_crypto_alg_skcipher_init_session(ctx, 283 alg, key, keylen, 1); 284 if (ret) 285 return ret; 286 /* Create decryption session */ 287 ret = virtio_crypto_alg_skcipher_init_session(ctx, 288 alg, key, keylen, 0); 289 if (ret) { 290 virtio_crypto_alg_skcipher_close_session(ctx, 1); 291 return ret; 292 } 293 return 0; 294 295bad_key: 296 crypto_skcipher_set_flags(ctx->tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 297 return -EINVAL; 298} 299 300/* Note: kernel crypto API realization */ 301static int virtio_crypto_skcipher_setkey(struct crypto_skcipher *tfm, 302 const uint8_t *key, 303 unsigned int keylen) 304{ 305 struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 306 uint32_t alg; 307 int ret; 308 309 ret = virtio_crypto_alg_validate_key(keylen, &alg); 310 if (ret) 311 return ret; 312 313 if (!ctx->vcrypto) { 314 /* New key */ 315 int node = virtio_crypto_get_current_node(); 316 struct virtio_crypto *vcrypto = 317 virtcrypto_get_dev_node(node, 318 VIRTIO_CRYPTO_SERVICE_CIPHER, alg); 319 if (!vcrypto) { 320 pr_err("virtio_crypto: Could not find a virtio device in the system or unsupported algo\n"); 321 return -ENODEV; 322 } 323 324 ctx->vcrypto = vcrypto; 325 } else { 326 /* Rekeying, we should close the created sessions previously */ 327 virtio_crypto_alg_skcipher_close_session(ctx, 1); 328 virtio_crypto_alg_skcipher_close_session(ctx, 0); 329 } 330 331 ret = virtio_crypto_alg_skcipher_init_sessions(ctx, key, keylen); 332 if (ret) { 333 virtcrypto_dev_put(ctx->vcrypto); 334 ctx->vcrypto = NULL; 335 336 return ret; 337 } 338 339 return 0; 340} 341 342static int 343__virtio_crypto_skcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req, 344 struct skcipher_request *req, 345 struct data_queue *data_vq) 346{ 347 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 348 struct virtio_crypto_skcipher_ctx *ctx = vc_sym_req->skcipher_ctx; 349 struct virtio_crypto_request *vc_req = &vc_sym_req->base; 350 unsigned int ivsize = crypto_skcipher_ivsize(tfm); 351 struct virtio_crypto *vcrypto = ctx->vcrypto; 352 struct virtio_crypto_op_data_req *req_data; 353 int src_nents, dst_nents; 354 int err; 355 unsigned long flags; 356 struct scatterlist outhdr, iv_sg, status_sg, **sgs; 357 int i; 358 u64 dst_len; 359 unsigned int num_out = 0, num_in = 0; 360 int sg_total; 361 uint8_t *iv; 362 363 src_nents = sg_nents_for_len(req->src, req->cryptlen); 364 dst_nents = sg_nents(req->dst); 365 366 pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n", 367 src_nents, dst_nents); 368 369 /* Why 3? outhdr + iv + inhdr */ 370 sg_total = src_nents + dst_nents + 3; 371 sgs = kcalloc_node(sg_total, sizeof(*sgs), GFP_KERNEL, 372 dev_to_node(&vcrypto->vdev->dev)); 373 if (!sgs) 374 return -ENOMEM; 375 376 req_data = kzalloc_node(sizeof(*req_data), GFP_KERNEL, 377 dev_to_node(&vcrypto->vdev->dev)); 378 if (!req_data) { 379 kfree(sgs); 380 return -ENOMEM; 381 } 382 383 vc_req->req_data = req_data; 384 vc_sym_req->type = VIRTIO_CRYPTO_SYM_OP_CIPHER; 385 /* Head of operation */ 386 if (vc_sym_req->encrypt) { 387 req_data->header.session_id = 388 cpu_to_le64(ctx->enc_sess_info.session_id); 389 req_data->header.opcode = 390 cpu_to_le32(VIRTIO_CRYPTO_CIPHER_ENCRYPT); 391 } else { 392 req_data->header.session_id = 393 cpu_to_le64(ctx->dec_sess_info.session_id); 394 req_data->header.opcode = 395 cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DECRYPT); 396 } 397 req_data->u.sym_req.op_type = cpu_to_le32(VIRTIO_CRYPTO_SYM_OP_CIPHER); 398 req_data->u.sym_req.u.cipher.para.iv_len = cpu_to_le32(ivsize); 399 req_data->u.sym_req.u.cipher.para.src_data_len = 400 cpu_to_le32(req->cryptlen); 401 402 dst_len = virtio_crypto_alg_sg_nents_length(req->dst); 403 if (unlikely(dst_len > U32_MAX)) { 404 pr_err("virtio_crypto: The dst_len is beyond U32_MAX\n"); 405 err = -EINVAL; 406 goto free; 407 } 408 409 pr_debug("virtio_crypto: src_len: %u, dst_len: %llu\n", 410 req->cryptlen, dst_len); 411 412 if (unlikely(req->cryptlen + dst_len + ivsize + 413 sizeof(vc_req->status) > vcrypto->max_size)) { 414 pr_err("virtio_crypto: The length is too big\n"); 415 err = -EINVAL; 416 goto free; 417 } 418 419 req_data->u.sym_req.u.cipher.para.dst_data_len = 420 cpu_to_le32((uint32_t)dst_len); 421 422 /* Outhdr */ 423 sg_init_one(&outhdr, req_data, sizeof(*req_data)); 424 sgs[num_out++] = &outhdr; 425 426 /* IV */ 427 428 /* 429 * Avoid to do DMA from the stack, switch to using 430 * dynamically-allocated for the IV 431 */ 432 iv = kzalloc_node(ivsize, GFP_ATOMIC, 433 dev_to_node(&vcrypto->vdev->dev)); 434 if (!iv) { 435 err = -ENOMEM; 436 goto free; 437 } 438 memcpy(iv, req->iv, ivsize); 439 if (!vc_sym_req->encrypt) 440 scatterwalk_map_and_copy(req->iv, req->src, 441 req->cryptlen - AES_BLOCK_SIZE, 442 AES_BLOCK_SIZE, 0); 443 444 sg_init_one(&iv_sg, iv, ivsize); 445 sgs[num_out++] = &iv_sg; 446 vc_sym_req->iv = iv; 447 448 /* Source data */ 449 for (i = 0; i < src_nents; i++) 450 sgs[num_out++] = &req->src[i]; 451 452 /* Destination data */ 453 for (i = 0; i < dst_nents; i++) 454 sgs[num_out + num_in++] = &req->dst[i]; 455 456 /* Status */ 457 sg_init_one(&status_sg, &vc_req->status, sizeof(vc_req->status)); 458 sgs[num_out + num_in++] = &status_sg; 459 460 vc_req->sgs = sgs; 461 462 spin_lock_irqsave(&data_vq->lock, flags); 463 err = virtqueue_add_sgs(data_vq->vq, sgs, num_out, 464 num_in, vc_req, GFP_ATOMIC); 465 virtqueue_kick(data_vq->vq); 466 spin_unlock_irqrestore(&data_vq->lock, flags); 467 if (unlikely(err < 0)) 468 goto free_iv; 469 470 return 0; 471 472free_iv: 473 kzfree(iv); 474free: 475 kzfree(req_data); 476 kfree(sgs); 477 return err; 478} 479 480static int virtio_crypto_skcipher_encrypt(struct skcipher_request *req) 481{ 482 struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(req); 483 struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(atfm); 484 struct virtio_crypto_sym_request *vc_sym_req = 485 skcipher_request_ctx(req); 486 struct virtio_crypto_request *vc_req = &vc_sym_req->base; 487 struct virtio_crypto *vcrypto = ctx->vcrypto; 488 /* Use the first data virtqueue as default */ 489 struct data_queue *data_vq = &vcrypto->data_vq[0]; 490 491 if (!req->cryptlen) 492 return 0; 493 if (req->cryptlen % AES_BLOCK_SIZE) 494 return -EINVAL; 495 496 vc_req->dataq = data_vq; 497 vc_req->alg_cb = virtio_crypto_dataq_sym_callback; 498 vc_sym_req->skcipher_ctx = ctx; 499 vc_sym_req->skcipher_req = req; 500 vc_sym_req->encrypt = true; 501 502 return crypto_transfer_skcipher_request_to_engine(data_vq->engine, req); 503} 504 505static int virtio_crypto_skcipher_decrypt(struct skcipher_request *req) 506{ 507 struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(req); 508 struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(atfm); 509 struct virtio_crypto_sym_request *vc_sym_req = 510 skcipher_request_ctx(req); 511 struct virtio_crypto_request *vc_req = &vc_sym_req->base; 512 struct virtio_crypto *vcrypto = ctx->vcrypto; 513 /* Use the first data virtqueue as default */ 514 struct data_queue *data_vq = &vcrypto->data_vq[0]; 515 516 if (!req->cryptlen) 517 return 0; 518 if (req->cryptlen % AES_BLOCK_SIZE) 519 return -EINVAL; 520 521 vc_req->dataq = data_vq; 522 vc_req->alg_cb = virtio_crypto_dataq_sym_callback; 523 vc_sym_req->skcipher_ctx = ctx; 524 vc_sym_req->skcipher_req = req; 525 vc_sym_req->encrypt = false; 526 527 return crypto_transfer_skcipher_request_to_engine(data_vq->engine, req); 528} 529 530static int virtio_crypto_skcipher_init(struct crypto_skcipher *tfm) 531{ 532 struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 533 534 crypto_skcipher_set_reqsize(tfm, sizeof(struct virtio_crypto_sym_request)); 535 ctx->tfm = tfm; 536 537 ctx->enginectx.op.do_one_request = virtio_crypto_skcipher_crypt_req; 538 ctx->enginectx.op.prepare_request = NULL; 539 ctx->enginectx.op.unprepare_request = NULL; 540 return 0; 541} 542 543static void virtio_crypto_skcipher_exit(struct crypto_skcipher *tfm) 544{ 545 struct virtio_crypto_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 546 547 if (!ctx->vcrypto) 548 return; 549 550 virtio_crypto_alg_skcipher_close_session(ctx, 1); 551 virtio_crypto_alg_skcipher_close_session(ctx, 0); 552 virtcrypto_dev_put(ctx->vcrypto); 553 ctx->vcrypto = NULL; 554} 555 556int virtio_crypto_skcipher_crypt_req( 557 struct crypto_engine *engine, void *vreq) 558{ 559 struct skcipher_request *req = container_of(vreq, struct skcipher_request, base); 560 struct virtio_crypto_sym_request *vc_sym_req = 561 skcipher_request_ctx(req); 562 struct virtio_crypto_request *vc_req = &vc_sym_req->base; 563 struct data_queue *data_vq = vc_req->dataq; 564 int ret; 565 566 ret = __virtio_crypto_skcipher_do_req(vc_sym_req, req, data_vq); 567 if (ret < 0) 568 return ret; 569 570 virtqueue_kick(data_vq->vq); 571 572 return 0; 573} 574 575static void virtio_crypto_skcipher_finalize_req( 576 struct virtio_crypto_sym_request *vc_sym_req, 577 struct skcipher_request *req, 578 int err) 579{ 580 if (vc_sym_req->encrypt) 581 scatterwalk_map_and_copy(req->iv, req->dst, 582 req->cryptlen - AES_BLOCK_SIZE, 583 AES_BLOCK_SIZE, 0); 584 crypto_finalize_skcipher_request(vc_sym_req->base.dataq->engine, 585 req, err); 586 kzfree(vc_sym_req->iv); 587 virtcrypto_clear_request(&vc_sym_req->base); 588} 589 590static struct virtio_crypto_algo virtio_crypto_algs[] = { { 591 .algonum = VIRTIO_CRYPTO_CIPHER_AES_CBC, 592 .service = VIRTIO_CRYPTO_SERVICE_CIPHER, 593 .algo = { 594 .base.cra_name = "cbc(aes)", 595 .base.cra_driver_name = "virtio_crypto_aes_cbc", 596 .base.cra_priority = 150, 597 .base.cra_flags = CRYPTO_ALG_ASYNC, 598 .base.cra_blocksize = AES_BLOCK_SIZE, 599 .base.cra_ctxsize = sizeof(struct virtio_crypto_skcipher_ctx), 600 .base.cra_module = THIS_MODULE, 601 .init = virtio_crypto_skcipher_init, 602 .exit = virtio_crypto_skcipher_exit, 603 .setkey = virtio_crypto_skcipher_setkey, 604 .decrypt = virtio_crypto_skcipher_decrypt, 605 .encrypt = virtio_crypto_skcipher_encrypt, 606 .min_keysize = AES_MIN_KEY_SIZE, 607 .max_keysize = AES_MAX_KEY_SIZE, 608 .ivsize = AES_BLOCK_SIZE, 609 }, 610} }; 611 612int virtio_crypto_algs_register(struct virtio_crypto *vcrypto) 613{ 614 int ret = 0; 615 int i = 0; 616 617 mutex_lock(&algs_lock); 618 619 for (i = 0; i < ARRAY_SIZE(virtio_crypto_algs); i++) { 620 621 uint32_t service = virtio_crypto_algs[i].service; 622 uint32_t algonum = virtio_crypto_algs[i].algonum; 623 624 if (!virtcrypto_algo_is_supported(vcrypto, service, algonum)) 625 continue; 626 627 if (virtio_crypto_algs[i].active_devs == 0) { 628 ret = crypto_register_skcipher(&virtio_crypto_algs[i].algo); 629 if (ret) 630 goto unlock; 631 } 632 633 virtio_crypto_algs[i].active_devs++; 634 dev_info(&vcrypto->vdev->dev, "Registered algo %s\n", 635 virtio_crypto_algs[i].algo.base.cra_name); 636 } 637 638unlock: 639 mutex_unlock(&algs_lock); 640 return ret; 641} 642 643void virtio_crypto_algs_unregister(struct virtio_crypto *vcrypto) 644{ 645 int i = 0; 646 647 mutex_lock(&algs_lock); 648 649 for (i = 0; i < ARRAY_SIZE(virtio_crypto_algs); i++) { 650 651 uint32_t service = virtio_crypto_algs[i].service; 652 uint32_t algonum = virtio_crypto_algs[i].algonum; 653 654 if (virtio_crypto_algs[i].active_devs == 0 || 655 !virtcrypto_algo_is_supported(vcrypto, service, algonum)) 656 continue; 657 658 if (virtio_crypto_algs[i].active_devs == 1) 659 crypto_unregister_skcipher(&virtio_crypto_algs[i].algo); 660 661 virtio_crypto_algs[i].active_devs--; 662 } 663 664 mutex_unlock(&algs_lock); 665}