]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic: Add some sha256 helper functions 31297/head
authorAdrian Vovk <adrianvovk@gmail.com>
Sat, 13 Jan 2024 16:08:12 +0000 (11:08 -0500)
committerAdrian Vovk <adrianvovk@gmail.com>
Tue, 13 Feb 2024 18:59:27 +0000 (13:59 -0500)
Adds a util function to sha256 an open fd (moved from dissect). Also
adds functions to check if a string contains a valid sha256 hash, and
parse it into a sha256 array.

src/basic/meson.build
src/basic/sha256.c [new file with mode: 0644]
src/basic/sha256.h [new file with mode: 0644]
src/boot/efi/random-seed.c
src/dissect/dissect.c
src/fundamental/meson.build
src/fundamental/sha256-fundamental.c [moved from src/fundamental/sha256.c with 99% similarity]
src/fundamental/sha256-fundamental.h [moved from src/fundamental/sha256.h with 100% similarity]

index 949ca4d81f971a41019890a8b48140a766cc5c0c..6b30908ce187d7e161434560010640f277c76c29 100644 (file)
@@ -79,6 +79,7 @@ basic_sources = files(
         'replace-var.c',
         'rlimit-util.c',
         'runtime-scope.c',
+        'sha256.c',
         'sigbus.c',
         'signal-util.c',
         'siphash24.c',
diff --git a/src/basic/sha256.c b/src/basic/sha256.c
new file mode 100644 (file)
index 0000000..f011695
--- /dev/null
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <unistd.h>
+
+#include "hexdecoct.h"
+#include "macro.h"
+#include "sha256.h"
+
+int sha256_fd(int fd, uint64_t max_size, uint8_t ret[static SHA256_DIGEST_SIZE]) {
+        struct sha256_ctx ctx;
+        uint64_t total_size = 0;
+
+        sha256_init_ctx(&ctx);
+
+        for (;;) {
+                uint8_t buffer[64 * 1024];
+                ssize_t n;
+
+                n = read(fd, buffer, sizeof(buffer));
+                if (n < 0)
+                        return -errno;
+                if (n == 0)
+                        break;
+
+                if (!INC_SAFE(&total_size, n) || total_size > max_size)
+                        return -EFBIG;
+
+                sha256_process_bytes(buffer, n, &ctx);
+        }
+
+        sha256_finish_ctx(&ctx, ret);
+        return 0;
+}
+
+int parse_sha256(const char *s, uint8_t ret[static SHA256_DIGEST_SIZE]) {
+        _cleanup_free_ uint8_t *data = NULL;
+        size_t size = 0;
+        int r;
+
+        if (!sha256_is_valid(s))
+                return -EINVAL;
+
+        r = unhexmem_full(s, SHA256_DIGEST_SIZE * 2, false, (void**) &data, &size);
+        if (r < 0)
+                return r;
+        assert(size == SHA256_DIGEST_SIZE);
+
+        memcpy(ret, data, size);
+        return 0;
+}
diff --git a/src/basic/sha256.h b/src/basic/sha256.h
new file mode 100644 (file)
index 0000000..95bac1b
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#pragma once
+
+#include <stdint.h>
+
+#include "sha256-fundamental.h"
+#include "string-util.h"
+
+int sha256_fd(int fd, uint64_t max_size, uint8_t ret[static SHA256_DIGEST_SIZE]);
+
+int parse_sha256(const char *s, uint8_t res[static SHA256_DIGEST_SIZE]);
+
+static inline bool sha256_is_valid(const char *s) {
+        return s && in_charset(s, HEXDIGITS) && (strlen(s) == SHA256_DIGEST_SIZE * 2);
+}
index 8147e545e4b53822bc9ebf261b4f93b840346afb..03f3ebd9b461a085895d457ad64114d0fd5736d2 100644 (file)
@@ -4,7 +4,7 @@
 #include "proto/rng.h"
 #include "random-seed.h"
 #include "secure-boot.h"
-#include "sha256.h"
+#include "sha256-fundamental.h"
 #include "util.h"
 
 #define RANDOM_MAX_SIZE_MIN (32U)
index 9ef991426cadf81deed8225fa64ac26ef3279abf..27669902969dfca418176fda0e61e4347a235c58 100644 (file)
@@ -1130,7 +1130,6 @@ static int list_print_item(
 
 static int get_file_sha256(int inode_fd, uint8_t ret[static SHA256_DIGEST_SIZE]) {
         _cleanup_close_ int fd = -EBADF;
-        struct sha256_ctx ctx;
 
         /* convert O_PATH fd into a regular one */
         fd = fd_reopen(inode_fd, O_RDONLY|O_CLOEXEC);
@@ -1140,23 +1139,7 @@ static int get_file_sha256(int inode_fd, uint8_t ret[static SHA256_DIGEST_SIZE])
         /* Calculating the SHA sum might be slow, hence let's flush STDOUT first, to give user an idea where we are slow. */
         fflush(stdout);
 
-        sha256_init_ctx(&ctx);
-
-        for (;;) {
-                uint8_t buffer[64 * 1024];
-                ssize_t n;
-
-                n = read(fd, buffer, sizeof(buffer));
-                if (n < 0)
-                        return -errno;
-                if (n == 0)
-                        break;
-
-                sha256_process_bytes(buffer, n, &ctx);
-        }
-
-        sha256_finish_ctx(&ctx, ret);
-        return 0;
+        return sha256_fd(fd, UINT64_MAX, ret);
 }
 
 static const char *pick_color_for_uid_gid(uid_t uid) {
index b7ca6cf10ee7698cd4b443344d1d3597331e8eeb..f5f57ac3cbf4f50906259317a32a57f7ea8ce9c3 100644 (file)
@@ -5,7 +5,7 @@ fundamental_include = include_directories('.')
 fundamental_sources = files(
         'bootspec-fundamental.c',
         'efivars-fundamental.c',
-        'sha256.c',
+        'sha256-fundamental.c',
         'string-util-fundamental.c',
         'uki.c',
 )
similarity index 99%
rename from src/fundamental/sha256.c
rename to src/fundamental/sha256-fundamental.c
index 4447ad8a66074afa585e179185b45804f3051ec7..f8524bae692d20142d8a3ea2c62ca04a79ce820f 100644 (file)
@@ -29,7 +29,7 @@
 #endif
 
 #include "macro-fundamental.h"
-#include "sha256.h"
+#include "sha256-fundamental.h"
 #include "unaligned-fundamental.h"
 
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__