diff options
| -rw-r--r-- | drivers/char/Kconfig | 14 | ||||
| -rw-r--r-- | drivers/char/random.c | 11 |
2 files changed, 24 insertions, 1 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 212f447938ae..ce277ee0a28a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -554,3 +554,17 @@ config ADI | |||
| 554 | 554 | ||
| 555 | endmenu | 555 | endmenu |
| 556 | 556 | ||
| 557 | config RANDOM_TRUST_CPU | ||
| 558 | bool "Trust the CPU manufacturer to initialize Linux's CRNG" | ||
| 559 | depends on X86 || S390 || PPC | ||
| 560 | default n | ||
| 561 | help | ||
| 562 | Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or | ||
| 563 | RDRAND, IBM for the S390 and Power PC architectures) is trustworthy | ||
| 564 | for the purposes of initializing Linux's CRNG. Since this is not | ||
| 565 | something that can be independently audited, this amounts to trusting | ||
| 566 | that CPU manufacturer (perhaps with the insistence or mandate | ||
| 567 | of a Nation State's intelligence or law enforcement agencies) | ||
| 568 | has not installed a hidden back door to compromise the CPU's | ||
| 569 | random number generation facilities. | ||
| 570 | |||
diff --git a/drivers/char/random.c b/drivers/char/random.c index 34ddfd57419b..f4013b8a711b 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
| @@ -782,6 +782,7 @@ static void invalidate_batched_entropy(void); | |||
| 782 | static void crng_initialize(struct crng_state *crng) | 782 | static void crng_initialize(struct crng_state *crng) |
| 783 | { | 783 | { |
| 784 | int i; | 784 | int i; |
| 785 | int arch_init = 1; | ||
| 785 | unsigned long rv; | 786 | unsigned long rv; |
| 786 | 787 | ||
| 787 | memcpy(&crng->state[0], "expand 32-byte k", 16); | 788 | memcpy(&crng->state[0], "expand 32-byte k", 16); |
| @@ -792,10 +793,18 @@ static void crng_initialize(struct crng_state *crng) | |||
| 792 | _get_random_bytes(&crng->state[4], sizeof(__u32) * 12); | 793 | _get_random_bytes(&crng->state[4], sizeof(__u32) * 12); |
| 793 | for (i = 4; i < 16; i++) { | 794 | for (i = 4; i < 16; i++) { |
| 794 | if (!arch_get_random_seed_long(&rv) && | 795 | if (!arch_get_random_seed_long(&rv) && |
| 795 | !arch_get_random_long(&rv)) | 796 | !arch_get_random_long(&rv)) { |
| 796 | rv = random_get_entropy(); | 797 | rv = random_get_entropy(); |
| 798 | arch_init = 0; | ||
| 799 | } | ||
| 797 | crng->state[i] ^= rv; | 800 | crng->state[i] ^= rv; |
| 798 | } | 801 | } |
| 802 | #ifdef CONFIG_RANDOM_TRUST_CPU | ||
| 803 | if (arch_init) { | ||
| 804 | crng_init = 2; | ||
| 805 | pr_notice("random: crng done (trusting CPU's manufacturer)\n"); | ||
| 806 | } | ||
| 807 | #endif | ||
| 799 | crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; | 808 | crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; |
| 800 | } | 809 | } |
| 801 | 810 | ||
