UINTN size,
const void *system_token,
UINTN system_token_size,
+ UINT64 uefi_monotonic_counter,
UINTN counter,
UINT8 ret[static HASH_VALUE_SIZE]) {
* 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.
*/
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);
}
UINTN size,
const void *system_token,
UINTN system_token_size,
+ UINT64 uefi_monotonic_counter,
UINTN counter_start,
UINTN n,
void **ret) {
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));
UINTN size,
const void *system_token,
UINTN system_token_size,
+ UINT64 uefi_monotonic_counter,
void **ret_new_seed,
void **ret_for_kernel) {
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;
_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);
* 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;