Merge pull request #23342 from poettering/efi-monotonic-counter-random-seed

sd-boot: include GetNextMonotonicCount() in random seed calculations
This commit is contained in:
Luca Boccassi 2022-05-21 15:08:21 +01:00 committed by GitHub
commit 051c4e5419
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 8 deletions

4
TODO
View file

@ -263,10 +263,6 @@ Features:
* sd-boot: rework random seed handling following recent kernel changes: always
pass seed to kernel, but credit only if secure boot is used
* sd-boot: hash data from GetNextHighMonotonicCount() into updated random seed,
so that we might even open up up the random seed logic to non-SecureBoot
systems?
* sd-boot: also include the hyperv "vm generation id" in the random seed hash,
to cover nicely for machine clones. It's found in the ACPI tables, which
should be easily accessible from UEFI.

View file

@ -48,6 +48,7 @@ static void hash_once(
UINTN size,
const void *system_token,
UINTN system_token_size,
UINT64 uefi_monotonic_counter,
UINTN counter,
UINT8 ret[static HASH_VALUE_SIZE]) {
@ -56,7 +57,8 @@ static void hash_once(
* 1. The contents of the old seed file
* 2. Some random data acquired from the UEFI RNG (optional)
* 3. Some 'system token' the installer installed as EFI variable (optional)
* 4. A counter value
* 4. The UEFI "monotonic counter" that increases with each boot
* 5. A supplied counter value
*
* And writes the result to the specified buffer.
*/
@ -72,6 +74,7 @@ static void hash_once(
sha256_process_bytes(rng, size, &hash);
if (system_token_size > 0)
sha256_process_bytes(system_token, system_token_size, &hash);
sha256_process_bytes(&uefi_monotonic_counter, sizeof(uefi_monotonic_counter), &hash);
sha256_process_bytes(&counter, sizeof(counter), &hash);
sha256_finish_ctx(&hash, ret);
}
@ -82,6 +85,7 @@ static EFI_STATUS hash_many(
UINTN size,
const void *system_token,
UINTN system_token_size,
UINT64 uefi_monotonic_counter,
UINTN counter_start,
UINTN n,
void **ret) {
@ -100,6 +104,7 @@ static EFI_STATUS hash_many(
for (UINTN i = 0; i < n; i++)
hash_once(old_seed, rng, size,
system_token, system_token_size,
uefi_monotonic_counter,
counter_start + i,
(UINT8*) output + (i * HASH_VALUE_SIZE));
@ -113,6 +118,7 @@ static EFI_STATUS mangle_random_seed(
UINTN size,
const void *system_token,
UINTN system_token_size,
UINT64 uefi_monotonic_counter,
void **ret_new_seed,
void **ret_for_kernel) {
@ -134,12 +140,12 @@ static EFI_STATUS mangle_random_seed(
n = (size + HASH_VALUE_SIZE - 1) / HASH_VALUE_SIZE;
/* Begin hashing in counter mode at counter 0 for the new seed for the disk */
err = hash_many(old_seed, rng, size, system_token, system_token_size, 0, n, &new_seed);
err = hash_many(old_seed, rng, size, system_token, system_token_size, uefi_monotonic_counter, 0, n, &new_seed);
if (EFI_ERROR(err))
return err;
/* Continue counting at 'n' for the seed for the kernel */
err = hash_many(old_seed, rng, size, system_token, system_token_size, n, n, &for_kernel);
err = hash_many(old_seed, rng, size, system_token, system_token_size, uefi_monotonic_counter, n, n, &for_kernel);
if (EFI_ERROR(err))
return err;
@ -228,6 +234,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
_cleanup_(file_closep) EFI_FILE *handle = NULL;
UINTN size, rsize, wsize, system_token_size = 0;
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
UINT64 uefi_monotonic_counter = 0;
EFI_STATUS err;
assert(root_dir);
@ -285,8 +292,15 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
* golden master images that are replicated many times. */
(void) acquire_rng(size, &rng); /* It's fine if this fails */
/* Let's also include the UEFI monotonic counter (which is supposedly increasing on every single
* boot) in the hash, so that even if the changes to the ESP for some reason should not be
* persistent, the random seed we generate will still be different on every single boot. */
err = BS->GetNextMonotonicCount(&uefi_monotonic_counter);
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Failed to acquire UEFI monotonic counter: %r", err);
/* Calculate new random seed for the disk and what to pass to the kernel */
err = mangle_random_seed(seed, rng, size, system_token, system_token_size, &new_seed, &for_kernel);
err = mangle_random_seed(seed, rng, size, system_token, system_token_size, uefi_monotonic_counter, &new_seed, &for_kernel);
if (EFI_ERROR(err))
return err;