You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
systemd/SOURCES/0712-sha256-add-helper-than...

102 lines
4.8 KiB

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)