mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #23342 from poettering/efi-monotonic-counter-random-seed
sd-boot: include GetNextMonotonicCount() in random seed calculations
This commit is contained in:
commit
051c4e5419
4
TODO
4
TODO
@ -263,10 +263,6 @@ Features:
|
|||||||
* sd-boot: rework random seed handling following recent kernel changes: always
|
* sd-boot: rework random seed handling following recent kernel changes: always
|
||||||
pass seed to kernel, but credit only if secure boot is used
|
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,
|
* 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
|
to cover nicely for machine clones. It's found in the ACPI tables, which
|
||||||
should be easily accessible from UEFI.
|
should be easily accessible from UEFI.
|
||||||
|
@ -48,6 +48,7 @@ static void hash_once(
|
|||||||
UINTN size,
|
UINTN size,
|
||||||
const void *system_token,
|
const void *system_token,
|
||||||
UINTN system_token_size,
|
UINTN system_token_size,
|
||||||
|
UINT64 uefi_monotonic_counter,
|
||||||
UINTN counter,
|
UINTN counter,
|
||||||
UINT8 ret[static HASH_VALUE_SIZE]) {
|
UINT8 ret[static HASH_VALUE_SIZE]) {
|
||||||
|
|
||||||
@ -56,7 +57,8 @@ static void hash_once(
|
|||||||
* 1. The contents of the old seed file
|
* 1. The contents of the old seed file
|
||||||
* 2. Some random data acquired from the UEFI RNG (optional)
|
* 2. Some random data acquired from the UEFI RNG (optional)
|
||||||
* 3. Some 'system token' the installer installed as EFI variable (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.
|
* And writes the result to the specified buffer.
|
||||||
*/
|
*/
|
||||||
@ -72,6 +74,7 @@ static void hash_once(
|
|||||||
sha256_process_bytes(rng, size, &hash);
|
sha256_process_bytes(rng, size, &hash);
|
||||||
if (system_token_size > 0)
|
if (system_token_size > 0)
|
||||||
sha256_process_bytes(system_token, system_token_size, &hash);
|
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_process_bytes(&counter, sizeof(counter), &hash);
|
||||||
sha256_finish_ctx(&hash, ret);
|
sha256_finish_ctx(&hash, ret);
|
||||||
}
|
}
|
||||||
@ -82,6 +85,7 @@ static EFI_STATUS hash_many(
|
|||||||
UINTN size,
|
UINTN size,
|
||||||
const void *system_token,
|
const void *system_token,
|
||||||
UINTN system_token_size,
|
UINTN system_token_size,
|
||||||
|
UINT64 uefi_monotonic_counter,
|
||||||
UINTN counter_start,
|
UINTN counter_start,
|
||||||
UINTN n,
|
UINTN n,
|
||||||
void **ret) {
|
void **ret) {
|
||||||
@ -100,6 +104,7 @@ static EFI_STATUS hash_many(
|
|||||||
for (UINTN i = 0; i < n; i++)
|
for (UINTN i = 0; i < n; i++)
|
||||||
hash_once(old_seed, rng, size,
|
hash_once(old_seed, rng, size,
|
||||||
system_token, system_token_size,
|
system_token, system_token_size,
|
||||||
|
uefi_monotonic_counter,
|
||||||
counter_start + i,
|
counter_start + i,
|
||||||
(UINT8*) output + (i * HASH_VALUE_SIZE));
|
(UINT8*) output + (i * HASH_VALUE_SIZE));
|
||||||
|
|
||||||
@ -113,6 +118,7 @@ static EFI_STATUS mangle_random_seed(
|
|||||||
UINTN size,
|
UINTN size,
|
||||||
const void *system_token,
|
const void *system_token,
|
||||||
UINTN system_token_size,
|
UINTN system_token_size,
|
||||||
|
UINT64 uefi_monotonic_counter,
|
||||||
void **ret_new_seed,
|
void **ret_new_seed,
|
||||||
void **ret_for_kernel) {
|
void **ret_for_kernel) {
|
||||||
|
|
||||||
@ -134,12 +140,12 @@ static EFI_STATUS mangle_random_seed(
|
|||||||
n = (size + HASH_VALUE_SIZE - 1) / HASH_VALUE_SIZE;
|
n = (size + HASH_VALUE_SIZE - 1) / HASH_VALUE_SIZE;
|
||||||
|
|
||||||
/* Begin hashing in counter mode at counter 0 for the new seed for the disk */
|
/* 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))
|
if (EFI_ERROR(err))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* Continue counting at 'n' for the seed for the kernel */
|
/* 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))
|
if (EFI_ERROR(err))
|
||||||
return 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;
|
_cleanup_(file_closep) EFI_FILE *handle = NULL;
|
||||||
UINTN size, rsize, wsize, system_token_size = 0;
|
UINTN size, rsize, wsize, system_token_size = 0;
|
||||||
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
|
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
|
||||||
|
UINT64 uefi_monotonic_counter = 0;
|
||||||
EFI_STATUS err;
|
EFI_STATUS err;
|
||||||
|
|
||||||
assert(root_dir);
|
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. */
|
* golden master images that are replicated many times. */
|
||||||
(void) acquire_rng(size, &rng); /* It's fine if this fails */
|
(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 */
|
/* 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))
|
if (EFI_ERROR(err))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user