]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sha256: add helper than hashes a buffer *and* its size
authorLennart Poettering <lennart@poettering.net>
Tue, 20 Dec 2022 10:53:37 +0000 (11:53 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 4 Jan 2023 14:18:10 +0000 (15:18 +0100)
We use this pattern all the time in order to thward extension attacks,
add a helper to make it shorter.

src/boot/bootctl-random-seed.c
src/fundamental/sha256.h
src/random-seed/random-seed.c

index ab02aa087bf2832891a5709f79b42d6a3d86e93d..1f33b5b71be7b89ca4625d4271b9d9b391d00beb 100644 (file)
@@ -43,8 +43,7 @@ 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) {
@@ -62,8 +61,7 @@ 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;
index 7c29c785cb46b0b0c3ca6f21d97c92065f869c93..4805cc553a75458d76aabf2a49b14e566761f681 100644 (file)
@@ -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]) {})
index 90890e33f291e41655b334a0b2bf6139b1f0cf09..a50fdc12ae68dbef5bfc77da7d95f0fe3f622578 100644 (file)
@@ -194,8 +194,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;
         }
@@ -288,8 +287,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);
@@ -370,8 +368,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
@@ -392,8 +389,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)