102 lines
4.8 KiB
Diff
102 lines
4.8 KiB
Diff
From 7b9e71d4f8d01557da700f2da11870f6246abdf2 Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Tue, 20 Dec 2022 11:53:37 +0100
|
|
Subject: [PATCH] sha256: add helper than hashes a buffer *and* its size
|
|
|
|
We use this pattern all the time in order to thward extension attacks,
|
|
add a helper to make it shorter.
|
|
|
|
(cherry picked from commit a16c65f3c4c93e24eda9cf7f14d5da4062c6ca10)
|
|
|
|
Related: RHEL-16952
|
|
---
|
|
src/boot/bootctl.c | 6 ++----
|
|
src/fundamental/sha256.h | 5 +++++
|
|
src/random-seed/random-seed.c | 12 ++++--------
|
|
3 files changed, 11 insertions(+), 12 deletions(-)
|
|
|
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
|
index fe8d7e83a1..3e9a89a759 100644
|
|
--- a/src/boot/bootctl.c
|
|
+++ b/src/boot/bootctl.c
|
|
@@ -2010,8 +2010,7 @@ static int install_random_seed(const char *esp) {
|
|
return log_error_errno(r, "Failed to acquire random seed: %m");
|
|
|
|
sha256_init_ctx(&hash_state);
|
|
- sha256_process_bytes(&(const size_t) { sizeof(buffer) }, sizeof(size_t), &hash_state);
|
|
- sha256_process_bytes(buffer, sizeof(buffer), &hash_state);
|
|
+ sha256_process_bytes_and_size(buffer, sizeof(buffer), &hash_state);
|
|
|
|
fd = openat(loader_dir_fd, "random-seed", O_NOFOLLOW|O_CLOEXEC|O_RDONLY|O_NOCTTY);
|
|
if (fd < 0) {
|
|
@@ -2029,8 +2028,7 @@ static int install_random_seed(const char *esp) {
|
|
if (n < 0)
|
|
return log_error_errno(errno, "Failed to read old random seed file: %m");
|
|
|
|
- sha256_process_bytes(&n, sizeof(n), &hash_state);
|
|
- sha256_process_bytes(buffer, n, &hash_state);
|
|
+ sha256_process_bytes_and_size(buffer, n, &hash_state);
|
|
|
|
fd = safe_close(fd);
|
|
refreshed = n > 0;
|
|
diff --git a/src/fundamental/sha256.h b/src/fundamental/sha256.h
|
|
index 31790c2ebd..2857900c80 100644
|
|
--- a/src/fundamental/sha256.h
|
|
+++ b/src/fundamental/sha256.h
|
|
@@ -28,6 +28,11 @@ void sha256_init_ctx(struct sha256_ctx *ctx);
|
|
uint8_t *sha256_finish_ctx(struct sha256_ctx *ctx, uint8_t resbuf[static SHA256_DIGEST_SIZE]);
|
|
void sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx);
|
|
|
|
+static inline void sha256_process_bytes_and_size(const void *buffer, size_t len, struct sha256_ctx *ctx) {
|
|
+ sha256_process_bytes(&len, sizeof(len), ctx);
|
|
+ sha256_process_bytes(buffer, len, ctx);
|
|
+}
|
|
+
|
|
uint8_t* sha256_direct(const void *buffer, size_t sz, uint8_t result[static SHA256_DIGEST_SIZE]);
|
|
|
|
#define SHA256_DIRECT(buffer, sz) sha256_direct(buffer, sz, (uint8_t[SHA256_DIGEST_SIZE]) {})
|
|
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
|
|
index ab1f942289..3bb78200c9 100644
|
|
--- a/src/random-seed/random-seed.c
|
|
+++ b/src/random-seed/random-seed.c
|
|
@@ -195,8 +195,7 @@ static int load_seed_file(
|
|
return log_oom();
|
|
|
|
sha256_init_ctx(hash_state);
|
|
- sha256_process_bytes(&k, sizeof(k), hash_state); /* Hash length to distinguish from new seed. */
|
|
- sha256_process_bytes(buf, k, hash_state);
|
|
+ sha256_process_bytes_and_size(buf, k, hash_state); /* Hash with length to distinguish from new seed. */
|
|
|
|
*ret_hash_state = hash_state;
|
|
}
|
|
@@ -289,8 +288,7 @@ static int save_seed_file(
|
|
if (hash_state) {
|
|
uint8_t hash[SHA256_DIGEST_SIZE];
|
|
|
|
- sha256_process_bytes(&k, sizeof(k), hash_state); /* Hash length to distinguish from old seed. */
|
|
- sha256_process_bytes(buf, k, hash_state);
|
|
+ sha256_process_bytes_and_size(buf, k, hash_state); /* Hash with length to distinguish from old seed. */
|
|
sha256_finish_ctx(hash_state, hash);
|
|
l = MIN((size_t)k, sizeof(hash));
|
|
memcpy((uint8_t *)buf + k - l, hash, l);
|
|
@@ -371,8 +369,7 @@ static int refresh_boot_seed(void) {
|
|
|
|
/* Hash the old seed in so that we never regress in entropy. */
|
|
sha256_init_ctx(&hash_state);
|
|
- sha256_process_bytes(&n, sizeof(n), &hash_state);
|
|
- sha256_process_bytes(seed_file_bytes, n, &hash_state);
|
|
+ sha256_process_bytes_and_size(seed_file_bytes, n, &hash_state);
|
|
|
|
/* We're doing this opportunistically, so if the seeding dance before didn't manage to initialize the
|
|
* RNG, there's no point in doing it here. Secondly, getrandom(GRND_NONBLOCK) has been around longer
|
|
@@ -393,8 +390,7 @@ static int refresh_boot_seed(void) {
|
|
assert(n == sizeof(buffer));
|
|
|
|
/* Hash the new seed into the state containing the old one to generate our final seed. */
|
|
- sha256_process_bytes(&n, sizeof(n), &hash_state);
|
|
- sha256_process_bytes(buffer, n, &hash_state);
|
|
+ sha256_process_bytes_and_size(buffer, n, &hash_state);
|
|
sha256_finish_ctx(&hash_state, buffer);
|
|
|
|
if (lseek(seed_fd, 0, SEEK_SET) < 0)
|