From 7b9e71d4f8d01557da700f2da11870f6246abdf2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering 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)