]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/6.6.26/x86-coco-require-seeding-rng-with-rdrand-on-coco-systems.patch
Linux 6.1.85
[thirdparty/kernel/stable-queue.git] / releases / 6.6.26 / x86-coco-require-seeding-rng-with-rdrand-on-coco-systems.patch
1 From 99485c4c026f024e7cb82da84c7951dbe3deb584 Mon Sep 17 00:00:00 2001
2 From: "Jason A. Donenfeld" <Jason@zx2c4.com>
3 Date: Tue, 26 Mar 2024 17:07:35 +0100
4 Subject: x86/coco: Require seeding RNG with RDRAND on CoCo systems
5
6 From: Jason A. Donenfeld <Jason@zx2c4.com>
7
8 commit 99485c4c026f024e7cb82da84c7951dbe3deb584 upstream.
9
10 There are few uses of CoCo that don't rely on working cryptography and
11 hence a working RNG. Unfortunately, the CoCo threat model means that the
12 VM host cannot be trusted and may actively work against guests to
13 extract secrets or manipulate computation. Since a malicious host can
14 modify or observe nearly all inputs to guests, the only remaining source
15 of entropy for CoCo guests is RDRAND.
16
17 If RDRAND is broken -- due to CPU hardware fault -- the RNG as a whole
18 is meant to gracefully continue on gathering entropy from other sources,
19 but since there aren't other sources on CoCo, this is catastrophic.
20 This is mostly a concern at boot time when initially seeding the RNG, as
21 after that the consequences of a broken RDRAND are much more
22 theoretical.
23
24 So, try at boot to seed the RNG using 256 bits of RDRAND output. If this
25 fails, panic(). This will also trigger if the system is booted without
26 RDRAND, as RDRAND is essential for a safe CoCo boot.
27
28 Add this deliberately to be "just a CoCo x86 driver feature" and not
29 part of the RNG itself. Many device drivers and platforms have some
30 desire to contribute something to the RNG, and add_device_randomness()
31 is specifically meant for this purpose.
32
33 Any driver can call it with seed data of any quality, or even garbage
34 quality, and it can only possibly make the quality of the RNG better or
35 have no effect, but can never make it worse.
36
37 Rather than trying to build something into the core of the RNG, consider
38 the particular CoCo issue just a CoCo issue, and therefore separate it
39 all out into driver (well, arch/platform) code.
40
41 [ bp: Massage commit message. ]
42
43 Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
44 Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
45 Reviewed-by: Elena Reshetova <elena.reshetova@intel.com>
46 Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
47 Reviewed-by: Theodore Ts'o <tytso@mit.edu>
48 Cc: stable@vger.kernel.org
49 Link: https://lore.kernel.org/r/20240326160735.73531-1-Jason@zx2c4.com
50 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
51 ---
52 arch/x86/coco/core.c | 41 +++++++++++++++++++++++++++++++++++++++++
53 arch/x86/include/asm/coco.h | 2 ++
54 arch/x86/kernel/setup.c | 2 ++
55 3 files changed, 45 insertions(+)
56
57 --- a/arch/x86/coco/core.c
58 +++ b/arch/x86/coco/core.c
59 @@ -3,13 +3,17 @@
60 * Confidential Computing Platform Capability checks
61 *
62 * Copyright (C) 2021 Advanced Micro Devices, Inc.
63 + * Copyright (C) 2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
64 *
65 * Author: Tom Lendacky <thomas.lendacky@amd.com>
66 */
67
68 #include <linux/export.h>
69 #include <linux/cc_platform.h>
70 +#include <linux/string.h>
71 +#include <linux/random.h>
72
73 +#include <asm/archrandom.h>
74 #include <asm/coco.h>
75 #include <asm/processor.h>
76
77 @@ -148,3 +152,40 @@ u64 cc_mkdec(u64 val)
78 }
79 }
80 EXPORT_SYMBOL_GPL(cc_mkdec);
81 +
82 +__init void cc_random_init(void)
83 +{
84 + /*
85 + * The seed is 32 bytes (in units of longs), which is 256 bits, which
86 + * is the security level that the RNG is targeting.
87 + */
88 + unsigned long rng_seed[32 / sizeof(long)];
89 + size_t i, longs;
90 +
91 + if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
92 + return;
93 +
94 + /*
95 + * Since the CoCo threat model includes the host, the only reliable
96 + * source of entropy that can be neither observed nor manipulated is
97 + * RDRAND. Usually, RDRAND failure is considered tolerable, but since
98 + * CoCo guests have no other unobservable source of entropy, it's
99 + * important to at least ensure the RNG gets some initial random seeds.
100 + */
101 + for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) {
102 + longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i);
103 +
104 + /*
105 + * A zero return value means that the guest doesn't have RDRAND
106 + * or the CPU is physically broken, and in both cases that
107 + * means most crypto inside of the CoCo instance will be
108 + * broken, defeating the purpose of CoCo in the first place. So
109 + * just panic here because it's absolutely unsafe to continue
110 + * executing.
111 + */
112 + if (longs == 0)
113 + panic("RDRAND is defective.");
114 + }
115 + add_device_randomness(rng_seed, sizeof(rng_seed));
116 + memzero_explicit(rng_seed, sizeof(rng_seed));
117 +}
118 --- a/arch/x86/include/asm/coco.h
119 +++ b/arch/x86/include/asm/coco.h
120 @@ -22,6 +22,7 @@ static inline void cc_set_mask(u64 mask)
121
122 u64 cc_mkenc(u64 val);
123 u64 cc_mkdec(u64 val);
124 +void cc_random_init(void);
125 #else
126 static inline u64 cc_mkenc(u64 val)
127 {
128 @@ -32,6 +33,7 @@ static inline u64 cc_mkdec(u64 val)
129 {
130 return val;
131 }
132 +static inline void cc_random_init(void) { }
133 #endif
134
135 #endif /* _ASM_X86_COCO_H */
136 --- a/arch/x86/kernel/setup.c
137 +++ b/arch/x86/kernel/setup.c
138 @@ -35,6 +35,7 @@
139 #include <asm/bios_ebda.h>
140 #include <asm/bugs.h>
141 #include <asm/cacheinfo.h>
142 +#include <asm/coco.h>
143 #include <asm/cpu.h>
144 #include <asm/efi.h>
145 #include <asm/gart.h>
146 @@ -1120,6 +1121,7 @@ void __init setup_arch(char **cmdline_p)
147 * memory size.
148 */
149 sev_setup_arch();
150 + cc_random_init();
151
152 efi_fake_memmap();
153 efi_find_mirror();