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

crypto: nx - Check for bogus firmware properties

The nx driver reads two crucial paramters from the firmware for
each crypto algorithm, the maximum SG list length and byte limit.
Unfortunately those two parameters may be bogus, or worse they
may be absent altogether. When this happens the algorithms will
still register successfully but will fail when used or tested.

This patch adds checks to report any firmware entries which are
found to be bogus, and avoid registering algorithms which have
bogus parameters. A warning is also printed when an algorithm
is not registered because of this as there may have been no firmware
entries for it at all.

Reported-by: Ondrej Moriš <omoris@redhat.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+118 -32
+118 -32
drivers/crypto/nx/nx.c
··· 32 32 #include <linux/scatterlist.h> 33 33 #include <linux/device.h> 34 34 #include <linux/of.h> 35 + #include <linux/types.h> 35 36 #include <asm/hvcall.h> 36 37 #include <asm/vio.h> 37 38 ··· 399 398 goto next_loop; 400 399 } 401 400 401 + if (!trip->sglen || trip->databytelen < NX_PAGE_SIZE) { 402 + dev_warn(dev, "bogus sglen/databytelen: " 403 + "%u/%u (ignored)\n", trip->sglen, 404 + trip->databytelen); 405 + goto next_loop; 406 + } 407 + 402 408 switch (trip->keybitlen) { 403 409 case 128: 404 410 case 160: ··· 498 490 nx_of_update_msc(dev, p, props); 499 491 } 500 492 493 + static bool nx_check_prop(struct device *dev, u32 fc, u32 mode, int slot) 494 + { 495 + struct alg_props *props = &nx_driver.of.ap[fc][mode][slot]; 496 + 497 + if (!props->sglen || props->databytelen < NX_PAGE_SIZE) { 498 + if (dev) 499 + dev_warn(dev, "bogus sglen/databytelen for %u/%u/%u: " 500 + "%u/%u (ignored)\n", fc, mode, slot, 501 + props->sglen, props->databytelen); 502 + return false; 503 + } 504 + 505 + return true; 506 + } 507 + 508 + static bool nx_check_props(struct device *dev, u32 fc, u32 mode) 509 + { 510 + int i; 511 + 512 + for (i = 0; i < 3; i++) 513 + if (!nx_check_prop(dev, fc, mode, i)) 514 + return false; 515 + 516 + return true; 517 + } 518 + 519 + static int nx_register_alg(struct crypto_alg *alg, u32 fc, u32 mode) 520 + { 521 + return nx_check_props(&nx_driver.viodev->dev, fc, mode) ? 522 + crypto_register_alg(alg) : 0; 523 + } 524 + 525 + static int nx_register_aead(struct aead_alg *alg, u32 fc, u32 mode) 526 + { 527 + return nx_check_props(&nx_driver.viodev->dev, fc, mode) ? 528 + crypto_register_aead(alg) : 0; 529 + } 530 + 531 + static int nx_register_shash(struct shash_alg *alg, u32 fc, u32 mode, int slot) 532 + { 533 + return (slot >= 0 ? nx_check_prop(&nx_driver.viodev->dev, 534 + fc, mode, slot) : 535 + nx_check_props(&nx_driver.viodev->dev, fc, mode)) ? 536 + crypto_register_shash(alg) : 0; 537 + } 538 + 539 + static void nx_unregister_alg(struct crypto_alg *alg, u32 fc, u32 mode) 540 + { 541 + if (nx_check_props(NULL, fc, mode)) 542 + crypto_unregister_alg(alg); 543 + } 544 + 545 + static void nx_unregister_aead(struct aead_alg *alg, u32 fc, u32 mode) 546 + { 547 + if (nx_check_props(NULL, fc, mode)) 548 + crypto_unregister_aead(alg); 549 + } 550 + 551 + static void nx_unregister_shash(struct shash_alg *alg, u32 fc, u32 mode, 552 + int slot) 553 + { 554 + if (slot >= 0 ? nx_check_prop(NULL, fc, mode, slot) : 555 + nx_check_props(NULL, fc, mode)) 556 + crypto_unregister_shash(alg); 557 + } 558 + 501 559 /** 502 560 * nx_register_algs - register algorithms with the crypto API 503 561 * ··· 588 514 589 515 nx_driver.of.status = NX_OKAY; 590 516 591 - rc = crypto_register_alg(&nx_ecb_aes_alg); 517 + rc = nx_register_alg(&nx_ecb_aes_alg, NX_FC_AES, NX_MODE_AES_ECB); 592 518 if (rc) 593 519 goto out; 594 520 595 - rc = crypto_register_alg(&nx_cbc_aes_alg); 521 + rc = nx_register_alg(&nx_cbc_aes_alg, NX_FC_AES, NX_MODE_AES_CBC); 596 522 if (rc) 597 523 goto out_unreg_ecb; 598 524 599 - rc = crypto_register_alg(&nx_ctr_aes_alg); 525 + rc = nx_register_alg(&nx_ctr_aes_alg, NX_FC_AES, NX_MODE_AES_CTR); 600 526 if (rc) 601 527 goto out_unreg_cbc; 602 528 603 - rc = crypto_register_alg(&nx_ctr3686_aes_alg); 529 + rc = nx_register_alg(&nx_ctr3686_aes_alg, NX_FC_AES, NX_MODE_AES_CTR); 604 530 if (rc) 605 531 goto out_unreg_ctr; 606 532 607 - rc = crypto_register_aead(&nx_gcm_aes_alg); 533 + rc = nx_register_aead(&nx_gcm_aes_alg, NX_FC_AES, NX_MODE_AES_GCM); 608 534 if (rc) 609 535 goto out_unreg_ctr3686; 610 536 611 - rc = crypto_register_aead(&nx_gcm4106_aes_alg); 537 + rc = nx_register_aead(&nx_gcm4106_aes_alg, NX_FC_AES, NX_MODE_AES_GCM); 612 538 if (rc) 613 539 goto out_unreg_gcm; 614 540 615 - rc = crypto_register_alg(&nx_ccm_aes_alg); 541 + rc = nx_register_alg(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); 616 542 if (rc) 617 543 goto out_unreg_gcm4106; 618 544 619 - rc = crypto_register_alg(&nx_ccm4309_aes_alg); 545 + rc = nx_register_alg(&nx_ccm4309_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); 620 546 if (rc) 621 547 goto out_unreg_ccm; 622 548 623 - rc = crypto_register_shash(&nx_shash_sha256_alg); 549 + rc = nx_register_shash(&nx_shash_sha256_alg, NX_FC_SHA, NX_MODE_SHA, 550 + NX_PROPS_SHA256); 624 551 if (rc) 625 552 goto out_unreg_ccm4309; 626 553 627 - rc = crypto_register_shash(&nx_shash_sha512_alg); 554 + rc = nx_register_shash(&nx_shash_sha512_alg, NX_FC_SHA, NX_MODE_SHA, 555 + NX_PROPS_SHA512); 628 556 if (rc) 629 557 goto out_unreg_s256; 630 558 631 - rc = crypto_register_shash(&nx_shash_aes_xcbc_alg); 559 + rc = nx_register_shash(&nx_shash_aes_xcbc_alg, 560 + NX_FC_AES, NX_MODE_AES_XCBC_MAC, -1); 632 561 if (rc) 633 562 goto out_unreg_s512; 634 563 635 564 goto out; 636 565 637 566 out_unreg_s512: 638 - crypto_unregister_shash(&nx_shash_sha512_alg); 567 + nx_unregister_shash(&nx_shash_sha512_alg, NX_FC_SHA, NX_MODE_SHA, 568 + NX_PROPS_SHA512); 639 569 out_unreg_s256: 640 - crypto_unregister_shash(&nx_shash_sha256_alg); 570 + nx_unregister_shash(&nx_shash_sha256_alg, NX_FC_SHA, NX_MODE_SHA, 571 + NX_PROPS_SHA256); 641 572 out_unreg_ccm4309: 642 - crypto_unregister_alg(&nx_ccm4309_aes_alg); 573 + nx_unregister_alg(&nx_ccm4309_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); 643 574 out_unreg_ccm: 644 - crypto_unregister_alg(&nx_ccm_aes_alg); 575 + nx_unregister_alg(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); 645 576 out_unreg_gcm4106: 646 - crypto_unregister_aead(&nx_gcm4106_aes_alg); 577 + nx_unregister_aead(&nx_gcm4106_aes_alg, NX_FC_AES, NX_MODE_AES_GCM); 647 578 out_unreg_gcm: 648 - crypto_unregister_aead(&nx_gcm_aes_alg); 579 + nx_unregister_aead(&nx_gcm_aes_alg, NX_FC_AES, NX_MODE_AES_GCM); 649 580 out_unreg_ctr3686: 650 - crypto_unregister_alg(&nx_ctr3686_aes_alg); 581 + nx_unregister_alg(&nx_ctr3686_aes_alg, NX_FC_AES, NX_MODE_AES_CTR); 651 582 out_unreg_ctr: 652 - crypto_unregister_alg(&nx_ctr_aes_alg); 583 + nx_unregister_alg(&nx_ctr_aes_alg, NX_FC_AES, NX_MODE_AES_CTR); 653 584 out_unreg_cbc: 654 - crypto_unregister_alg(&nx_cbc_aes_alg); 585 + nx_unregister_alg(&nx_cbc_aes_alg, NX_FC_AES, NX_MODE_AES_CBC); 655 586 out_unreg_ecb: 656 - crypto_unregister_alg(&nx_ecb_aes_alg); 587 + nx_unregister_alg(&nx_ecb_aes_alg, NX_FC_AES, NX_MODE_AES_ECB); 657 588 out: 658 589 return rc; 659 590 } ··· 804 725 if (nx_driver.of.status == NX_OKAY) { 805 726 NX_DEBUGFS_FINI(&nx_driver); 806 727 807 - crypto_unregister_alg(&nx_ccm_aes_alg); 808 - crypto_unregister_alg(&nx_ccm4309_aes_alg); 809 - crypto_unregister_aead(&nx_gcm_aes_alg); 810 - crypto_unregister_aead(&nx_gcm4106_aes_alg); 811 - crypto_unregister_alg(&nx_ctr_aes_alg); 812 - crypto_unregister_alg(&nx_ctr3686_aes_alg); 813 - crypto_unregister_alg(&nx_cbc_aes_alg); 814 - crypto_unregister_alg(&nx_ecb_aes_alg); 815 - crypto_unregister_shash(&nx_shash_sha256_alg); 816 - crypto_unregister_shash(&nx_shash_sha512_alg); 817 - crypto_unregister_shash(&nx_shash_aes_xcbc_alg); 728 + nx_unregister_shash(&nx_shash_aes_xcbc_alg, 729 + NX_FC_AES, NX_MODE_AES_XCBC_MAC, -1); 730 + nx_unregister_shash(&nx_shash_sha512_alg, 731 + NX_FC_SHA, NX_MODE_SHA, NX_PROPS_SHA256); 732 + nx_unregister_shash(&nx_shash_sha256_alg, 733 + NX_FC_SHA, NX_MODE_SHA, NX_PROPS_SHA512); 734 + nx_unregister_alg(&nx_ccm4309_aes_alg, 735 + NX_FC_AES, NX_MODE_AES_CCM); 736 + nx_unregister_alg(&nx_ccm_aes_alg, NX_FC_AES, NX_MODE_AES_CCM); 737 + nx_unregister_aead(&nx_gcm4106_aes_alg, 738 + NX_FC_AES, NX_MODE_AES_GCM); 739 + nx_unregister_aead(&nx_gcm_aes_alg, 740 + NX_FC_AES, NX_MODE_AES_GCM); 741 + nx_unregister_alg(&nx_ctr3686_aes_alg, 742 + NX_FC_AES, NX_MODE_AES_CTR); 743 + nx_unregister_alg(&nx_ctr_aes_alg, NX_FC_AES, NX_MODE_AES_CTR); 744 + nx_unregister_alg(&nx_cbc_aes_alg, NX_FC_AES, NX_MODE_AES_CBC); 745 + nx_unregister_alg(&nx_ecb_aes_alg, NX_FC_AES, NX_MODE_AES_ECB); 818 746 } 819 747 820 748 return 0;