diff options
author | Luca Boccassi <luca.boccassi@microsoft.com> | 2021-10-07 22:49:19 +0200 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@microsoft.com> | 2021-10-08 14:11:00 +0200 |
commit | 1fc8d0c9dd6a21de81e49cfa01af4a4d9a3ed37d (patch) | |
tree | ec80fc4e73847526eee39a58b32f64414365d254 | |
parent | libsystemd/sd-id128: use only internal hmac, remove khash/OpenSSL support (diff) | |
download | systemd-1fc8d0c9dd6a21de81e49cfa01af4a4d9a3ed37d.tar.xz systemd-1fc8d0c9dd6a21de81e49cfa01af4a4d9a3ed37d.zip |
basic: remove khash helpers
No longer used anywhere. So long, and thanks for all the hashes!
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/basic/khash.c | 321 | ||||
-rw-r--r-- | src/basic/khash.h | 37 | ||||
-rw-r--r-- | src/basic/meson.build | 2 | ||||
-rw-r--r-- | src/test/meson.build | 2 | ||||
-rw-r--r-- | src/test/test-hash.c | 76 |
6 files changed, 0 insertions, 440 deletions
@@ -352,11 +352,9 @@ Features: * unify on openssl (as soon as OpenSSL 3.0 is out, and the Debian license confusion is gone) - - port sd_id128_get_machine_app_specific() over from khash - port resolved over from libgcrypt (DNSSEC code) - port journald + fsprg over from libgcrypt - port importd over from libgcrypt - - when that's done: kill khash.c - when that's done: kill gnutls support in resolved * add growvol and makevol options for /etc/crypttab, similar to diff --git a/src/basic/khash.c b/src/basic/khash.c deleted file mode 100644 index 6a4d1dd594..0000000000 --- a/src/basic/khash.c +++ /dev/null @@ -1,321 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include <linux/if_alg.h> -#include <stdbool.h> -#include <sys/socket.h> - -#include "alloc-util.h" -#include "fd-util.h" -#include "hexdecoct.h" -#include "khash.h" -#include "macro.h" -#include "missing_socket.h" -#include "string-util.h" -#include "util.h" - -/* On current kernels the maximum digest (according to "grep digestsize /proc/crypto | sort -u") is actually 32, but - * let's add some extra room, the few wasted bytes don't really matter... */ -#define LONGEST_DIGEST 128 - -struct khash { - int fd; - char *algorithm; - uint8_t digest[LONGEST_DIGEST+1]; - size_t digest_size; - bool digest_valid; -}; - -int khash_supported(void) { - static const union { - struct sockaddr sa; - struct sockaddr_alg alg; - } sa = { - .alg.salg_family = AF_ALG, - .alg.salg_type = "hash", - .alg.salg_name = "sha256", /* a very common algorithm */ - }; - - static int cached = -1; - - if (cached < 0) { - _cleanup_close_ int fd1 = -1, fd2 = -1; - uint8_t buf[LONGEST_DIGEST+1]; - - fd1 = socket(AF_ALG, SOCK_SEQPACKET|SOCK_CLOEXEC, 0); - if (fd1 < 0) { - /* The kernel returns EAFNOSUPPORT if AF_ALG is not supported at all */ - if (IN_SET(errno, EAFNOSUPPORT, EOPNOTSUPP)) - return (cached = false); - - return -errno; - } - - if (bind(fd1, &sa.sa, sizeof(sa)) < 0) { - /* The kernel returns ENOENT if the selected algorithm is not supported at all. We use a check - * for SHA256 as a proxy for whether the whole API is supported at all. After all it's one of - * the most common hash functions, and if it isn't supported, that's ample indication that - * something is really off. */ - - if (IN_SET(errno, ENOENT, EOPNOTSUPP)) - return (cached = false); - - return -errno; - } - - fd2 = accept4(fd1, NULL, 0, SOCK_CLOEXEC); - if (fd2 < 0) { - if (errno == EOPNOTSUPP) - return (cached = false); - - return -errno; - } - - if (recv(fd2, buf, sizeof(buf), 0) < 0) { - /* On some kernels we get ENOKEY for non-keyed hash functions (such as sha256), let's refuse - * using the API in those cases, since the kernel is - * broken. https://github.com/systemd/systemd/issues/8278 */ - - if (IN_SET(errno, ENOKEY, EOPNOTSUPP)) - return (cached = false); - } - - cached = true; - } - - return cached; -} - -int khash_new_with_key(khash **ret, const char *algorithm, const void *key, size_t key_size) { - union { - struct sockaddr sa; - struct sockaddr_alg alg; - } sa = { - .alg.salg_family = AF_ALG, - .alg.salg_type = "hash", - }; - - _cleanup_(khash_unrefp) khash *h = NULL; - _cleanup_close_ int fd = -1; - int supported; - ssize_t n; - - assert(ret); - assert(key || key_size == 0); - - /* Filter out an empty algorithm early, as we do not support an algorithm by that name. */ - if (isempty(algorithm)) - return -EINVAL; - - /* Overly long hash algorithm names we definitely do not support */ - if (strlen(algorithm) >= sizeof(sa.alg.salg_name)) - return -EOPNOTSUPP; - - supported = khash_supported(); - if (supported < 0) - return supported; - if (supported == 0) - return -EOPNOTSUPP; - - fd = socket(AF_ALG, SOCK_SEQPACKET|SOCK_CLOEXEC, 0); - if (fd < 0) - return -errno; - - strcpy((char*) sa.alg.salg_name, algorithm); - if (bind(fd, &sa.sa, sizeof(sa)) < 0) { - if (errno == ENOENT) - return -EOPNOTSUPP; - return -errno; - } - - if (key) { - if (setsockopt(fd, SOL_ALG, ALG_SET_KEY, key, key_size) < 0) - return -errno; - } - - h = new0(khash, 1); - if (!h) - return -ENOMEM; - - h->fd = accept4(fd, NULL, 0, SOCK_CLOEXEC); - if (h->fd < 0) - return -errno; - - h->algorithm = strdup(algorithm); - if (!h->algorithm) - return -ENOMEM; - - /* Temporary fix for rc kernel bug: https://bugzilla.redhat.com/show_bug.cgi?id=1395896 */ - (void) send(h->fd, NULL, 0, 0); - - /* Figure out the digest size */ - n = recv(h->fd, h->digest, sizeof(h->digest), 0); - if (n < 0) - return -errno; - if (n >= LONGEST_DIGEST) /* longer than what we expected? If so, we don't support this */ - return -EOPNOTSUPP; - - h->digest_size = (size_t) n; - h->digest_valid = true; - - /* Temporary fix for rc kernel bug: https://bugzilla.redhat.com/show_bug.cgi?id=1395896 */ - (void) send(h->fd, NULL, 0, 0); - - *ret = TAKE_PTR(h); - - return 0; -} - -int khash_new(khash **ret, const char *algorithm) { - return khash_new_with_key(ret, algorithm, NULL, 0); -} - -khash* khash_unref(khash *h) { - if (!h) - return NULL; - - safe_close(h->fd); - free(h->algorithm); - return mfree(h); -} - -int khash_dup(khash *h, khash **ret) { - _cleanup_(khash_unrefp) khash *copy = NULL; - - assert(h); - assert(ret); - - copy = newdup(khash, h, 1); - if (!copy) - return -ENOMEM; - - copy->fd = -1; - copy->algorithm = strdup(h->algorithm); - if (!copy->algorithm) - return -ENOMEM; - - copy->fd = accept4(h->fd, NULL, 0, SOCK_CLOEXEC); - if (copy->fd < 0) - return -errno; - - *ret = TAKE_PTR(copy); - - return 0; -} - -const char *khash_get_algorithm(khash *h) { - assert(h); - - return h->algorithm; -} - -size_t khash_get_size(khash *h) { - assert(h); - - return h->digest_size; -} - -int khash_reset(khash *h) { - ssize_t n; - - assert(h); - - n = send(h->fd, NULL, 0, 0); - if (n < 0) - return -errno; - - h->digest_valid = false; - - return 0; -} - -int khash_put(khash *h, const void *buffer, size_t size) { - ssize_t n; - - assert(h); - assert(buffer || size == 0); - - if (size <= 0) - return 0; - - n = send(h->fd, buffer, size, MSG_MORE); - if (n < 0) - return -errno; - - h->digest_valid = false; - - return 0; -} - -int khash_put_iovec(khash *h, const struct iovec *iovec, size_t n) { - struct msghdr mh = { - .msg_iov = (struct iovec*) iovec, - .msg_iovlen = n, - }; - ssize_t k; - - assert(h); - assert(iovec || n == 0); - - if (n <= 0) - return 0; - - k = sendmsg(h->fd, &mh, MSG_MORE); - if (k < 0) - return -errno; - - h->digest_valid = false; - - return 0; -} - -static int retrieve_digest(khash *h) { - ssize_t n; - - assert(h); - - if (h->digest_valid) - return 0; - - n = recv(h->fd, h->digest, h->digest_size, 0); - if (n < 0) - return n; - if ((size_t) n != h->digest_size) /* digest size changed? */ - return -EIO; - - h->digest_valid = true; - - return 0; -} - -int khash_digest_data(khash *h, const void **ret) { - int r; - - assert(h); - assert(ret); - - r = retrieve_digest(h); - if (r < 0) - return r; - - *ret = h->digest; - return 0; -} - -int khash_digest_string(khash *h, char **ret) { - int r; - char *p; - - assert(h); - assert(ret); - - r = retrieve_digest(h); - if (r < 0) - return r; - - p = hexmem(h->digest, h->digest_size); - if (!p) - return -ENOMEM; - - *ret = p; - return 0; -} diff --git a/src/basic/khash.h b/src/basic/khash.h deleted file mode 100644 index a343d306e9..0000000000 --- a/src/basic/khash.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include <inttypes.h> -#include <sys/types.h> -#include <sys/uio.h> - -#include "macro.h" - -typedef struct khash khash; - -int khash_supported(void); - -/* For plain hash functions. Hash functions commonly supported on today's kernels are: crc32c, crct10dif, crc32, - * sha224, sha256, sha512, sha384, sha1, md5, md4, sha3-224, sha3-256, sha3-384, sha3-512, and more. */ -int khash_new(khash **ret, const char *algorithm); - -/* For keyed hash functions. Hash functions commonly supported on today's kernels are: hmac(sha256), cmac(aes), - * cmac(des3_ede), hmac(sha3-512), hmac(sha3-384), hmac(sha3-256), hmac(sha3-224), hmac(rmd160), hmac(rmd128), - * hmac(sha224), hmac(sha512), hmac(sha384), hmac(sha1), hmac(md5), and more. */ -int khash_new_with_key(khash **ret, const char *algorithm, const void *key, size_t key_size); - -int khash_dup(khash *h, khash **ret); -khash* khash_unref(khash *h); - -const char *khash_get_algorithm(khash *h); -size_t khash_get_size(khash *h); - -int khash_reset(khash *h); - -int khash_put(khash *h, const void *buffer, size_t size); -int khash_put_iovec(khash *h, const struct iovec *iovec, size_t n); - -int khash_digest_data(khash *h, const void **ret); -int khash_digest_string(khash *h, char **ret); - -DEFINE_TRIVIAL_CLEANUP_FUNC(khash*, khash_unref); diff --git a/src/basic/meson.build b/src/basic/meson.build index a4a7469856..cf97f6de1d 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -82,8 +82,6 @@ basic_sources = files(''' inotify-util.h io-util.c io-util.h - khash.c - khash.h limits-util.c limits-util.h linux/btrfs.h diff --git a/src/test/meson.build b/src/test/meson.build index c24641fc7e..292b6329e4 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -592,8 +592,6 @@ tests += [ [['src/test/test-id128.c']], - [['src/test/test-hash.c']], - [['src/test/test-gcrypt-util.c'], [], [], [], 'HAVE_GCRYPT'], diff --git a/src/test/test-hash.c b/src/test/test-hash.c deleted file mode 100644 index 270fcd0df4..0000000000 --- a/src/test/test-hash.c +++ /dev/null @@ -1,76 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include <errno.h> -#include <stdio.h> - -#include "alloc-util.h" -#include "log.h" -#include "string-util.h" -#include "khash.h" -#include "tests.h" - -int main(int argc, char *argv[]) { - _cleanup_(khash_unrefp) khash *h = NULL, *copy = NULL; - _cleanup_free_ char *s = NULL; - int r; - - test_setup_logging(LOG_DEBUG); - - assert_se(khash_new(&h, NULL) == -EINVAL); - assert_se(khash_new(&h, "") == -EINVAL); - - r = khash_supported(); - assert_se(r >= 0); - if (r == 0) - return log_tests_skipped("khash not supported on this kernel"); - - assert_se(khash_new(&h, "foobar") == -EOPNOTSUPP); /* undefined hash function */ - - assert_se(khash_new(&h, "sha256") >= 0); - assert_se(khash_get_size(h) == 32); - assert_se(streq(khash_get_algorithm(h), "sha256")); - - assert_se(khash_digest_string(h, &s) >= 0); - assert_se(streq(s, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")); - s = mfree(s); - - assert_se(khash_put(h, "foobar", 6) >= 0); - assert_se(khash_digest_string(h, &s) >= 0); - assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2")); - s = mfree(s); - - assert_se(khash_put(h, "piep", 4) >= 0); - assert_se(khash_digest_string(h, &s) >= 0); - assert_se(streq(s, "f114d872b5ea075d3be9040d0b7a429514b3f9324a8e8e3dc3fb24c34ee56bea")); - s = mfree(s); - - assert_se(khash_put(h, "foo", 3) >= 0); - assert_se(khash_dup(h, ©) >= 0); - - assert_se(khash_put(h, "bar", 3) >= 0); - assert_se(khash_put(copy, "bar", 3) >= 0); - - assert_se(khash_digest_string(h, &s) >= 0); - assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2")); - s = mfree(s); - - assert_se(khash_digest_string(copy, &s) >= 0); - assert_se(streq(s, "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2")); - s = mfree(s); - - h = khash_unref(h); - - assert_se(khash_new_with_key(&h, "hmac(sha256)", "quux", 4) >= 0); - assert_se(khash_get_size(h) == 32); - assert_se(streq(khash_get_algorithm(h), "hmac(sha256)")); - - assert_se(khash_digest_string(h, &s) >= 0); - assert_se(streq(s, "abed9f8218ab473f77218a6a7d39abf1d21fa46d0700c4898e330ba88309d5ae")); - s = mfree(s); - - assert_se(khash_put(h, "foobar", 6) >= 0); - assert_se(khash_digest_string(h, &s) >= 0); - assert_se(streq(s, "33f6c70a60db66007d5325d5d1dea37c371354e5b83347a59ad339ce9f4ba3dc")); - - return 0; -} |