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.

crypto: hisilicon/hpre - support the hpre algorithm fallback

When all hardware queues are busy and no shareable queue,
new processes fail to apply for queues. To avoid affecting
tasks, support fallback mechanism when hardware queues are
unavailable.

HPRE driver supports DH algorithm, limited to prime numbers up to 4K.
It supports prime numbers larger than 4K via fallback mechanism.

Fixes: 05e7b906aa7c ("crypto: hisilicon/hpre - add 'ECDH' algorithm")
Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Weili Qian and committed by
Herbert Xu
6aff4d97 73398f85

+199 -39
+199 -39
drivers/crypto/hisilicon/hpre/hpre_crypto.c
··· 93 93 94 94 char *g; /* m */ 95 95 dma_addr_t dma_g; 96 + struct crypto_kpp *soft_tfm; 96 97 }; 97 98 98 99 struct hpre_ecdh_ctx { ··· 104 103 /* low address: x->y */ 105 104 unsigned char *g; 106 105 dma_addr_t dma_g; 106 + struct crypto_kpp *soft_tfm; 107 107 }; 108 108 109 109 struct hpre_ctx { ··· 122 120 unsigned int curve_id; 123 121 /* for high performance core */ 124 122 u8 enable_hpcore; 123 + bool fallback; 125 124 }; 126 125 127 126 struct hpre_asym_request { ··· 385 382 struct hpre *hpre; 386 383 387 384 qp = hpre_create_qp(type); 388 - if (!qp) 385 + if (!qp) { 386 + ctx->qp = NULL; 389 387 return -ENODEV; 388 + } 390 389 391 390 qp->req_cb = hpre_alg_cb; 392 391 ctx->qp = qp; ··· 514 509 return ret; 515 510 } 516 511 512 + static struct kpp_request *hpre_dh_prepare_fb_req(struct kpp_request *req) 513 + { 514 + struct kpp_request *fb_req = kpp_request_ctx(req); 515 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 516 + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 517 + 518 + kpp_request_set_tfm(fb_req, ctx->dh.soft_tfm); 519 + kpp_request_set_callback(fb_req, req->base.flags, req->base.complete, req->base.data); 520 + kpp_request_set_input(fb_req, req->src, req->src_len); 521 + kpp_request_set_output(fb_req, req->dst, req->dst_len); 522 + 523 + return fb_req; 524 + } 525 + 526 + static int hpre_dh_generate_public_key(struct kpp_request *req) 527 + { 528 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 529 + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 530 + struct kpp_request *fb_req; 531 + 532 + if (ctx->fallback) { 533 + fb_req = hpre_dh_prepare_fb_req(req); 534 + return crypto_kpp_generate_public_key(fb_req); 535 + } 536 + 537 + return hpre_dh_compute_value(req); 538 + } 539 + 540 + static int hpre_dh_compute_shared_secret(struct kpp_request *req) 541 + { 542 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 543 + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 544 + struct kpp_request *fb_req; 545 + 546 + if (ctx->fallback) { 547 + fb_req = hpre_dh_prepare_fb_req(req); 548 + return crypto_kpp_compute_shared_secret(fb_req); 549 + } 550 + 551 + return hpre_dh_compute_value(req); 552 + } 553 + 517 554 static int hpre_is_dh_params_length_valid(unsigned int key_sz) 518 555 { 519 556 #define _HPRE_DH_GRP1 768 ··· 581 534 { 582 535 struct device *dev = ctx->dev; 583 536 unsigned int sz; 584 - 585 - if (params->p_size > HPRE_DH_MAX_P_SZ) 586 - return -EINVAL; 587 - 588 - if (hpre_is_dh_params_length_valid(params->p_size << 589 - HPRE_BITS_2_BYTES_SHIFT)) 590 - return -EINVAL; 591 537 592 538 sz = ctx->key_sz = params->p_size; 593 539 ctx->dh.xa_p = dma_alloc_coherent(dev, sz << 1, ··· 614 574 struct device *dev = ctx->dev; 615 575 unsigned int sz = ctx->key_sz; 616 576 577 + if (!ctx->qp) 578 + return; 579 + 617 580 if (ctx->dh.g) { 618 581 dma_free_coherent(dev, sz, ctx->dh.g, ctx->dh.dma_g); 619 582 ctx->dh.g = NULL; ··· 642 599 if (crypto_dh_decode_key(buf, len, &params) < 0) 643 600 return -EINVAL; 644 601 602 + if (!ctx->qp) 603 + goto set_soft_secret; 604 + 605 + if (hpre_is_dh_params_length_valid(params.p_size << 606 + HPRE_BITS_2_BYTES_SHIFT)) 607 + goto set_soft_secret; 608 + 645 609 /* Free old secret if any */ 646 610 hpre_dh_clear_ctx(ctx, false); 647 611 ··· 659 609 memcpy(ctx->dh.xa_p + (ctx->key_sz - params.key_size), params.key, 660 610 params.key_size); 661 611 612 + ctx->fallback = false; 662 613 return 0; 663 614 664 615 err_clear_ctx: 665 616 hpre_dh_clear_ctx(ctx, false); 666 617 return ret; 618 + set_soft_secret: 619 + ctx->fallback = true; 620 + return crypto_kpp_set_secret(ctx->dh.soft_tfm, buf, len); 667 621 } 668 622 669 623 static unsigned int hpre_dh_max_size(struct crypto_kpp *tfm) 670 624 { 671 625 struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 626 + 627 + if (ctx->fallback) 628 + return crypto_kpp_maxsize(ctx->dh.soft_tfm); 672 629 673 630 return ctx->key_sz; 674 631 } ··· 683 626 static int hpre_dh_init_tfm(struct crypto_kpp *tfm) 684 627 { 685 628 struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 629 + const char *alg = kpp_alg_name(tfm); 630 + unsigned int reqsize; 631 + int ret; 686 632 687 - kpp_set_reqsize(tfm, sizeof(struct hpre_asym_request) + hpre_align_pd()); 633 + ctx->dh.soft_tfm = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK); 634 + if (IS_ERR(ctx->dh.soft_tfm)) { 635 + pr_err("Failed to alloc dh tfm!\n"); 636 + return PTR_ERR(ctx->dh.soft_tfm); 637 + } 688 638 689 - return hpre_ctx_init(ctx, HPRE_V2_ALG_TYPE); 639 + crypto_kpp_set_flags(ctx->dh.soft_tfm, crypto_kpp_get_flags(tfm)); 640 + 641 + reqsize = max(sizeof(struct hpre_asym_request) + hpre_align_pd(), 642 + sizeof(struct kpp_request) + crypto_kpp_reqsize(ctx->dh.soft_tfm)); 643 + kpp_set_reqsize(tfm, reqsize); 644 + 645 + ret = hpre_ctx_init(ctx, HPRE_V2_ALG_TYPE); 646 + if (ret && ret != -ENODEV) { 647 + crypto_free_kpp(ctx->dh.soft_tfm); 648 + return ret; 649 + } else if (ret == -ENODEV) { 650 + ctx->fallback = true; 651 + } 652 + 653 + return 0; 690 654 } 691 655 692 656 static void hpre_dh_exit_tfm(struct crypto_kpp *tfm) ··· 715 637 struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 716 638 717 639 hpre_dh_clear_ctx(ctx, true); 640 + crypto_free_kpp(ctx->dh.soft_tfm); 718 641 } 719 642 720 643 static void hpre_rsa_drop_leading_zeros(const char **ptr, size_t *len) ··· 755 676 struct hpre_sqe *msg = &hpre_req->req; 756 677 int ret; 757 678 758 - /* For 512 and 1536 bits key size, use soft tfm instead */ 759 - if (ctx->key_sz == HPRE_RSA_512BITS_KSZ || 760 - ctx->key_sz == HPRE_RSA_1536BITS_KSZ) { 679 + /* For unsupported key size and unavailable devices, use soft tfm instead */ 680 + if (ctx->fallback) { 761 681 akcipher_request_set_tfm(req, ctx->rsa.soft_tfm); 762 682 ret = crypto_akcipher_encrypt(req); 763 683 akcipher_request_set_tfm(req, tfm); ··· 801 723 struct hpre_sqe *msg = &hpre_req->req; 802 724 int ret; 803 725 804 - /* For 512 and 1536 bits key size, use soft tfm instead */ 805 - if (ctx->key_sz == HPRE_RSA_512BITS_KSZ || 806 - ctx->key_sz == HPRE_RSA_1536BITS_KSZ) { 726 + /* For unsupported key size and unavailable devices, use soft tfm instead */ 727 + if (ctx->fallback) { 807 728 akcipher_request_set_tfm(req, ctx->rsa.soft_tfm); 808 729 ret = crypto_akcipher_decrypt(req); 809 730 akcipher_request_set_tfm(req, tfm); ··· 855 778 ctx->key_sz = vlen; 856 779 857 780 /* if invalid key size provided, we use software tfm */ 858 - if (!hpre_rsa_key_size_is_support(ctx->key_sz)) 781 + if (!hpre_rsa_key_size_is_support(ctx->key_sz)) { 782 + ctx->fallback = true; 859 783 return 0; 784 + } 860 785 861 786 ctx->rsa.pubkey = dma_alloc_coherent(ctx->dev, vlen << 1, 862 787 &ctx->rsa.dma_pubkey, ··· 993 914 unsigned int half_key_sz = ctx->key_sz >> 1; 994 915 struct device *dev = ctx->dev; 995 916 917 + if (!ctx->qp) 918 + return; 919 + 996 920 if (ctx->rsa.pubkey) { 997 921 dma_free_coherent(dev, ctx->key_sz << 1, 998 922 ctx->rsa.pubkey, ctx->rsa.dma_pubkey); ··· 1075 993 goto free; 1076 994 } 1077 995 996 + ctx->fallback = false; 1078 997 return 0; 1079 998 1080 999 free: ··· 1093 1010 if (ret) 1094 1011 return ret; 1095 1012 1013 + if (!ctx->qp) 1014 + return 0; 1015 + 1096 1016 return hpre_rsa_setkey(ctx, key, keylen, false); 1097 1017 } 1098 1018 ··· 1109 1023 if (ret) 1110 1024 return ret; 1111 1025 1026 + if (!ctx->qp) 1027 + return 0; 1028 + 1112 1029 return hpre_rsa_setkey(ctx, key, keylen, true); 1113 1030 } 1114 1031 ··· 1119 1030 { 1120 1031 struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); 1121 1032 1122 - /* For 512 and 1536 bits key size, use soft tfm instead */ 1123 - if (ctx->key_sz == HPRE_RSA_512BITS_KSZ || 1124 - ctx->key_sz == HPRE_RSA_1536BITS_KSZ) 1033 + /* For unsupported key size and unavailable devices, use soft tfm instead */ 1034 + if (ctx->fallback) 1125 1035 return crypto_akcipher_maxsize(ctx->rsa.soft_tfm); 1126 1036 1127 1037 return ctx->key_sz; ··· 1141 1053 hpre_align_pd()); 1142 1054 1143 1055 ret = hpre_ctx_init(ctx, HPRE_V2_ALG_TYPE); 1144 - if (ret) 1056 + if (ret && ret != -ENODEV) { 1145 1057 crypto_free_akcipher(ctx->rsa.soft_tfm); 1058 + return ret; 1059 + } else if (ret == -ENODEV) { 1060 + ctx->fallback = true; 1061 + } 1146 1062 1147 - return ret; 1063 + return 0; 1148 1064 } 1149 1065 1150 1066 static void hpre_rsa_exit_tfm(struct crypto_akcipher *tfm) ··· 1351 1259 char key[HPRE_ECC_MAX_KSZ]; 1352 1260 struct ecdh params; 1353 1261 int ret; 1262 + 1263 + if (ctx->fallback) 1264 + return crypto_kpp_set_secret(ctx->ecdh.soft_tfm, buf, len); 1354 1265 1355 1266 if (crypto_ecdh_decode_key(buf, len, &params) < 0) { 1356 1267 dev_err(dev, "failed to decode ecdh key!\n"); ··· 1580 1485 return ret; 1581 1486 } 1582 1487 1488 + static int hpre_ecdh_generate_public_key(struct kpp_request *req) 1489 + { 1490 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 1491 + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 1492 + int ret; 1493 + 1494 + if (ctx->fallback) { 1495 + kpp_request_set_tfm(req, ctx->ecdh.soft_tfm); 1496 + ret = crypto_kpp_generate_public_key(req); 1497 + kpp_request_set_tfm(req, tfm); 1498 + return ret; 1499 + } 1500 + 1501 + return hpre_ecdh_compute_value(req); 1502 + } 1503 + 1504 + static int hpre_ecdh_compute_shared_secret(struct kpp_request *req) 1505 + { 1506 + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); 1507 + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 1508 + int ret; 1509 + 1510 + if (ctx->fallback) { 1511 + kpp_request_set_tfm(req, ctx->ecdh.soft_tfm); 1512 + ret = crypto_kpp_compute_shared_secret(req); 1513 + kpp_request_set_tfm(req, tfm); 1514 + return ret; 1515 + } 1516 + 1517 + return hpre_ecdh_compute_value(req); 1518 + } 1519 + 1583 1520 static unsigned int hpre_ecdh_max_size(struct crypto_kpp *tfm) 1584 1521 { 1585 1522 struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 1586 1523 1524 + if (ctx->fallback) 1525 + return crypto_kpp_maxsize(ctx->ecdh.soft_tfm); 1526 + 1587 1527 /* max size is the pub_key_size, include x and y */ 1588 1528 return ctx->key_sz << 1; 1529 + } 1530 + 1531 + static int hpre_ecdh_init_tfm(struct crypto_kpp *tfm) 1532 + { 1533 + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 1534 + const char *alg = kpp_alg_name(tfm); 1535 + int ret; 1536 + 1537 + ret = hpre_ctx_init(ctx, HPRE_V3_ECC_ALG_TYPE); 1538 + if (!ret) { 1539 + kpp_set_reqsize(tfm, sizeof(struct hpre_asym_request) + hpre_align_pd()); 1540 + return 0; 1541 + } else if (ret && ret != -ENODEV) { 1542 + return ret; 1543 + } 1544 + 1545 + ctx->ecdh.soft_tfm = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK); 1546 + if (IS_ERR(ctx->ecdh.soft_tfm)) { 1547 + pr_err("Failed to alloc %s tfm!\n", alg); 1548 + return PTR_ERR(ctx->ecdh.soft_tfm); 1549 + } 1550 + 1551 + crypto_kpp_set_flags(ctx->ecdh.soft_tfm, crypto_kpp_get_flags(tfm)); 1552 + ctx->fallback = true; 1553 + 1554 + return 0; 1589 1555 } 1590 1556 1591 1557 static int hpre_ecdh_nist_p192_init_tfm(struct crypto_kpp *tfm) ··· 1655 1499 1656 1500 ctx->curve_id = ECC_CURVE_NIST_P192; 1657 1501 1658 - kpp_set_reqsize(tfm, sizeof(struct hpre_asym_request) + hpre_align_pd()); 1659 - 1660 - return hpre_ctx_init(ctx, HPRE_V3_ECC_ALG_TYPE); 1502 + return hpre_ecdh_init_tfm(tfm); 1661 1503 } 1662 1504 1663 1505 static int hpre_ecdh_nist_p256_init_tfm(struct crypto_kpp *tfm) ··· 1665 1511 ctx->curve_id = ECC_CURVE_NIST_P256; 1666 1512 ctx->enable_hpcore = 1; 1667 1513 1668 - kpp_set_reqsize(tfm, sizeof(struct hpre_asym_request) + hpre_align_pd()); 1669 - 1670 - return hpre_ctx_init(ctx, HPRE_V3_ECC_ALG_TYPE); 1514 + return hpre_ecdh_init_tfm(tfm); 1671 1515 } 1672 1516 1673 1517 static int hpre_ecdh_nist_p384_init_tfm(struct crypto_kpp *tfm) ··· 1674 1522 1675 1523 ctx->curve_id = ECC_CURVE_NIST_P384; 1676 1524 1677 - kpp_set_reqsize(tfm, sizeof(struct hpre_asym_request) + hpre_align_pd()); 1678 - 1679 - return hpre_ctx_init(ctx, HPRE_V3_ECC_ALG_TYPE); 1525 + return hpre_ecdh_init_tfm(tfm); 1680 1526 } 1681 1527 1682 1528 static void hpre_ecdh_exit_tfm(struct crypto_kpp *tfm) 1683 1529 { 1684 1530 struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); 1531 + 1532 + if (ctx->fallback) { 1533 + crypto_free_kpp(ctx->ecdh.soft_tfm); 1534 + return; 1535 + } 1685 1536 1686 1537 hpre_ecc_clear_ctx(ctx, true); 1687 1538 } ··· 1703 1548 .cra_name = "rsa", 1704 1549 .cra_driver_name = "hpre-rsa", 1705 1550 .cra_module = THIS_MODULE, 1551 + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 1706 1552 }, 1707 1553 }; 1708 1554 1709 1555 static struct kpp_alg dh = { 1710 1556 .set_secret = hpre_dh_set_secret, 1711 - .generate_public_key = hpre_dh_compute_value, 1712 - .compute_shared_secret = hpre_dh_compute_value, 1557 + .generate_public_key = hpre_dh_generate_public_key, 1558 + .compute_shared_secret = hpre_dh_compute_shared_secret, 1713 1559 .max_size = hpre_dh_max_size, 1714 1560 .init = hpre_dh_init_tfm, 1715 1561 .exit = hpre_dh_exit_tfm, ··· 1720 1564 .cra_name = "dh", 1721 1565 .cra_driver_name = "hpre-dh", 1722 1566 .cra_module = THIS_MODULE, 1567 + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 1723 1568 }, 1724 1569 }; 1725 1570 1726 1571 static struct kpp_alg ecdh_curves[] = { 1727 1572 { 1728 1573 .set_secret = hpre_ecdh_set_secret, 1729 - .generate_public_key = hpre_ecdh_compute_value, 1730 - .compute_shared_secret = hpre_ecdh_compute_value, 1574 + .generate_public_key = hpre_ecdh_generate_public_key, 1575 + .compute_shared_secret = hpre_ecdh_compute_shared_secret, 1731 1576 .max_size = hpre_ecdh_max_size, 1732 1577 .init = hpre_ecdh_nist_p192_init_tfm, 1733 1578 .exit = hpre_ecdh_exit_tfm, ··· 1738 1581 .cra_name = "ecdh-nist-p192", 1739 1582 .cra_driver_name = "hpre-ecdh-nist-p192", 1740 1583 .cra_module = THIS_MODULE, 1584 + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 1741 1585 }, 1742 1586 }, { 1743 1587 .set_secret = hpre_ecdh_set_secret, 1744 - .generate_public_key = hpre_ecdh_compute_value, 1745 - .compute_shared_secret = hpre_ecdh_compute_value, 1588 + .generate_public_key = hpre_ecdh_generate_public_key, 1589 + .compute_shared_secret = hpre_ecdh_compute_shared_secret, 1746 1590 .max_size = hpre_ecdh_max_size, 1747 1591 .init = hpre_ecdh_nist_p256_init_tfm, 1748 1592 .exit = hpre_ecdh_exit_tfm, ··· 1753 1595 .cra_name = "ecdh-nist-p256", 1754 1596 .cra_driver_name = "hpre-ecdh-nist-p256", 1755 1597 .cra_module = THIS_MODULE, 1598 + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 1756 1599 }, 1757 1600 }, { 1758 1601 .set_secret = hpre_ecdh_set_secret, 1759 - .generate_public_key = hpre_ecdh_compute_value, 1760 - .compute_shared_secret = hpre_ecdh_compute_value, 1602 + .generate_public_key = hpre_ecdh_generate_public_key, 1603 + .compute_shared_secret = hpre_ecdh_compute_shared_secret, 1761 1604 .max_size = hpre_ecdh_max_size, 1762 1605 .init = hpre_ecdh_nist_p384_init_tfm, 1763 1606 .exit = hpre_ecdh_exit_tfm, ··· 1768 1609 .cra_name = "ecdh-nist-p384", 1769 1610 .cra_driver_name = "hpre-ecdh-nist-p384", 1770 1611 .cra_module = THIS_MODULE, 1612 + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 1771 1613 }, 1772 1614 } 1773 1615 };