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