From 0bac442251a189fd9add36e964c86d2358c41212 Mon Sep 17 00:00:00 2001 From: Adrian Vovk Date: Sat, 13 Jan 2024 11:08:12 -0500 Subject: [PATCH] basic: Add some sha256 helper functions 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 | 1 + src/basic/sha256.c | 50 +++++++++++++++++++ src/basic/sha256.h | 16 ++++++ src/boot/efi/random-seed.c | 2 +- src/dissect/dissect.c | 19 +------ src/fundamental/meson.build | 2 +- .../{sha256.c => sha256-fundamental.c} | 2 +- .../{sha256.h => sha256-fundamental.h} | 0 8 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 src/basic/sha256.c create mode 100644 src/basic/sha256.h rename src/fundamental/{sha256.c => sha256-fundamental.c} (99%) rename src/fundamental/{sha256.h => sha256-fundamental.h} (100%) diff --git a/src/basic/meson.build b/src/basic/meson.build index 949ca4d81f9..6b30908ce18 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -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 index 00000000000..f0116957510 --- /dev/null +++ b/src/basic/sha256.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include + +#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 index 00000000000..95bac1bc1db --- /dev/null +++ b/src/basic/sha256.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#pragma once + +#include + +#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); +} diff --git a/src/boot/efi/random-seed.c b/src/boot/efi/random-seed.c index 8147e545e4b..03f3ebd9b46 100644 --- a/src/boot/efi/random-seed.c +++ b/src/boot/efi/random-seed.c @@ -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) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 9ef991426ca..27669902969 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -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) { diff --git a/src/fundamental/meson.build b/src/fundamental/meson.build index b7ca6cf10ee..f5f57ac3cbf 100644 --- a/src/fundamental/meson.build +++ b/src/fundamental/meson.build @@ -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', ) diff --git a/src/fundamental/sha256.c b/src/fundamental/sha256-fundamental.c similarity index 99% rename from src/fundamental/sha256.c rename to src/fundamental/sha256-fundamental.c index 4447ad8a660..f8524bae692 100644 --- a/src/fundamental/sha256.c +++ b/src/fundamental/sha256-fundamental.c @@ -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__ diff --git a/src/fundamental/sha256.h b/src/fundamental/sha256-fundamental.h similarity index 100% rename from src/fundamental/sha256.h rename to src/fundamental/sha256-fundamental.h -- 2.47.3