]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tree-wide: Load libcrypto and libssl via dlopen()
authorDaan De Meyer <daan@amutable.com>
Mon, 20 Apr 2026 13:08:29 +0000 (13:08 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 24 Apr 2026 04:32:42 +0000 (06:32 +0200)
Until now OpenSSL was linked into every binary and library that needed
cryptography, pulling libcrypto (and, for resolved, libssl) into the
address space of services that never touch them at runtime. This commit
moves all OpenSSL usage behind the same dlopen helper pattern that we
already use for other optional libraries (libpam, libseccomp, libxz, …)
so libcrypto/libssl are only loaded on demand.

The bulk of the work lives in src/shared/crypto-util.{c,h} (libcrypto)
and src/shared/ssl-util.{c,h} (libssl), which replace the previous
src/shared/openssl-util.{c,h}:

 - crypto-util.{c,h} declares every libcrypto function we call via
   DLSYM_PROTOTYPE() and resolves them inside dlopen_libcrypto().

 - ssl-util.{c,h} holds the libssl-specific DLSYM_PROTOTYPEs,
   dlopen_libssl(), and the SSL_freep cleanup helper, so translation
   units that only need libcrypto do not pull in libssl declarations.

 - Callers refer to the symbols through sym_* aliases rather than the
   original names.

 - Convenience macros that used to be provided by the OpenSSL headers
   (OPENSSL_free, BN_num_bytes, the sk_TYPE_* helpers, …) are
   reimplemented as sym_* wrappers so no code path needs to fall back
   to the linker-resolved symbols.

 - All _cleanup_ helpers are redefined in terms of the sym_* variants
   (EVP_PKEY_freep, X509_freep, BIO_freep, …) so cleanup attributes
   keep working without pulling in libcrypto symbols at link time.

 - The public crypto-util.c entry points (openssl_pubkey_from_pem,
   openssl_digest_many, openssl_hmac_many, openssl_cipher_many,
   kdf_ss_derive, kdf_kb_hmac_derive, rsa_* / ecc_* helpers,
   pubkey_fingerprint, digest_and_sign, pkcs7_new, x509_fingerprint,
   openssl_extract_public_key, pkey_generate_volume_keys, the load_*
   helpers, …) now call dlopen_libcrypto() at entry before touching any
   sym_* pointer.

The call sites across the tree have been converted to call
dlopen_libcrypto()/dlopen_libssl() at the appropriate entry point
before their first sym_* use, and to use sym_* variants throughout:

 - bootctl, sbsign, measure, pcrlock, pcrextend, tpm2-setup, repart,
   cryptsetup, cryptenroll, homectl, homed, homework, keyutil,
   sysupdate, creds, import, dissect-image, pe-binary, pkcs11-util,
   pkcs7-util, tpm2-util, creds-util. resolved additionally dlopens
   libssl for DoT.

The meson build files are updated to depend on libopenssl_cflags (a
new partial dependency that exposes include paths and compile flags
only, not the linker flags) instead of libopenssl for every target that
previously linked against OpenSSL. Nothing links against libcrypto or
libssl directly anymore.

A new src/sbsign/authenticode.c hosts the Authenticode ASN.1 type
definitions that used to live inline in sbsign.c. The OpenSSL
ASN1_SEQUENCE / ASN1_CHOICE / IMPLEMENT_ASN1_FUNCTIONS macros expand to
code that references libcrypto symbols directly, so to keep this
translation unit unlinked from libcrypto we redirect ASN1_item_* to
the sym_* variants via #define and wrap the ASN1_*_it() getters (which
appear as constant function pointers in static initializers) in small
trampoline functions that forward to the sym_* pointers at runtime.

test-dlopen-so gains assertions for dlopen_libcrypto and dlopen_libssl
so the dlopen contract is exercised in CI, and the openssl-specific
test was renamed from test-openssl.c to test-crypto-util.c to match
the new header naming.

70 files changed:
meson.build
src/basic/basic-forward.h
src/bootctl/bootctl-install.c
src/bootctl/bootctl.c
src/bootctl/meson.build
src/creds/meson.build
src/cryptenroll/cryptenroll-pkcs11.c
src/cryptenroll/meson.build
src/cryptsetup/cryptsetup.c
src/cryptsetup/meson.build
src/home/homectl-pkcs11.c
src/home/homectl.c
src/home/homed-manager-bus.c
src/home/homed-manager.c
src/home/homed-manager.h
src/home/homework-fscrypt.c
src/home/homework-luks.c
src/home/meson.build
src/home/user-record-sign.c
src/home/user-record-sign.h
src/import/meson.build
src/import/pull-common.c
src/import/pull-job.c
src/import/pull-job.h
src/import/pull-oci.c
src/import/pull-raw.c
src/keyutil/keyutil.c
src/keyutil/meson.build
src/measure/measure-tool.c
src/measure/meson.build
src/pcrextend/meson.build
src/pcrextend/pcrextend.c
src/pcrlock/meson.build
src/pcrlock/pcrlock-firmware.c
src/pcrlock/pcrlock.c
src/repart/meson.build
src/repart/repart.c
src/resolve/meson.build
src/resolve/resolvectl.c
src/resolve/resolved-dns-dnssec.c
src/resolve/resolved-dnstls.c
src/resolve/resolved-dnstls.h
src/sbsign/authenticode.c [new file with mode: 0644]
src/sbsign/authenticode.h
src/sbsign/meson.build
src/sbsign/sbsign.c
src/shared/creds-util.c
src/shared/crypto-util.c [moved from src/shared/openssl-util.c with 51% similarity]
src/shared/crypto-util.h [new file with mode: 0644]
src/shared/dissect-image.c
src/shared/meson.build
src/shared/openssl-util.h [deleted file]
src/shared/pe-binary.c
src/shared/pe-binary.h
src/shared/pkcs11-util.c
src/shared/pkcs11-util.h
src/shared/pkcs7-util.c
src/shared/shared-forward.h
src/shared/ssl-util.c [new file with mode: 0644]
src/shared/ssl-util.h [new file with mode: 0644]
src/shared/tpm2-util.c
src/shared/tpm2-util.h
src/sysupdate/meson.build
src/test/meson.build
src/test/test-crypto-util.c [moved from src/test/test-openssl.c with 93% similarity]
src/test/test-cryptolib.c [deleted file]
src/test/test-dlopen-so.c
src/test/test-tpm2.c
src/tpm2-setup/meson.build
src/tpm2-setup/tpm2-setup.c

index a902bc96aa2048752f9b2b8ac7b05494ef6f2a7d..4f1a791bc7651a3afe06b72861bacf12d090c367 100644 (file)
@@ -1258,6 +1258,7 @@ libgnutls_cflags = libgnutls.partial_dependency(includes: true, compile_args: tr
 libopenssl = dependency('openssl',
                         version : '>= 3.0.0',
                         required : get_option('openssl'))
+libopenssl_cflags = libopenssl.partial_dependency(includes: true, compile_args: true)
 conf.set10('HAVE_OPENSSL', libopenssl.found())
 
 libp11kit = dependency('p11-kit-1',
index 1ca9ecfeff43e399b2d422ed847f451140e3b868..396056a8e55ebe93aa1d5c90767b508bfe661dec 100644 (file)
@@ -69,6 +69,15 @@ struct fdisk_context;
 struct fdisk_table;
 struct crypt_device;
 
+typedef struct buf_mem_st BUF_MEM;
+typedef struct evp_pkey_st EVP_PKEY;
+typedef struct evp_md_st EVP_MD;
+typedef struct evp_md_ctx_st EVP_MD_CTX;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+typedef struct ssl_session_st SSL_SESSION;
+typedef struct x509_st X509;
+
 /* basic/ forward declarations */
 
 typedef void (*hash_func_t)(const void *p, struct siphash *state);
@@ -111,6 +120,7 @@ typedef struct Set Set;
 
 typedef struct dual_timestamp dual_timestamp;
 typedef struct triple_timestamp triple_timestamp;
+typedef struct Compressor Compressor;
 typedef struct ConfFile ConfFile;
 typedef struct LockFile LockFile;
 typedef struct PidRef PidRef;
index a8ac742b9a760a3cab9e3d44eeeebc7b41d6f82d..20958d0b0bc6fd9ca11da3bfa23917e746161f0c 100644 (file)
@@ -7,6 +7,7 @@
 #include "sd-varlink.h"
 
 #include "alloc-util.h"
+#include "ask-password-api.h"
 #include "blockdev-util.h"
 #include "boot-entry.h"
 #include "bootctl.h"
@@ -15,6 +16,7 @@
 #include "bootctl-util.h"
 #include "chase.h"
 #include "copy.h"
+#include "crypto-util.h"
 #include "dirent-util.h"
 #include "efi-api.h"
 #include "efi-fundamental.h"
@@ -31,7 +33,6 @@
 #include "json-util.h"
 #include "kernel-config.h"
 #include "log.h"
-#include "openssl-util.h"
 #include "parse-argument.h"
 #include "path-util.h"
 #include "pe-binary.h"
@@ -117,11 +118,11 @@ static void install_context_done(InstallContext *c) {
         c->xbootldr_fd = safe_close(c->xbootldr_fd);
 #if HAVE_OPENSSL
         if (c->secure_boot_private_key) {
-                EVP_PKEY_free(c->secure_boot_private_key);
+                sym_EVP_PKEY_free(c->secure_boot_private_key);
                 c->secure_boot_private_key = NULL;
         }
         if (c->secure_boot_certificate) {
-                X509_free(c->secure_boot_certificate);
+                sym_X509_free(c->secure_boot_certificate);
                 c->secure_boot_certificate = NULL;
         }
 #endif
@@ -1035,12 +1036,16 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
         if (!c->secure_boot_certificate || !c->secure_boot_private_key)
                 return 0;
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         _cleanup_free_ uint8_t *dercert = NULL;
         int dercertsz;
-        dercertsz = i2d_X509(c->secure_boot_certificate, &dercert);
+        dercertsz = sym_i2d_X509(c->secure_boot_certificate, &dercert);
         if (dercertsz < 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert X.509 certificate to DER: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         if (c->esp_fd < 0)
                 return c->esp_fd;
@@ -1087,7 +1092,7 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
         FOREACH_STRING(db, "PK", "KEK", "db") {
                 _cleanup_(BIO_freep) BIO *bio = NULL;
 
-                bio = BIO_new(BIO_s_mem());
+                bio = sym_BIO_new(sym_BIO_s_mem());
                 if (!bio)
                         return log_oom();
 
@@ -1096,34 +1101,34 @@ static int install_secure_boot_auto_enroll(InstallContext *c) {
                         return log_oom();
 
                 /* Don't count the trailing NUL terminator. */
-                if (BIO_write(bio, db16, char16_strsize(db16) - sizeof(char16_t)) < 0)
+                if (sym_BIO_write(bio, db16, char16_strsize(db16) - sizeof(char16_t)) < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable name to bio");
 
                 EFI_GUID *guid = STR_IN_SET(db, "PK", "KEK") ? &(EFI_GUID) EFI_GLOBAL_VARIABLE : &(EFI_GUID) EFI_IMAGE_SECURITY_DATABASE_GUID;
 
-                if (BIO_write(bio, guid, sizeof(*guid)) < 0)
+                if (sym_BIO_write(bio, guid, sizeof(*guid)) < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable GUID to bio");
 
-                if (BIO_write(bio, &attrs, sizeof(attrs)) < 0)
+                if (sym_BIO_write(bio, &attrs, sizeof(attrs)) < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable attributes to bio");
 
-                if (BIO_write(bio, &timestamp, sizeof(timestamp)) < 0)
+                if (sym_BIO_write(bio, &timestamp, sizeof(timestamp)) < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write timestamp to bio");
 
-                if (BIO_write(bio, siglist, siglistsz) < 0)
+                if (sym_BIO_write(bio, siglist, siglistsz) < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write signature list to bio");
 
                 _cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
-                p7 = PKCS7_sign(c->secure_boot_certificate, c->secure_boot_private_key, /* certs= */ NULL, bio, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY|PKCS7_NOSMIMECAP);
+                p7 = sym_PKCS7_sign(c->secure_boot_certificate, c->secure_boot_private_key, /* certs= */ NULL, bio, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY|PKCS7_NOSMIMECAP);
                 if (!p7)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to calculate PKCS7 signature: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
                 _cleanup_free_ uint8_t *sig = NULL;
-                int sigsz = i2d_PKCS7(p7, &sig);
+                int sigsz = sym_i2d_PKCS7(p7, &sig);
                 if (sigsz < 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
                 size_t authsz = offsetof(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo.CertData) + sigsz;
                 _cleanup_free_ EFI_VARIABLE_AUTHENTICATION_2 *auth = malloc(authsz);
index 59a93d07c3f225b0fee34b1c0f160b50c8d03883..942ef4d681875ea4fb00095c6be396cb942d7b7a 100644 (file)
@@ -17,6 +17,7 @@
 #include "bootctl-unlink.h"
 #include "bootctl-util.h"
 #include "build.h"
+#include "crypto-util.h"
 #include "devnum-util.h"
 #include "dissect-image.h"
 #include "efi-loader.h"
@@ -30,7 +31,6 @@
 #include "loop-util.h"
 #include "main-func.h"
 #include "mount-util.h"
-#include "openssl-util.h"
 #include "options.h"
 #include "pager.h"
 #include "parse-argument.h"
index 8cfbb7c14acb092eeb95d5b1ca842424d2f08f62..f8349df7168e33113d363438af061d1c656ec299 100644 (file)
@@ -23,6 +23,6 @@ executables += [
                 ],
                 'sources' : bootctl_sources,
                 'link_with' : boot_link_with,
-                'dependencies' : [libopenssl],
+                'dependencies' : [libopenssl_cflags],
         },
 ]
index a6e66495b6059412c49f7626c851e72bf9c3327d..dc4a5a28ae3162d502b3084ad2459c60aed32086 100644 (file)
@@ -11,7 +11,7 @@ executables += [
                 'sources' : files('creds.c'),
                 'dependencies' : [
                         libmount_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         threads,
                 ],
         },
index 51c2a5fa77e38a34cfcc5e63ea172450d90f9c27..ae678f96e477d2e4b1cbdcf21230514007a0ff06 100644 (file)
@@ -2,10 +2,10 @@
 
 #include "alloc-util.h"
 #include "cryptenroll-pkcs11.h"
+#include "crypto-util.h"
 #include "cryptsetup-util.h"
 #include "hexdecoct.h"
 #include "json-util.h"
-#include "openssl-util.h"
 #include "pkcs11-util.h"
 
 #if HAVE_P11KIT && HAVE_OPENSSL
index 2d882343d307824e0e5444f611c50162dc10148a..8213a0e6725725ad47118e73c2dbc6f3b669a555 100644 (file)
@@ -24,7 +24,7 @@ executables += [
                         libcryptsetup_cflags,
                         libdl,
                         libfido2_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         libp11kit_cflags,
                 ],
         },
index 8e5161eba05d4018927922ce2a8a28694dd98c7c..d772ba9a9afee2b3509e022f291d76a136959346 100644 (file)
@@ -12,6 +12,7 @@
 #include "alloc-util.h"
 #include "ask-password-api.h"
 #include "build.h"
+#include "crypto-util.h"
 #include "cryptsetup-fido2.h"
 #include "cryptsetup-keyfile.h"
 #include "cryptsetup-pkcs11.h"
@@ -537,6 +538,10 @@ static int parse_one_option(const char *option) {
 #if HAVE_OPENSSL
                 _cleanup_strv_free_ char **l = NULL;
 
+                r = dlopen_libcrypto(LOG_ERR);
+                if (r < 0)
+                        return r;
+
                 l = strv_split(val, ":");
                 if (!l)
                         return log_oom();
@@ -544,11 +549,11 @@ static int parse_one_option(const char *option) {
                 STRV_FOREACH(i, l) {
                         const EVP_MD *implementation;
 
-                        implementation = EVP_get_digestbyname(*i);
+                        implementation = sym_EVP_get_digestbyname(*i);
                         if (!implementation)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", val);
 
-                        if (strv_extend(&arg_tpm2_measure_banks, EVP_MD_name(implementation)) < 0)
+                        if (strv_extend(&arg_tpm2_measure_banks, sym_EVP_MD_get0_name(implementation)) < 0)
                                 return log_oom();
                 }
 #else
index 9249f70177b376a18e061bd7d5b823e2182b6707..9b7f3fa344da5fadd3bebddd33e25f74485dd8a5 100644 (file)
@@ -21,7 +21,7 @@ executables += [
                         libcryptsetup_cflags,
                         libfido2_cflags,
                         libmount_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         libp11kit_cflags,
                 ],
         },
index a72aecf1356437ebb512338ec2adbc644d281c7a..3ef1b80c225e30b5c74d43f2c4b1eaf4c6da361c 100644 (file)
@@ -2,12 +2,12 @@
 
 #include "sd-json.h"
 
+#include "crypto-util.h"
 #include "errno-util.h"
 #include "hexdecoct.h"
 #include "homectl-pkcs11.h"
 #include "libcrypt-util.h"
 #include "log.h"
-#include "openssl-util.h"
 #include "pkcs11-util.h"
 #include "string-util.h"
 #include "strv.h"
index 4ebf47ca9e75a1ca486e456d8e5366de1e5e9208..271e03587502b10b3329ff837708ffefb8ea1a5d 100644 (file)
@@ -18,6 +18,7 @@
 #include "cgroup-util.h"
 #include "chase.h"
 #include "creds-util.h"
+#include "crypto-util.h"
 #include "dirent-util.h"
 #include "dns-domain.h"
 #include "env-util.h"
@@ -39,7 +40,6 @@
 #include "libfido2-util.h"
 #include "locale-util.h"
 #include "main-func.h"
-#include "openssl-util.h"
 #include "pager.h"
 #include "parse-argument.h"
 #include "parse-util.h"
@@ -5316,13 +5316,17 @@ static int verb_list_signing_keys(int argc, char *argv[], uintptr_t _data, void
                         /* Let's decode the PEM key to DER (so that we lose prefix/suffix), then truncate it
                          * for display reasons. */
 
+                        r = dlopen_libcrypto(LOG_DEBUG);
+                        if (r < 0)
+                                return r;
+
                         _cleanup_(EVP_PKEY_freep) EVP_PKEY *key = NULL;
                         r = openssl_pubkey_from_pem(pem, SIZE_MAX, &key);
                         if (r < 0)
                                 return log_error_errno(r, "Failed to parse PEM: %m");
 
                         _cleanup_free_ void *der = NULL;
-                        int n = i2d_PUBKEY(key, (unsigned char**) &der);
+                        int n = sym_i2d_PUBKEY(key, (unsigned char**) &der);
                         if (n < 0)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to encode key as DER.");
 
index f35268567218ee44c374ac09887ebdba4e0b9c54..b8385c781e2b44f54a7509cf9a3b44aeb60a1c20 100644 (file)
@@ -12,6 +12,7 @@
 #include "bus-message-util.h"
 #include "bus-object.h"
 #include "bus-polkit.h"
+#include "crypto-util.h"
 #include "fileio.h"
 #include "format-util.h"
 #include "home-util.h"
@@ -22,7 +23,6 @@
 #include "homed-manager-bus.h"
 #include "homed-operation.h"
 #include "log.h"
-#include "openssl-util.h"
 #include "path-util.h"
 #include "set.h"
 #include "string-util.h"
@@ -936,14 +936,14 @@ static bool manager_has_public_key(Manager *m, EVP_PKEY *needle) {
 
         EVP_PKEY *pkey;
         HASHMAP_FOREACH(pkey, m->public_keys) {
-                r = EVP_PKEY_eq(pkey, needle);
+                r = sym_EVP_PKEY_eq(pkey, needle);
                 if (r > 0)
                         return true;
 
                 /* EVP_PKEY_eq() returns -1 and -2 too under some conditions, which we'll all treat as "not the same" */
         }
 
-        r = EVP_PKEY_eq(m->private_key, needle);
+        r = sym_EVP_PKEY_eq(m->private_key, needle);
         if (r > 0)
                 return true;
 
index 6c229abadcf6aad56d3b634c9e8ceb3da9994032..fc6fe8a4b1c448179984b5d5b3fe9cf40523e288 100644 (file)
@@ -4,7 +4,6 @@
 #include <linux/fscrypt.h>
 #include <linux/magic.h>
 #include <math.h>
-#include <openssl/pem.h>
 #include <pwd.h>
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
@@ -25,6 +24,7 @@
 #include "clean-ipc.h"
 #include "common-signal.h"
 #include "conf-files.h"
+#include "crypto-util.h"
 #include "device-util.h"
 #include "dirent-util.h"
 #include "errno-util.h"
@@ -43,7 +43,6 @@
 #include "homed-varlink.h"
 #include "mkdir.h"
 #include "notify-recv.h"
-#include "openssl-util.h"
 #include "ordered-set.h"
 #include "quota-util.h"
 #include "random-util.h"
@@ -313,7 +312,7 @@ Manager* manager_free(Manager *m) {
         m->homes_by_sysfs = hashmap_free(m->homes_by_sysfs);
 
         if (m->private_key)
-                EVP_PKEY_free(m->private_key);
+                sym_EVP_PKEY_free(m->private_key);
 
         hashmap_free(m->public_keys);
 
@@ -1317,7 +1316,7 @@ static int manager_load_key_pair(Manager *m) {
         assert(m);
 
         if (m->private_key) {
-                EVP_PKEY_free(m->private_key);
+                sym_EVP_PKEY_free(m->private_key);
                 m->private_key = NULL;
         }
 
@@ -1337,7 +1336,7 @@ static int manager_load_key_pair(Manager *m) {
         if (st.st_uid != 0 || (st.st_mode & 0077) != 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Private key file is readable by more than the root user");
 
-        m->private_key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
+        m->private_key = sym_PEM_read_PrivateKey(f, NULL, NULL, NULL);
         if (!m->private_key)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to load private key pair");
 
@@ -1353,20 +1352,20 @@ static int manager_generate_key_pair(Manager *m) {
         int r;
 
         if (m->private_key) {
-                EVP_PKEY_free(m->private_key);
+                sym_EVP_PKEY_free(m->private_key);
                 m->private_key = NULL;
         }
 
-        ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
+        ctx = sym_EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
         if (!ctx)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate Ed25519 key generation context.");
 
-        if (EVP_PKEY_keygen_init(ctx) <= 0)
+        if (sym_EVP_PKEY_keygen_init(ctx) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize Ed25519 key generation context.");
 
         log_info("Generating key pair for signing local user identity records.");
 
-        if (EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
+        if (sym_EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate Ed25519 key pair");
 
         log_info("Successfully created Ed25519 key pair.");
@@ -1378,7 +1377,7 @@ static int manager_generate_key_pair(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to open key file for writing: %m");
 
-        if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
+        if (sym_PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
 
         (void) fchmod(fileno(fpublic), 0444); /* Make public key world readable */
@@ -1394,7 +1393,7 @@ static int manager_generate_key_pair(Manager *m) {
         if (r < 0)
                 return log_error_errno(r, "Failed to open key file for writing: %m");
 
-        if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, NULL) <= 0)
+        if (sym_PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, NULL) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
 
         (void) fchmod(fileno(fprivate), 0400); /* Make private key root readable */
@@ -1459,7 +1458,8 @@ int manager_sign_user_record(Manager *m, UserRecord *u, UserRecord **ret, sd_bus
         return user_record_sign(u, m->private_key, ret);
 }
 
-DEFINE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, EVP_PKEY_free);
+/* dlopen_libcrypto() must have been called before populating this hashmap. */
+DEFINE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, sym_EVP_PKEY_free);
 
 static int manager_load_public_key_one(Manager *m, const char *path) {
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
@@ -1495,7 +1495,7 @@ static int manager_load_public_key_one(Manager *m, const char *path) {
         if (st.st_uid != 0 || (st.st_mode & 0022) != 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Public key file %s is writable by more than the root user, refusing.", path);
 
-        pkey = PEM_read_PUBKEY(f, &pkey, NULL, NULL);
+        pkey = sym_PEM_read_PUBKEY(f, &pkey, NULL, NULL);
         if (!pkey)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key file %s.", path);
 
@@ -1537,6 +1537,10 @@ int manager_startup(Manager *m) {
 
         assert(m);
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         r = manager_listen_notify(m);
         if (r < 0)
                 return r;
index fe1041e01e5fc267018c5bddaf7db48aa842801a..a399c31bf8fb12df3e07f33670c592d32695e087 100644 (file)
@@ -1,8 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <openssl/evp.h>
-
 #include "homed-forward.h"
 #include "user-record.h"
 
index c2134142ded6cde3b6280070f7f3a286745da101..6f8ae4b8c9c1c308fc9529151502712c722e3017 100644 (file)
@@ -1,8 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <linux/fscrypt.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -10,6 +8,7 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "crypto-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "format-util.h"
@@ -25,7 +24,6 @@
 #include "mkdir.h"
 #include "mount-util.h"
 #include "nulstr-util.h"
-#include "openssl-util.h"
 #include "parse-util.h"
 #include "process-util.h"
 #include "random-util.h"
@@ -180,8 +178,8 @@ static void calculate_key_descriptor(
 
         /* Derive the key descriptor from the volume key via double SHA512, in order to be compatible with e4crypt */
 
-        assert_se(SHA512(key, key_size, hashed) == hashed);
-        assert_se(SHA512(hashed, sizeof(hashed), hashed2) == hashed2);
+        assert_se(sym_SHA512(key, key_size, hashed) == hashed);
+        assert_se(sym_SHA512(hashed, sizeof(hashed), hashed2) == hashed2);
 
         assert_cc(sizeof(hashed2) >= FS_KEY_DESCRIPTOR_SIZE);
 
@@ -211,6 +209,10 @@ static int fscrypt_slot_try_one(
         assert(encrypted_size > 0);
         assert(match_key_descriptor);
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         /* Our construction is like this:
          *
          *   1. In each key slot we store a salt value plus the encrypted volume key
@@ -226,37 +228,37 @@ static int fscrypt_slot_try_one(
 
         CLEANUP_ERASE(derived);
 
-        if (PKCS5_PBKDF2_HMAC(
+        if (sym_PKCS5_PBKDF2_HMAC(
                             password, strlen(password),
                             salt, salt_size,
-                            0xFFFF, EVP_sha512(),
+                            0xFFFF, sym_EVP_sha512(),
                             sizeof(derived), derived) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed.");
 
-        context = EVP_CIPHER_CTX_new();
+        context = sym_EVP_CIPHER_CTX_new();
         if (!context)
                 return log_oom();
 
         /* We use AES256 in counter mode */
-        assert_se(cc = EVP_aes_256_ctr());
+        assert_se(cc = sym_EVP_aes_256_ctr());
 
         /* We only use the first half of the derived key */
-        assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
+        assert(sizeof(derived) >= (size_t) sym_EVP_CIPHER_get_key_length(cc));
 
-        if (EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)
+        if (sym_EVP_DecryptInit_ex(context, cc, NULL, derived, NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
 
-        decrypted_size = encrypted_size + EVP_CIPHER_key_length(cc) * 2;
+        decrypted_size = encrypted_size + sym_EVP_CIPHER_get_key_length(cc) * 2;
         decrypted = malloc(decrypted_size);
         if (!decrypted)
                 return log_oom();
 
-        if (EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
+        if (sym_EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt volume key.");
 
         assert((size_t) decrypted_size_out1 <= decrypted_size);
 
-        if (EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
+        if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish decryption of volume key.");
 
         assert((size_t) decrypted_size_out1 + (size_t) decrypted_size_out2 < decrypted_size);
@@ -484,43 +486,47 @@ static int fscrypt_slot_set(
         size_t encrypted_size;
         ssize_t ss;
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         r = crypto_random_bytes(salt, sizeof(salt));
         if (r < 0)
                 return log_error_errno(r, "Failed to generate salt: %m");
 
         CLEANUP_ERASE(derived);
 
-        if (PKCS5_PBKDF2_HMAC(
+        if (sym_PKCS5_PBKDF2_HMAC(
                             password, strlen(password),
                             salt, sizeof(salt),
-                            0xFFFF, EVP_sha512(),
+                            0xFFFF, sym_EVP_sha512(),
                             sizeof(derived), derived) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "PBKDF2 failed");
 
-        context = EVP_CIPHER_CTX_new();
+        context = sym_EVP_CIPHER_CTX_new();
         if (!context)
                 return log_oom();
 
         /* We use AES256 in counter mode */
-        cc = EVP_aes_256_ctr();
+        cc = sym_EVP_aes_256_ctr();
 
         /* We only use the first half of the derived key */
-        assert(sizeof(derived) >= (size_t) EVP_CIPHER_key_length(cc));
+        assert(sizeof(derived) >= (size_t) sym_EVP_CIPHER_get_key_length(cc));
 
-        if (EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)
+        if (sym_EVP_EncryptInit_ex(context, cc, NULL, derived, NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
 
-        encrypted_size = volume_key_size + EVP_CIPHER_key_length(cc) * 2;
+        encrypted_size = volume_key_size + sym_EVP_CIPHER_get_key_length(cc) * 2;
         encrypted = malloc(encrypted_size);
         if (!encrypted)
                 return log_oom();
 
-        if (EVP_EncryptUpdate(context, (uint8_t*) encrypted, &encrypted_size_out1, volume_key, volume_key_size) != 1)
+        if (sym_EVP_EncryptUpdate(context, (uint8_t*) encrypted, &encrypted_size_out1, volume_key, volume_key_size) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt volume key.");
 
         assert((size_t) encrypted_size_out1 <= encrypted_size);
 
-        if (EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
+        if (sym_EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish encryption of volume key.");
 
         assert((size_t) encrypted_size_out1 + (size_t) encrypted_size_out2 < encrypted_size);
@@ -569,6 +575,10 @@ int home_create_fscrypt(
         assert(setup);
         assert(ret_home);
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         assert_se(ip = user_record_image_path(h));
 
         r = tempfn_random(ip, "homework", &d);
index 96ac65a6fbbeee6b863cf2230d319c52a8eee1d3..e85153d61dbc2f090850233c02fd587ad13a9b66 100644 (file)
@@ -21,6 +21,7 @@
 #include "blockdev-util.h"
 #include "btrfs-util.h"
 #include "chattr-util.h"
+#include "crypto-util.h"
 #include "cryptsetup-util.h"
 #include "device-util.h"
 #include "devnum-util.h"
@@ -48,7 +49,6 @@
 #include "memory-util.h"
 #include "mkdir.h"
 #include "mkfs-util.h"
-#include "openssl-util.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "pidref.h"
@@ -805,6 +805,10 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
         assert(cd);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         /* Let's find the right OpenSSL EVP_CIPHER object that matches the encryption settings of the LUKS
          * device */
 
@@ -832,12 +836,12 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER
         if (asprintf(&cipher_name, "%s-%zu-%s", cipher, key_bits, cipher_mode) < 0)
                 return log_oom();
 
-        cc = EVP_get_cipherbyname(cipher_name);
+        cc = sym_EVP_get_cipherbyname(cipher_name);
         if (!cc)
                 return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Selected cipher mode '%s' not supported, can't encrypt JSON record.", cipher_name);
 
         /* Verify that our key length calculations match what OpenSSL thinks */
-        r = EVP_CIPHER_key_length(cc);
+        r = sym_EVP_CIPHER_get_key_length(cc);
         if (r < 0 || (uint64_t) r != key_size)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Key size of selected cipher doesn't meet our expectations.");
 
@@ -909,27 +913,27 @@ static int luks_validate_home_record(
                 r = crypt_device_to_evp_cipher(cd, &cc);
                 if (r < 0)
                         return r;
-                if (iv_size > INT_MAX || EVP_CIPHER_iv_length(cc) != (int) iv_size)
+                if (iv_size > INT_MAX || sym_EVP_CIPHER_get_iv_length(cc) != (int) iv_size)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "IV size doesn't match.");
 
-                context = EVP_CIPHER_CTX_new();
+                context = sym_EVP_CIPHER_CTX_new();
                 if (!context)
                         return log_oom();
 
-                if (EVP_DecryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
+                if (sym_EVP_DecryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context.");
 
-                decrypted_size = encrypted_size + EVP_CIPHER_key_length(cc) * 2;
+                decrypted_size = encrypted_size + sym_EVP_CIPHER_get_key_length(cc) * 2;
                 decrypted = new(char, decrypted_size);
                 if (!decrypted)
                         return log_oom();
 
-                if (EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
+                if (sym_EVP_DecryptUpdate(context, (uint8_t*) decrypted, &decrypted_size_out1, encrypted, encrypted_size) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt JSON record.");
 
                 assert((size_t) decrypted_size_out1 <= decrypted_size);
 
-                if (EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
+                if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) decrypted + decrypted_size_out1, &decrypted_size_out2) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish decryption of JSON record.");
 
                 assert((size_t) decrypted_size_out1 + (size_t) decrypted_size_out2 < decrypted_size);
@@ -990,8 +994,8 @@ static int format_luks_token_text(
         if (r < 0)
                 return r;
 
-        key_size = EVP_CIPHER_key_length(cc);
-        iv_size = EVP_CIPHER_iv_length(cc);
+        key_size = sym_EVP_CIPHER_get_key_length(cc);
+        iv_size = sym_EVP_CIPHER_get_iv_length(cc);
 
         if (iv_size > 0) {
                 iv = malloc(iv_size);
@@ -1003,11 +1007,11 @@ static int format_luks_token_text(
                         return log_error_errno(r, "Failed to generate IV: %m");
         }
 
-        context = EVP_CIPHER_CTX_new();
+        context = sym_EVP_CIPHER_CTX_new();
         if (!context)
                 return log_oom();
 
-        if (EVP_EncryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
+        if (sym_EVP_EncryptInit_ex(context, cc, NULL, volume_key, iv) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context.");
 
         r = sd_json_variant_format(hr->json, 0, &text);
@@ -1021,12 +1025,12 @@ static int format_luks_token_text(
         if (!encrypted)
                 return log_oom();
 
-        if (EVP_EncryptUpdate(context, encrypted, &encrypted_size_out1, (uint8_t*) text, text_length) != 1)
+        if (sym_EVP_EncryptUpdate(context, encrypted, &encrypted_size_out1, (uint8_t*) text, text_length) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt JSON record.");
 
         assert((size_t) encrypted_size_out1 <= encrypted_size);
 
-        if (EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
+        if (sym_EVP_EncryptFinal_ex(context, (uint8_t*) encrypted + encrypted_size_out1, &encrypted_size_out2) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finish encryption of JSON record.");
 
         assert((size_t) encrypted_size_out1 + (size_t) encrypted_size_out2 <= encrypted_size);
index b051bf580c803621e55f9f8a4c81638e27bf237b..53c5675c83f881196f1f2c509f2b4392eb9837de 100644 (file)
@@ -65,7 +65,7 @@ executables += [
                 'extract' : systemd_homed_extract_sources,
                 'dependencies' : [
                         libm,
-                        libopenssl,
+                        libopenssl_cflags,
                         threads,
                 ],
         },
@@ -76,7 +76,7 @@ executables += [
                 'dependencies' : [
                         libblkid_cflags,
                         libfdisk_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         libp11kit_cflags,
                         threads,
                 ],
@@ -88,7 +88,7 @@ executables += [
                 'objects' : ['systemd-homed'],
                 'dependencies' : [
                         libdl,
-                        libopenssl,
+                        libopenssl_cflags,
                         libp11kit_cflags,
                         threads,
                 ],
index 7a80ef1e7ab9153f873602cb5e560e43c75fd77c..6bc97af27a675d63a004b429487aa432ea54294b 100644 (file)
@@ -1,9 +1,9 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "alloc-util.h"
+#include "crypto-util.h"
 #include "json-util.h"
 #include "log.h"
-#include "openssl-util.h"
 #include "user-record-sign.h"
 #include "user-record.h"
 
@@ -118,14 +118,14 @@ int user_record_verify(UserRecord *ur, EVP_PKEY *public_key) {
                 if (r < 0)
                         return r;
 
-                md_ctx = EVP_MD_CTX_new();
+                md_ctx = sym_EVP_MD_CTX_new();
                 if (!md_ctx)
                         return -ENOMEM;
 
-                if (EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, public_key) <= 0)
+                if (sym_EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, public_key) <= 0)
                         return -EIO;
 
-                if (EVP_DigestVerify(md_ctx, signature, signature_size, (uint8_t*) text, strlen(text)) <= 0) {
+                if (sym_EVP_DigestVerify(md_ctx, signature, signature_size, (uint8_t*) text, strlen(text)) <= 0) {
                         n_bad++;
                         continue;
                 }
index 3007d00b01d0102b3cd682169f107af28d122730..673c7b2b372aa5df55d8d817548ea8fe9e20b4c4 100644 (file)
@@ -1,8 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <openssl/evp.h>
-
 #include "shared-forward.h"
 
 int user_record_sign(UserRecord *ur, EVP_PKEY *private_key, UserRecord **ret);
index 63e632a6cd1fb1f90a7b885378b73bd44902423d..c2879c5d843cfc0e581a9f283ae3574e6daf16f9 100644 (file)
@@ -31,7 +31,7 @@ executables += [
                         'pull-tar.c',
                 ),
                 'objects' : ['systemd-importd'],
-                'dependencies' : libopenssl,
+                'dependencies' : libopenssl_cflags,
         },
         libexec_template + {
                 'name' : 'systemd-import',
index ac921addb28aa7068a9cca8884466e14405ec1a3..49f87bcac44e24fffc76281a03227bd9c14f6b1b 100644 (file)
@@ -10,6 +10,7 @@
 #include "fd-util.h"
 #include "hexdecoct.h"
 #include "io-util.h"
+#include "iovec-util.h"
 #include "log.h"
 #include "memory-util.h"
 #include "os-util.h"
index 69346ff4778fe58ab97f8e2e852b2dffee58c17a..4c3fb05dd3533a18002d4e6b3f104cf5748a7f6b 100644 (file)
@@ -6,6 +6,8 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "compress.h"
+#include "crypto-util.h"
 #include "curl-util.h"
 #include "fd-util.h"
 #include "format-util.h"
@@ -57,7 +59,7 @@ PullJob* pull_job_unref(PullJob *j) {
         j->compress = compressor_free(j->compress);
 
         if (j->checksum_ctx)
-                EVP_MD_CTX_free(j->checksum_ctx);
+                sym_EVP_MD_CTX_free(j->checksum_ctx);
 
         free(j->url);
         free(j->etag);
@@ -138,7 +140,7 @@ int pull_job_restart(PullJob *j, const char *new_url) {
         j->compress = compressor_free(j->compress);
 
         if (j->checksum_ctx) {
-                EVP_MD_CTX_free(j->checksum_ctx);
+                sym_EVP_MD_CTX_free(j->checksum_ctx);
                 j->checksum_ctx = NULL;
         }
 
@@ -279,7 +281,7 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
                         goto finish;
                 }
 
-                r = EVP_DigestFinal_ex(j->checksum_ctx, j->checksum.iov_base, &checksum_len);
+                r = sym_EVP_DigestFinal_ex(j->checksum_ctx, j->checksum.iov_base, &checksum_len);
                 if (r == 0) {
                         r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get checksum.");
                         goto finish;
@@ -294,7 +296,7 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
                                 goto finish;
                         }
 
-                        log_debug("%s of %s is %s.", EVP_MD_CTX_get0_name(j->checksum_ctx), pull_job_description(j), h);
+                        log_debug("%s of %s is %s.", sym_EVP_MD_CTX_get0_name(j->checksum_ctx), pull_job_description(j), h);
                 }
 
                 if (iovec_is_set(&j->expected_checksum) &&
@@ -448,7 +450,7 @@ static int pull_job_write_compressed(PullJob *j, const struct iovec *data) {
                                        "Content length incorrect.");
 
         if (j->checksum_ctx) {
-                r = EVP_DigestUpdate(j->checksum_ctx, data->iov_base, data->iov_len);
+                r = sym_EVP_DigestUpdate(j->checksum_ctx, data->iov_base, data->iov_len);
                 if (r == 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                                "Could not hash chunk.");
@@ -485,11 +487,15 @@ static int pull_job_open_disk(PullJob *j) {
         }
 
         if (j->calc_checksum) {
-                j->checksum_ctx = EVP_MD_CTX_new();
+                r = dlopen_libcrypto(LOG_ERR);
+                if (r < 0)
+                        return r;
+
+                j->checksum_ctx = sym_EVP_MD_CTX_new();
                 if (!j->checksum_ctx)
                         return log_oom();
 
-                r = EVP_DigestInit_ex(j->checksum_ctx, EVP_sha256(), NULL);
+                r = sym_EVP_DigestInit_ex(j->checksum_ctx, sym_EVP_sha256(), NULL);
                 if (r == 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                                "Failed to initialize hash context.");
index 1daa006c1c373d47a12102c502dbc2a4a8ef3892..0b878292f096b7b7922fb60f7dcd596032f01f88 100644 (file)
@@ -3,9 +3,8 @@
 
 #include <curl/curl.h>
 #include <sys/stat.h>
+#include <sys/uio.h>
 
-#include "compress.h"
-#include "openssl-util.h"
 #include "shared-forward.h"
 
 typedef struct CurlGlue CurlGlue;
index f4878e3c87d31f81de220008b98ad7561b0bf105..acea93b09de9a6fc3741009915e8ba4bc090e3ba 100644 (file)
@@ -31,6 +31,7 @@
 #include "pull-oci.h"
 #include "rm-rf.h"
 #include "set.h"
+#include "sha256-fundamental.h"
 #include "signal-util.h"
 #include "stat-util.h"
 #include "string-util.h"
index 6fde8c5f8bcccdbab1062eb280e693865a5793bf..0ddde7c0919625f0a741cc78a464a7994ba6ace9 100644 (file)
@@ -13,6 +13,7 @@
 #include "import-common.h"
 #include "import-util.h"
 #include "install-file.h"
+#include "iovec-util.h"
 #include "log.h"
 #include "mkdir-label.h"
 #include "pull-common.h"
index dcdd26422674fedcc1d895cadf511a18302f14f6..01f27dcdedcc5241bcccf5fcc621de0b2cb08bff 100644 (file)
@@ -3,13 +3,13 @@
 #include "alloc-util.h"
 #include "ask-password-api.h"
 #include "build.h"
+#include "crypto-util.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "format-table.h"
 #include "fs-util.h"
 #include "log.h"
 #include "main-func.h"
-#include "openssl-util.h"
 #include "options.h"
 #include "parse-argument.h"
 #include "pretty-print.h"
@@ -240,6 +240,10 @@ static int verb_extract_public(int argc, char *argv[], uintptr_t _data, void *us
                                 return r;
                 }
 
+                r = dlopen_libcrypto(LOG_ERR);
+                if (r < 0)
+                        return r;
+
                 r = openssl_load_x509_certificate(
                                 arg_certificate_source_type,
                                 arg_certificate_source,
@@ -248,7 +252,7 @@ static int verb_extract_public(int argc, char *argv[], uintptr_t _data, void *us
                 if (r < 0)
                         return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
 
-                public_key = X509_get_pubkey(certificate);
+                public_key = sym_X509_get_pubkey(certificate);
                 if (!public_key)
                         return log_error_errno(
                                         SYNTHETIC_ERRNO(EIO),
@@ -288,7 +292,7 @@ static int verb_extract_public(int argc, char *argv[], uintptr_t _data, void *us
         } else
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "One of --certificate=, or --private-key= must be specified");
 
-        if (PEM_write_PUBKEY(stdout, public_key) == 0)
+        if (sym_PEM_write_PUBKEY(stdout, public_key) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key to stdout");
 
         return 0;
@@ -317,7 +321,7 @@ static int verb_extract_certificate(int argc, char *argv[], uintptr_t _data, voi
         if (r < 0)
                 return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
 
-        if (PEM_write_X509(stdout, certificate) == 0)
+        if (sym_PEM_write_X509(stdout, certificate) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write certificate to stdout.");
 
         return 0;
@@ -376,18 +380,18 @@ static int verb_pkcs7(int argc, char *argv[], uintptr_t _data, void *userdata) {
                 if (content_len == 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Content file %s is empty", arg_content);
 
-                if (!PKCS7_content_new(pkcs7, NID_pkcs7_data))
+                if (!sym_PKCS7_content_new(pkcs7, NID_pkcs7_data))
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Error creating new PKCS7 content field");
 
-                ASN1_STRING_set0(pkcs7->d.sign->contents->d.data, TAKE_PTR(content), content_len);
+                sym_ASN1_STRING_set0(pkcs7->d.sign->contents->d.data, TAKE_PTR(content), content_len);
         } else
-                if (PKCS7_set_detached(pkcs7, true) == 0)
+                if (sym_PKCS7_set_detached(pkcs7, true) == 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO),
                                                "Failed to set PKCS#7 detached attribute: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         /* Add PKCS1 signature to PKCS7_SIGNER_INFO */
-        ASN1_STRING_set0(signer_info->enc_digest, TAKE_PTR(pkcs1), pkcs1_len);
+        sym_ASN1_STRING_set0(signer_info->enc_digest, TAKE_PTR(pkcs1), pkcs1_len);
 
         _cleanup_fclose_ FILE *output = NULL;
         _cleanup_(unlink_and_freep) char *tmp = NULL;
@@ -395,9 +399,9 @@ static int verb_pkcs7(int argc, char *argv[], uintptr_t _data, void *userdata) {
         if (r < 0)
                 return log_error_errno(r, "Failed to open temporary file: %m");
 
-        if (!i2d_PKCS7_fp(output, pkcs7))
+        if (!sym_i2d_PKCS7_fp(output, pkcs7))
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write PKCS#7 file: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         r = flink_tmpfile(output, tmp, arg_output, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
         if (r < 0)
index 956f6039895de804b634bceaa1f339c18acca0ad..ae3db9a276cf30118543f7a150415ab612c0d01a 100644 (file)
@@ -7,6 +7,6 @@ executables += [
                         'HAVE_OPENSSL',
                 ],
                 'sources' : files('keyutil.c'),
-                'dependencies' : libopenssl,
+                'dependencies' : libopenssl_cflags,
         },
 ]
index 09c04d888c8338abb7e341f9917f7927281b175c..44619cab7db4bd8b1b224aec543534c62dd29bbe 100644 (file)
@@ -7,6 +7,7 @@
 #include "alloc-util.h"
 #include "ask-password-api.h"
 #include "build.h"
+#include "crypto-util.h"
 #include "efi-loader.h"
 #include "efivars.h"
 #include "fd-util.h"
@@ -15,7 +16,6 @@
 #include "hexdecoct.h"
 #include "log.h"
 #include "main-func.h"
-#include "openssl-util.h"
 #include "options.h"
 #include "pager.h"
 #include "parse-argument.h"
@@ -178,11 +178,15 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
                             "Select TPM bank (SHA1, SHA256, SHA384, SHA512)"): {
                         const EVP_MD *implementation;
 
-                        implementation = EVP_get_digestbyname(arg);
+                        r = dlopen_libcrypto(LOG_ERR);
+                        if (r < 0)
+                                return r;
+
+                        implementation = sym_EVP_get_digestbyname(arg);
                         if (!implementation)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", arg);
 
-                        if (strv_extend(&arg_banks, EVP_MD_name(implementation)) < 0)
+                        if (strv_extend(&arg_banks, sym_EVP_MD_get0_name(implementation)) < 0)
                                 return log_oom();
 
                         break;
@@ -529,7 +533,7 @@ static void evp_md_ctx_free_all(EVP_MD_CTX **md[]) {
                 return;
 
         for (size_t i = 0; (*md)[i]; i++)
-                EVP_MD_CTX_free((*md)[i]);
+                sym_EVP_MD_CTX_free((*md)[i]);
 
         *md = mfree(*md);
 }
@@ -546,22 +550,22 @@ static int pcr_state_extend(PcrState *pcr_state, const void *data, size_t sz) {
 
         /* Extends a (virtual) PCR by the given data */
 
-        mc = EVP_MD_CTX_new();
+        mc = sym_EVP_MD_CTX_new();
         if (!mc)
                 return log_oom();
 
-        if (EVP_DigestInit_ex(mc, pcr_state->md, NULL) != 1)
+        if (sym_EVP_DigestInit_ex(mc, pcr_state->md, NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize %s context.", pcr_state->bank);
 
         /* First thing we do, is hash the old PCR value */
-        if (EVP_DigestUpdate(mc, pcr_state->value, pcr_state->value_size) != 1)
+        if (sym_EVP_DigestUpdate(mc, pcr_state->value, pcr_state->value_size) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
 
         /* Then, we hash the new data */
-        if (EVP_DigestUpdate(mc, data, sz) != 1)
+        if (sym_EVP_DigestUpdate(mc, data, sz) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
 
-        if (EVP_DigestFinal_ex(mc, pcr_state->value, &value_size) != 1)
+        if (sym_EVP_DigestFinal_ex(mc, pcr_state->value, &value_size) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize hash context.");
 
         assert(value_size == pcr_state->value_size);
@@ -629,11 +633,11 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
                         return log_oom();
 
                 for (size_t i = 0; i < n; i++) {
-                        mdctx[i] = EVP_MD_CTX_new();
+                        mdctx[i] = sym_EVP_MD_CTX_new();
                         if (!mdctx[i])
                                 return log_oom();
 
-                        if (EVP_DigestInit_ex(mdctx[i], pcr_states[i].md, NULL) != 1)
+                        if (sym_EVP_DigestInit_ex(mdctx[i], pcr_states[i].md, NULL) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                        "Failed to initialize data %s context.", pcr_states[i].bank);
                 }
@@ -648,7 +652,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
                                 break;
 
                         for (size_t i = 0; i < n; i++)
-                                if (EVP_DigestUpdate(mdctx[i], buffer, sz) != 1)
+                                if (sym_EVP_DigestUpdate(mdctx[i], buffer, sz) != 1)
                                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
 
                         m += sz;
@@ -668,7 +672,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
                                 return log_oom();
 
                         /* Measure name of section */
-                        if (EVP_Digest(unified_sections[c], strlen(unified_sections[c]) + 1, data_hash, &data_hash_size, pcr_states[i].md, NULL) != 1)
+                        if (sym_EVP_Digest(unified_sections[c], strlen(unified_sections[c]) + 1, data_hash, &data_hash_size, pcr_states[i].md, NULL) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to hash section name with %s.", pcr_states[i].bank);
 
                         assert(data_hash_size == (unsigned) pcr_states[i].value_size);
@@ -678,7 +682,7 @@ static int measure_kernel(PcrState *pcr_states, size_t n) {
                                 return r;
 
                         /* Retrieve hash of data and measure it */
-                        if (EVP_DigestFinal_ex(mdctx[i], data_hash, &data_hash_size) != 1)
+                        if (sym_EVP_DigestFinal_ex(mdctx[i], data_hash, &data_hash_size) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize hash context.");
 
                         assert(data_hash_size == (unsigned) pcr_states[i].value_size);
@@ -719,7 +723,7 @@ static int measure_phase(PcrState *pcr_states, size_t n, const char *phase) {
                         _cleanup_free_ void *b = NULL;
                         int bsz;
 
-                        bsz = EVP_MD_size(pcr_states[i].md);
+                        bsz = sym_EVP_MD_get_size(pcr_states[i].md);
                         assert(bsz > 0);
 
                         b = malloc(bsz);
@@ -727,7 +731,7 @@ static int measure_phase(PcrState *pcr_states, size_t n, const char *phase) {
                                 return log_oom();
 
                         /* First hash the word itself */
-                        if (EVP_Digest(*word, wl, b, NULL, pcr_states[i].md, NULL) != 1)
+                        if (sym_EVP_Digest(*word, wl, b, NULL, pcr_states[i].md, NULL) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash word '%s'.", *word);
 
                         /* And then extend the PCR with the resulting hash */
@@ -757,13 +761,13 @@ static int pcr_states_allocate(PcrState **ret) {
                 _cleanup_free_ char *b = NULL;
                 int sz;
 
-                assert_se(implementation = EVP_get_digestbyname(*d)); /* Must work, we already checked while parsing  command line */
+                assert_se(implementation = sym_EVP_get_digestbyname(*d)); /* Must work, we already checked while parsing  command line */
 
-                b = strdup(EVP_MD_name(implementation));
+                b = strdup(sym_EVP_MD_get0_name(implementation));
                 if (!b)
                         return log_oom();
 
-                sz = EVP_MD_size(implementation);
+                sz = sym_EVP_MD_get_size(implementation);
                 if (sz <= 0 || sz >= INT_MAX)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unexpected digest size: %i", sz);
 
@@ -986,11 +990,11 @@ static int build_policy_digest(bool sign) {
                 if (!pubkeyf)
                         return log_error_errno(errno, "Failed to open public key file '%s': %m", arg_public_key);
 
-                pubkey = PEM_read_PUBKEY(pubkeyf, NULL, NULL, NULL);
+                pubkey = sym_PEM_read_PUBKEY(pubkeyf, NULL, NULL, NULL);
                 if (!pubkey)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key);
         } else if (certificate) {
-                pubkey = X509_get_pubkey(certificate);
+                pubkey = sym_X509_get_pubkey(certificate);
                 if (!pubkey)
                         return log_error_errno(
                                         SYNTHETIC_ERRNO(EIO),
@@ -1026,7 +1030,7 @@ static int build_policy_digest(bool sign) {
                 for (size_t i = 0; i < n; i++) {
                         PcrState *p = pcr_states + i;
 
-                        int tpmalg = tpm2_hash_alg_from_string(EVP_MD_name(p->md));
+                        int tpmalg = tpm2_hash_alg_from_string(sym_EVP_MD_get0_name(p->md));
                         if (tpmalg < 0)
                                 return log_error_errno(tpmalg, "Unsupported PCR bank");
 
@@ -1044,19 +1048,19 @@ static int build_policy_digest(bool sign) {
                         size_t ss = 0;
                         if (privkey) {
                                 /* We always use SHA256 for signing currently. Regardless of the bank. */
-                                const EVP_MD *sha256 = ASSERT_PTR(EVP_get_digestbyname("sha256"));
+                                const EVP_MD *sha256 = ASSERT_PTR(sym_EVP_get_digestbyname("sha256"));
 
                                 r = digest_and_sign(sha256, privkey, pcr_policy_digest.buffer, pcr_policy_digest.size, &sig, &ss);
                                 if (r == -EADDRNOTAVAIL)
-                                        return log_error_errno(r, "Hash algorithm '%s' not available while signing. (Maybe OS security policy disables this algorithm?)", EVP_MD_name(p->md));
+                                        return log_error_errno(r, "Hash algorithm '%s' not available while signing. (Maybe OS security policy disables this algorithm?)", sym_EVP_MD_get0_name(p->md));
                                 if (r < 0)
-                                        return log_error_errno(r, "Failed to sign PCR policy with hash algorithm '%s': %m", EVP_MD_name(p->md));
+                                        return log_error_errno(r, "Failed to sign PCR policy with hash algorithm '%s': %m", sym_EVP_MD_get0_name(p->md));
                         }
 
                         _cleanup_free_ void *pubkey_fp = NULL;
                         size_t pubkey_fp_size = 0;
                         if (pubkey) {
-                                r = pubkey_fingerprint(pubkey, EVP_sha256(), &pubkey_fp, &pubkey_fp_size);
+                                r = pubkey_fingerprint(pubkey, sym_EVP_sha256(), &pubkey_fp, &pubkey_fp_size);
                                 if (r < 0)
                                         return r;
                         }
@@ -1121,6 +1125,10 @@ static int run(int argc, char *argv[]) {
         if (r <= 0)
                 return r;
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         return dispatch_verb_with_args(args, NULL);
 }
 
index e4e4f579dfa0639fc6c8fdb211f93c6d94c5d171..ff777dc5d9842e8642ee7c23dd79e81de1f270c9 100644 (file)
@@ -9,6 +9,6 @@ executables += [
                         'HAVE_TPM2',
                 ],
                 'sources' : files('measure-tool.c'),
-                'dependencies' : libopenssl,
+                'dependencies' : libopenssl_cflags,
         },
 ]
index 3a8824eaa84444288b0494740cbe7bd69acd4f54..f2f5f3b46e3e89dcc2d7db49c76178c0923ff903 100644 (file)
@@ -11,7 +11,7 @@ executables += [
                 ],
                 'sources' : files('pcrextend.c'),
                 'dependencies' : [
-                        libopenssl,
+                        libopenssl_cflags,
                         tpm2,
                 ],
         },
index 639331ba97dc8135c0cc3752097872806840013c..c92d3f981124acb95f9de93eb05dbefb94f087d7 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "alloc-util.h"
 #include "build.h"
+#include "crypto-util.h"
 #include "efi-loader.h"
 #include "escape.h"
 #include "format-table.h"
@@ -96,11 +97,15 @@ static int parse_argv(int argc, char *argv[], char ***ret_args) {
                 OPTION_LONG("bank", "DIGEST", "Select TPM PCR bank (SHA1, SHA256)"): {
                         const EVP_MD *implementation;
 
-                        implementation = EVP_get_digestbyname(arg);
+                        r = dlopen_libcrypto(LOG_ERR);
+                        if (r < 0)
+                                return r;
+
+                        implementation = sym_EVP_get_digestbyname(arg);
                         if (!implementation)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", arg);
 
-                        if (strv_extend(&arg_banks, EVP_MD_name(implementation)) < 0)
+                        if (strv_extend(&arg_banks, sym_EVP_MD_get0_name(implementation)) < 0)
                                 return log_oom();
 
                         break;
index c5b609ed4aa676e731d77609c69c4f3c24db15f0..a80cd31947977bc4d7da8caf776a554646af2715 100644 (file)
@@ -13,7 +13,7 @@ executables += [
                 ),
                 'dependencies' : [
                         libm,
-                        libopenssl,
+                        libopenssl_cflags,
                         tpm2,
                 ],
                 'public' : true,
index 81481dc168968d0cf663794f096f29cbdf362396..5abf66077e7e4ded042a0de91d396edef003bbb3 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <openssl/evp.h>
-
+#include "crypto-util.h"
 #include "log.h"
 #include "memory-util.h"
 #include "pcrlock-firmware.h"
@@ -149,13 +148,13 @@ int validate_firmware_header(
                         continue;
                 }
 
-                implementation = EVP_get_digestbyname(a);
+                implementation = sym_EVP_get_digestbyname(a);
                 if (!implementation) {
                         log_notice("Event log advertises hash algorithm '%s' we don't implement, can't validate.", a);
                         continue;
                 }
 
-                if (EVP_MD_size(implementation) !=  id->digestSizes[i].digestSize)
+                if (sym_EVP_MD_get_size(implementation) !=  id->digestSizes[i].digestSize)
                         return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Advertised digest size for '%s' is wrong, refusing.", a);
         }
 
index 62a84a26cb688feccf2c962440575e55760edf5c..ecf7b18c351bfbf153c08335c53bc43864216421 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <openssl/evp.h>
 #include <sys/file.h>
 #include <unistd.h>
 
@@ -18,6 +17,7 @@
 #include "color-util.h"
 #include "conf-files.h"
 #include "creds-util.h"
+#include "crypto-util.h"
 #include "efi-api.h"
 #include "efivars.h"
 #include "env-util.h"
@@ -1346,7 +1346,7 @@ static int event_log_calculate_pcrs(EventLog *el) {
                 const char *a;
 
                 assert_se(a = tpm2_hash_alg_to_string(el->algorithms[i]));
-                assert_se(md = EVP_get_digestbyname(a));
+                assert_se(md = sym_EVP_get_digestbyname(a));
 
                 el->mds[i] = md;
         }
@@ -1354,7 +1354,7 @@ static int event_log_calculate_pcrs(EventLog *el) {
         for (uint32_t pcr = 0; pcr < TPM2_PCRS_MAX; pcr++)
                 for (size_t i = 0; i < el->n_algorithms; i++) {
                         EventLogRegisterBank *b = el->registers[pcr].banks + i;
-                        event_log_initial_pcr_state(el, pcr, EVP_MD_size(el->mds[i]), &b->calculated);
+                        event_log_initial_pcr_state(el, pcr, sym_EVP_MD_get_size(el->mds[i]), &b->calculated);
                 }
 
         FOREACH_ARRAY(rr, el->records, el->n_records) {
@@ -1379,20 +1379,20 @@ static int event_log_calculate_pcrs(EventLog *el) {
 
                         reg_b = reg->banks + i;
 
-                        mc = EVP_MD_CTX_new();
+                        mc = sym_EVP_MD_CTX_new();
                         if (!mc)
                                 return log_oom();
 
-                        if (EVP_DigestInit_ex(mc, el->mds[i], NULL) != 1)
+                        if (sym_EVP_DigestInit_ex(mc, el->mds[i], NULL) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize %s message digest context.", n);
 
-                        if (EVP_DigestUpdate(mc, reg_b->calculated.buffer, reg_b->calculated.size) != 1)
+                        if (sym_EVP_DigestUpdate(mc, reg_b->calculated.buffer, reg_b->calculated.size) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
 
-                        if (EVP_DigestUpdate(mc, rec_b->hash.buffer, rec_b->hash.size) != 1)
+                        if (sym_EVP_DigestUpdate(mc, rec_b->hash.buffer, rec_b->hash.size) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to run digest.");
 
-                        if (EVP_DigestFinal_ex(mc, reg_b->calculated.buffer, &sz) != 1)
+                        if (sym_EVP_DigestFinal_ex(mc, reg_b->calculated.buffer, &sz) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize hash context.");
 
                         assert(sz == reg_b->calculated.size);
@@ -1481,7 +1481,7 @@ static int event_log_record_validate_hash_firmware(
                 strict = false;
         }
 
-        int mdsz = EVP_MD_size(md);
+        int mdsz = sym_EVP_MD_get_size(md);
         assert(mdsz > 0);
         assert((size_t) mdsz <= sizeof_field(TPM2B_DIGEST, buffer));
 
@@ -1491,13 +1491,13 @@ static int event_log_record_validate_hash_firmware(
 
         unsigned dsz = mdsz;
 
-        if (EVP_Digest(hdata, hsz, payload_hash.buffer, &dsz, md, NULL) != 1)
+        if (sym_EVP_Digest(hdata, hsz, payload_hash.buffer, &dsz, md, NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to calculate event payload hash.");
         assert(dsz == (unsigned) mdsz);
 
         /* If this didn't match then let's try the alternative format here, if we have one, and check things then. */
         if (memcmp_nn(bank->hash.buffer, bank->hash.size, payload_hash.buffer, payload_hash.size) != 0 && hdata_alternative) {
-                if (EVP_Digest(hdata_alternative, hsz_alternative, payload_hash.buffer, &dsz, md, NULL) != 1)
+                if (sym_EVP_Digest(hdata_alternative, hsz_alternative, payload_hash.buffer, &dsz, md, NULL) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to calculate event payload hash.");
                 assert(dsz == (unsigned) mdsz);
         }
@@ -1541,7 +1541,7 @@ static int event_log_record_validate_hash_userspace(
         assert(sd_json_variant_is_string(js));
         s = sd_json_variant_string(js);
 
-        mdsz = EVP_MD_size(md);
+        mdsz = sym_EVP_MD_get_size(md);
         assert(mdsz > 0);
 
         payload_hash_size = mdsz;
@@ -1549,7 +1549,7 @@ static int event_log_record_validate_hash_userspace(
         if (!payload_hash)
                 return log_oom();
 
-        if (EVP_Digest(s, strlen(s), payload_hash, &payload_hash_size, md, NULL) != 1)
+        if (sym_EVP_Digest(s, strlen(s), payload_hash, &payload_hash_size, md, NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to calculate event payload hash.");
 
         assert((int) payload_hash_size == mdsz);
@@ -1575,7 +1575,7 @@ static int event_log_validate_record_hashes(EventLog *el) {
                         const char *a;
 
                         assert_se(a = tpm2_hash_alg_to_string(bank->algorithm));
-                        assert_se(md = EVP_get_digestbyname(a));
+                        assert_se(md = sym_EVP_get_digestbyname(a));
 
                         r = event_log_record_validate_hash_firmware(*rr, bank, md);
                         if (r < 0)
@@ -2788,8 +2788,8 @@ static int make_pcrlock_record(
                 const char *a;
 
                 assert_se(a = tpm2_hash_alg_to_string(*pa));
-                assert_se(md = EVP_get_digestbyname(a));
-                hash_ssize = EVP_MD_size(md);
+                assert_se(md = sym_EVP_get_digestbyname(a));
+                hash_ssize = sym_EVP_MD_get_size(md);
                 assert(hash_ssize > 0);
                 hash_usize = hash_ssize;
 
@@ -2797,7 +2797,7 @@ static int make_pcrlock_record(
                 if (!hash)
                         return log_oom();
 
-                if (EVP_Digest(data, data_size, hash, &hash_usize, md, NULL) != 1)
+                if (sym_EVP_Digest(data, data_size, hash, &hash_usize, md, NULL) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data with algorithm '%s'.", a);
 
                 r = sd_json_variant_append_arraybo(
@@ -2821,7 +2821,7 @@ static void evp_md_ctx_free_all(EVP_MD_CTX *(*md)[TPM2_N_HASH_ALGORITHMS]) {
         assert(md);
         FOREACH_ARRAY(alg, *md, TPM2_N_HASH_ALGORITHMS)
                 if (*alg)
-                        EVP_MD_CTX_free(*alg);
+                        sym_EVP_MD_CTX_free(*alg);
 }
 
 static int make_pcrlock_record_from_stream(
@@ -2841,13 +2841,13 @@ static int make_pcrlock_record_from_stream(
                 const EVP_MD *md;
 
                 assert_se(a = tpm2_hash_alg_to_string(tpm2_hash_algorithms[i]));
-                assert_se(md = EVP_get_digestbyname(a));
+                assert_se(md = sym_EVP_get_digestbyname(a));
 
-                mdctx[i] = EVP_MD_CTX_new();
+                mdctx[i] = sym_EVP_MD_CTX_new();
                 if (!mdctx[i])
                         return log_oom();
 
-                if (EVP_DigestInit_ex(mdctx[i], md, NULL) != 1)
+                if (sym_EVP_DigestInit_ex(mdctx[i], md, NULL) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                                "Failed to initialize message digest for %s.", a);
         }
@@ -2863,7 +2863,7 @@ static int make_pcrlock_record_from_stream(
                         break;
 
                 for (size_t i = 0; i < TPM2_N_HASH_ALGORITHMS; i++)
-                        if (EVP_DigestUpdate(mdctx[i], buffer, n) != 1)
+                        if (sym_EVP_DigestUpdate(mdctx[i], buffer, n) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
         }
 
@@ -2873,12 +2873,12 @@ static int make_pcrlock_record_from_stream(
                 unsigned hash_usize;
 
                 assert_se(a = tpm2_hash_alg_to_string(tpm2_hash_algorithms[i]));
-                hash_ssize = EVP_MD_CTX_size(mdctx[i]);
+                hash_ssize = sym_EVP_MD_CTX_get_size(mdctx[i]);
                 assert(hash_ssize > 0 && hash_ssize <= EVP_MAX_MD_SIZE);
                 hash_usize = hash_ssize;
                 unsigned char hash[hash_usize];
 
-                if (EVP_DigestFinal_ex(mdctx[i], hash, &hash_usize) != 1)
+                if (sym_EVP_DigestFinal_ex(mdctx[i], hash, &hash_usize) != 1)
                         return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                                "Failed to finalize hash context for algorithn '%s'.", a);
 
@@ -3072,7 +3072,7 @@ static const EVP_MD* evp_from_tpm2_alg(uint16_t alg) {
         if (!name)
                 return NULL;
 
-        return EVP_get_digestbyname(name);
+        return sym_EVP_get_digestbyname(name);
 }
 
 static int event_log_component_variant_calculate(
@@ -3106,13 +3106,13 @@ static int event_log_component_variant_calculate(
                                 continue;
                         }
 
-                        md_ctx = EVP_MD_CTX_new();
+                        md_ctx = sym_EVP_MD_CTX_new();
                         if (!md_ctx)
                                 return log_oom();
 
                         const EVP_MD *md = ASSERT_PTR(evp_from_tpm2_alg(tpm2_hash_algorithms[i]));
 
-                        int sz = EVP_MD_size(md);
+                        int sz = sym_EVP_MD_get_size(md);
                         assert(sz > 0);
                         assert((size_t) sz <= sizeof_field(TPM2B_DIGEST, buffer));
 
@@ -3121,17 +3121,17 @@ static int event_log_component_variant_calculate(
                         assert(result->hash[i].size == (size_t) sz);
                         assert(b->hash.size == (size_t) sz);
 
-                        if (EVP_DigestInit_ex(md_ctx, md, NULL) != 1)
+                        if (sym_EVP_DigestInit_ex(md_ctx, md, NULL) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to initialize message digest.");
 
-                        if (EVP_DigestUpdate(md_ctx, result->hash[i].buffer, sz) != 1)
+                        if (sym_EVP_DigestUpdate(md_ctx, result->hash[i].buffer, sz) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash bank value.");
 
-                        if (EVP_DigestUpdate(md_ctx, b->hash.buffer, sz) != 1)
+                        if (sym_EVP_DigestUpdate(md_ctx, b->hash.buffer, sz) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data value.");
 
                         unsigned l = (unsigned) sz;
-                        if (EVP_DigestFinal_ex(md_ctx, result->hash[i].buffer, &l) != 1)
+                        if (sym_EVP_DigestFinal_ex(md_ctx, result->hash[i].buffer, &l) != 1)
                                 return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to finalize message digest.");
 
                         assert(l == (unsigned) sz);
@@ -4749,7 +4749,7 @@ static int verb_lock_pe(int argc, char *argv[], uintptr_t _data, void *userdata)
                         const char *a;
 
                         assert_se(a = tpm2_hash_alg_to_string(*pa));
-                        assert_se(md = EVP_get_digestbyname(a));
+                        assert_se(md = sym_EVP_get_digestbyname(a));
 
                         r = pe_hash(fd < 0 ? STDIN_FILENO : fd, md, &hash, &hash_size);
                         if (r < 0)
@@ -4813,7 +4813,7 @@ static int verb_lock_uki(int argc, char *argv[], uintptr_t _data, void *userdata
                 const char *a;
 
                 assert_se(a = tpm2_hash_alg_to_string(tpm2_hash_algorithms[i]));
-                assert_se(md = EVP_get_digestbyname(a));
+                assert_se(md = sym_EVP_get_digestbyname(a));
 
                 r = pe_hash(fd < 0 ? STDIN_FILENO : fd, md, &peh, hash_sizes + i);
                 if (r < 0)
@@ -5472,6 +5472,10 @@ static int run(int argc, char *argv[]) {
         if (r <= 0)
                 return r;
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         if (arg_varlink) {
                 _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
 
index b7c70be068574772f1d6aa6a6a1497bd8a0fbdb9..9b89f56f7a0f252144e37f360616d25373f56e88 100644 (file)
@@ -16,7 +16,7 @@ executables += [
                         libblkid_cflags,
                         libfdisk_cflags,
                         libmount_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         threads,
                 ],
         },
@@ -34,7 +34,7 @@ executables += [
                         libblkid_cflags,
                         libfdisk_cflags,
                         libmount_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         threads,
                 ],
         },
index e5853137132368844424a831856fcedfab1d665e..0aab755d2cf25d4c83fa338b95e481f2651be734 100644 (file)
@@ -24,6 +24,7 @@
 #include "conf-parser.h"
 #include "constants.h"
 #include "copy.h"
+#include "crypto-util.h"
 #include "cryptsetup-util.h"
 #include "device-util.h"
 #include "devnum-util.h"
@@ -59,7 +60,6 @@
 #include "mount-util.h"
 #include "mountpoint-util.h"
 #include "nulstr-util.h"
-#include "openssl-util.h"
 #include "options.h"
 #include "parse-argument.h"
 #include "parse-helpers.h"
@@ -985,9 +985,11 @@ static Context* context_free(Context *context) {
                 free(context->node);
 
 #if HAVE_OPENSSL
-        X509_free(context->certificate);
+        if (context->certificate)
+                sym_X509_free(context->certificate);
         openssl_ask_password_ui_free(context->ui);
-        EVP_PKEY_free(context->private_key);
+        if (context->private_key)
+                sym_EVP_PKEY_free(context->private_key);
 #endif
 
         context->link = sd_varlink_unref(context->link);
@@ -5826,7 +5828,7 @@ static int sign_verity_roothash(
         _cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
         _cleanup_free_ char *hex = NULL;
         _cleanup_free_ uint8_t *sig = NULL;
-        int sigsz;
+        int sigsz, r;
 
         assert(context);
         assert(context->certificate);
@@ -5835,23 +5837,27 @@ static int sign_verity_roothash(
         assert(iovec_is_set(roothash));
         assert(ret_signature);
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         hex = hexmem(roothash->iov_base, roothash->iov_len);
         if (!hex)
                 return log_oom();
 
-        rb = BIO_new_mem_buf(hex, -1);
+        rb = sym_BIO_new_mem_buf(hex, -1);
         if (!rb)
                 return log_oom();
 
-        p7 = PKCS7_sign(context->certificate, context->private_key, NULL, rb, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY);
+        p7 = sym_PKCS7_sign(context->certificate, context->private_key, NULL, rb, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY);
         if (!p7)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to calculate PKCS7 signature: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        sigsz = i2d_PKCS7(p7, &sig);
+        sigsz = sym_i2d_PKCS7(p7, &sig);
         if (sigsz < 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret_signature = IOVEC_MAKE(TAKE_PTR(sig), sigsz);
 
index b9b2e24b18123255cce60bedfcb94cc1cbd1b850..5802889746e97e9effcd2f3bb3b4e7efb7c827e6 100644 (file)
@@ -70,7 +70,7 @@ endif
 resolve_common_template = {
         'dependencies' : [
                 libidn2_cflags,
-                libopenssl,
+                libopenssl_cflags,
                 libm,
                 threads,
         ],
index 8cc9e73f93cd527aea6422516b1a9436e43cefaa..1452131b59e7d387018754e16e0fb251b854c512 100644 (file)
@@ -20,6 +20,7 @@
 #include "bus-locator.h"
 #include "bus-message-util.h"
 #include "bus-util.h"
+#include "crypto-util.h"
 #include "dns-configuration.h"
 #include "dns-domain.h"
 #include "dns-packet.h"
@@ -34,7 +35,6 @@
 #include "main-func.h"
 #include "missing-network.h"
 #include "netlink-util.h"
-#include "openssl-util.h"
 #include "ordered-set.h"
 #include "pager.h"
 #include "parse-argument.h"
index 1a634810beafec616416d58a8389d21d7594a4b3..017c370b0eb52f4e627fc7f3929c5496c7723641 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "alloc-util.h"
 #include "bitmap.h"
+#include "crypto-util.h"
 #include "dns-answer.h"
 #include "dns-domain.h"
 #include "dns-rr.h"
 #include "log.h"
 #include "memory-util.h"
 #include "memstream-util.h"
-#include "openssl-util.h"
 #include "resolved-dns-dnssec.h"
 #include "sort-util.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "time-util.h"
 
-#if HAVE_OPENSSL
-DISABLE_WARNING_DEPRECATED_DECLARATIONS;
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(RSA*, RSA_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL);
-REENABLE_WARNING;
-#endif
 
 #define VERIFY_RRS_MAX 256
 #define MAX_KEY_SIZE (32*1024)
@@ -84,49 +78,49 @@ static int dnssec_rsa_verify_raw(
 
         assert(hash_algorithm);
 
-        e = BN_bin2bn(exponent, exponent_size, NULL);
+        e = sym_BN_bin2bn(exponent, exponent_size, NULL);
         if (!e)
                 return -EIO;
 
-        m = BN_bin2bn(modulus, modulus_size, NULL);
+        m = sym_BN_bin2bn(modulus, modulus_size, NULL);
         if (!m)
                 return -EIO;
 
-        rpubkey = RSA_new();
+        rpubkey = sym_RSA_new();
         if (!rpubkey)
                 return -ENOMEM;
 
-        if (RSA_set0_key(rpubkey, m, e, NULL) <= 0)
+        if (sym_RSA_set0_key(rpubkey, m, e, NULL) <= 0)
                 return -EIO;
         e = m = NULL;
 
-        if ((size_t) RSA_size(rpubkey) != signature_size)
+        if ((size_t) sym_RSA_size(rpubkey) != signature_size)
                 return -EINVAL;
 
-        epubkey = EVP_PKEY_new();
+        epubkey = sym_EVP_PKEY_new();
         if (!epubkey)
                 return -ENOMEM;
 
-        if (EVP_PKEY_assign_RSA(epubkey, RSAPublicKey_dup(rpubkey)) <= 0)
+        if (sym_EVP_PKEY_assign_RSA(epubkey, sym_RSAPublicKey_dup(rpubkey)) <= 0)
                 return -EIO;
 
-        ctx = EVP_PKEY_CTX_new(epubkey, NULL);
+        ctx = sym_EVP_PKEY_CTX_new(epubkey, NULL);
         if (!ctx)
                 return -ENOMEM;
 
-        if (EVP_PKEY_verify_init(ctx) <= 0)
+        if (sym_EVP_PKEY_verify_init(ctx) <= 0)
                 return -EIO;
 
-        if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+        if (sym_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
                 return -EIO;
 
-        if (EVP_PKEY_CTX_set_signature_md(ctx, hash_algorithm) <= 0)
+        if (sym_EVP_PKEY_CTX_set_signature_md(ctx, hash_algorithm) <= 0)
                 return -EIO;
 
-        r = EVP_PKEY_verify(ctx, signature, signature_size, data, data_size);
+        r = sym_EVP_PKEY_verify(ctx, signature, signature_size, data, data_size);
         if (r < 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
-                                       "Signature verification failed: 0x%lx", ERR_get_error());
+                                       "Signature verification failed: 0x%lx", sym_ERR_get_error());
 
         REENABLE_WARNING;
         return r;
@@ -207,58 +201,58 @@ static int dnssec_ecdsa_verify_raw(
 
         assert(hash_algorithm);
 
-        ec_group = EC_GROUP_new_by_curve_name(curve);
+        ec_group = sym_EC_GROUP_new_by_curve_name(curve);
         if (!ec_group)
                 return -ENOMEM;
 
-        p = EC_POINT_new(ec_group);
+        p = sym_EC_POINT_new(ec_group);
         if (!p)
                 return -ENOMEM;
 
-        bctx = BN_CTX_new();
+        bctx = sym_BN_CTX_new();
         if (!bctx)
                 return -ENOMEM;
 
-        if (EC_POINT_oct2point(ec_group, p, key, key_size, bctx) <= 0)
+        if (sym_EC_POINT_oct2point(ec_group, p, key, key_size, bctx) <= 0)
                 return -EIO;
 
-        eckey = EC_KEY_new();
+        eckey = sym_EC_KEY_new();
         if (!eckey)
                 return -ENOMEM;
 
-        if (EC_KEY_set_group(eckey, ec_group) <= 0)
+        if (sym_EC_KEY_set_group(eckey, ec_group) <= 0)
                 return -EIO;
 
-        if (EC_KEY_set_public_key(eckey, p) <= 0)
+        if (sym_EC_KEY_set_public_key(eckey, p) <= 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
-                                       "EC_KEY_set_public_key failed: 0x%lx", ERR_get_error());
+                                       "EC_KEY_set_public_key failed: 0x%lx", sym_ERR_get_error());
 
-        if (EC_KEY_check_key(eckey) != 1)
+        if (sym_EC_KEY_check_key(eckey) != 1)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
-                                       "EC_KEY_check_key failed: 0x%lx", ERR_get_error());
+                                       "EC_KEY_check_key failed: 0x%lx", sym_ERR_get_error());
 
-        r = BN_bin2bn(signature_r, signature_r_size, NULL);
+        r = sym_BN_bin2bn(signature_r, signature_r_size, NULL);
         if (!r)
                 return -EIO;
 
-        s = BN_bin2bn(signature_s, signature_s_size, NULL);
+        s = sym_BN_bin2bn(signature_s, signature_s_size, NULL);
         if (!s)
                 return -EIO;
 
         /* TODO: We should eventually use the EVP API once it supports ECDSA signature verification */
 
-        sig = ECDSA_SIG_new();
+        sig = sym_ECDSA_SIG_new();
         if (!sig)
                 return -ENOMEM;
 
-        if (ECDSA_SIG_set0(sig, r, s) <= 0)
+        if (sym_ECDSA_SIG_set0(sig, r, s) <= 0)
                 return -EIO;
         r = s = NULL;
 
-        k = ECDSA_do_verify(data, data_size, sig, eckey);
+        k = sym_ECDSA_do_verify(data, data_size, sig, eckey);
         if (k < 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
-                                       "Signature verification failed: 0x%lx", ERR_get_error());
+                                       "Signature verification failed: 0x%lx", sym_ERR_get_error());
 
         REENABLE_WARNING;
         return k;
@@ -326,30 +320,30 @@ static int dnssec_eddsa_verify_raw(
         q[0] = 0x04; /* Prepend 0x04 to indicate an uncompressed key */
         memcpy(q+1, signature, signature_size);
 
-        evkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, key, key_size);
+        evkey = sym_EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, key, key_size);
         if (!evkey)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
-                                       "EVP_PKEY_new_raw_public_key failed: 0x%lx", ERR_get_error());
+                                       "EVP_PKEY_new_raw_public_key failed: 0x%lx", sym_ERR_get_error());
 
-        pctx = EVP_PKEY_CTX_new(evkey, NULL);
+        pctx = sym_EVP_PKEY_CTX_new(evkey, NULL);
         if (!pctx)
                 return -ENOMEM;
 
-        ctx = EVP_MD_CTX_new();
+        ctx = sym_EVP_MD_CTX_new();
         if (!ctx)
                 return -ENOMEM;
 
         /* This prevents EVP_DigestVerifyInit from managing pctx and complicating our free logic. */
-        EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
+        sym_EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
 
         /* One might be tempted to use EVP_PKEY_verify_init, but see Ed25519(7ssl). */
-        if (EVP_DigestVerifyInit(ctx, &pctx, NULL, NULL, evkey) <= 0)
+        if (sym_EVP_DigestVerifyInit(ctx, &pctx, NULL, NULL, evkey) <= 0)
                 return -EIO;
 
-        r = EVP_DigestVerify(ctx, signature, signature_size, data, data_size);
+        r = sym_EVP_DigestVerify(ctx, signature, signature_size, data, data_size);
         if (r < 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
-                                       "Signature verification failed: 0x%lx", ERR_get_error());
+                                       "Signature verification failed: 0x%lx", sym_ERR_get_error());
 
         return r;
 }
@@ -382,12 +376,12 @@ static int dnssec_eddsa_verify(
 }
 
 static int md_add_uint8(EVP_MD_CTX *ctx, uint8_t v) {
-        return EVP_DigestUpdate(ctx, &v, sizeof(v));
+        return sym_EVP_DigestUpdate(ctx, &v, sizeof(v));
 }
 
 static int md_add_uint16(EVP_MD_CTX *ctx, uint16_t v) {
         v = htobe16(v);
-        return EVP_DigestUpdate(ctx, &v, sizeof(v));
+        return sym_EVP_DigestUpdate(ctx, &v, sizeof(v));
 }
 
 static void fwrite_uint8(FILE *fp, uint8_t v) {
@@ -504,17 +498,17 @@ static const EVP_MD* algorithm_to_implementation_id(uint8_t algorithm) {
 
         case DNSSEC_ALGORITHM_RSASHA1:
         case DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1:
-                return EVP_sha1();
+                return sym_EVP_sha1();
 
         case DNSSEC_ALGORITHM_RSASHA256:
         case DNSSEC_ALGORITHM_ECDSAP256SHA256:
-                return EVP_sha256();
+                return sym_EVP_sha256();
 
         case DNSSEC_ALGORITHM_ECDSAP384SHA384:
-                return EVP_sha384();
+                return sym_EVP_sha384();
 
         case DNSSEC_ALGORITHM_RSASHA512:
-                return EVP_sha512();
+                return sym_EVP_sha512();
 
         default:
                 return NULL;
@@ -645,19 +639,19 @@ static int dnssec_rrset_verify_sig(
                 if (!md_algorithm)
                         return -EOPNOTSUPP;
 
-                _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+                _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = sym_EVP_MD_CTX_new();
                 if (!ctx)
                         return -ENOMEM;
 
                 /* If the signature algorithm is supported by systemd-resolved but disabled by host policy,
                  * also return -EOPNOTSUPP. */
-                if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
+                if (sym_EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
                         return -EOPNOTSUPP;
 
-                if (EVP_DigestUpdate(ctx, sig_data, sig_size) <= 0)
+                if (sym_EVP_DigestUpdate(ctx, sig_data, sig_size) <= 0)
                         return -EIO;
 
-                if (EVP_DigestFinal_ex(ctx, hash, &hash_size) <= 0)
+                if (sym_EVP_DigestFinal_ex(ctx, hash, &hash_size) <= 0)
                         return -EIO;
 
                 assert(hash_size > 0);
@@ -709,6 +703,11 @@ int dnssec_verify_rrset(
         assert(rrsig);
         assert(dnskey);
         assert(result);
+
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         assert(rrsig->key->type == DNS_TYPE_RRSIG);
         assert(dnskey->key->type == DNS_TYPE_DNSKEY);
 
@@ -1041,13 +1040,13 @@ static const EVP_MD* digest_to_hash_md(uint8_t algorithm) {
         switch (algorithm) {
 
         case DNSSEC_DIGEST_SHA1:
-                return EVP_sha1();
+                return sym_EVP_sha1();
 
         case DNSSEC_DIGEST_SHA256:
-                return EVP_sha256();
+                return sym_EVP_sha256();
 
         case DNSSEC_DIGEST_SHA384:
-                return EVP_sha384();
+                return sym_EVP_sha384();
 
         default:
                 return NULL;
@@ -1062,6 +1061,10 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
         assert(dnskey);
         assert(ds);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         /* Implements DNSKEY verification by a DS, according to RFC 4035, section 5.2 */
 
         if (dnskey->key->type != DNS_TYPE_DNSKEY)
@@ -1092,22 +1095,22 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
         _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = NULL;
         uint8_t result[EVP_MAX_MD_SIZE];
 
-        unsigned hash_size = EVP_MD_size(md_algorithm);
+        unsigned hash_size = sym_EVP_MD_get_size(md_algorithm);
         assert(hash_size > 0);
 
         if (ds->ds.digest_size != hash_size)
                 return 0;
 
-        ctx = EVP_MD_CTX_new();
+        ctx = sym_EVP_MD_CTX_new();
         if (!ctx)
                 return -ENOMEM;
 
         /* If the digest is supported by systemd-resolved but disabled by host policy, also return -EOPNOTSUPP
          */
-        if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
+        if (sym_EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
                 return -EOPNOTSUPP;
 
-        if (EVP_DigestUpdate(ctx, wire_format, encoded_length) <= 0)
+        if (sym_EVP_DigestUpdate(ctx, wire_format, encoded_length) <= 0)
                 return -EIO;
 
         if (mask_revoke)
@@ -1121,10 +1124,10 @@ int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds,
         r = md_add_uint8(ctx, dnskey->dnskey.algorithm);
         if (r <= 0)
                 return r;
-        if (EVP_DigestUpdate(ctx, dnskey->dnskey.key, dnskey->dnskey.key_size) <= 0)
+        if (sym_EVP_DigestUpdate(ctx, dnskey->dnskey.key, dnskey->dnskey.key_size) <= 0)
                 return -EIO;
 
-        if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
+        if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
                 return -EIO;
 
         return memcmp(result, ds->ds.digest, ds->ds.digest_size) == 0;
@@ -1183,7 +1186,7 @@ static const EVP_MD* nsec3_hash_to_hash_md(uint8_t algorithm) {
         switch (algorithm) {
 
         case NSEC3_ALGORITHM_SHA1:
-                return EVP_sha1();
+                return sym_EVP_sha1();
 
         default:
                 return NULL;
@@ -1198,6 +1201,10 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
         assert(name);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         if (nsec3->key->type != DNS_TYPE_NSEC3)
                 return -EINVAL;
 
@@ -1210,41 +1217,41 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
         if (!algorithm)
                 return -EOPNOTSUPP;
 
-        size_t hash_size = EVP_MD_size(algorithm);
+        size_t hash_size = sym_EVP_MD_get_size(algorithm);
         assert(hash_size > 0);
 
         if (nsec3->nsec3.next_hashed_name_size != hash_size)
                 return -EINVAL;
 
-        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = sym_EVP_MD_CTX_new();
         if (!ctx)
                 return -ENOMEM;
 
-        if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
+        if (sym_EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
                 return -EOPNOTSUPP;
 
         r = dns_name_to_wire_format(name, wire_format, sizeof(wire_format), true);
         if (r < 0)
                 return r;
 
-        if (EVP_DigestUpdate(ctx, wire_format, r) <= 0)
+        if (sym_EVP_DigestUpdate(ctx, wire_format, r) <= 0)
                 return -EIO;
-        if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
+        if (sym_EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
                 return -EIO;
 
         uint8_t result[EVP_MAX_MD_SIZE];
-        if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
+        if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
                 return -EIO;
 
         for (unsigned k = 0; k < nsec3->nsec3.iterations; k++) {
-                if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
+                if (sym_EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
                         return -EOPNOTSUPP;
-                if (EVP_DigestUpdate(ctx, result, hash_size) <= 0)
+                if (sym_EVP_DigestUpdate(ctx, result, hash_size) <= 0)
                         return -EIO;
-                if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
+                if (sym_EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
                         return -EIO;
 
-                if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
+                if (sym_EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
                         return -EIO;
         }
 
index 042077ab066dd75b2954bfde74ad4ee2ed5fe941..f59c2fa348f6759253f58a523d663fb52559e7b0 100644 (file)
@@ -4,22 +4,21 @@
 #error This source file requires DNS-over-TLS to be enabled and OpenSSL to be available.
 #endif
 
-#include <openssl/bio.h>
-#include <openssl/err.h>
 #include <openssl/x509v3.h>
 
 #include "alloc-util.h"
-#include "openssl-util.h"
+#include "crypto-util.h"
 #include "log.h"
 #include "resolved-dns-server.h"
 #include "resolved-dns-stream.h"
 #include "resolved-dnstls.h"
 #include "resolved-manager.h"
+#include "ssl-util.h"
 
 static char *dnstls_error_string(int ssl_error, char *buf, size_t count) {
         assert(buf || count == 0);
         if (ssl_error == SSL_ERROR_SSL)
-                ERR_error_string_n(ERR_get_error(), buf, count);
+                sym_ERR_error_string_n(sym_ERR_get_error(), buf, count);
         else
                 snprintf(buf, count, "SSL_get_error()=%d", ssl_error);
         return buf;
@@ -54,7 +53,7 @@ static int dnstls_flush_write_buffer(DnsStream *stream) {
                                 stream->dnstls_events |= EPOLLOUT;
                                 return -EAGAIN;
                         } else {
-                                BIO_reset(SSL_get_wbio(stream->dnstls_data.ssl));
+                                sym_BIO_reset(sym_SSL_get_wbio(stream->dnstls_data.ssl));
                                 stream->dnstls_data.buffer_offset = 0;
                         }
                 }
@@ -72,55 +71,55 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
         assert(stream->manager);
         assert(server);
 
-        rb = BIO_new_socket(stream->fd, 0);
+        rb = sym_BIO_new_socket(stream->fd, 0);
         if (!rb)
                 return -ENOMEM;
 
-        wb = BIO_new(BIO_s_mem());
+        wb = sym_BIO_new(sym_BIO_s_mem());
         if (!wb)
                 return -ENOMEM;
 
-        BIO_get_mem_ptr(wb, &stream->dnstls_data.write_buffer);
+        sym_BIO_get_mem_ptr(wb, &stream->dnstls_data.write_buffer);
         stream->dnstls_data.buffer_offset = 0;
 
-        s = SSL_new(stream->manager->dnstls_data.ctx);
+        s = sym_SSL_new(stream->manager->dnstls_data.ctx);
         if (!s)
                 return -ENOMEM;
 
-        SSL_set_connect_state(s);
-        r = SSL_set_session(s, server->dnstls_data.session);
+        sym_SSL_set_connect_state(s);
+        r = sym_SSL_set_session(s, server->dnstls_data.session);
         if (r == 0)
                 return -EIO;
-        SSL_set_bio(s, TAKE_PTR(rb), TAKE_PTR(wb));
+        sym_SSL_set_bio(s, TAKE_PTR(rb), TAKE_PTR(wb));
 
         if (server->manager->dns_over_tls_mode == DNS_OVER_TLS_YES) {
                 X509_VERIFY_PARAM *v;
 
-                SSL_set_verify(s, SSL_VERIFY_PEER, NULL);
-                v = SSL_get0_param(s);
+                sym_SSL_set_verify(s, SSL_VERIFY_PEER, NULL);
+                v = sym_SSL_get0_param(s);
                 if (server->server_name) {
-                        X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
-                        if (X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0)
+                        sym_X509_VERIFY_PARAM_set_hostflags(v, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+                        if (sym_X509_VERIFY_PARAM_set1_host(v, server->server_name, 0) == 0)
                                 return -ECONNREFUSED;
                 } else {
                         const unsigned char *ip;
                         ip = server->family == AF_INET ? (const unsigned char*) &server->address.in.s_addr : server->address.in6.s6_addr;
-                        if (X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0)
+                        if (sym_X509_VERIFY_PARAM_set1_ip(v, ip, FAMILY_ADDRESS_SIZE(server->family)) == 0)
                                 return -ECONNREFUSED;
                 }
         }
 
         if (server->server_name) {
-                r = SSL_set_tlsext_host_name(s, server->server_name);
+                r = sym_SSL_set_tlsext_host_name(s, server->server_name);
                 if (r <= 0)
                         return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                                "Failed to set server name: %s", DNSTLS_ERROR_STRING(SSL_ERROR_SSL));
         }
 
-        ERR_clear_error();
-        stream->dnstls_data.handshake = SSL_do_handshake(s);
+        sym_ERR_clear_error();
+        stream->dnstls_data.handshake = sym_SSL_do_handshake(s);
         if (stream->dnstls_data.handshake <= 0) {
-                error = SSL_get_error(s, stream->dnstls_data.handshake);
+                error = sym_SSL_get_error(s, stream->dnstls_data.handshake);
                 if (!IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE))
                         return log_debug_errno(SYNTHETIC_ERRNO(ECONNREFUSED),
                                                "Failed to invoke SSL_do_handshake: %s", DNSTLS_ERROR_STRING(error));
@@ -131,7 +130,7 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
 
         r = dnstls_flush_write_buffer(stream);
         if (r < 0 && r != -EAGAIN) {
-                SSL_free(TAKE_PTR(stream->dnstls_data.ssl));
+                sym_SSL_free(TAKE_PTR(stream->dnstls_data.ssl));
                 return r;
         }
 
@@ -143,7 +142,7 @@ void dnstls_stream_free(DnsStream *stream) {
         assert(stream->encrypted);
 
         if (stream->dnstls_data.ssl)
-                SSL_free(stream->dnstls_data.ssl);
+                sym_SSL_free(stream->dnstls_data.ssl);
 }
 
 int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
@@ -161,8 +160,8 @@ int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
         }
 
         if (stream->dnstls_data.shutdown) {
-                ERR_clear_error();
-                r = SSL_shutdown(stream->dnstls_data.ssl);
+                sym_ERR_clear_error();
+                r = sym_SSL_shutdown(stream->dnstls_data.ssl);
                 if (r == 0) {
                         stream->dnstls_events = 0;
 
@@ -172,7 +171,7 @@ int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
 
                         return -EAGAIN;
                 } else if (r < 0) {
-                        error = SSL_get_error(stream->dnstls_data.ssl, r);
+                        error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
                         if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
                                 stream->dnstls_events = error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
 
@@ -198,10 +197,10 @@ int dnstls_stream_on_io(DnsStream *stream, uint32_t revents) {
                 dns_stream_unref(stream);
                 return DNSTLS_STREAM_CLOSED;
         } else if (stream->dnstls_data.handshake <= 0) {
-                ERR_clear_error();
-                stream->dnstls_data.handshake = SSL_do_handshake(stream->dnstls_data.ssl);
+                sym_ERR_clear_error();
+                stream->dnstls_data.handshake = sym_SSL_do_handshake(stream->dnstls_data.ssl);
                 if (stream->dnstls_data.handshake <= 0) {
-                        error = SSL_get_error(stream->dnstls_data.ssl, stream->dnstls_data.handshake);
+                        error = sym_SSL_get_error(stream->dnstls_data.ssl, stream->dnstls_data.handshake);
                         if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
                                 stream->dnstls_events = error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
                                 r = dnstls_flush_write_buffer(stream);
@@ -233,18 +232,18 @@ int dnstls_stream_shutdown(DnsStream *stream, int error) {
         assert(stream->dnstls_data.ssl);
 
         if (stream->server) {
-                s = SSL_get1_session(stream->dnstls_data.ssl);
+                s = sym_SSL_get1_session(stream->dnstls_data.ssl);
                 if (s) {
                         if (stream->server->dnstls_data.session)
-                                SSL_SESSION_free(stream->server->dnstls_data.session);
+                                sym_SSL_SESSION_free(stream->server->dnstls_data.session);
 
                         stream->server->dnstls_data.session = s;
                 }
         }
 
         if (error == ETIMEDOUT) {
-                ERR_clear_error();
-                r = SSL_shutdown(stream->dnstls_data.ssl);
+                sym_ERR_clear_error();
+                r = sym_SSL_shutdown(stream->dnstls_data.ssl);
                 if (r == 0) {
                         if (!stream->dnstls_data.shutdown) {
                                 stream->dnstls_data.shutdown = true;
@@ -259,7 +258,7 @@ int dnstls_stream_shutdown(DnsStream *stream, int error) {
 
                         return -EAGAIN;
                 } else if (r < 0) {
-                        ssl_error = SSL_get_error(stream->dnstls_data.ssl, r);
+                        ssl_error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
                         if (IN_SET(ssl_error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
                                 stream->dnstls_events = ssl_error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
                                 r = dnstls_flush_write_buffer(stream);
@@ -291,10 +290,10 @@ static ssize_t dnstls_stream_write(DnsStream *stream, const char *buf, size_t co
         int error, r;
         ssize_t ss;
 
-        ERR_clear_error();
-        ss = r = SSL_write(stream->dnstls_data.ssl, buf, count);
+        sym_ERR_clear_error();
+        ss = r = sym_SSL_write(stream->dnstls_data.ssl, buf, count);
         if (r <= 0) {
-                error = SSL_get_error(stream->dnstls_data.ssl, r);
+                error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
                 if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
                         stream->dnstls_events = error == SSL_ERROR_WANT_READ ? EPOLLIN : EPOLLOUT;
                         ss = -EAGAIN;
@@ -352,10 +351,10 @@ ssize_t dnstls_stream_read(DnsStream *stream, void *buf, size_t count) {
         assert(stream->dnstls_data.ssl);
         assert(buf);
 
-        ERR_clear_error();
-        ss = r = SSL_read(stream->dnstls_data.ssl, buf, count);
+        sym_ERR_clear_error();
+        ss = r = sym_SSL_read(stream->dnstls_data.ssl, buf, count);
         if (r <= 0) {
-                error = SSL_get_error(stream->dnstls_data.ssl, r);
+                error = sym_SSL_get_error(stream->dnstls_data.ssl, r);
                 if (IN_SET(error, SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE)) {
                         /* If we receive SSL_ERROR_WANT_READ here, there are two possible scenarios:
                            * OpenSSL needs to renegotiate (so we want to get an EPOLLIN event), or
@@ -390,7 +389,7 @@ void dnstls_server_free(DnsServer *server) {
         assert(server);
 
         if (server->dnstls_data.session)
-                SSL_SESSION_free(server->dnstls_data.session);
+                sym_SSL_SESSION_free(server->dnstls_data.session);
 }
 
 int dnstls_manager_init(Manager *manager) {
@@ -398,25 +397,33 @@ int dnstls_manager_init(Manager *manager) {
 
         assert(manager);
 
-        manager->dnstls_data.ctx = SSL_CTX_new(TLS_client_method());
+        r = dlopen_libcrypto(LOG_WARNING);
+        if (r < 0)
+                return r;
+
+        r = dlopen_libssl(LOG_WARNING);
+        if (r < 0)
+                return r;
+
+        manager->dnstls_data.ctx = sym_SSL_CTX_new(sym_TLS_client_method());
         if (!manager->dnstls_data.ctx)
                 return log_warning_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                          "Failed to create SSL context: %s",
-                                         ERR_error_string(ERR_get_error(), NULL));
+                                         sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        r = SSL_CTX_set_min_proto_version(manager->dnstls_data.ctx, TLS1_2_VERSION);
+        r = sym_SSL_CTX_set_min_proto_version(manager->dnstls_data.ctx, TLS1_2_VERSION);
         if (r == 0)
                 return log_warning_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
                                          "Failed to set protocol version on SSL context: %s",
-                                         ERR_error_string(ERR_get_error(), NULL));
+                                         sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        (void) SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
+        (void) sym_SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
 
-        r = SSL_CTX_set_default_verify_paths(manager->dnstls_data.ctx);
+        r = sym_SSL_CTX_set_default_verify_paths(manager->dnstls_data.ctx);
         if (r == 0)
                 return log_warning_errno(SYNTHETIC_ERRNO(EIO),
                                          "Failed to load system trust store: %s",
-                                         ERR_error_string(ERR_get_error(), NULL));
+                                         sym_ERR_error_string(sym_ERR_get_error(), NULL));
         return 0;
 }
 
@@ -424,5 +431,5 @@ void dnstls_manager_free(Manager *manager) {
         assert(manager);
 
         if (manager->dnstls_data.ctx)
-                SSL_CTX_free(manager->dnstls_data.ctx);
+                sym_SSL_CTX_free(manager->dnstls_data.ctx);
 }
index 35a8d785defa1d61fe62552267775b8abed14467..b87b84a0d5cad7e30bba2564e32181bec670f782 100644 (file)
@@ -7,8 +7,6 @@
 #error This source file requires OpenSSL to be available.
 #endif
 
-#include <openssl/ssl.h>
-
 #include "resolved-forward.h"
 
 typedef struct DnsTlsManagerData {
diff --git a/src/sbsign/authenticode.c b/src/sbsign/authenticode.c
new file mode 100644 (file)
index 0000000..9971cf9
--- /dev/null
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <openssl/asn1t.h>
+
+#include "authenticode.h"
+#include "crypto-util.h"
+
+/* OpenSSL's ASN1_SEQUENCE/ASN1_CHOICE/IMPLEMENT_ASN1_FUNCTIONS macros expand to code that references
+ * libcrypto symbols directly, which would force us to link this object against libcrypto and defeat the
+ * dlopen approach used everywhere else. We work around that in two different ways depending on where the
+ * reference appears in the macro expansion:
+ *
+ *  - ASN1_item_new/ASN1_item_free/ASN1_item_d2i/ASN1_item_i2d are called from the bodies of the functions
+ *    generated by IMPLEMENT_ASN1_FUNCTIONS. We can simply #define them to the matching sym_* variants, so
+ *    the generated bodies end up calling our dlopen'd pointers.
+ *
+ *  - ASN1_ANY_it/ASN1_BIT_STRING_it/... (the "_it" getters) are embedded as function pointers in the
+ *    static const ASN1_ADB / ASN1_TEMPLATE tables emitted by the ASN1_SEQUENCE/ASN1_CHOICE macros. Static
+ *    initializers can only contain constant expressions, so we can't point them at the sym_* variables
+ *    (which are non-const globals filled in at dlopen time). Instead we define static trampoline
+ *    functions (openssl_ASN1_*_it) whose addresses are constant, each forwarding to the corresponding
+ *    sym_* pointer at runtime, and #define the OpenSSL names to our trampolines before the tables are
+ *    emitted.
+ *
+ * Note that this file must only call these redefined macros indirectly, via the IMPLEMENT_ASN1_FUNCTIONS
+ * expansions, and callers of those generated wrappers (e.g. sbsign.c) must have dlopen_libcrypto()
+ * before invoking them, otherwise the sym_* pointers will still be NULL. */
+
+static const ASN1_ITEM* openssl_ASN1_ANY_it(void) {
+        assert(sym_ASN1_ANY_it);
+        return sym_ASN1_ANY_it();
+}
+
+static const ASN1_ITEM* openssl_ASN1_BIT_STRING_it(void) {
+        assert(sym_ASN1_BIT_STRING_it);
+        return sym_ASN1_BIT_STRING_it();
+}
+
+static const ASN1_ITEM* openssl_ASN1_BMPSTRING_it(void) {
+        assert(sym_ASN1_BMPSTRING_it);
+        return sym_ASN1_BMPSTRING_it();
+}
+
+static const ASN1_ITEM* openssl_ASN1_IA5STRING_it(void) {
+        assert(sym_ASN1_IA5STRING_it);
+        return sym_ASN1_IA5STRING_it();
+}
+
+static const ASN1_ITEM* openssl_ASN1_OBJECT_it(void) {
+        assert(sym_ASN1_OBJECT_it);
+        return sym_ASN1_OBJECT_it();
+}
+
+static const ASN1_ITEM* openssl_ASN1_OCTET_STRING_it(void) {
+        assert(sym_ASN1_OCTET_STRING_it);
+        return sym_ASN1_OCTET_STRING_it();
+}
+
+#define ASN1_item_new           sym_ASN1_item_new
+#define ASN1_item_free          sym_ASN1_item_free
+#define ASN1_item_d2i           sym_ASN1_item_d2i
+#define ASN1_item_i2d           sym_ASN1_item_i2d
+#define ASN1_ANY_it             openssl_ASN1_ANY_it
+#define ASN1_BIT_STRING_it      openssl_ASN1_BIT_STRING_it
+#define ASN1_BMPSTRING_it       openssl_ASN1_BMPSTRING_it
+#define ASN1_IA5STRING_it       openssl_ASN1_IA5STRING_it
+#define ASN1_OBJECT_it          openssl_ASN1_OBJECT_it
+#define ASN1_OCTET_STRING_it    openssl_ASN1_OCTET_STRING_it
+
+ASN1_SEQUENCE(SpcAttributeTypeAndOptionalValue) = {
+        ASN1_SIMPLE(SpcAttributeTypeAndOptionalValue, type, ASN1_OBJECT),
+        ASN1_OPT(SpcAttributeTypeAndOptionalValue, value, ASN1_ANY)
+} ASN1_SEQUENCE_END(SpcAttributeTypeAndOptionalValue);
+
+IMPLEMENT_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue);
+
+ASN1_SEQUENCE(AlgorithmIdentifier) = {
+        ASN1_SIMPLE(AlgorithmIdentifier, algorithm, ASN1_OBJECT),
+        ASN1_OPT(AlgorithmIdentifier, parameters, ASN1_ANY)
+} ASN1_SEQUENCE_END(AlgorithmIdentifier)
+
+IMPLEMENT_ASN1_FUNCTIONS(AlgorithmIdentifier);
+
+ASN1_SEQUENCE(DigestInfo) = {
+        ASN1_SIMPLE(DigestInfo, digestAlgorithm, AlgorithmIdentifier),
+        ASN1_SIMPLE(DigestInfo, digest, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(DigestInfo);
+
+IMPLEMENT_ASN1_FUNCTIONS(DigestInfo);
+
+ASN1_SEQUENCE(SpcIndirectDataContent) = {
+        ASN1_SIMPLE(SpcIndirectDataContent, data, SpcAttributeTypeAndOptionalValue),
+        ASN1_SIMPLE(SpcIndirectDataContent, messageDigest, DigestInfo)
+} ASN1_SEQUENCE_END(SpcIndirectDataContent);
+
+IMPLEMENT_ASN1_FUNCTIONS(SpcIndirectDataContent);
+
+ASN1_CHOICE(SpcString) = {
+        ASN1_IMP_OPT(SpcString, value.unicode, ASN1_BMPSTRING, 0),
+        ASN1_IMP_OPT(SpcString, value.ascii, ASN1_IA5STRING, 1)
+} ASN1_CHOICE_END(SpcString);
+
+IMPLEMENT_ASN1_FUNCTIONS(SpcString);
+
+ASN1_SEQUENCE(SpcSerializedObject) = {
+        ASN1_SIMPLE(SpcSerializedObject, classId, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(SpcSerializedObject, serializedData, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(SpcSerializedObject);
+
+IMPLEMENT_ASN1_FUNCTIONS(SpcSerializedObject);
+
+ASN1_CHOICE(SpcLink) = {
+        ASN1_IMP_OPT(SpcLink, value.url, ASN1_IA5STRING, 0),
+        ASN1_IMP_OPT(SpcLink, value.moniker, SpcSerializedObject, 1),
+        ASN1_EXP_OPT(SpcLink, value.file, SpcString, 2)
+} ASN1_CHOICE_END(SpcLink);
+
+IMPLEMENT_ASN1_FUNCTIONS(SpcLink);
+
+ASN1_SEQUENCE(SpcPeImageData) = {
+        ASN1_SIMPLE(SpcPeImageData, flags, ASN1_BIT_STRING),
+        ASN1_EXP_OPT(SpcPeImageData, file, SpcLink, 0)
+} ASN1_SEQUENCE_END(SpcPeImageData)
+
+IMPLEMENT_ASN1_FUNCTIONS(SpcPeImageData);
index 95d5499a8e061e4e36749b7992d3165c7a105738..c076fe36241d88e0e53c6be8b087b6fd32c2e6b1 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include <openssl/asn1t.h>
+#include <openssl/asn1.h>
 
 #include "shared-forward.h"
 
@@ -15,13 +15,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue);
 
-ASN1_SEQUENCE(SpcAttributeTypeAndOptionalValue) = {
-        ASN1_SIMPLE(SpcAttributeTypeAndOptionalValue, type, ASN1_OBJECT),
-        ASN1_OPT(SpcAttributeTypeAndOptionalValue, value, ASN1_ANY)
-} ASN1_SEQUENCE_END(SpcAttributeTypeAndOptionalValue);
-
-IMPLEMENT_ASN1_FUNCTIONS(SpcAttributeTypeAndOptionalValue);
-
 typedef struct {
         ASN1_OBJECT *algorithm;
         ASN1_TYPE *parameters;
@@ -29,13 +22,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(AlgorithmIdentifier);
 
-ASN1_SEQUENCE(AlgorithmIdentifier) = {
-        ASN1_SIMPLE(AlgorithmIdentifier, algorithm, ASN1_OBJECT),
-        ASN1_OPT(AlgorithmIdentifier, parameters, ASN1_ANY)
-} ASN1_SEQUENCE_END(AlgorithmIdentifier)
-
-IMPLEMENT_ASN1_FUNCTIONS(AlgorithmIdentifier);
-
 typedef struct {
         AlgorithmIdentifier *digestAlgorithm;
         ASN1_OCTET_STRING *digest;
@@ -43,13 +29,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(DigestInfo);
 
-ASN1_SEQUENCE(DigestInfo) = {
-        ASN1_SIMPLE(DigestInfo, digestAlgorithm, AlgorithmIdentifier),
-        ASN1_SIMPLE(DigestInfo, digest, ASN1_OCTET_STRING)
-} ASN1_SEQUENCE_END(DigestInfo);
-
-IMPLEMENT_ASN1_FUNCTIONS(DigestInfo);
-
 typedef struct {
         SpcAttributeTypeAndOptionalValue *data;
         DigestInfo *messageDigest;
@@ -57,15 +36,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(SpcIndirectDataContent);
 
-ASN1_SEQUENCE(SpcIndirectDataContent) = {
-        ASN1_SIMPLE(SpcIndirectDataContent, data, SpcAttributeTypeAndOptionalValue),
-        ASN1_SIMPLE(SpcIndirectDataContent, messageDigest, DigestInfo)
-} ASN1_SEQUENCE_END(SpcIndirectDataContent);
-
-IMPLEMENT_ASN1_FUNCTIONS(SpcIndirectDataContent);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcIndirectDataContent*, SpcIndirectDataContent_free, NULL);
-
 typedef struct {
         int type;
         union {
@@ -76,13 +46,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(SpcString);
 
-ASN1_CHOICE(SpcString) = {
-        ASN1_IMP_OPT(SpcString, value.unicode, ASN1_BMPSTRING, 0),
-        ASN1_IMP_OPT(SpcString, value.ascii, ASN1_IA5STRING, 1)
-} ASN1_CHOICE_END(SpcString);
-
-IMPLEMENT_ASN1_FUNCTIONS(SpcString);
-
 typedef struct {
         ASN1_OCTET_STRING *classId;
         ASN1_OCTET_STRING *serializedData;
@@ -90,13 +53,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(SpcSerializedObject);
 
-ASN1_SEQUENCE(SpcSerializedObject) = {
-        ASN1_SIMPLE(SpcSerializedObject, classId, ASN1_OCTET_STRING),
-        ASN1_SIMPLE(SpcSerializedObject, serializedData, ASN1_OCTET_STRING)
-} ASN1_SEQUENCE_END(SpcSerializedObject);
-
-IMPLEMENT_ASN1_FUNCTIONS(SpcSerializedObject);
-
 typedef struct {
         int type;
         union {
@@ -108,16 +64,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(SpcLink);
 
-ASN1_CHOICE(SpcLink) = {
-        ASN1_IMP_OPT(SpcLink, value.url, ASN1_IA5STRING, 0),
-        ASN1_IMP_OPT(SpcLink, value.moniker, SpcSerializedObject, 1),
-        ASN1_EXP_OPT(SpcLink, value.file, SpcString, 2)
-} ASN1_CHOICE_END(SpcLink);
-
-IMPLEMENT_ASN1_FUNCTIONS(SpcLink);
-
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcLink*, SpcLink_free, NULL);
-
 typedef struct {
         ASN1_BIT_STRING *flags;
         SpcLink *file;
@@ -125,11 +71,6 @@ typedef struct {
 
 DECLARE_ASN1_FUNCTIONS(SpcPeImageData);
 
-ASN1_SEQUENCE(SpcPeImageData) = {
-        ASN1_SIMPLE(SpcPeImageData, flags, ASN1_BIT_STRING),
-        ASN1_EXP_OPT(SpcPeImageData, file, SpcLink, 0)
-} ASN1_SEQUENCE_END(SpcPeImageData)
-
-IMPLEMENT_ASN1_FUNCTIONS(SpcPeImageData);
-
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcIndirectDataContent*, SpcIndirectDataContent_free, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcLink*, SpcLink_free, NULL);
 DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SpcPeImageData*, SpcPeImageData_free, NULL);
index b6e0dbcde9c038f81ddc064ddbb7b29d6c14d641..f28d4648f94a06432fbfb21fe0bf5cb85730369b 100644 (file)
@@ -6,7 +6,10 @@ executables += [
                 'conditions' : [
                         'HAVE_OPENSSL',
                 ],
-                'sources' : files('sbsign.c'),
-                'dependencies' : libopenssl,
+                'sources' : files(
+                        'sbsign.c',
+                        'authenticode.c',
+                ),
+                'dependencies' : libopenssl_cflags,
         },
 ]
index a8c554ffcfb50d5b302612da18f111e5cbaeefad..012f39dcc309490db4f011179f3b9643aaf8ab86 100644 (file)
@@ -4,9 +4,11 @@
 
 #include "alloc-util.h"
 #include "ansi-color.h"
+#include "ask-password-api.h"
 #include "authenticode.h"
 #include "build.h"
 #include "copy.h"
+#include "crypto-util.h"
 #include "efi-fundamental.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -16,7 +18,6 @@
 #include "io-util.h"
 #include "log.h"
 #include "main-func.h"
-#include "openssl-util.h"
 #include "options.h"
 #include "parse-argument.h"
 #include "pe-binary.h"
@@ -203,13 +204,13 @@ static int spc_indirect_data_content_new(const void *digest, size_t digestsz, ui
                 return log_oom();
 
         link->value.file->type = 0;
-        link->value.file->value.unicode = ASN1_BMPSTRING_new();
+        link->value.file->value.unicode = sym_ASN1_BMPSTRING_new();
         if (!link->value.file->value.unicode)
                 return log_oom();
 
-        if (ASN1_STRING_set(link->value.file->value.unicode, obsolete, sizeof(obsolete)) == 0)
+        if (sym_ASN1_STRING_set(link->value.file->value.unicode, obsolete, sizeof(obsolete)) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set ASN1 string: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         _cleanup_(SpcPeImageData_freep) SpcPeImageData *peid = SpcPeImageData_new();
         if (!peid)
@@ -221,46 +222,46 @@ static int spc_indirect_data_content_new(const void *digest, size_t digestsz, ui
         int peidrawsz = i2d_SpcPeImageData(peid, &peidraw);
         if (peidrawsz < 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert SpcPeImageData to BER: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         _cleanup_(SpcIndirectDataContent_freep) SpcIndirectDataContent *idc = SpcIndirectDataContent_new();
-        idc->data->value = ASN1_TYPE_new();
+        idc->data->value = sym_ASN1_TYPE_new();
         if (!idc->data->value)
                 return log_oom();
 
         idc->data->value->type = V_ASN1_SEQUENCE;
-        idc->data->value->value.sequence = ASN1_STRING_new();
+        idc->data->value->value.sequence = sym_ASN1_STRING_new();
         if (!idc->data->value->value.sequence)
                 return log_oom();
 
-        idc->data->type = OBJ_txt2obj(SPC_PE_IMAGE_DATA_OBJID, /* no_name= */ 1);
+        idc->data->type = sym_OBJ_txt2obj(SPC_PE_IMAGE_DATA_OBJID, /* no_name= */ 1);
         if (!idc->data->type)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SpcPeImageData object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (!ASN1_STRING_set(idc->data->value->value.sequence, peidraw, peidrawsz))
+        if (!sym_ASN1_STRING_set(idc->data->value->value.sequence, peidraw, peidrawsz))
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set ASN1_STRING data.");
 
-        idc->messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(NID_sha256);
+        idc->messageDigest->digestAlgorithm->algorithm = sym_OBJ_nid2obj(NID_sha256);
         if (!idc->messageDigest->digestAlgorithm->algorithm)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SHA256 object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        idc->messageDigest->digestAlgorithm->parameters = ASN1_TYPE_new();
+        idc->messageDigest->digestAlgorithm->parameters = sym_ASN1_TYPE_new();
         if (!idc->messageDigest->digestAlgorithm->parameters)
                 return log_oom();
 
         idc->messageDigest->digestAlgorithm->parameters->type = V_ASN1_NULL;
 
-        if (ASN1_OCTET_STRING_set(idc->messageDigest->digest, digest, digestsz) == 0)
+        if (sym_ASN1_OCTET_STRING_set(idc->messageDigest->digest, digest, digestsz) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set digest: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         _cleanup_free_ uint8_t *idcraw = NULL;
         int idcrawsz = i2d_SpcIndirectDataContent(idc, &idcraw);
         if (idcrawsz < 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert SpcIndirectDataContent to BER: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret_idc = TAKE_PTR(idcraw);
         *ret_idcsz = (size_t) idcrawsz;
@@ -276,12 +277,12 @@ static int asn1_timestamp(ASN1_TIME **ret) {
         usec_t epoch = parse_source_date_epoch();
 
         if (epoch == USEC_INFINITY) {
-                time = X509_gmtime_adj(NULL, 0);
+                time = sym_X509_gmtime_adj(NULL, 0);
                 if (!time)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get current time: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
         } else {
-                time = ASN1_TIME_set(NULL, (time_t) (epoch / USEC_PER_SEC));
+                time = sym_ASN1_TIME_set(NULL, (time_t) (epoch / USEC_PER_SEC));
                 if (!time)
                         return log_oom();
         }
@@ -323,37 +324,37 @@ static int pkcs7_new_with_attributes(
         }
 
         /* Add an empty SMIMECAP attribute to indicate we don't have any SMIME capabilities. */
-        _cleanup_(x509_algor_free_manyp) STACK_OF(X509_ALGOR) *smcap = sk_X509_ALGOR_new_null();
+        _cleanup_(x509_algor_free_manyp) STACK_OF(X509_ALGOR) *smcap = (STACK_OF(X509_ALGOR)*) sym_OPENSSL_sk_new_null();
         if (!smcap)
                 return log_oom();
 
-        if (PKCS7_add_attrib_smimecap(si, smcap) == 0)
+        if (sym_PKCS7_add_attrib_smimecap(si, smcap) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add smimecap signed attribute to signer info: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (PKCS7_add_attrib_content_type(si, NULL) == 0)
+        if (sym_PKCS7_add_attrib_content_type(si, NULL) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add content type signed attribute to signer info: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         _cleanup_(ASN1_TIME_freep) ASN1_TIME *time = NULL;
         r = asn1_timestamp(&time);
         if (r < 0)
                 return r;
 
-        if (PKCS7_add0_attrib_signing_time(si, time) == 0)
+        if (sym_PKCS7_add0_attrib_signing_time(si, time) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add signing time signed attribute to signer info: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         TAKE_PTR(time);
 
-        ASN1_OBJECT *idc = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
+        ASN1_OBJECT *idc = sym_OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
         if (!idc)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SpcIndirectDataContent object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, idc) == 0)
+        if (sym_PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, idc) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add signed attribute to pkcs7 signer info: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret_p7 = TAKE_PTR(p7);
         *ret_si = TAKE_PTR(si);
@@ -363,23 +364,23 @@ static int pkcs7_new_with_attributes(
 static int pkcs7_populate_data_bio(PKCS7* p7, const void *data, size_t size, BIO **ret) {
         assert(ret);
 
-        _cleanup_(BIO_free_allp) BIO *bio = PKCS7_dataInit(p7, NULL);
+        _cleanup_(BIO_free_allp) BIO *bio = sym_PKCS7_dataInit(p7, NULL);
         if (!bio)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to create PKCS7 data bio: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         int tag, class;
         long psz;
         const uint8_t *p = data;
 
         /* This function weirdly enough reports errors by setting the 0x80 bit in its return value. */
-        if (ASN1_get_object(&p, &psz, &tag, &class, size) & 0x80)
+        if (sym_ASN1_get_object(&p, &psz, &tag, &class, size) & 0x80)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse ASN.1 object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (BIO_write(bio, p, psz) < 0)
+        if (sym_BIO_write(bio, p, psz) < 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write to PKCS7 data bio: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret = TAKE_PTR(bio);
 
@@ -391,26 +392,26 @@ static int pkcs7_add_digest_attribute(PKCS7 *p7, BIO *data, PKCS7_SIGNER_INFO *s
         assert(data);
         assert(si);
 
-        BIO *mdbio = BIO_find_type(data, BIO_TYPE_MD);
+        BIO *mdbio = sym_BIO_find_type(data, BIO_TYPE_MD);
         if (!mdbio)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to find digest bio: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         EVP_MD_CTX *mdc;
-        if (BIO_get_md_ctx(mdbio, &mdc) <= 0)
+        if (sym_BIO_get_md_ctx(mdbio, &mdc) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest context from bio: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         unsigned char digest[EVP_MAX_MD_SIZE];
         unsigned digestsz;
 
-        if (EVP_DigestFinal_ex(mdc, digest, &digestsz) == 0)
+        if (sym_EVP_DigestFinal_ex(mdc, digest, &digestsz) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (PKCS7_add1_attrib_digest(si, digest, digestsz) == 0)
+        if (sym_PKCS7_add1_attrib_digest(si, digest, digestsz) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to add PKCS9 message digest signed attribute to signer info: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         return 0;
 }
@@ -425,6 +426,10 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
         _cleanup_(iovec_done) struct iovec signed_attributes_signature = {};
         int r;
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         if (argc < 2)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No input file specified");
 
@@ -487,9 +492,9 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
                         return log_error_errno(r, "Failed to read signed attributes file '%s': %m", arg_signed_data);
 
                 const uint8_t *p = content;
-                if (!ASN1_item_d2i((ASN1_VALUE **) &signed_attributes, &p, contentsz, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)))
+                if (!sym_ASN1_item_d2i((ASN1_VALUE **) &signed_attributes, &p, contentsz, sym_PKCS7_ATTR_SIGN_it()))
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse signed attributes: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
         }
 
         if (arg_signed_data_signature) {
@@ -526,7 +531,7 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
 
         _cleanup_free_ void *pehash = NULL;
         size_t pehashsz;
-        r = pe_hash(srcfd, EVP_sha256(), &pehash, &pehashsz);
+        r = pe_hash(srcfd, sym_EVP_sha256(), &pehash, &pehashsz);
         if (r < 0)
                 return log_error_errno(r, "Failed to hash PE binary %s: %m", argv[0]);
 
@@ -555,10 +560,10 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
                         return r;
 
                 _cleanup_free_ unsigned char *abuf = NULL;
-                int alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+                int alen = sym_ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, sym_PKCS7_ATTR_SIGN_it());
                 if (alen < 0 || !abuf)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert signed attributes ASN.1 to DER: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
                 r = loop_write(dstfd, abuf, alen);
                 if (r < 0)
@@ -573,51 +578,51 @@ static int verb_sign(int argc, char *argv[], uintptr_t _data, void *userdata) {
         }
 
         if (iovec_is_set(&signed_attributes_signature))
-                ASN1_STRING_set0(si->enc_digest, TAKE_PTR(signed_attributes_signature.iov_base), signed_attributes_signature.iov_len);
+                sym_ASN1_STRING_set0(si->enc_digest, TAKE_PTR(signed_attributes_signature.iov_base), signed_attributes_signature.iov_len);
         else {
                 _cleanup_(BIO_free_allp) BIO *bio = NULL;
                 r = pkcs7_populate_data_bio(p7, idcraw, idcrawsz, &bio);
                 if (r < 0)
                         return r;
 
-                if (PKCS7_dataFinal(p7, bio) == 0)
+                if (sym_PKCS7_dataFinal(p7, bio) == 0)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to sign data: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
         }
 
-        _cleanup_(PKCS7_freep) PKCS7 *p7c = PKCS7_new();
+        _cleanup_(PKCS7_freep) PKCS7 *p7c = sym_PKCS7_new();
         if (!p7c)
                 return log_oom();
 
-        p7c->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
+        p7c->type = sym_OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, /* no_name= */ true);
         if (!p7c->type)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get SpcIndirectDataContent object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        p7c->d.other = ASN1_TYPE_new();
+        p7c->d.other = sym_ASN1_TYPE_new();
         if (!p7c->d.other)
                 return log_oom();
 
         p7c->d.other->type = V_ASN1_SEQUENCE;
-        p7c->d.other->value.sequence = ASN1_STRING_new();
+        p7c->d.other->value.sequence = sym_ASN1_STRING_new();
         if (!p7c->d.other->value.sequence)
                 return log_oom();
 
-        if (ASN1_STRING_set(p7c->d.other->value.sequence, idcraw, idcrawsz) == 0)
+        if (sym_ASN1_STRING_set(p7c->d.other->value.sequence, idcraw, idcrawsz) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set ASN1 string: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (PKCS7_set_content(p7, p7c) == 0)
+        if (sym_PKCS7_set_content(p7, p7c) == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 data: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         TAKE_PTR(p7c);
 
         _cleanup_free_ uint8_t *sig = NULL;
-        int sigsz = i2d_PKCS7(p7, &sig);
+        int sigsz = sym_i2d_PKCS7(p7, &sig);
         if (sigsz < 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         _cleanup_free_ IMAGE_DOS_HEADER *dos_header = NULL;
         _cleanup_free_ PeHeader *pe_header = NULL;
index d3383aebb6faf074266a6e66f7a9e91d949d78f2..dd2a93844dbddb3cefc374f4e65a0e2cddb58fb4 100644 (file)
@@ -6,10 +6,6 @@
 #include "efivars.h"
 #include "time-util.h"
 
-#if HAVE_OPENSSL
-#include <openssl/err.h>
-#endif
-
 #include "sd-id128.h"
 #include "sd-json.h"
 #include "sd-varlink.h"
@@ -19,6 +15,7 @@
 #include "chattr-util.h"
 #include "copy.h"
 #include "creds-util.h"
+#include "crypto-util.h"
 #include "efi-api.h"
 #include "env-util.h"
 #include "errno-util.h"
@@ -32,7 +29,6 @@
 #include "log.h"
 #include "memory-util.h"
 #include "mkdir-label.h"
-#include "openssl-util.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "random-util.h"
@@ -734,6 +730,7 @@ static int sha256_hash_host_and_tpm2_key(
 
         _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *md = NULL;
         unsigned l;
+        int r;
 
         assert(iovec_is_valid(host_key));
         assert(iovec_is_valid(tpm2_key));
@@ -741,22 +738,26 @@ static int sha256_hash_host_and_tpm2_key(
 
         /* Combines the host key and the TPM2 HMAC hash into a SHA256 hash value we'll use as symmetric encryption key. */
 
-        md = EVP_MD_CTX_new();
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        md = sym_EVP_MD_CTX_new();
         if (!md)
                 return log_oom();
 
-        if (EVP_DigestInit_ex(md, EVP_sha256(), NULL) != 1)
+        if (sym_EVP_DigestInit_ex(md, sym_EVP_sha256(), NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initial SHA256 context.");
 
-        if (iovec_is_set(host_key) && EVP_DigestUpdate(md, host_key->iov_base, host_key->iov_len) != 1)
+        if (iovec_is_set(host_key) && sym_EVP_DigestUpdate(md, host_key->iov_base, host_key->iov_len) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to hash host key.");
 
-        if (iovec_is_set(tpm2_key) && EVP_DigestUpdate(md, tpm2_key->iov_base, tpm2_key->iov_len) != 1)
+        if (iovec_is_set(tpm2_key) && sym_EVP_DigestUpdate(md, tpm2_key->iov_base, tpm2_key->iov_len) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to hash TPM2 key.");
 
-        assert(EVP_MD_CTX_size(md) == SHA256_DIGEST_LENGTH);
+        assert(sym_EVP_MD_CTX_get_size(md) == SHA256_DIGEST_LENGTH);
 
-        if (EVP_DigestFinal_ex(md, ret, &l) != 1)
+        if (sym_EVP_DigestFinal_ex(md, ret, &l) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize SHA256 hash.");
 
         assert(l == SHA256_DIGEST_LENGTH);
@@ -1039,16 +1040,20 @@ int encrypt_credential_and_warn(
                         return r;
         }
 
-        assert_se(cc = EVP_aes_256_gcm());
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        assert_se(cc = sym_EVP_aes_256_gcm());
 
-        ksz = EVP_CIPHER_key_length(cc);
+        ksz = sym_EVP_CIPHER_get_key_length(cc);
         assert(ksz == sizeof(md));
 
-        bsz = EVP_CIPHER_block_size(cc);
+        bsz = sym_EVP_CIPHER_get_block_size(cc);
         assert(bsz > 0);
         assert((size_t) bsz <= CREDENTIAL_FIELD_SIZE_MAX);
 
-        ivsz = EVP_CIPHER_iv_length(cc);
+        ivsz = sym_EVP_CIPHER_get_iv_length(cc);
         if (ivsz > 0) {
                 assert((size_t) ivsz <= CREDENTIAL_FIELD_SIZE_MAX);
 
@@ -1059,14 +1064,14 @@ int encrypt_credential_and_warn(
 
         tsz = 16; /* FIXME: On OpenSSL 3 there is EVP_CIPHER_CTX_get_tag_length(), until then let's hardcode this */
 
-        context = EVP_CIPHER_CTX_new();
+        context = sym_EVP_CIPHER_CTX_new();
         if (!context)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to allocate encryption object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (EVP_EncryptInit_ex(context, cc, NULL, md, iv.iov_base) != 1)
+        if (sym_EVP_EncryptInit_ex(context, cc, NULL, md, iv.iov_base) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize encryption context: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         /* Just an upper estimate */
         output.iov_len =
@@ -1131,9 +1136,9 @@ int encrypt_credential_and_warn(
         }
 
         /* Pass the encrypted + TPM2 header + scoped header as AAD */
-        if (EVP_EncryptUpdate(context, NULL, &added, output.iov_base, p) != 1)
+        if (sym_EVP_EncryptUpdate(context, NULL, &added, output.iov_base, p) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to write AAD data: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         /* Now construct the metadata header */
         ml = strlen_ptr(name);
@@ -1147,27 +1152,27 @@ int encrypt_credential_and_warn(
         memcpy_safe(m->name, name, ml);
 
         /* And encrypt the metadata header */
-        if (EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, (const unsigned char*) m, ALIGN8(offsetof(struct metadata_credential_header, name) + ml)) != 1)
+        if (sym_EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, (const unsigned char*) m, ALIGN8(offsetof(struct metadata_credential_header, name) + ml)) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt metadata header: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         assert(added >= 0);
         assert((size_t) added <= output.iov_len - p);
         p += added;
 
         /* Then encrypt the plaintext */
-        if (EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, input->iov_base, input->iov_len) != 1)
+        if (sym_EVP_EncryptUpdate(context, (uint8_t*) output.iov_base + p, &added, input->iov_base, input->iov_len) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to encrypt data: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         assert(added >= 0);
         assert((size_t) added <= output.iov_len - p);
         p += added;
 
         /* Finalize */
-        if (EVP_EncryptFinal_ex(context, (uint8_t*) output.iov_base + p, &added) != 1)
+        if (sym_EVP_EncryptFinal_ex(context, (uint8_t*) output.iov_base + p, &added) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to finalize data encryption: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         assert(added >= 0);
         assert((size_t) added <= output.iov_len - p);
@@ -1176,9 +1181,9 @@ int encrypt_credential_and_warn(
         assert(p <= output.iov_len - tsz);
 
         /* Append tag */
-        if (EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_GET_TAG, tsz, (uint8_t*) output.iov_base + p) != 1)
+        if (sym_EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_GET_TAG, tsz, (uint8_t*) output.iov_base + p) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to get tag: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         p += tsz;
         assert(p <= output.iov_len);
@@ -1435,59 +1440,63 @@ int decrypt_credential_and_warn(
                         return r;
         }
 
-        assert_se(cc = EVP_aes_256_gcm());
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        assert_se(cc = sym_EVP_aes_256_gcm());
 
         /* Make sure cipher expectations match the header */
-        if (EVP_CIPHER_key_length(cc) != (int) le32toh(h->key_size))
+        if (sym_EVP_CIPHER_get_key_length(cc) != (int) le32toh(h->key_size))
                 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Unexpected key size in header.");
-        if (EVP_CIPHER_block_size(cc) != (int) le32toh(h->block_size))
+        if (sym_EVP_CIPHER_get_block_size(cc) != (int) le32toh(h->block_size))
                 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Unexpected block size in header.");
 
-        context = EVP_CIPHER_CTX_new();
+        context = sym_EVP_CIPHER_CTX_new();
         if (!context)
                 return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to allocate decryption object: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (EVP_DecryptInit_ex(context, cc, NULL, NULL, NULL) != 1)
+        if (sym_EVP_DecryptInit_ex(context, cc, NULL, NULL, NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to initialize decryption context: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_IVLEN, le32toh(h->iv_size), NULL) != 1)
+        if (sym_EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_IVLEN, le32toh(h->iv_size), NULL) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set IV size on decryption context: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (EVP_DecryptInit_ex(context, NULL, NULL, md, h->iv) != 1)
+        if (sym_EVP_DecryptInit_ex(context, NULL, NULL, md, h->iv) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set IV and key: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (EVP_DecryptUpdate(context, NULL, &added, input->iov_base, p) != 1)
+        if (sym_EVP_DecryptUpdate(context, NULL, &added, input->iov_base, p) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to write AAD data: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         plaintext.iov_base = malloc(input->iov_len - p - le32toh(h->tag_size));
         if (!plaintext.iov_base)
                 return -ENOMEM;
 
-        if (EVP_DecryptUpdate(
+        if (sym_EVP_DecryptUpdate(
                             context,
                             plaintext.iov_base,
                             &added,
                             (uint8_t*) input->iov_base + p,
                             input->iov_len - p - le32toh(h->tag_size)) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to decrypt data: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         assert(added >= 0);
         assert((size_t) added <= input->iov_len - p - le32toh(h->tag_size));
         plaintext.iov_len = added;
 
-        if (EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_TAG, le32toh(h->tag_size), (uint8_t*) input->iov_base + input->iov_len - le32toh(h->tag_size)) != 1)
+        if (sym_EVP_CIPHER_CTX_ctrl(context, EVP_CTRL_GCM_SET_TAG, le32toh(h->tag_size), (uint8_t*) input->iov_base + input->iov_len - le32toh(h->tag_size)) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set tag: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (EVP_DecryptFinal_ex(context, (uint8_t*) plaintext.iov_base + plaintext.iov_len, &added) != 1)
+        if (sym_EVP_DecryptFinal_ex(context, (uint8_t*) plaintext.iov_base + plaintext.iov_len, &added) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Decryption failed (incorrect key?): %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         plaintext.iov_len += added;
 
similarity index 51%
rename from src/shared/openssl-util.c
rename to src/shared/crypto-util.c
index 18c6b06b17dc1eb37e2b7376dc2842340c2de7f8..bf770f2432175003a9bea3ed21a75d3a0eae3529 100644 (file)
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include "sd-dlopen.h"
+
 #include "alloc-util.h"
 #include "ask-password-api.h"
+#include "crypto-util.h"
+#include "dlfcn-util.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "hexdecoct.h"
 #include "log.h"
 #include "memory-util.h"
 #include "memstream-util.h"
-#include "openssl-util.h"
 #include "random-util.h"
 #include "string-util.h"
 #include "strv.h"
 
 #if HAVE_OPENSSL
-#  include <openssl/ec.h>
-#  include <openssl/rsa.h>
+#  include <openssl/core_names.h>
+#  include <openssl/kdf.h>
+#  include <openssl/provider.h>
+#  include <openssl/store.h>
 
 #  if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
 #    include <openssl/engine.h>
+#  endif
+
+#  ifndef OPENSSL_NO_UI_CONSOLE
+#    include <openssl/ui.h>
+#  endif
+
+struct OpenSSLAskPasswordUI {
+        AskPasswordRequest request;
+#ifndef OPENSSL_NO_UI_CONSOLE
+        UI_METHOD *method;
+#endif
+};
+
+static void *libcrypto_dl = NULL;
+
+static DLSYM_PROTOTYPE(ASN1_INTEGER_dup) = NULL;
+static DLSYM_PROTOTYPE(ASN1_INTEGER_free) = NULL;
+static DLSYM_PROTOTYPE(ASN1_INTEGER_set) = NULL;
+DLSYM_PROTOTYPE(ASN1_ANY_it) = NULL;
+DLSYM_PROTOTYPE(ASN1_BIT_STRING_it) = NULL;
+DLSYM_PROTOTYPE(ASN1_BMPSTRING_it) = NULL;
+DLSYM_PROTOTYPE(ASN1_BMPSTRING_new) = NULL;
+DLSYM_PROTOTYPE(ASN1_IA5STRING_it) = NULL;
+DLSYM_PROTOTYPE(ASN1_OBJECT_it) = NULL;
+DLSYM_PROTOTYPE(ASN1_OCTET_STRING_free) = NULL;
+DLSYM_PROTOTYPE(ASN1_OCTET_STRING_it) = NULL;
+DLSYM_PROTOTYPE(ASN1_OCTET_STRING_set) = NULL;
+DLSYM_PROTOTYPE(ASN1_STRING_get0_data) = NULL;
+DLSYM_PROTOTYPE(ASN1_STRING_length) = NULL;
+DLSYM_PROTOTYPE(ASN1_STRING_new) = NULL;
+DLSYM_PROTOTYPE(ASN1_STRING_set) = NULL;
+DLSYM_PROTOTYPE(ASN1_STRING_set0) = NULL;
+DLSYM_PROTOTYPE(ASN1_TIME_free) = NULL;
+DLSYM_PROTOTYPE(ASN1_TIME_set) = NULL;
+DLSYM_PROTOTYPE(ASN1_TYPE_new) = NULL;
+DLSYM_PROTOTYPE(ASN1_get_object) = NULL;
+DLSYM_PROTOTYPE(ASN1_item_d2i) = NULL;
+DLSYM_PROTOTYPE(ASN1_item_free) = NULL;
+DLSYM_PROTOTYPE(ASN1_item_i2d) = NULL;
+DLSYM_PROTOTYPE(ASN1_item_new) = NULL;
+DLSYM_PROTOTYPE(BIO_ctrl) = NULL;
+DLSYM_PROTOTYPE(BIO_find_type) = NULL;
+DLSYM_PROTOTYPE(BIO_free) = NULL;
+DLSYM_PROTOTYPE(BIO_free_all) = NULL;
+DLSYM_PROTOTYPE(BIO_new) = NULL;
+DLSYM_PROTOTYPE(BIO_new_mem_buf) = NULL;
+DLSYM_PROTOTYPE(BIO_new_socket) = NULL;
+DLSYM_PROTOTYPE(BIO_s_mem) = NULL;
+DLSYM_PROTOTYPE(BIO_write) = NULL;
+DLSYM_PROTOTYPE(BN_CTX_free) = NULL;
+DLSYM_PROTOTYPE(BN_CTX_new) = NULL;
+DLSYM_PROTOTYPE(BN_bin2bn) = NULL;
+static DLSYM_PROTOTYPE(BN_bn2bin) = NULL;
+DLSYM_PROTOTYPE(BN_bn2nativepad) = NULL;
+DLSYM_PROTOTYPE(BN_free) = NULL;
+DLSYM_PROTOTYPE(BN_new) = NULL;
+DLSYM_PROTOTYPE(BN_num_bits) = NULL;
+DLSYM_PROTOTYPE(CRYPTO_free) = NULL;
+DLSYM_PROTOTYPE(ECDSA_SIG_free) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_free) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_get0_generator) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_get0_order) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_get_curve) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_get_curve_name) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_get_field_type) = NULL;
+DLSYM_PROTOTYPE(EC_GROUP_new_by_curve_name) = NULL;
+DLSYM_PROTOTYPE(EC_POINT_free) = NULL;
+DLSYM_PROTOTYPE(EC_POINT_new) = NULL;
+DLSYM_PROTOTYPE(EC_POINT_oct2point) = NULL;
+static DLSYM_PROTOTYPE(EC_POINT_point2buf) = NULL;
+DLSYM_PROTOTYPE(EC_POINT_point2oct) = NULL;
+static DLSYM_PROTOTYPE(EC_POINT_set_affine_coordinates) = NULL;
+DLSYM_PROTOTYPE(ERR_clear_error) = NULL;
+DLSYM_PROTOTYPE(ERR_error_string) = NULL;
+DLSYM_PROTOTYPE(ERR_error_string_n) = NULL;
+DLSYM_PROTOTYPE(ERR_get_error) = NULL;
+static DLSYM_PROTOTYPE(ERR_peek_last_error) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_CTX_ctrl) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_CTX_free) = NULL;
+static DLSYM_PROTOTYPE(EVP_CIPHER_CTX_get_block_size) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_CTX_new) = NULL;
+static DLSYM_PROTOTYPE(EVP_CIPHER_fetch) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_free) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_get_block_size) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_get_iv_length) = NULL;
+DLSYM_PROTOTYPE(EVP_CIPHER_get_key_length) = NULL;
+DLSYM_PROTOTYPE(EVP_DecryptFinal_ex) = NULL;
+DLSYM_PROTOTYPE(EVP_DecryptInit_ex) = NULL;
+DLSYM_PROTOTYPE(EVP_DecryptUpdate) = NULL;
+DLSYM_PROTOTYPE(EVP_Digest) = NULL;
+DLSYM_PROTOTYPE(EVP_DigestFinal_ex) = NULL;
+DLSYM_PROTOTYPE(EVP_DigestInit_ex) = NULL;
+static DLSYM_PROTOTYPE(EVP_DigestSign) = NULL;
+static DLSYM_PROTOTYPE(EVP_DigestSignInit) = NULL;
+DLSYM_PROTOTYPE(EVP_DigestUpdate) = NULL;
+DLSYM_PROTOTYPE(EVP_DigestVerify) = NULL;
+DLSYM_PROTOTYPE(EVP_DigestVerifyInit) = NULL;
+DLSYM_PROTOTYPE(EVP_EncryptFinal_ex) = NULL;
+static DLSYM_PROTOTYPE(EVP_EncryptInit) = NULL;
+DLSYM_PROTOTYPE(EVP_EncryptInit_ex) = NULL;
+DLSYM_PROTOTYPE(EVP_EncryptUpdate) = NULL;
+static DLSYM_PROTOTYPE(EVP_KDF_CTX_free) = NULL;
+static DLSYM_PROTOTYPE(EVP_KDF_CTX_new) = NULL;
+static DLSYM_PROTOTYPE(EVP_KDF_derive) = NULL;
+static DLSYM_PROTOTYPE(EVP_KDF_fetch) = NULL;
+static DLSYM_PROTOTYPE(EVP_KDF_free) = NULL;
+DLSYM_PROTOTYPE(EVP_MAC_CTX_free) = NULL;
+static DLSYM_PROTOTYPE(EVP_MAC_CTX_get_mac_size) = NULL;
+static DLSYM_PROTOTYPE(EVP_MAC_CTX_new) = NULL;
+static DLSYM_PROTOTYPE(EVP_MAC_fetch) = NULL;
+static DLSYM_PROTOTYPE(EVP_MAC_final) = NULL;
+DLSYM_PROTOTYPE(EVP_MAC_free) = NULL;
+static DLSYM_PROTOTYPE(EVP_MAC_init) = NULL;
+static DLSYM_PROTOTYPE(EVP_MAC_update) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_CTX_free) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_CTX_get0_md) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_CTX_new) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_CTX_set_pkey_ctx) = NULL;
+static DLSYM_PROTOTYPE(EVP_MD_fetch) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_free) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_get0_name) = NULL;
+DLSYM_PROTOTYPE(EVP_MD_get_size) = NULL;
+static DLSYM_PROTOTYPE(EVP_MD_get_type) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_CTX_free) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_CTX_new) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_CTX_new_from_name) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_CTX_new_id) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_CTX_set0_rsa_oaep_label) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_ec_paramgen_curve_nid) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_rsa_oaep_md) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_rsa_padding) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_signature_md) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_derive) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_derive_init) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_derive_set_peer) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_encrypt) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_encrypt_init) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_eq) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_free) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_fromdata) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_fromdata_init) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_get1_encoded_public_key) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_get_base_id) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_get_bits) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_get_bn_param) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_get_group_name) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_get_id) = NULL;
+static DLSYM_PROTOTYPE(EVP_PKEY_get_utf8_string_param) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_keygen) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_keygen_init) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_new) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_new_raw_public_key) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_verify) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_verify_init) = NULL;
+DLSYM_PROTOTYPE(EVP_aes_256_ctr) = NULL;
+DLSYM_PROTOTYPE(EVP_aes_256_gcm) = NULL;
+DLSYM_PROTOTYPE(EVP_get_cipherbyname) = NULL;
+DLSYM_PROTOTYPE(EVP_get_digestbyname) = NULL;
+DLSYM_PROTOTYPE(EVP_sha1) = NULL;
+DLSYM_PROTOTYPE(EVP_sha256) = NULL;
+DLSYM_PROTOTYPE(EVP_sha384) = NULL;
+DLSYM_PROTOTYPE(EVP_sha512) = NULL;
+DLSYM_PROTOTYPE(HMAC) = NULL;
+DLSYM_PROTOTYPE(SHA1) = NULL;
+DLSYM_PROTOTYPE(SHA512) = NULL;
+DLSYM_PROTOTYPE(OBJ_nid2obj) = NULL;
+DLSYM_PROTOTYPE(OBJ_nid2sn) = NULL;
+DLSYM_PROTOTYPE(OBJ_sn2nid) = NULL;
+DLSYM_PROTOTYPE(OBJ_txt2obj) = NULL;
+DLSYM_PROTOTYPE(OPENSSL_sk_new_null) = NULL;
+DLSYM_PROTOTYPE(OPENSSL_sk_num) = NULL;
+DLSYM_PROTOTYPE(OPENSSL_sk_pop_free) = NULL;
+DLSYM_PROTOTYPE(OPENSSL_sk_push) = NULL;
+DLSYM_PROTOTYPE(OPENSSL_sk_value) = NULL;
+DLSYM_PROTOTYPE(OSSL_EC_curve_nid2name) = NULL;
+static DLSYM_PROTOTYPE(OSSL_PARAM_BLD_new) = NULL;
+static DLSYM_PROTOTYPE(OSSL_PARAM_BLD_free) = NULL;
+static DLSYM_PROTOTYPE(OSSL_PARAM_BLD_push_octet_string) = NULL;
+static DLSYM_PROTOTYPE(OSSL_PARAM_BLD_push_utf8_string) = NULL;
+static DLSYM_PROTOTYPE(OSSL_PARAM_BLD_to_param) = NULL;
+DLSYM_PROTOTYPE(OSSL_PARAM_construct_BN) = NULL;
+DLSYM_PROTOTYPE(OSSL_PARAM_construct_end) = NULL;
+DLSYM_PROTOTYPE(OSSL_PARAM_construct_octet_string) = NULL;
+DLSYM_PROTOTYPE(OSSL_PARAM_construct_utf8_string) = NULL;
+DLSYM_PROTOTYPE(OSSL_PARAM_free) = NULL;
+static DLSYM_PROTOTYPE(OSSL_PROVIDER_try_load) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_INFO_free) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_INFO_get1_CERT) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_INFO_get1_PKEY) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_close) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_expect) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_load) = NULL;
+static DLSYM_PROTOTYPE(OSSL_STORE_open) = NULL;
+DLSYM_PROTOTYPE(PEM_read_PUBKEY) = NULL;
+DLSYM_PROTOTYPE(PEM_read_PrivateKey) = NULL;
+DLSYM_PROTOTYPE(PEM_read_X509) = NULL;
+static DLSYM_PROTOTYPE(PEM_read_bio_PrivateKey) = NULL;
+static DLSYM_PROTOTYPE(PEM_read_bio_X509) = NULL;
+DLSYM_PROTOTYPE(PKCS5_PBKDF2_HMAC) = NULL;
+DLSYM_PROTOTYPE(PEM_write_PUBKEY) = NULL;
+DLSYM_PROTOTYPE(PEM_write_PrivateKey) = NULL;
+DLSYM_PROTOTYPE(PEM_write_X509) = NULL;
+DLSYM_PROTOTYPE(PKCS7_SIGNER_INFO_free) = NULL;
+DLSYM_PROTOTYPE(PKCS7_ATTR_SIGN_it) = NULL;
+static DLSYM_PROTOTYPE(PKCS7_SIGNER_INFO_new) = NULL;
+static DLSYM_PROTOTYPE(PKCS7_SIGNER_INFO_set) = NULL;
+DLSYM_PROTOTYPE(PKCS7_add0_attrib_signing_time) = NULL;
+DLSYM_PROTOTYPE(PKCS7_add1_attrib_digest) = NULL;
+DLSYM_PROTOTYPE(PKCS7_add_attrib_content_type) = NULL;
+DLSYM_PROTOTYPE(PKCS7_add_attrib_smimecap) = NULL;
+static DLSYM_PROTOTYPE(PKCS7_add_certificate) = NULL;
+DLSYM_PROTOTYPE(PKCS7_add_signed_attribute) = NULL;
+static DLSYM_PROTOTYPE(PKCS7_add_signer) = NULL;
+DLSYM_PROTOTYPE(PKCS7_content_new) = NULL;
+DLSYM_PROTOTYPE(PKCS7_ctrl) = NULL;
+DLSYM_PROTOTYPE(PKCS7_dataFinal) = NULL;
+DLSYM_PROTOTYPE(PKCS7_dataInit) = NULL;
+DLSYM_PROTOTYPE(PKCS7_free) = NULL;
+DLSYM_PROTOTYPE(PKCS7_get_signer_info) = NULL;
+DLSYM_PROTOTYPE(PKCS7_new) = NULL;
+DLSYM_PROTOTYPE(PKCS7_set_content) = NULL;
+static DLSYM_PROTOTYPE(PKCS7_set_type) = NULL;
+DLSYM_PROTOTYPE(PKCS7_sign) = NULL;
+DLSYM_PROTOTYPE(PKCS7_verify) = NULL;
+static DLSYM_PROTOTYPE(X509_ALGOR_set0) = NULL;
+DLSYM_PROTOTYPE(X509_NAME_free) = NULL;
+DLSYM_PROTOTYPE(X509_ALGOR_free) = NULL;
+DLSYM_PROTOTYPE(X509_ATTRIBUTE_free) = NULL;
+DLSYM_PROTOTYPE(X509_NAME_oneline) = NULL;
+static DLSYM_PROTOTYPE(X509_NAME_set) = NULL;
+DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set1_host) = NULL;
+DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set1_ip) = NULL;
+DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set_hostflags) = NULL;
+DLSYM_PROTOTYPE(X509_free) = NULL;
+DLSYM_PROTOTYPE(X509_gmtime_adj) = NULL;
+static DLSYM_PROTOTYPE(X509_get0_serialNumber) = NULL;
+static DLSYM_PROTOTYPE(X509_get_issuer_name) = NULL;
+DLSYM_PROTOTYPE(X509_get_pubkey) = NULL;
+static DLSYM_PROTOTYPE(X509_get_signature_info) = NULL;
+DLSYM_PROTOTYPE(X509_get_subject_name) = NULL;
+DLSYM_PROTOTYPE(d2i_ASN1_OCTET_STRING) = NULL;
+DLSYM_PROTOTYPE(d2i_ECPKParameters) = NULL;
+DLSYM_PROTOTYPE(d2i_PKCS7) = NULL;
+DLSYM_PROTOTYPE(d2i_PUBKEY) = NULL;
+DLSYM_PROTOTYPE(d2i_X509) = NULL;
+DLSYM_PROTOTYPE(i2d_ASN1_INTEGER) = NULL;
+DLSYM_PROTOTYPE(i2d_PKCS7) = NULL;
+DLSYM_PROTOTYPE(i2d_PKCS7_fp) = NULL;
+DLSYM_PROTOTYPE(i2d_PUBKEY) = NULL;
+static DLSYM_PROTOTYPE(i2d_PUBKEY_fp) = NULL;
+static DLSYM_PROTOTYPE(i2d_PublicKey) = NULL;
+DLSYM_PROTOTYPE(i2d_X509) = NULL;
+DLSYM_PROTOTYPE(i2d_X509_NAME) = NULL;
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(OSSL_PARAM_BLD*, sym_OSSL_PARAM_BLD_free, OSSL_PARAM_BLD_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(OSSL_STORE_CTX*, sym_OSSL_STORE_close, OSSL_STORE_closep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(OSSL_STORE_INFO*, sym_OSSL_STORE_INFO_free, OSSL_STORE_INFO_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_KDF*, sym_EVP_KDF_free, EVP_KDF_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_KDF_CTX*, sym_EVP_KDF_CTX_free, EVP_KDF_CTX_freep, NULL);
+
+#if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
 DISABLE_WARNING_DEPRECATED_DECLARATIONS;
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ENGINE*, ENGINE_free, NULL);
+static DLSYM_PROTOTYPE(ENGINE_by_id) = NULL;
+static DLSYM_PROTOTYPE(ENGINE_free) = NULL;
+static DLSYM_PROTOTYPE(ENGINE_init) = NULL;
+static DLSYM_PROTOTYPE(ENGINE_load_private_key) = NULL;
 REENABLE_WARNING;
-#  endif
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ENGINE*, sym_ENGINE_free, ENGINE_freep, NULL);
+#endif
+
+#if !defined(OPENSSL_NO_DEPRECATED_3_0)
+DISABLE_WARNING_DEPRECATED_DECLARATIONS;
+DLSYM_PROTOTYPE(ECDSA_SIG_new) = NULL;
+DLSYM_PROTOTYPE(ECDSA_SIG_set0) = NULL;
+DLSYM_PROTOTYPE(ECDSA_do_verify) = NULL;
+DLSYM_PROTOTYPE(EC_KEY_check_key) = NULL;
+DLSYM_PROTOTYPE(EC_KEY_free) = NULL;
+DLSYM_PROTOTYPE(EC_KEY_new) = NULL;
+DLSYM_PROTOTYPE(EC_KEY_set_group) = NULL;
+DLSYM_PROTOTYPE(EC_KEY_set_public_key) = NULL;
+DLSYM_PROTOTYPE(EVP_PKEY_assign) = NULL;
+DLSYM_PROTOTYPE(RSA_free) = NULL;
+DLSYM_PROTOTYPE(RSA_new) = NULL;
+DLSYM_PROTOTYPE(RSA_set0_key) = NULL;
+DLSYM_PROTOTYPE(RSA_size) = NULL;
+DLSYM_PROTOTYPE(RSAPublicKey_dup) = NULL;
+REENABLE_WARNING;
+#endif
 
 #ifndef OPENSSL_NO_UI_CONSOLE
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(UI_METHOD*, UI_destroy_method, NULL);
+static DLSYM_PROTOTYPE(UI_OpenSSL) = NULL;
+static DLSYM_PROTOTYPE(UI_create_method) = NULL;
+static DLSYM_PROTOTYPE(UI_destroy_method) = NULL;
+static DLSYM_PROTOTYPE(UI_get0_output_string) = NULL;
+static DLSYM_PROTOTYPE(UI_get_default_method) = NULL;
+static DLSYM_PROTOTYPE(UI_get_method) = NULL;
+static DLSYM_PROTOTYPE(UI_get_string_type) = NULL;
+static DLSYM_PROTOTYPE(UI_method_get_ex_data) = NULL;
+static DLSYM_PROTOTYPE(UI_method_get_reader) = NULL;
+static DLSYM_PROTOTYPE(UI_method_set_ex_data) = NULL;
+static DLSYM_PROTOTYPE(UI_method_set_reader) = NULL;
+static DLSYM_PROTOTYPE(UI_set_default_method) = NULL;
+static DLSYM_PROTOTYPE(UI_set_result) = NULL;
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(UI_METHOD*, sym_UI_destroy_method, UI_destroy_methodp, NULL);
 #endif
 
+#endif
+
+int dlopen_libcrypto(int log_level) {
+#if HAVE_OPENSSL
+        SD_ELF_NOTE_DLOPEN(
+                        "libcrypto",
+                        "Support for cryptographic operations",
+                        SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libcrypto.so.3");
+
+        return dlopen_many_sym_or_warn(
+                        &libcrypto_dl,
+                        "libcrypto.so.3",
+                        log_level,
+                        DLSYM_ARG(ASN1_ANY_it),
+                        DLSYM_ARG(ASN1_BIT_STRING_it),
+                        DLSYM_ARG(ASN1_BMPSTRING_it),
+                        DLSYM_ARG(ASN1_BMPSTRING_new),
+                        DLSYM_ARG(ASN1_get_object),
+                        DLSYM_ARG(ASN1_IA5STRING_it),
+                        DLSYM_ARG(ASN1_INTEGER_dup),
+                        DLSYM_ARG(ASN1_INTEGER_free),
+                        DLSYM_ARG(ASN1_INTEGER_set),
+                        DLSYM_ARG(ASN1_item_d2i),
+                        DLSYM_ARG(ASN1_item_free),
+                        DLSYM_ARG(ASN1_item_i2d),
+                        DLSYM_ARG(ASN1_item_new),
+                        DLSYM_ARG(ASN1_OBJECT_it),
+                        DLSYM_ARG(ASN1_OCTET_STRING_free),
+                        DLSYM_ARG(ASN1_OCTET_STRING_it),
+                        DLSYM_ARG(ASN1_OCTET_STRING_set),
+                        DLSYM_ARG(ASN1_STRING_get0_data),
+                        DLSYM_ARG(ASN1_STRING_length),
+                        DLSYM_ARG(ASN1_STRING_new),
+                        DLSYM_ARG(ASN1_STRING_set),
+                        DLSYM_ARG(ASN1_STRING_set0),
+                        DLSYM_ARG(ASN1_TIME_free),
+                        DLSYM_ARG(ASN1_TIME_set),
+                        DLSYM_ARG(ASN1_TYPE_new),
+                        DLSYM_ARG(BIO_ctrl),
+                        DLSYM_ARG(BIO_find_type),
+                        DLSYM_ARG(BIO_free_all),
+                        DLSYM_ARG(BIO_free),
+                        DLSYM_ARG(BIO_new_mem_buf),
+                        DLSYM_ARG(BIO_new_socket),
+                        DLSYM_ARG(BIO_new),
+                        DLSYM_ARG(BIO_s_mem),
+                        DLSYM_ARG(BIO_write),
+                        DLSYM_ARG(BN_bin2bn),
+                        DLSYM_ARG(BN_bn2bin),
+                        DLSYM_ARG(BN_bn2nativepad),
+                        DLSYM_ARG(BN_CTX_free),
+                        DLSYM_ARG(BN_CTX_new),
+                        DLSYM_ARG(BN_free),
+                        DLSYM_ARG(BN_new),
+                        DLSYM_ARG(BN_num_bits),
+                        DLSYM_ARG(CRYPTO_free),
+                        DLSYM_ARG(d2i_ASN1_OCTET_STRING),
+                        DLSYM_ARG(d2i_ECPKParameters),
+                        DLSYM_ARG(d2i_PKCS7),
+                        DLSYM_ARG(d2i_PUBKEY),
+                        DLSYM_ARG(d2i_X509),
+                        DLSYM_ARG(EC_GROUP_free),
+                        DLSYM_ARG(EC_GROUP_get_curve_name),
+                        DLSYM_ARG(EC_GROUP_get_curve),
+                        DLSYM_ARG(EC_GROUP_get_field_type),
+                        DLSYM_ARG(EC_GROUP_get0_generator),
+                        DLSYM_ARG(EC_GROUP_get0_order),
+                        DLSYM_ARG(EC_GROUP_new_by_curve_name),
+                        DLSYM_ARG(EC_POINT_free),
+                        DLSYM_ARG(EC_POINT_new),
+                        DLSYM_ARG(EC_POINT_oct2point),
+                        DLSYM_ARG(EC_POINT_point2buf),
+                        DLSYM_ARG(EC_POINT_point2oct),
+                        DLSYM_ARG(EC_POINT_set_affine_coordinates),
+                        DLSYM_ARG(ECDSA_SIG_free),
+#if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
+                        DLSYM_ARG_FORCE(ENGINE_by_id),
+                        DLSYM_ARG_FORCE(ENGINE_free),
+                        DLSYM_ARG_FORCE(ENGINE_init),
+                        DLSYM_ARG_FORCE(ENGINE_load_private_key),
+#endif
+#if !defined(OPENSSL_NO_DEPRECATED_3_0)
+                        DLSYM_ARG_FORCE(EC_KEY_check_key),
+                        DLSYM_ARG_FORCE(EC_KEY_free),
+                        DLSYM_ARG_FORCE(EC_KEY_new),
+                        DLSYM_ARG_FORCE(EC_KEY_set_group),
+                        DLSYM_ARG_FORCE(EC_KEY_set_public_key),
+                        DLSYM_ARG_FORCE(ECDSA_do_verify),
+                        DLSYM_ARG_FORCE(ECDSA_SIG_new),
+                        DLSYM_ARG_FORCE(ECDSA_SIG_set0),
+                        DLSYM_ARG_FORCE(EVP_PKEY_assign),
+                        DLSYM_ARG_FORCE(RSA_free),
+                        DLSYM_ARG_FORCE(RSA_new),
+                        DLSYM_ARG_FORCE(RSA_set0_key),
+                        DLSYM_ARG_FORCE(RSA_size),
+                        DLSYM_ARG_FORCE(RSAPublicKey_dup),
+#endif
+                        DLSYM_ARG(ERR_clear_error),
+                        DLSYM_ARG(ERR_error_string_n),
+                        DLSYM_ARG(ERR_error_string),
+                        DLSYM_ARG(ERR_get_error),
+                        DLSYM_ARG(ERR_peek_last_error),
+                        DLSYM_ARG(EVP_aes_256_ctr),
+                        DLSYM_ARG(EVP_aes_256_gcm),
+                        DLSYM_ARG(EVP_CIPHER_CTX_ctrl),
+                        DLSYM_ARG(EVP_CIPHER_CTX_free),
+                        DLSYM_ARG(EVP_CIPHER_CTX_get_block_size),
+                        DLSYM_ARG(EVP_CIPHER_CTX_new),
+                        DLSYM_ARG(EVP_CIPHER_fetch),
+                        DLSYM_ARG(EVP_CIPHER_free),
+                        DLSYM_ARG(EVP_CIPHER_get_block_size),
+                        DLSYM_ARG(EVP_CIPHER_get_iv_length),
+                        DLSYM_ARG(EVP_CIPHER_get_key_length),
+                        DLSYM_ARG(EVP_DecryptFinal_ex),
+                        DLSYM_ARG(EVP_DecryptInit_ex),
+                        DLSYM_ARG(EVP_DecryptUpdate),
+                        DLSYM_ARG(EVP_Digest),
+                        DLSYM_ARG(EVP_DigestFinal_ex),
+                        DLSYM_ARG(EVP_DigestInit_ex),
+                        DLSYM_ARG(EVP_DigestSign),
+                        DLSYM_ARG(EVP_DigestSignInit),
+                        DLSYM_ARG(EVP_DigestUpdate),
+                        DLSYM_ARG(EVP_DigestVerify),
+                        DLSYM_ARG(EVP_DigestVerifyInit),
+                        DLSYM_ARG(EVP_EncryptFinal_ex),
+                        DLSYM_ARG(EVP_EncryptInit_ex),
+                        DLSYM_ARG(EVP_EncryptInit),
+                        DLSYM_ARG(EVP_EncryptUpdate),
+                        DLSYM_ARG(EVP_get_cipherbyname),
+                        DLSYM_ARG(EVP_get_digestbyname),
+                        DLSYM_ARG(EVP_KDF_CTX_free),
+                        DLSYM_ARG(EVP_KDF_CTX_new),
+                        DLSYM_ARG(EVP_KDF_derive),
+                        DLSYM_ARG(EVP_KDF_fetch),
+                        DLSYM_ARG(EVP_KDF_free),
+                        DLSYM_ARG(EVP_MAC_CTX_free),
+                        DLSYM_ARG(EVP_MAC_CTX_get_mac_size),
+                        DLSYM_ARG(EVP_MAC_CTX_new),
+                        DLSYM_ARG(EVP_MAC_fetch),
+                        DLSYM_ARG(EVP_MAC_final),
+                        DLSYM_ARG(EVP_MAC_free),
+                        DLSYM_ARG(EVP_MAC_init),
+                        DLSYM_ARG(EVP_MAC_update),
+                        DLSYM_ARG(EVP_MD_CTX_free),
+                        DLSYM_ARG(EVP_MD_CTX_get0_md),
+                        DLSYM_ARG(EVP_MD_CTX_new),
+                        DLSYM_ARG(EVP_MD_CTX_set_pkey_ctx),
+                        DLSYM_ARG(EVP_MD_fetch),
+                        DLSYM_ARG(EVP_MD_free),
+                        DLSYM_ARG(EVP_MD_get_size),
+                        DLSYM_ARG(EVP_MD_get_type),
+                        DLSYM_ARG(EVP_MD_get0_name),
+                        DLSYM_ARG(EVP_PKEY_CTX_free),
+                        DLSYM_ARG(EVP_PKEY_CTX_new_from_name),
+                        DLSYM_ARG(EVP_PKEY_CTX_new_id),
+                        DLSYM_ARG(EVP_PKEY_CTX_new),
+                        DLSYM_ARG(EVP_PKEY_CTX_set_ec_paramgen_curve_nid),
+                        DLSYM_ARG(EVP_PKEY_CTX_set_rsa_oaep_md),
+                        DLSYM_ARG(EVP_PKEY_CTX_set_rsa_padding),
+                        DLSYM_ARG(EVP_PKEY_CTX_set_signature_md),
+                        DLSYM_ARG(EVP_PKEY_CTX_set0_rsa_oaep_label),
+                        DLSYM_ARG(EVP_PKEY_derive_init),
+                        DLSYM_ARG(EVP_PKEY_derive_set_peer),
+                        DLSYM_ARG(EVP_PKEY_derive),
+                        DLSYM_ARG(EVP_PKEY_encrypt_init),
+                        DLSYM_ARG(EVP_PKEY_encrypt),
+                        DLSYM_ARG(EVP_PKEY_eq),
+                        DLSYM_ARG(EVP_PKEY_free),
+                        DLSYM_ARG(EVP_PKEY_fromdata_init),
+                        DLSYM_ARG(EVP_PKEY_fromdata),
+                        DLSYM_ARG(EVP_PKEY_get_base_id),
+                        DLSYM_ARG(EVP_PKEY_get_bits),
+                        DLSYM_ARG(EVP_PKEY_get_bn_param),
+                        DLSYM_ARG(EVP_PKEY_get_group_name),
+                        DLSYM_ARG(EVP_PKEY_get_id),
+                        DLSYM_ARG(EVP_PKEY_get_utf8_string_param),
+                        DLSYM_ARG(EVP_PKEY_get1_encoded_public_key),
+                        DLSYM_ARG(EVP_PKEY_keygen_init),
+                        DLSYM_ARG(EVP_PKEY_keygen),
+                        DLSYM_ARG(EVP_PKEY_new_raw_public_key),
+                        DLSYM_ARG(EVP_PKEY_new),
+                        DLSYM_ARG(EVP_PKEY_verify_init),
+                        DLSYM_ARG(EVP_PKEY_verify),
+                        DLSYM_ARG(EVP_sha1),
+                        DLSYM_ARG(EVP_sha256),
+                        DLSYM_ARG(EVP_sha384),
+                        DLSYM_ARG(EVP_sha512),
+                        DLSYM_ARG(HMAC),
+                        DLSYM_ARG(i2d_ASN1_INTEGER),
+                        DLSYM_ARG(i2d_PKCS7_fp),
+                        DLSYM_ARG(i2d_PKCS7),
+                        DLSYM_ARG(i2d_PUBKEY_fp),
+                        DLSYM_ARG(i2d_PUBKEY),
+                        DLSYM_ARG(i2d_PublicKey),
+                        DLSYM_ARG(i2d_X509_NAME),
+                        DLSYM_ARG(i2d_X509),
+                        DLSYM_ARG(OBJ_nid2obj),
+                        DLSYM_ARG(OBJ_nid2sn),
+                        DLSYM_ARG(OBJ_sn2nid),
+                        DLSYM_ARG(OBJ_txt2obj),
+                        DLSYM_ARG(OPENSSL_sk_new_null),
+                        DLSYM_ARG(OPENSSL_sk_num),
+                        DLSYM_ARG(OPENSSL_sk_pop_free),
+                        DLSYM_ARG(OPENSSL_sk_push),
+                        DLSYM_ARG(OPENSSL_sk_value),
+                        DLSYM_ARG(OSSL_EC_curve_nid2name),
+                        DLSYM_ARG(OSSL_PARAM_BLD_free),
+                        DLSYM_ARG(OSSL_PARAM_BLD_new),
+                        DLSYM_ARG(OSSL_PARAM_BLD_push_octet_string),
+                        DLSYM_ARG(OSSL_PARAM_BLD_push_utf8_string),
+                        DLSYM_ARG(OSSL_PARAM_BLD_to_param),
+                        DLSYM_ARG(OSSL_PARAM_construct_BN),
+                        DLSYM_ARG(OSSL_PARAM_construct_end),
+                        DLSYM_ARG(OSSL_PARAM_construct_octet_string),
+                        DLSYM_ARG(OSSL_PARAM_construct_utf8_string),
+                        DLSYM_ARG(OSSL_PARAM_free),
+                        DLSYM_ARG(OSSL_PROVIDER_try_load),
+                        DLSYM_ARG(OSSL_STORE_close),
+                        DLSYM_ARG(OSSL_STORE_expect),
+                        DLSYM_ARG(OSSL_STORE_INFO_free),
+                        DLSYM_ARG(OSSL_STORE_INFO_get1_CERT),
+                        DLSYM_ARG(OSSL_STORE_INFO_get1_PKEY),
+                        DLSYM_ARG(OSSL_STORE_load),
+                        DLSYM_ARG(OSSL_STORE_open),
+                        DLSYM_ARG(PEM_read_bio_PrivateKey),
+                        DLSYM_ARG(PEM_read_bio_X509),
+                        DLSYM_ARG(PEM_read_PrivateKey),
+                        DLSYM_ARG(PEM_read_PUBKEY),
+                        DLSYM_ARG(PEM_read_X509),
+                        DLSYM_ARG(PEM_write_PrivateKey),
+                        DLSYM_ARG(PEM_write_PUBKEY),
+                        DLSYM_ARG(PEM_write_X509),
+                        DLSYM_ARG(PKCS5_PBKDF2_HMAC),
+                        DLSYM_ARG(PKCS7_add_attrib_content_type),
+                        DLSYM_ARG(PKCS7_add_attrib_smimecap),
+                        DLSYM_ARG(PKCS7_add_certificate),
+                        DLSYM_ARG(PKCS7_add_signed_attribute),
+                        DLSYM_ARG(PKCS7_add_signer),
+                        DLSYM_ARG(PKCS7_add0_attrib_signing_time),
+                        DLSYM_ARG(PKCS7_add1_attrib_digest),
+                        DLSYM_ARG(PKCS7_ATTR_SIGN_it),
+                        DLSYM_ARG(PKCS7_content_new),
+                        DLSYM_ARG(PKCS7_ctrl),
+                        DLSYM_ARG(PKCS7_dataFinal),
+                        DLSYM_ARG(PKCS7_dataInit),
+                        DLSYM_ARG(PKCS7_free),
+                        DLSYM_ARG(PKCS7_get_signer_info),
+                        DLSYM_ARG(PKCS7_new),
+                        DLSYM_ARG(PKCS7_set_content),
+                        DLSYM_ARG(PKCS7_set_type),
+                        DLSYM_ARG(PKCS7_sign),
+                        DLSYM_ARG(PKCS7_SIGNER_INFO_free),
+                        DLSYM_ARG(PKCS7_SIGNER_INFO_new),
+                        DLSYM_ARG(PKCS7_SIGNER_INFO_set),
+                        DLSYM_ARG(PKCS7_verify),
+                        DLSYM_ARG(SHA1),
+                        DLSYM_ARG(SHA512),
+#ifndef OPENSSL_NO_UI_CONSOLE
+                        DLSYM_ARG(UI_create_method),
+                        DLSYM_ARG(UI_destroy_method),
+                        DLSYM_ARG(UI_get_default_method),
+                        DLSYM_ARG(UI_get_method),
+                        DLSYM_ARG(UI_get_string_type),
+                        DLSYM_ARG(UI_get0_output_string),
+                        DLSYM_ARG(UI_method_get_ex_data),
+                        DLSYM_ARG(UI_method_get_reader),
+                        DLSYM_ARG(UI_method_set_ex_data),
+                        DLSYM_ARG(UI_method_set_reader),
+                        DLSYM_ARG(UI_OpenSSL),
+                        DLSYM_ARG(UI_set_default_method),
+                        DLSYM_ARG(UI_set_result),
+#endif
+                        DLSYM_ARG(X509_ALGOR_free),
+                        DLSYM_ARG(X509_ALGOR_set0),
+                        DLSYM_ARG(X509_ATTRIBUTE_free),
+                        DLSYM_ARG(X509_free),
+                        DLSYM_ARG(X509_get_issuer_name),
+                        DLSYM_ARG(X509_get_pubkey),
+                        DLSYM_ARG(X509_get_signature_info),
+                        DLSYM_ARG(X509_get_subject_name),
+                        DLSYM_ARG(X509_get0_serialNumber),
+                        DLSYM_ARG(X509_gmtime_adj),
+                        DLSYM_ARG(X509_NAME_free),
+                        DLSYM_ARG(X509_NAME_oneline),
+                        DLSYM_ARG(X509_NAME_set),
+                        DLSYM_ARG(X509_VERIFY_PARAM_set_hostflags),
+                        DLSYM_ARG(X509_VERIFY_PARAM_set1_host),
+                        DLSYM_ARG(X509_VERIFY_PARAM_set1_ip));
+#else
+        return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
+                              "libcrypto support is not compiled in.");
+#endif
+}
+
+#if HAVE_OPENSSL
+
 /* For each error in the OpenSSL thread error queue, log the provided message and the OpenSSL error
  * string. If there are no errors in the OpenSSL thread queue, this logs the message with "No OpenSSL
  * errors." This logs at level debug. Returns -EIO (or -ENOMEM). */
@@ -45,19 +646,25 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(UI_METHOD*, UI_destroy_method, NULL);
         ({                                                              \
                 int UNIQ_T(R, u) = 0;                                   \
                 for (;;) {                                              \
-                        unsigned long UNIQ_T(E, u) = ERR_get_error();   \
+                        unsigned long UNIQ_T(E, u) = sym_ERR_get_error();   \
                         if (UNIQ_T(E, u) == 0)                          \
                                 break;                                  \
-                        ERR_error_string_n(UNIQ_T(E, u), buf, max);     \
+                        sym_ERR_error_string_n(UNIQ_T(E, u), buf, max);     \
                         UNIQ_T(R, u) = log_debug_errno(SYNTHETIC_ERRNO(EIO), fmt ": %s", ##__VA_ARGS__, buf); \
                 }                                                       \
                 UNIQ_T(R, u);                                           \
         })
 
 int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret) {
+        int r;
+
         assert(pem);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         if (pem_size == SIZE_MAX)
                 pem_size = strlen(pem);
 
@@ -66,7 +673,7 @@ int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret) {
         if (!f)
                 return log_oom_debug();
 
-        _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = PEM_read_PUBKEY(f, /* x= */ NULL, /* pam_password_cb= */ NULL, /* userdata= */ NULL);
+        _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = sym_PEM_read_PUBKEY(f, /* x= */ NULL, /* pam_password_cb= */ NULL, /* userdata= */ NULL);
         if (!pkey)
                 return log_openssl_errors("Failed to parse PEM");
 
@@ -75,15 +682,21 @@ int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret) {
 }
 
 int openssl_pubkey_to_pem(EVP_PKEY *pkey, char **ret) {
+        int r;
+
         assert(pkey);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         _cleanup_(memstream_done) MemStream m = {};
         FILE *f = memstream_init(&m);
         if (!f)
                 return -ENOMEM;
 
-        if (PEM_write_PUBKEY(f, pkey) <= 0)
+        if (sym_PEM_write_PUBKEY(f, pkey) <= 0)
                 return -EIO;
 
         return memstream_finalize(&m, ret, /* ret_size= */ NULL);
@@ -94,15 +707,21 @@ int openssl_pubkey_to_pem(EVP_PKEY *pkey, char **ret) {
  * e.g. shake128. Returns 0 on success, -EOPNOTSUPP if the algorithm is not supported, or < 0 for any other
  * error. */
 int openssl_digest_size(const char *digest_alg, size_t *ret_digest_size) {
+        int r;
+
         assert(digest_alg);
         assert(ret_digest_size);
 
-        _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_MD_freep) EVP_MD *md = sym_EVP_MD_fetch(NULL, digest_alg, NULL);
         if (!md)
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                        "Digest algorithm '%s' not supported.", digest_alg);
 
-        size_t digest_size = EVP_MD_get_size(md);
+        size_t digest_size = sym_EVP_MD_get_size(md);
         if (digest_size == 0)
                 return log_openssl_errors("Failed to get Digest size");
 
@@ -127,20 +746,24 @@ int openssl_digest_many(
         assert(ret_digest);
         /* ret_digest_size is optional, as caller may already know the digest size */
 
-        _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_MD_freep) EVP_MD *md = sym_EVP_MD_fetch(NULL, digest_alg, NULL);
         if (!md)
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                        "Digest algorithm '%s' not supported.", digest_alg);
 
-        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = sym_EVP_MD_CTX_new();
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_MD_CTX");
 
-        if (!EVP_DigestInit_ex(ctx, md, NULL))
+        if (!sym_EVP_DigestInit_ex(ctx, md, NULL))
                 return log_openssl_errors("Failed to initialize EVP_MD_CTX");
 
         for (size_t i = 0; i < n_data; i++)
-                if (!EVP_DigestUpdate(ctx, data[i].iov_base, data[i].iov_len))
+                if (!sym_EVP_DigestUpdate(ctx, data[i].iov_base, data[i].iov_len))
                         return log_openssl_errors("Failed to update Digest");
 
         size_t digest_size;
@@ -153,7 +776,7 @@ int openssl_digest_many(
                 return log_oom_debug();
 
         unsigned size;
-        if (!EVP_DigestFinal_ex(ctx, buf, &size))
+        if (!sym_EVP_DigestFinal_ex(ctx, buf, &size))
                 return log_openssl_errors("Failed to finalize Digest");
 
         assert(size == digest_size);
@@ -177,44 +800,50 @@ int openssl_hmac_many(
                 void **ret_digest,
                 size_t *ret_digest_size) {
 
+        int r;
+
         assert(digest_alg);
         assert(key);
         assert(data || n_data == 0);
         assert(ret_digest);
         /* ret_digest_size is optional, as caller may already know the digest size */
 
-        _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_MD_freep) EVP_MD *md = sym_EVP_MD_fetch(NULL, digest_alg, NULL);
         if (!md)
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                        "Digest algorithm '%s' not supported.", digest_alg);
 
-        _cleanup_(EVP_MAC_freep) EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+        _cleanup_(EVP_MAC_freep) EVP_MAC *mac = sym_EVP_MAC_fetch(NULL, "HMAC", NULL);
         if (!mac)
                 return log_openssl_errors("Failed to create new EVP_MAC");
 
-        _cleanup_(EVP_MAC_CTX_freep) EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac);
+        _cleanup_(EVP_MAC_CTX_freep) EVP_MAC_CTX *ctx = sym_EVP_MAC_CTX_new(mac);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_MAC_CTX");
 
-        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
+        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
         if (!bld)
                 return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_MAC_PARAM_DIGEST, (char*) digest_alg, 0))
+        if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_MAC_PARAM_DIGEST, (char*) digest_alg, 0))
                 return log_openssl_errors("Failed to set HMAC OSSL_MAC_PARAM_DIGEST");
 
-        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
+        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
         if (!params)
                 return log_openssl_errors("Failed to build HMAC OSSL_PARAM");
 
-        if (!EVP_MAC_init(ctx, key, key_size, params))
+        if (!sym_EVP_MAC_init(ctx, key, key_size, params))
                 return log_openssl_errors("Failed to initialize EVP_MAC_CTX");
 
         for (size_t i = 0; i < n_data; i++)
-                if (!EVP_MAC_update(ctx, data[i].iov_base, data[i].iov_len))
+                if (!sym_EVP_MAC_update(ctx, data[i].iov_base, data[i].iov_len))
                         return log_openssl_errors("Failed to update HMAC");
 
-        size_t digest_size = EVP_MAC_CTX_get_mac_size(ctx);
+        size_t digest_size = sym_EVP_MAC_CTX_get_mac_size(ctx);
         if (digest_size == 0)
                 return log_openssl_errors("Failed to get HMAC digest size");
 
@@ -223,7 +852,7 @@ int openssl_hmac_many(
                 return log_oom_debug();
 
         size_t size;
-        if (!EVP_MAC_final(ctx, buf, &size, digest_size))
+        if (!sym_EVP_MAC_final(ctx, buf, &size, digest_size))
                 return log_openssl_errors("Failed to finalize HMAC");
 
         assert(size == digest_size);
@@ -253,6 +882,8 @@ int openssl_cipher_many(
                 void **ret,
                 size_t *ret_size) {
 
+        int r;
+
         assert(alg);
         assert(bits > 0);
         assert(mode);
@@ -262,28 +893,32 @@ int openssl_cipher_many(
         assert(ret);
         assert(ret_size);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         _cleanup_free_ char *cipher_alg = NULL;
         if (asprintf(&cipher_alg, "%s-%zu-%s", alg, bits, mode) < 0)
                 return log_oom_debug();
 
-        _cleanup_(EVP_CIPHER_freep) EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, cipher_alg, NULL);
+        _cleanup_(EVP_CIPHER_freep) EVP_CIPHER *cipher = sym_EVP_CIPHER_fetch(NULL, cipher_alg, NULL);
         if (!cipher)
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                        "Cipher algorithm '%s' not supported.", cipher_alg);
 
-        _cleanup_(EVP_CIPHER_CTX_freep) EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+        _cleanup_(EVP_CIPHER_CTX_freep) EVP_CIPHER_CTX *ctx = sym_EVP_CIPHER_CTX_new();
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_CIPHER_CTX");
 
         /* Verify enough key data was provided. */
-        int cipher_key_length = EVP_CIPHER_key_length(cipher);
+        int cipher_key_length = sym_EVP_CIPHER_get_key_length(cipher);
         assert(cipher_key_length >= 0);
         if ((size_t) cipher_key_length > key_size)
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Not enough key bytes provided, require %d", cipher_key_length);
 
         /* Verify enough IV data was provided or, if no IV was provided, use a zeroed buffer for IV data. */
-        int cipher_iv_length = EVP_CIPHER_iv_length(cipher);
+        int cipher_iv_length = sym_EVP_CIPHER_get_iv_length(cipher);
         assert(cipher_iv_length >= 0);
         _cleanup_free_ void *zero_iv = NULL;
         if (iv_size == 0) {
@@ -298,10 +933,10 @@ int openssl_cipher_many(
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "Not enough IV bytes provided, require %d", cipher_iv_length);
 
-        if (!EVP_EncryptInit(ctx, cipher, key, iv))
+        if (!sym_EVP_EncryptInit(ctx, cipher, key, iv))
                 return log_openssl_errors("Failed to initialize EVP_CIPHER_CTX.");
 
-        int cipher_block_size = EVP_CIPHER_CTX_block_size(ctx);
+        int cipher_block_size = sym_EVP_CIPHER_CTX_get_block_size(ctx);
         assert(cipher_block_size > 0);
 
         _cleanup_free_ uint8_t *buf = NULL;
@@ -313,7 +948,7 @@ int openssl_cipher_many(
                         return log_oom_debug();
 
                 int update_size;
-                if (!EVP_EncryptUpdate(ctx, &buf[size], &update_size, data[i].iov_base, data[i].iov_len))
+                if (!sym_EVP_EncryptUpdate(ctx, &buf[size], &update_size, data[i].iov_base, data[i].iov_len))
                         return log_openssl_errors("Failed to update Cipher.");
 
                 size += update_size;
@@ -323,7 +958,7 @@ int openssl_cipher_many(
                 return log_oom_debug();
 
         int final_size;
-        if (!EVP_EncryptFinal_ex(ctx, &buf[size], &final_size))
+        if (!sym_EVP_EncryptFinal_ex(ctx, &buf[size], &final_size))
                 return log_openssl_errors("Failed to finalize Cipher.");
 
         *ret = TAKE_PTR(buf);
@@ -347,20 +982,26 @@ int kdf_ss_derive(
                 size_t derive_size,
                 void **ret) {
 
+        int r;
+
         assert(digest);
         assert(key);
         assert(derive_size > 0);
         assert(ret);
 
-        _cleanup_(EVP_KDF_freep) EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_KDF_freep) EVP_KDF *kdf = sym_EVP_KDF_fetch(NULL, "SSKDF", NULL);
         if (!kdf)
                 return log_openssl_errors("Failed to create new EVP_KDF");
 
-        _cleanup_(EVP_KDF_CTX_freep) EVP_KDF_CTX *ctx = EVP_KDF_CTX_new(kdf);
+        _cleanup_(EVP_KDF_CTX_freep) EVP_KDF_CTX *ctx = sym_EVP_KDF_CTX_new(kdf);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_KDF_CTX");
 
-        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
+        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
         if (!bld)
                 return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
 
@@ -368,25 +1009,25 @@ int kdf_ss_derive(
         if (!buf)
                 return log_oom_debug();
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_DIGEST, (char*) digest, 0))
+        if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_DIGEST, (char*) digest, 0))
                 return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_DIGEST");
 
-        if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_KEY, (char*) key, key_size))
+        if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_KEY, (char*) key, key_size))
                 return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_KEY");
 
         if (salt)
-                if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SALT, (char*) salt, salt_size))
+                if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SALT, (char*) salt, salt_size))
                         return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_SALT");
 
         if (info)
-                if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_INFO, (char*) info, info_size))
+                if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_INFO, (char*) info, info_size))
                         return log_openssl_errors("Failed to add KDF-SS OSSL_KDF_PARAM_INFO");
 
-        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
+        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
         if (!params)
                 return log_openssl_errors("Failed to build KDF-SS OSSL_PARAM");
 
-        if (EVP_KDF_derive(ctx, buf, derive_size, params) <= 0)
+        if (sym_EVP_KDF_derive(ctx, buf, derive_size, params) <= 0)
                 return log_openssl_errors("OpenSSL KDF-SS derive failed");
 
         *ret = TAKE_PTR(buf);
@@ -413,6 +1054,8 @@ int kdf_kb_hmac_derive(
                 size_t derive_size,
                 void **ret) {
 
+        int r;
+
         assert(mode);
         assert(strcaseeq(mode, "COUNTER") || strcaseeq(mode, "FEEDBACK"));
         assert(digest);
@@ -423,44 +1066,48 @@ int kdf_kb_hmac_derive(
         assert(derive_size > 0);
         assert(ret);
 
-        _cleanup_(EVP_KDF_freep) EVP_KDF *kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_KDF_freep) EVP_KDF *kdf = sym_EVP_KDF_fetch(NULL, "KBKDF", NULL);
         if (!kdf)
                 return log_openssl_errors("Failed to create new EVP_KDF");
 
-        _cleanup_(EVP_KDF_CTX_freep) EVP_KDF_CTX *ctx = EVP_KDF_CTX_new(kdf);
+        _cleanup_(EVP_KDF_CTX_freep) EVP_KDF_CTX *ctx = sym_EVP_KDF_CTX_new(kdf);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_KDF_CTX");
 
-        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
+        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
         if (!bld)
                 return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_MAC, (char*) "HMAC", 0))
+        if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_MAC, (char*) "HMAC", 0))
                 return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_MAC");
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_MODE, (char*) mode, 0))
+        if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_MODE, (char*) mode, 0))
                 return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_MODE");
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_DIGEST, (char*) digest, 0))
+        if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_KDF_PARAM_DIGEST, (char*) digest, 0))
                 return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_DIGEST");
 
         if (key)
-                if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_KEY, (char*) key, key_size))
+                if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_KEY, (char*) key, key_size))
                         return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_KEY");
 
         if (salt)
-                if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SALT, (char*) salt, salt_size))
+                if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SALT, (char*) salt, salt_size))
                         return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_SALT");
 
         if (info)
-                if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_INFO, (char*) info, info_size))
+                if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_INFO, (char*) info, info_size))
                         return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_INFO");
 
         if (seed)
-                if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SEED, (char*) seed, seed_size))
+                if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_KDF_PARAM_SEED, (char*) seed, seed_size))
                         return log_openssl_errors("Failed to add KDF-KB OSSL_KDF_PARAM_SEED");
 
-        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
+        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
         if (!params)
                 return log_openssl_errors("Failed to build KDF-KB OSSL_PARAM");
 
@@ -468,7 +1115,7 @@ int kdf_kb_hmac_derive(
         if (!buf)
                 return log_oom_debug();
 
-        if (EVP_KDF_derive(ctx, buf, derive_size, params) <= 0)
+        if (sym_EVP_KDF_derive(ctx, buf, derive_size, params) <= 0)
                 return log_openssl_errors("OpenSSL KDF-KB derive failed");
 
         *ret = TAKE_PTR(buf);
@@ -486,28 +1133,33 @@ int rsa_encrypt_bytes(
         _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
         _cleanup_free_ void *b = NULL;
         size_t l;
+        int r;
 
         assert(ret_encrypt_key);
         assert(ret_encrypt_key_size);
 
-        ctx = EVP_PKEY_CTX_new(pkey, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        ctx = sym_EVP_PKEY_CTX_new(pkey, NULL);
         if (!ctx)
                 return log_openssl_errors("Failed to allocate public key context");
 
-        if (EVP_PKEY_encrypt_init(ctx) <= 0)
+        if (sym_EVP_PKEY_encrypt_init(ctx) <= 0)
                 return log_openssl_errors("Failed to initialize public key context");
 
-        if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+        if (sym_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
                 return log_openssl_errors("Failed to configure PKCS#1 padding");
 
-        if (EVP_PKEY_encrypt(ctx, NULL, &l, decrypted_key, decrypted_key_size) <= 0)
+        if (sym_EVP_PKEY_encrypt(ctx, NULL, &l, decrypted_key, decrypted_key_size) <= 0)
                 return log_openssl_errors("Failed to determine encrypted key size");
 
         b = malloc(l);
         if (!b)
                 return -ENOMEM;
 
-        if (EVP_PKEY_encrypt(ctx, b, &l, decrypted_key, decrypted_key_size) <= 0)
+        if (sym_EVP_PKEY_encrypt(ctx, b, &l, decrypted_key, decrypted_key_size) <= 0)
                 return log_openssl_errors("Failed to determine encrypted key size");
 
         *ret_encrypt_key = TAKE_PTR(b);
@@ -526,6 +1178,8 @@ int rsa_oaep_encrypt_bytes(
                 void **ret_encrypt_key,
                 size_t *ret_encrypt_key_size) {
 
+        int r;
+
         assert(pkey);
         assert(digest_alg);
         assert(label);
@@ -534,42 +1188,46 @@ int rsa_oaep_encrypt_bytes(
         assert(ret_encrypt_key);
         assert(ret_encrypt_key_size);
 
-        _cleanup_(EVP_MD_freep) EVP_MD *md = EVP_MD_fetch(NULL, digest_alg, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_MD_freep) EVP_MD *md = sym_EVP_MD_fetch(NULL, digest_alg, NULL);
         if (!md)
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                        "Digest algorithm '%s' not supported.", digest_alg);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new((EVP_PKEY*) pkey, NULL);
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new((EVP_PKEY*) pkey, NULL);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
 
-        if (EVP_PKEY_encrypt_init(ctx) <= 0)
+        if (sym_EVP_PKEY_encrypt_init(ctx) <= 0)
                 return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
 
-        if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
+        if (sym_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
                 return log_openssl_errors("Failed to configure RSA-OAEP padding");
 
-        if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
+        if (sym_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) <= 0)
                 return log_openssl_errors("Failed to configure RSA-OAEP MD");
 
         _cleanup_free_ char *duplabel = strdup(label);
         if (!duplabel)
                 return log_oom_debug();
 
-        if (EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, duplabel, strlen(duplabel) + 1) <= 0)
+        if (sym_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, duplabel, strlen(duplabel) + 1) <= 0)
                 return log_openssl_errors("Failed to configure RSA-OAEP label");
         /* ctx owns this now, don't free */
         TAKE_PTR(duplabel);
 
         size_t size = 0;
-        if (EVP_PKEY_encrypt(ctx, NULL, &size, decrypted_key, decrypted_key_size) <= 0)
+        if (sym_EVP_PKEY_encrypt(ctx, NULL, &size, decrypted_key, decrypted_key_size) <= 0)
                 return log_openssl_errors("Failed to determine RSA-OAEP encrypted key size");
 
         _cleanup_free_ void *buf = malloc(size);
         if (!buf)
                 return log_oom_debug();
 
-        if (EVP_PKEY_encrypt(ctx, buf, &size, decrypted_key, decrypted_key_size) <= 0)
+        if (sym_EVP_PKEY_encrypt(ctx, buf, &size, decrypted_key, decrypted_key_size) <= 0)
                 return log_openssl_errors("Failed to RSA-OAEP encrypt");
 
         *ret_encrypt_key = TAKE_PTR(buf);
@@ -583,7 +1241,7 @@ int rsa_pkey_to_suitable_key_size(
                 size_t *ret_suitable_key_size) {
 
         size_t suitable_key_size;
-        int bits;
+        int bits, r;
 
         assert(pkey);
         assert(ret_suitable_key_size);
@@ -591,10 +1249,14 @@ int rsa_pkey_to_suitable_key_size(
         /* Analyzes the specified public key and that it is RSA. If so, will return a suitable size for a
          * disk encryption key to encrypt with RSA for use in PKCS#11 security token schemes. */
 
-        if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA)
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        if (sym_EVP_PKEY_get_base_id(pkey) != EVP_PKEY_RSA)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "X.509 certificate does not refer to RSA key.");
 
-        bits = EVP_PKEY_bits(pkey);
+        bits = sym_EVP_PKEY_get_bits(pkey);
         log_debug("Bits in RSA key: %i", bits);
 
         /* We use PKCS#1 padding for the RSA cleartext, hence let's leave some extra space for it, hence only
@@ -612,6 +1274,7 @@ int rsa_pkey_to_suitable_key_size(
  * in big-endian format, e.g. wrap it with htobe32() for uint32_t. */
 int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size, EVP_PKEY **ret) {
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
+        int r;
 
         assert(n);
         assert(n_size != 0);
@@ -619,18 +1282,22 @@ int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size
         assert(e_size != 0);
         assert(ret);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
 
-        if (EVP_PKEY_fromdata_init(ctx) <= 0)
+        if (sym_EVP_PKEY_fromdata_init(ctx) <= 0)
                 return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
 
         OSSL_PARAM params[3];
 
 #if __BYTE_ORDER == __BIG_ENDIAN
-        params[0] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, (void*)n, n_size);
-        params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, (void*)e, e_size);
+        params[0] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, (void*)n, n_size);
+        params[1] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, (void*)e, e_size);
 #else
         _cleanup_free_ void *native_n = memdup_reverse(n, n_size);
         if (!native_n)
@@ -640,12 +1307,12 @@ int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size
         if (!native_e)
                 return log_oom_debug();
 
-        params[0] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, native_n, n_size);
-        params[1] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, native_e, e_size);
+        params[0] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, native_n, n_size);
+        params[1] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, native_e, e_size);
 #endif
-        params[2] = OSSL_PARAM_construct_end();
+        params[2] = sym_OSSL_PARAM_construct_end();
 
-        if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+        if (sym_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
                 return log_openssl_errors("Failed to create RSA EVP_PKEY");
 
         *ret = TAKE_PTR(pkey);
@@ -661,27 +1328,33 @@ int rsa_pkey_to_n_e(
                 void **ret_e,
                 size_t *ret_e_size) {
 
+        int r;
+
         assert(pkey);
         assert(ret_n);
         assert(ret_n_size);
         assert(ret_e);
         assert(ret_e_size);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         _cleanup_(BN_freep) BIGNUM *bn_n = NULL;
-        if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn_n))
+        if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bn_n))
                 return log_openssl_errors("Failed to get RSA n");
 
         _cleanup_(BN_freep) BIGNUM *bn_e = NULL;
-        if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn_e))
+        if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &bn_e))
                 return log_openssl_errors("Failed to get RSA e");
 
-        size_t n_size = BN_num_bytes(bn_n), e_size = BN_num_bytes(bn_e);
+        size_t n_size = sym_BN_num_bytes(bn_n), e_size = sym_BN_num_bytes(bn_e);
         _cleanup_free_ void *n = malloc(n_size), *e = malloc(e_size);
         if (!n || !e)
                 return log_oom_debug();
 
-        assert(BN_bn2bin(bn_n, n) == (int) n_size);
-        assert(BN_bn2bin(bn_e, e) == (int) e_size);
+        assert(sym_BN_bn2bin(bn_n, n) == (int) n_size);
+        assert(sym_BN_bn2bin(bn_e, e) == (int) e_size);
 
         *ret_n = TAKE_PTR(n);
         *ret_n_size = n_size;
@@ -700,58 +1373,64 @@ int ecc_pkey_from_curve_x_y(
                 size_t y_size,
                 EVP_PKEY **ret) {
 
+        int r;
+
         assert(x);
         assert(y);
         assert(ret);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
 
-        _cleanup_(BN_freep) BIGNUM *bn_x = BN_bin2bn(x, x_size, NULL);
+        _cleanup_(BN_freep) BIGNUM *bn_x = sym_BN_bin2bn(x, x_size, NULL);
         if (!bn_x)
                 return log_openssl_errors("Failed to create BIGNUM x");
 
-        _cleanup_(BN_freep) BIGNUM *bn_y = BN_bin2bn(y, y_size, NULL);
+        _cleanup_(BN_freep) BIGNUM *bn_y = sym_BN_bin2bn(y, y_size, NULL);
         if (!bn_y)
                 return log_openssl_errors("Failed to create BIGNUM y");
 
-        _cleanup_(EC_GROUP_freep) EC_GROUP *group = EC_GROUP_new_by_curve_name(curve_id);
+        _cleanup_(EC_GROUP_freep) EC_GROUP *group = sym_EC_GROUP_new_by_curve_name(curve_id);
         if (!group)
                 return log_openssl_errors("ECC curve id %d not supported", curve_id);
 
-        _cleanup_(EC_POINT_freep) EC_POINT *point = EC_POINT_new(group);
+        _cleanup_(EC_POINT_freep) EC_POINT *point = sym_EC_POINT_new(group);
         if (!point)
                 return log_openssl_errors("Failed to create new EC_POINT");
 
-        if (!EC_POINT_set_affine_coordinates(group, point, bn_x, bn_y, NULL))
+        if (!sym_EC_POINT_set_affine_coordinates(group, point, bn_x, bn_y, NULL))
                 return log_openssl_errors("Failed to set ECC coordinates");
 
-        if (EVP_PKEY_fromdata_init(ctx) <= 0)
+        if (sym_EVP_PKEY_fromdata_init(ctx) <= 0)
                 return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
 
-        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
+        _cleanup_(OSSL_PARAM_BLD_freep) OSSL_PARAM_BLD *bld = sym_OSSL_PARAM_BLD_new();
         if (!bld)
                 return log_openssl_errors("Failed to create new OSSL_PARAM_BLD");
 
-        if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, (char*) OSSL_EC_curve_nid2name(curve_id), 0))
+        if (!sym_OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, (char*) sym_OSSL_EC_curve_nid2name(curve_id), 0))
                 return log_openssl_errors("Failed to add ECC OSSL_PKEY_PARAM_GROUP_NAME");
 
         _cleanup_(OPENSSL_freep) void *pbuf = NULL;
         size_t pbuf_len = 0;
-        pbuf_len = EC_POINT_point2buf(group, point, POINT_CONVERSION_UNCOMPRESSED, (unsigned char**) &pbuf, NULL);
+        pbuf_len = sym_EC_POINT_point2buf(group, point, POINT_CONVERSION_UNCOMPRESSED, (unsigned char**) &pbuf, NULL);
         if (pbuf_len == 0)
                 return log_openssl_errors("Failed to convert ECC point to buffer");
 
-        if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, pbuf, pbuf_len))
+        if (!sym_OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY, pbuf, pbuf_len))
                 return log_openssl_errors("Failed to add ECC OSSL_PKEY_PARAM_PUB_KEY");
 
-        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = OSSL_PARAM_BLD_to_param(bld);
+        _cleanup_(OSSL_PARAM_freep) OSSL_PARAM *params = sym_OSSL_PARAM_BLD_to_param(bld);
         if (!params)
                 return log_openssl_errors("Failed to build ECC OSSL_PARAM");
 
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
-        if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
+        if (sym_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
                 return log_openssl_errors("Failed to create ECC EVP_PKEY");
 
         *ret = TAKE_PTR(pkey);
@@ -767,38 +1446,42 @@ int ecc_pkey_to_curve_x_y(
                 size_t *ret_y_size) {
 
         _cleanup_(BN_freep) BIGNUM *bn_x = NULL, *bn_y = NULL;
-        int curve_id;
+        int curve_id, r;
 
         assert(pkey);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         size_t name_size;
-        if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0, &name_size))
+        if (!sym_EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0, &name_size))
                 return log_openssl_errors("Failed to get ECC group name size");
 
         _cleanup_free_ char *name = new(char, name_size + 1);
         if (!name)
                 return log_oom_debug();
 
-        if (!EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, name, name_size + 1, NULL))
+        if (!sym_EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME, name, name_size + 1, NULL))
                 return log_openssl_errors("Failed to get ECC group name");
 
-        curve_id = OBJ_sn2nid(name);
+        curve_id = sym_OBJ_sn2nid(name);
         if (curve_id == NID_undef)
                 return log_openssl_errors("Failed to get ECC curve id");
 
-        if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &bn_x))
+        if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &bn_x))
                 return log_openssl_errors("Failed to get ECC point x");
 
-        if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &bn_y))
+        if (!sym_EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &bn_y))
                 return log_openssl_errors("Failed to get ECC point y");
 
-        size_t x_size = BN_num_bytes(bn_x), y_size = BN_num_bytes(bn_y);
+        size_t x_size = sym_BN_num_bytes(bn_x), y_size = sym_BN_num_bytes(bn_y);
         _cleanup_free_ void *x = malloc(x_size), *y = malloc(y_size);
         if (!x || !y)
                 return log_oom_debug();
 
-        assert(BN_bn2bin(bn_x, x) == (int) x_size);
-        assert(BN_bn2bin(bn_y, y) == (int) y_size);
+        assert(sym_BN_bn2bin(bn_x, x) == (int) x_size);
+        assert(sym_BN_bn2bin(bn_y, y) == (int) y_size);
 
         if (ret_curve_id)
                 *ret_curve_id = curve_id;
@@ -816,20 +1499,26 @@ int ecc_pkey_to_curve_x_y(
 
 /* Generate a new ECC key for the specified ECC curve id. */
 int ecc_pkey_new(int curve_id, EVP_PKEY **ret) {
+        int r;
+
         assert(ret);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
 
-        if (EVP_PKEY_keygen_init(ctx) <= 0)
+        if (sym_EVP_PKEY_keygen_init(ctx) <= 0)
                 return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
 
-        if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve_id) <= 0)
+        if (sym_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve_id) <= 0)
                 return log_openssl_errors("Failed to set ECC curve %d", curve_id);
 
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
-        if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+        if (sym_EVP_PKEY_keygen(ctx, &pkey) <= 0)
                 return log_openssl_errors("Failed to generate ECC key");
 
         *ret = TAKE_PTR(pkey);
@@ -847,30 +1536,36 @@ int ecc_ecdh(const EVP_PKEY *private_pkey,
              void **ret_shared_secret,
              size_t *ret_shared_secret_size) {
 
+        int r;
+
         assert(private_pkey);
         assert(peer_pkey);
         assert(ret_shared_secret);
         assert(ret_shared_secret_size);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new((EVP_PKEY*) private_pkey, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new((EVP_PKEY*) private_pkey, NULL);
         if (!ctx)
                 return log_openssl_errors("Failed to create new EVP_PKEY_CTX");
 
-        if (EVP_PKEY_derive_init(ctx) <= 0)
+        if (sym_EVP_PKEY_derive_init(ctx) <= 0)
                 return log_openssl_errors("Failed to initialize EVP_PKEY_CTX");
 
-        if (EVP_PKEY_derive_set_peer(ctx, (EVP_PKEY*) peer_pkey) <= 0)
+        if (sym_EVP_PKEY_derive_set_peer(ctx, (EVP_PKEY*) peer_pkey) <= 0)
                 return log_openssl_errors("Failed to set ECC derive peer");
 
         size_t shared_secret_size;
-        if (EVP_PKEY_derive(ctx, NULL, &shared_secret_size) <= 0)
+        if (sym_EVP_PKEY_derive(ctx, NULL, &shared_secret_size) <= 0)
                 return log_openssl_errors("Failed to get ECC shared secret size");
 
         _cleanup_(erase_and_freep) void *shared_secret = malloc(shared_secret_size);
         if (!shared_secret)
                 return log_oom_debug();
 
-        if (EVP_PKEY_derive(ctx, (unsigned char*) shared_secret, &shared_secret_size) <= 0)
+        if (sym_EVP_PKEY_derive(ctx, (unsigned char*) shared_secret, &shared_secret_size) <= 0)
                 return log_openssl_errors("Failed to derive ECC shared secret");
 
         *ret_shared_secret = TAKE_PTR(shared_secret);
@@ -885,6 +1580,7 @@ int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_s
         int sz, lsz, msz;
         unsigned umsz;
         unsigned char *dd;
+        int r;
 
         /* Calculates a message digest of the DER encoded public key */
 
@@ -893,7 +1589,11 @@ int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_s
         assert(ret);
         assert(ret_size);
 
-        sz = i2d_PublicKey(pk, NULL);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        sz = sym_i2d_PublicKey(pk, NULL);
         if (sz < 0)
                 return log_openssl_errors("Unable to convert public key to DER format");
 
@@ -901,21 +1601,21 @@ int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_s
         if (!d)
                 return log_oom_debug();
 
-        lsz = i2d_PublicKey(pk, &dd);
+        lsz = sym_i2d_PublicKey(pk, &dd);
         if (lsz < 0)
                 return log_openssl_errors("Unable to convert public key to DER format");
 
-        m = EVP_MD_CTX_new();
+        m = sym_EVP_MD_CTX_new();
         if (!m)
                 return log_openssl_errors("Failed to create new EVP_MD_CTX");
 
-        if (EVP_DigestInit_ex(m, md, NULL) != 1)
-                return log_openssl_errors("Failed to initialize %s context", EVP_MD_name(md));
+        if (sym_EVP_DigestInit_ex(m, md, NULL) != 1)
+                return log_openssl_errors("Failed to initialize %s context", sym_EVP_MD_get0_name(md));
 
-        if (EVP_DigestUpdate(m, d, lsz) != 1)
-                return log_openssl_errors("Failed to run %s context", EVP_MD_name(md));
+        if (sym_EVP_DigestUpdate(m, d, lsz) != 1)
+                return log_openssl_errors("Failed to run %s context", sym_EVP_MD_get0_name(md));
 
-        msz = EVP_MD_size(md);
+        msz = sym_EVP_MD_get_size(md);
         assert(msz > 0);
 
         h = malloc(msz);
@@ -923,7 +1623,7 @@ int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_s
                 return log_oom_debug();
 
         umsz = msz;
-        if (EVP_DigestFinal_ex(m, h, &umsz) != 1)
+        if (sym_EVP_DigestFinal_ex(m, h, &umsz) != 1)
                 return log_openssl_errors("Failed to finalize hash context");
 
         assert(umsz == (unsigned) msz);
@@ -946,6 +1646,10 @@ int digest_and_sign(
         assert(ret);
         assert(ret_size);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         if (size == 0)
                 data = ""; /* make sure to pass a valid pointer to OpenSSL */
         else {
@@ -955,28 +1659,28 @@ int digest_and_sign(
                         size = strlen(data);
         }
 
-        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
+        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX* mdctx = sym_EVP_MD_CTX_new();
         if (!mdctx)
                 return log_openssl_errors("Failed to create new EVP_MD_CTX");
 
-        if (EVP_DigestSignInit(mdctx, NULL, md, NULL, privkey) != 1) {
+        if (sym_EVP_DigestSignInit(mdctx, NULL, md, NULL, privkey) != 1) {
                 /* Distro security policies often disable support for SHA-1. Let's return a recognizable
                  * error for that case. */
-                bool invalid_digest = ERR_GET_REASON(ERR_peek_last_error()) == EVP_R_INVALID_DIGEST;
+                bool invalid_digest = ERR_GET_REASON(sym_ERR_peek_last_error()) == EVP_R_INVALID_DIGEST;
                 r = log_openssl_errors("Failed to initialize signature context");
                 return invalid_digest ? -EADDRNOTAVAIL : r;
         }
 
         /* Determine signature size */
         size_t ss;
-        if (EVP_DigestSign(mdctx, NULL, &ss, data, size) != 1)
+        if (sym_EVP_DigestSign(mdctx, NULL, &ss, data, size) != 1)
                 return log_openssl_errors("Failed to determine size of signature");
 
         _cleanup_free_ void *sig = malloc(ss);
         if (!sig)
                 return log_oom_debug();
 
-        if (EVP_DigestSign(mdctx, sig, &ss, data, size) != 1)
+        if (sym_EVP_DigestSign(mdctx, sig, &ss, data, size) != 1)
                 return log_openssl_errors("Failed to sign data");
 
         *ret = TAKE_PTR(sig);
@@ -985,6 +1689,8 @@ int digest_and_sign(
 }
 
 int pkcs7_new(X509 *certificate, EVP_PKEY *private_key, const char *hash_algorithm, PKCS7 **ret_p7, PKCS7_SIGNER_INFO **ret_si) {
+        int r;
+
         assert(certificate);
         assert(ret_p7);
 
@@ -994,67 +1700,71 @@ int pkcs7_new(X509 *certificate, EVP_PKEY *private_key, const char *hash_algorit
          * copied into the signer info's "enc_digest" field. If the signing hash algorithm is not provided,
          * SHA-256 is used. */
 
-        _cleanup_(PKCS7_freep) PKCS7 *p7 = PKCS7_new();
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(PKCS7_freep) PKCS7 *p7 = sym_PKCS7_new();
         if (!p7)
                 return log_oom();
 
-        if (PKCS7_set_type(p7, NID_pkcs7_signed) == 0)
+        if (sym_PKCS7_set_type(p7, NID_pkcs7_signed) == 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 type: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (PKCS7_content_new(p7, NID_pkcs7_data) == 0)
+        if (sym_PKCS7_content_new(p7, NID_pkcs7_data) == 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 content: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        if (PKCS7_add_certificate(p7, certificate) == 0)
+        if (sym_PKCS7_add_certificate(p7, certificate) == 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 certificate: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         int x509_pknid = 0;
-        if (X509_get_signature_info(certificate, NULL, &x509_pknid, NULL, NULL) == 0)
+        if (sym_X509_get_signature_info(certificate, NULL, &x509_pknid, NULL, NULL) == 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to get X509 digest NID: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-        const EVP_MD *md = EVP_get_digestbyname(hash_algorithm ?: "SHA256");
+        const EVP_MD *md = sym_EVP_get_digestbyname(hash_algorithm ?: "SHA256");
         if (!md)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to get digest algorithm '%s'",
                                        hash_algorithm ?: "SHA256");
 
-        _cleanup_(PKCS7_SIGNER_INFO_freep) PKCS7_SIGNER_INFO *si = PKCS7_SIGNER_INFO_new();
+        _cleanup_(PKCS7_SIGNER_INFO_freep) PKCS7_SIGNER_INFO *si = sym_PKCS7_SIGNER_INFO_new();
         if (!si)
                 return log_oom();
 
         if (private_key) {
-                if (PKCS7_SIGNER_INFO_set(si, certificate, private_key, md) <= 0)
+                if (sym_PKCS7_SIGNER_INFO_set(si, certificate, private_key, md) <= 0)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to configure signer info: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
         } else {
-                if (ASN1_INTEGER_set(si->version, 1) == 0)
+                if (sym_ASN1_INTEGER_set(si->version, 1) == 0)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info version: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-                if (X509_NAME_set(&si->issuer_and_serial->issuer, X509_get_issuer_name(certificate)) == 0)
+                if (sym_X509_NAME_set(&si->issuer_and_serial->issuer, sym_X509_get_issuer_name(certificate)) == 0)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info issuer: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-                ASN1_INTEGER_free(si->issuer_and_serial->serial);
-                si->issuer_and_serial->serial = ASN1_INTEGER_dup(X509_get0_serialNumber(certificate));
+                sym_ASN1_INTEGER_free(si->issuer_and_serial->serial);
+                si->issuer_and_serial->serial = sym_ASN1_INTEGER_dup(sym_X509_get0_serialNumber(certificate));
                 if (!si->issuer_and_serial->serial)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info serial: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-                if (X509_ALGOR_set0(si->digest_alg, OBJ_nid2obj(EVP_MD_type(md)), V_ASN1_NULL, NULL) == 0)
+                if (sym_X509_ALGOR_set0(si->digest_alg, sym_OBJ_nid2obj(sym_EVP_MD_get_type(md)), V_ASN1_NULL, NULL) == 0)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info digest algorithm: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
-                if (X509_ALGOR_set0(si->digest_enc_alg, OBJ_nid2obj(x509_pknid), V_ASN1_NULL, NULL) == 0)
+                if (sym_X509_ALGOR_set0(si->digest_enc_alg, sym_OBJ_nid2obj(x509_pknid), V_ASN1_NULL, NULL) == 0)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set signer info signing algorithm: %s",
-                                               ERR_error_string(ERR_get_error(), NULL));
+                                               sym_ERR_error_string(sym_ERR_get_error(), NULL));
         }
 
-        if (PKCS7_add_signer(p7, si) == 0)
+        if (sym_PKCS7_add_signer(p7, si) == 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS7 signer info: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret_p7 = TAKE_PTR(p7);
         if (ret_si)
@@ -1114,7 +1824,11 @@ static int ecc_pkey_generate_volume_keys(
         _cleanup_free_ char *curve_name = NULL;
         size_t len = 0;
 
-        if (EVP_PKEY_get_group_name(pkey, NULL, 0, &len) != 1 || len == 0)
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        if (sym_EVP_PKEY_get_group_name(pkey, NULL, 0, &len) != 1 || len == 0)
                 return log_openssl_errors("Failed to determine PKEY group name length");
 
         len++;
@@ -1122,10 +1836,10 @@ static int ecc_pkey_generate_volume_keys(
         if (!curve_name)
                 return log_oom_debug();
 
-        if (EVP_PKEY_get_group_name(pkey, curve_name, len, &len) != 1)
+        if (sym_EVP_PKEY_get_group_name(pkey, curve_name, len, &len) != 1)
                 return log_openssl_errors("Failed to get PKEY group name");
 
-        r = ecc_pkey_new(OBJ_sn2nid(curve_name), &pkey_new);
+        r = ecc_pkey_new(sym_OBJ_sn2nid(curve_name), &pkey_new);
         if (r < 0)
                 return log_debug_errno(r, "Failed to generate a new EC keypair: %m");
 
@@ -1135,7 +1849,7 @@ static int ecc_pkey_generate_volume_keys(
 
         /* EVP_PKEY_get1_encoded_public_key() always returns uncompressed format of EC points.
            See https://github.com/openssl/openssl/discussions/22835 */
-        saved_key_size = EVP_PKEY_get1_encoded_public_key(pkey_new, &saved_key);
+        saved_key_size = sym_EVP_PKEY_get1_encoded_public_key(pkey_new, &saved_key);
         if (saved_key_size == 0)
                 return log_openssl_errors("Failed to convert the generated public key to SEC1 format");
 
@@ -1195,13 +1909,19 @@ int pkey_generate_volume_keys(
                 void **ret_saved_key,
                 size_t *ret_saved_key_size) {
 
+        int r;
+
         assert(pkey);
         assert(ret_decrypted_key);
         assert(ret_decrypted_key_size);
         assert(ret_saved_key);
         assert(ret_saved_key_size);
 
-        int type = EVP_PKEY_get_base_id(pkey);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        int type = sym_EVP_PKEY_get_base_id(pkey);
         switch (type) {
 
         case EVP_PKEY_RSA:
@@ -1214,7 +1934,7 @@ int pkey_generate_volume_keys(
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine a type of public key.");
 
         default:
-                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported public key type: %s", OBJ_nid2sn(type));
+                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported public key type: %s", sym_OBJ_nid2sn(type));
         }
 }
 
@@ -1224,18 +1944,24 @@ static int load_key_from_provider(
                 UI_METHOD *ui_method,
                 EVP_PKEY **ret) {
 
+        int r;
+
         assert(provider);
         assert(private_key_uri);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         /* Load the provider so that this can work without any custom written configuration in /etc/.
          * Also load the 'default' as that seems to be the recommendation. */
-        if (!OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true))
+        if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true))
                 return log_openssl_errors("Failed to load OpenSSL provider '%s'", provider);
-        if (!OSSL_PROVIDER_try_load(/* ctx= */ NULL, "default", /* retain_fallbacks= */ true))
+        if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, "default", /* retain_fallbacks= */ true))
                 return log_openssl_errors("Failed to load OpenSSL provider 'default'");
 
-        _cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = OSSL_STORE_open(
+        _cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = sym_OSSL_STORE_open(
                         private_key_uri,
                         ui_method,
                         /* ui_data= */ NULL,
@@ -1244,14 +1970,14 @@ static int load_key_from_provider(
         if (!store)
                 return log_openssl_errors("Failed to open OpenSSL store via '%s'", private_key_uri);
 
-        if (OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) == 0)
+        if (sym_OSSL_STORE_expect(store, OSSL_STORE_INFO_PKEY) == 0)
                 return log_openssl_errors("Failed to filter store by private keys");
 
-        _cleanup_(OSSL_STORE_INFO_freep) OSSL_STORE_INFO *info = OSSL_STORE_load(store);
+        _cleanup_(OSSL_STORE_INFO_freep) OSSL_STORE_INFO *info = sym_OSSL_STORE_load(store);
         if (!info)
                 return log_openssl_errors("Failed to load OpenSSL store via '%s'", private_key_uri);
 
-        _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = OSSL_STORE_INFO_get1_PKEY(info);
+        _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = sym_OSSL_STORE_INFO_get1_PKEY(info);
         if (!private_key)
                 return log_openssl_errors("Failed to load private key via '%s'", private_key_uri);
 
@@ -1261,20 +1987,28 @@ static int load_key_from_provider(
 }
 
 static int load_key_from_engine(const char *engine, const char *private_key_uri, UI_METHOD *ui_method, EVP_PKEY **ret) {
+#if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
+        int r;
+#endif
+
         assert(engine);
         assert(private_key_uri);
         assert(ret);
 
 #if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         DISABLE_WARNING_DEPRECATED_DECLARATIONS;
-        _cleanup_(ENGINE_freep) ENGINE *e = ENGINE_by_id(engine);
+        _cleanup_(ENGINE_freep) ENGINE *e = sym_ENGINE_by_id(engine);
         if (!e)
                 return log_openssl_errors("Failed to load signing engine '%s'", engine);
 
-        if (ENGINE_init(e) == 0)
+        if (sym_ENGINE_init(e) == 0)
                 return log_openssl_errors("Failed to initialize signing engine '%s'", engine);
 
-        _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = ENGINE_load_private_key(e, private_key_uri, ui_method, /* callback_data= */ NULL);
+        _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = sym_ENGINE_load_private_key(e, private_key_uri, ui_method, /* callback_data= */ NULL);
         if (!private_key)
                 return log_openssl_errors("Failed to load private key from '%s'", private_key_uri);
         REENABLE_WARNING;
@@ -1291,14 +2025,14 @@ static int load_key_from_engine(const char *engine, const char *private_key_uri,
 static int openssl_ask_password_ui_read(UI *ui, UI_STRING *uis) {
         int r;
 
-        switch(UI_get_string_type(uis)) {
+        switch(sym_UI_get_string_type(uis)) {
         case UIT_PROMPT: {
                 /* If no ask password request was configured use the default openssl UI. */
-                AskPasswordRequest *req = (AskPasswordRequest*) UI_method_get_ex_data(UI_get_method(ui), 0);
+                AskPasswordRequest *req = (AskPasswordRequest*) sym_UI_method_get_ex_data(sym_UI_get_method(ui), 0);
                 if (!req)
-                        return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
+                        return (sym_UI_method_get_reader(sym_UI_OpenSSL()))(ui, uis);
 
-                req->message = UI_get0_output_string(uis);
+                req->message = sym_UI_get0_output_string(uis);
 
                 _cleanup_strv_free_ char **l = NULL;
                 r = ask_password_auto(req, ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE, &l);
@@ -1312,7 +2046,7 @@ static int openssl_ask_password_ui_read(UI *ui, UI_STRING *uis) {
                         return 0;
                 }
 
-                if (UI_set_result(ui, uis, *l) != 0) {
+                if (sym_UI_set_result(ui, uis, *l) != 0) {
                         log_openssl_errors("Failed to set user interface result");
                         return 0;
                 }
@@ -1320,7 +2054,7 @@ static int openssl_ask_password_ui_read(UI *ui, UI_STRING *uis) {
                 return 1;
         }
         default:
-                return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
+                return (sym_UI_method_get_reader(sym_UI_OpenSSL()))(ui, uis);
         }
 }
 #endif
@@ -1335,6 +2069,10 @@ static int openssl_load_private_key_from_file(const char *path, EVP_PKEY **ret)
         assert(path);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         r = read_full_file_full(
                         AT_FDCWD, path, UINT64_MAX, SIZE_MAX,
                         READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
@@ -1343,14 +2081,14 @@ static int openssl_load_private_key_from_file(const char *path, EVP_PKEY **ret)
         if (r < 0)
                 return log_debug_errno(r, "Failed to read key file '%s': %m", path);
 
-        kb = BIO_new_mem_buf(rawkey, rawkeysz);
+        kb = sym_BIO_new_mem_buf(rawkey, rawkeysz);
         if (!kb)
                 return log_oom_debug();
 
-        pk = PEM_read_bio_PrivateKey(kb, NULL, NULL, NULL);
+        pk = sym_PEM_read_bio_PrivateKey(kb, NULL, NULL, NULL);
         if (!pk)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse PEM private key: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret = TAKE_PTR(pk);
 
@@ -1358,15 +2096,23 @@ static int openssl_load_private_key_from_file(const char *path, EVP_PKEY **ret)
 }
 
 static int openssl_ask_password_ui_new(const AskPasswordRequest *request, OpenSSLAskPasswordUI **ret) {
+#ifndef OPENSSL_NO_UI_CONSOLE
+        int r;
+#endif
+
         assert(request);
         assert(ret);
 
 #ifndef OPENSSL_NO_UI_CONSOLE
-        _cleanup_(UI_destroy_methodp) UI_METHOD *method = UI_create_method("systemd-ask-password");
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        _cleanup_(UI_destroy_methodp) UI_METHOD *method = sym_UI_create_method("systemd-ask-password");
         if (!method)
                 return log_openssl_errors("Failed to initialize openssl user interface");
 
-        if (UI_method_set_reader(method, openssl_ask_password_ui_read) != 0)
+        if (sym_UI_method_set_reader(method, openssl_ask_password_ui_read) != 0)
                 return log_openssl_errors("Failed to set openssl user interface reader");
 
         OpenSSLAskPasswordUI *ui = new(OpenSSLAskPasswordUI, 1);
@@ -1378,9 +2124,9 @@ static int openssl_ask_password_ui_new(const AskPasswordRequest *request, OpenSS
                 .request = *request,
         };
 
-        UI_set_default_method(ui->method);
+        sym_UI_set_default_method(ui->method);
 
-        if (UI_method_set_ex_data(ui->method, 0, &ui->request) == 0)
+        if (sym_UI_method_set_ex_data(ui->method, 0, &ui->request) == 0)
                 return log_openssl_errors("Failed to set extra data for UI method");
 
         *ret = TAKE_PTR(ui);
@@ -1400,6 +2146,10 @@ static int load_x509_certificate_from_file(const char *path, X509 **ret) {
         assert(path);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         r = read_full_file_full(
                         AT_FDCWD, path, UINT64_MAX, SIZE_MAX,
                         READ_FULL_FILE_CONNECT_SOCKET,
@@ -1408,14 +2158,14 @@ static int load_x509_certificate_from_file(const char *path, X509 **ret) {
         if (r < 0)
                 return log_debug_errno(r, "Failed to read certificate file '%s': %m", path);
 
-        cb = BIO_new_mem_buf(rawcert, rawcertsz);
+        cb = sym_BIO_new_mem_buf(rawcert, rawcertsz);
         if (!cb)
                 return log_oom_debug();
 
-        cert = PEM_read_bio_X509(cb, NULL, NULL, NULL);
+        cert = sym_PEM_read_bio_X509(cb, NULL, NULL, NULL);
         if (!cert)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse X.509 certificate: %s",
-                                       ERR_error_string(ERR_get_error(), NULL));
+                                       sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         *ret = TAKE_PTR(cert);
 
@@ -1423,18 +2173,24 @@ static int load_x509_certificate_from_file(const char *path, X509 **ret) {
 }
 
 static int load_x509_certificate_from_provider(const char *provider, const char *certificate_uri, X509 **ret) {
+        int r;
+
         assert(provider);
         assert(certificate_uri);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         /* Load the provider so that this can work without any custom written configuration in /etc/.
          * Also load the 'default' as that seems to be the recommendation. */
-        if (!OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true))
+        if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, provider, /* retain_fallbacks= */ true))
                 return log_openssl_errors("Failed to load OpenSSL provider '%s'", provider);
-        if (!OSSL_PROVIDER_try_load(/* ctx= */ NULL, "default", /* retain_fallbacks= */ true))
+        if (!sym_OSSL_PROVIDER_try_load(/* ctx= */ NULL, "default", /* retain_fallbacks= */ true))
                 return log_openssl_errors("Failed to load OpenSSL provider 'default'");
 
-        _cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = OSSL_STORE_open(
+        _cleanup_(OSSL_STORE_closep) OSSL_STORE_CTX *store = sym_OSSL_STORE_open(
                         certificate_uri,
                         /* ui_method= */ NULL,
                         /* ui_method= */ NULL,
@@ -1443,14 +2199,14 @@ static int load_x509_certificate_from_provider(const char *provider, const char
         if (!store)
                 return log_openssl_errors("Failed to open OpenSSL store via '%s'", certificate_uri);
 
-        if (OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) == 0)
+        if (sym_OSSL_STORE_expect(store, OSSL_STORE_INFO_CERT) == 0)
                 return log_openssl_errors("Failed to filter store by X.509 certificates");
 
-        _cleanup_(OSSL_STORE_INFO_freep) OSSL_STORE_INFO *info = OSSL_STORE_load(store);
+        _cleanup_(OSSL_STORE_INFO_freep) OSSL_STORE_INFO *info = sym_OSSL_STORE_load(store);
         if (!info)
                 return log_openssl_errors("Failed to load OpenSSL store via '%s'", certificate_uri);
 
-        _cleanup_(X509_freep) X509 *cert = OSSL_STORE_INFO_get1_CERT(info);
+        _cleanup_(X509_freep) X509 *cert = sym_OSSL_STORE_INFO_get1_CERT(info);
         if (!cert)
                 return log_openssl_errors("Failed to load certificate via '%s'", certificate_uri);
 
@@ -1464,20 +2220,24 @@ OpenSSLAskPasswordUI* openssl_ask_password_ui_free(OpenSSLAskPasswordUI *ui) {
                 return NULL;
 
 #ifndef OPENSSL_NO_UI_CONSOLE
-        assert(UI_get_default_method() == ui->method);
-        UI_set_default_method(UI_OpenSSL());
-        UI_destroy_method(ui->method);
+        assert(sym_UI_get_default_method() == ui->method);
+        sym_UI_set_default_method(sym_UI_OpenSSL());
+        sym_UI_destroy_method(ui->method);
 #endif
         return mfree(ui);
 }
 
 int x509_fingerprint(X509 *cert, uint8_t buffer[static SHA256_DIGEST_SIZE]) {
         _cleanup_free_ uint8_t *der = NULL;
-        int dersz;
+        int dersz, r;
 
         assert(cert);
 
-        dersz = i2d_X509(cert, &der);
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
+        dersz = sym_i2d_X509(cert, &der);
         if (dersz < 0)
                 return log_openssl_errors("Unable to convert PEM certificate to DER format");
 
@@ -1581,12 +2341,16 @@ int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret) {
         assert(private_key);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         _cleanup_(memstream_done) MemStream m = {};
         FILE *tf = memstream_init(&m);
         if (!tf)
                 return -ENOMEM;
 
-        if (i2d_PUBKEY_fp(tf, private_key) != 1)
+        if (sym_i2d_PUBKEY_fp(tf, private_key) != 1)
                 return -EIO;
 
         _cleanup_(erase_and_freep) char *buf = NULL;
@@ -1596,7 +2360,7 @@ int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret) {
                 return r;
 
         const unsigned char *t = (const unsigned char*) buf;
-        if (!d2i_PUBKEY(ret, &t, len))
+        if (!sym_d2i_PUBKEY(ret, &t, len))
                 return -EIO;
 
         return 0;
diff --git a/src/shared/crypto-util.h b/src/shared/crypto-util.h
new file mode 100644 (file)
index 0000000..08c5e1a
--- /dev/null
@@ -0,0 +1,406 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "shared-forward.h"
+#include "iovec-util.h"
+#include "sha256.h"
+
+typedef enum CertificateSourceType {
+        OPENSSL_CERTIFICATE_SOURCE_FILE,
+        OPENSSL_CERTIFICATE_SOURCE_PROVIDER,
+        _OPENSSL_CERTIFICATE_SOURCE_MAX,
+        _OPENSSL_CERTIFICATE_SOURCE_INVALID = -EINVAL,
+} CertificateSourceType;
+
+typedef enum KeySourceType {
+        OPENSSL_KEY_SOURCE_FILE,
+        OPENSSL_KEY_SOURCE_ENGINE,
+        OPENSSL_KEY_SOURCE_PROVIDER,
+        _OPENSSL_KEY_SOURCE_MAX,
+        _OPENSSL_KEY_SOURCE_INVALID = -EINVAL,
+} KeySourceType;
+
+typedef struct OpenSSLAskPasswordUI OpenSSLAskPasswordUI;
+
+int parse_openssl_certificate_source_argument(const char *argument, char **certificate_source, CertificateSourceType *certificate_source_type);
+
+int parse_openssl_key_source_argument(const char *argument, char **private_key_source, KeySourceType *private_key_source_type);
+
+int dlopen_libcrypto(int log_level);
+
+#define X509_FINGERPRINT_SIZE SHA256_DIGEST_SIZE
+
+#if HAVE_OPENSSL
+#  include <openssl/bio.h>              /* IWYU pragma: export */
+#  include <openssl/bn.h>               /* IWYU pragma: export */
+#  include <openssl/crypto.h>           /* IWYU pragma: export */
+#  include <openssl/ec.h>               /* IWYU pragma: export */
+#  include <openssl/err.h>              /* IWYU pragma: export */
+#  include <openssl/evp.h>              /* IWYU pragma: export */
+#  include <openssl/hmac.h>             /* IWYU pragma: export */
+#  include <openssl/param_build.h>      /* IWYU pragma: export */
+#  include <openssl/pem.h>              /* IWYU pragma: export */
+#  include <openssl/pkcs7.h>            /* IWYU pragma: export */
+#  include <openssl/rsa.h>              /* IWYU pragma: export */
+#  include <openssl/sha.h>              /* IWYU pragma: export */
+
+#  include "dlfcn-util.h"
+
+extern DLSYM_PROTOTYPE(ASN1_ANY_it);
+extern DLSYM_PROTOTYPE(ASN1_BIT_STRING_it);
+extern DLSYM_PROTOTYPE(ASN1_BMPSTRING_it);
+extern DLSYM_PROTOTYPE(ASN1_BMPSTRING_new);
+extern DLSYM_PROTOTYPE(ASN1_get_object);
+extern DLSYM_PROTOTYPE(ASN1_IA5STRING_it);
+extern DLSYM_PROTOTYPE(ASN1_item_d2i);
+extern DLSYM_PROTOTYPE(ASN1_item_free);
+extern DLSYM_PROTOTYPE(ASN1_item_i2d);
+extern DLSYM_PROTOTYPE(ASN1_item_new);
+extern DLSYM_PROTOTYPE(ASN1_OBJECT_it);
+extern DLSYM_PROTOTYPE(ASN1_OCTET_STRING_free);
+extern DLSYM_PROTOTYPE(ASN1_OCTET_STRING_it);
+extern DLSYM_PROTOTYPE(ASN1_OCTET_STRING_set);
+extern DLSYM_PROTOTYPE(ASN1_STRING_get0_data);
+extern DLSYM_PROTOTYPE(ASN1_STRING_length);
+extern DLSYM_PROTOTYPE(ASN1_STRING_new);
+extern DLSYM_PROTOTYPE(ASN1_STRING_set);
+extern DLSYM_PROTOTYPE(ASN1_STRING_set0);
+extern DLSYM_PROTOTYPE(ASN1_TIME_free);
+extern DLSYM_PROTOTYPE(ASN1_TIME_set);
+extern DLSYM_PROTOTYPE(ASN1_TYPE_new);
+extern DLSYM_PROTOTYPE(BIO_ctrl);
+extern DLSYM_PROTOTYPE(BIO_find_type);
+extern DLSYM_PROTOTYPE(BIO_free_all);
+extern DLSYM_PROTOTYPE(BIO_free);
+extern DLSYM_PROTOTYPE(BIO_new_mem_buf);
+extern DLSYM_PROTOTYPE(BIO_new_socket);
+extern DLSYM_PROTOTYPE(BIO_new);
+extern DLSYM_PROTOTYPE(BIO_s_mem);
+extern DLSYM_PROTOTYPE(BIO_write);
+extern DLSYM_PROTOTYPE(BN_bin2bn);
+extern DLSYM_PROTOTYPE(BN_bn2nativepad);
+extern DLSYM_PROTOTYPE(BN_CTX_free);
+extern DLSYM_PROTOTYPE(BN_CTX_new);
+extern DLSYM_PROTOTYPE(BN_free);
+extern DLSYM_PROTOTYPE(BN_new);
+extern DLSYM_PROTOTYPE(BN_num_bits);
+extern DLSYM_PROTOTYPE(CRYPTO_free);
+extern DLSYM_PROTOTYPE(d2i_ASN1_OCTET_STRING);
+extern DLSYM_PROTOTYPE(d2i_ECPKParameters);
+extern DLSYM_PROTOTYPE(d2i_PKCS7);
+extern DLSYM_PROTOTYPE(d2i_PUBKEY);
+extern DLSYM_PROTOTYPE(d2i_X509);
+extern DLSYM_PROTOTYPE(EC_GROUP_free);
+extern DLSYM_PROTOTYPE(EC_GROUP_get_curve_name);
+extern DLSYM_PROTOTYPE(EC_GROUP_get_curve);
+extern DLSYM_PROTOTYPE(EC_GROUP_get_field_type);
+extern DLSYM_PROTOTYPE(EC_GROUP_get0_generator);
+extern DLSYM_PROTOTYPE(EC_GROUP_get0_order);
+extern DLSYM_PROTOTYPE(EC_GROUP_new_by_curve_name);
+extern DLSYM_PROTOTYPE(EC_POINT_free);
+extern DLSYM_PROTOTYPE(EC_POINT_new);
+extern DLSYM_PROTOTYPE(EC_POINT_oct2point);
+extern DLSYM_PROTOTYPE(EC_POINT_point2oct);
+extern DLSYM_PROTOTYPE(ECDSA_SIG_free);
+extern DLSYM_PROTOTYPE(ERR_clear_error);
+extern DLSYM_PROTOTYPE(ERR_error_string_n);
+extern DLSYM_PROTOTYPE(ERR_error_string);
+extern DLSYM_PROTOTYPE(ERR_get_error);
+extern DLSYM_PROTOTYPE(EVP_aes_256_ctr);
+extern DLSYM_PROTOTYPE(EVP_aes_256_gcm);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_CTX_ctrl);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_CTX_free);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_CTX_new);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_free);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_get_block_size);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_get_iv_length);
+extern DLSYM_PROTOTYPE(EVP_CIPHER_get_key_length);
+extern DLSYM_PROTOTYPE(EVP_DecryptFinal_ex);
+extern DLSYM_PROTOTYPE(EVP_DecryptInit_ex);
+extern DLSYM_PROTOTYPE(EVP_DecryptUpdate);
+extern DLSYM_PROTOTYPE(EVP_Digest);
+extern DLSYM_PROTOTYPE(EVP_DigestFinal_ex);
+extern DLSYM_PROTOTYPE(EVP_DigestInit_ex);
+extern DLSYM_PROTOTYPE(EVP_DigestUpdate);
+extern DLSYM_PROTOTYPE(EVP_DigestVerify);
+extern DLSYM_PROTOTYPE(EVP_DigestVerifyInit);
+extern DLSYM_PROTOTYPE(EVP_EncryptFinal_ex);
+extern DLSYM_PROTOTYPE(EVP_EncryptInit_ex);
+extern DLSYM_PROTOTYPE(EVP_EncryptUpdate);
+extern DLSYM_PROTOTYPE(EVP_get_cipherbyname);
+extern DLSYM_PROTOTYPE(EVP_get_digestbyname);
+extern DLSYM_PROTOTYPE(EVP_MAC_CTX_free);
+extern DLSYM_PROTOTYPE(EVP_MAC_free);
+extern DLSYM_PROTOTYPE(EVP_MD_CTX_free);
+extern DLSYM_PROTOTYPE(EVP_MD_CTX_get0_md);
+extern DLSYM_PROTOTYPE(EVP_MD_CTX_new);
+extern DLSYM_PROTOTYPE(EVP_MD_CTX_set_pkey_ctx);
+extern DLSYM_PROTOTYPE(EVP_MD_free);
+extern DLSYM_PROTOTYPE(EVP_MD_get_size);
+extern DLSYM_PROTOTYPE(EVP_MD_get0_name);
+extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_free);
+extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_new_from_name);
+extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_new_id);
+extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_new);
+extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_rsa_padding);
+extern DLSYM_PROTOTYPE(EVP_PKEY_CTX_set_signature_md);
+extern DLSYM_PROTOTYPE(EVP_PKEY_eq);
+extern DLSYM_PROTOTYPE(EVP_PKEY_free);
+extern DLSYM_PROTOTYPE(EVP_PKEY_fromdata_init);
+extern DLSYM_PROTOTYPE(EVP_PKEY_fromdata);
+extern DLSYM_PROTOTYPE(EVP_PKEY_get_id);
+extern DLSYM_PROTOTYPE(EVP_PKEY_keygen_init);
+extern DLSYM_PROTOTYPE(EVP_PKEY_keygen);
+extern DLSYM_PROTOTYPE(EVP_PKEY_new_raw_public_key);
+extern DLSYM_PROTOTYPE(EVP_PKEY_new);
+extern DLSYM_PROTOTYPE(EVP_PKEY_verify_init);
+extern DLSYM_PROTOTYPE(EVP_PKEY_verify);
+extern DLSYM_PROTOTYPE(EVP_sha1);
+extern DLSYM_PROTOTYPE(EVP_sha256);
+extern DLSYM_PROTOTYPE(EVP_sha384);
+extern DLSYM_PROTOTYPE(EVP_sha512);
+extern DLSYM_PROTOTYPE(HMAC);
+extern DLSYM_PROTOTYPE(i2d_ASN1_INTEGER);
+extern DLSYM_PROTOTYPE(i2d_PKCS7_fp);
+extern DLSYM_PROTOTYPE(i2d_PKCS7);
+extern DLSYM_PROTOTYPE(i2d_PUBKEY);
+extern DLSYM_PROTOTYPE(i2d_X509_NAME);
+extern DLSYM_PROTOTYPE(i2d_X509);
+extern DLSYM_PROTOTYPE(OBJ_nid2obj);
+extern DLSYM_PROTOTYPE(OBJ_nid2sn);
+extern DLSYM_PROTOTYPE(OBJ_sn2nid);
+extern DLSYM_PROTOTYPE(OBJ_txt2obj);
+extern DLSYM_PROTOTYPE(OPENSSL_sk_new_null);
+extern DLSYM_PROTOTYPE(OPENSSL_sk_num);
+extern DLSYM_PROTOTYPE(OPENSSL_sk_pop_free);
+extern DLSYM_PROTOTYPE(OPENSSL_sk_push);
+extern DLSYM_PROTOTYPE(OPENSSL_sk_value);
+extern DLSYM_PROTOTYPE(OSSL_EC_curve_nid2name);
+extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_BN);
+extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_end);
+extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_octet_string);
+extern DLSYM_PROTOTYPE(OSSL_PARAM_construct_utf8_string);
+extern DLSYM_PROTOTYPE(OSSL_PARAM_free);
+extern DLSYM_PROTOTYPE(PEM_read_PrivateKey);
+extern DLSYM_PROTOTYPE(PEM_read_PUBKEY);
+extern DLSYM_PROTOTYPE(PEM_read_X509);
+extern DLSYM_PROTOTYPE(PEM_write_PrivateKey);
+extern DLSYM_PROTOTYPE(PEM_write_PUBKEY);
+extern DLSYM_PROTOTYPE(PEM_write_X509);
+extern DLSYM_PROTOTYPE(PKCS5_PBKDF2_HMAC);
+extern DLSYM_PROTOTYPE(PKCS7_add_attrib_content_type);
+extern DLSYM_PROTOTYPE(PKCS7_add_attrib_smimecap);
+extern DLSYM_PROTOTYPE(PKCS7_add_signed_attribute);
+extern DLSYM_PROTOTYPE(PKCS7_add0_attrib_signing_time);
+extern DLSYM_PROTOTYPE(PKCS7_add1_attrib_digest);
+extern DLSYM_PROTOTYPE(PKCS7_ATTR_SIGN_it);
+extern DLSYM_PROTOTYPE(PKCS7_content_new);
+extern DLSYM_PROTOTYPE(PKCS7_ctrl);
+extern DLSYM_PROTOTYPE(PKCS7_dataFinal);
+extern DLSYM_PROTOTYPE(PKCS7_dataInit);
+extern DLSYM_PROTOTYPE(PKCS7_free);
+extern DLSYM_PROTOTYPE(PKCS7_get_signer_info);
+extern DLSYM_PROTOTYPE(PKCS7_new);
+extern DLSYM_PROTOTYPE(PKCS7_set_content);
+extern DLSYM_PROTOTYPE(PKCS7_sign);
+extern DLSYM_PROTOTYPE(PKCS7_SIGNER_INFO_free);
+extern DLSYM_PROTOTYPE(PKCS7_verify);
+extern DLSYM_PROTOTYPE(SHA1);
+extern DLSYM_PROTOTYPE(SHA512);
+extern DLSYM_PROTOTYPE(X509_ALGOR_free);
+extern DLSYM_PROTOTYPE(X509_ATTRIBUTE_free);
+extern DLSYM_PROTOTYPE(X509_free);
+extern DLSYM_PROTOTYPE(X509_get_pubkey);
+extern DLSYM_PROTOTYPE(X509_get_subject_name);
+extern DLSYM_PROTOTYPE(X509_gmtime_adj);
+extern DLSYM_PROTOTYPE(X509_NAME_free);
+extern DLSYM_PROTOTYPE(X509_NAME_oneline);
+extern DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set_hostflags);
+extern DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set1_host);
+extern DLSYM_PROTOTYPE(X509_VERIFY_PARAM_set1_ip);
+
+#if !defined(OPENSSL_NO_DEPRECATED_3_0)
+DISABLE_WARNING_DEPRECATED_DECLARATIONS;
+extern DLSYM_PROTOTYPE(ECDSA_SIG_new);
+extern DLSYM_PROTOTYPE(ECDSA_SIG_set0);
+extern DLSYM_PROTOTYPE(ECDSA_do_verify);
+extern DLSYM_PROTOTYPE(EC_KEY_check_key);
+extern DLSYM_PROTOTYPE(EC_KEY_free);
+extern DLSYM_PROTOTYPE(EC_KEY_new);
+extern DLSYM_PROTOTYPE(EC_KEY_set_group);
+extern DLSYM_PROTOTYPE(EC_KEY_set_public_key);
+extern DLSYM_PROTOTYPE(EVP_PKEY_assign);
+extern DLSYM_PROTOTYPE(RSA_free);
+extern DLSYM_PROTOTYPE(RSA_new);
+extern DLSYM_PROTOTYPE(RSA_set0_key);
+extern DLSYM_PROTOTYPE(RSA_size);
+extern DLSYM_PROTOTYPE(RSAPublicKey_dup);
+REENABLE_WARNING;
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EC_KEY*, sym_EC_KEY_free, EC_KEY_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(RSA*, sym_RSA_free, RSA_freep, NULL);
+#endif
+
+/* Mirrors of OpenSSL macros that go through our dlopen'd sym_* variants, so we don't end up linking against
+ * libcrypto just for these. */
+#define sym_BIO_get_md_ctx(b, mdcp) sym_BIO_ctrl((b), BIO_C_GET_MD_CTX, 0, (char*) (mdcp))
+#define sym_BIO_get_mem_ptr(b, pp) sym_BIO_ctrl((b), BIO_C_GET_BUF_MEM_PTR, 0, (char *) (pp))
+#define sym_BIO_reset(b) sym_BIO_ctrl((b), BIO_CTRL_RESET, 0, NULL)
+#define sym_BN_num_bytes(a) ((sym_BN_num_bits(a) + 7) / 8)
+#define sym_EVP_MD_CTX_get_size(ctx) sym_EVP_MD_get_size(sym_EVP_MD_CTX_get0_md(ctx))
+#define sym_EVP_MD_CTX_get0_name(ctx) sym_EVP_MD_get0_name(sym_EVP_MD_CTX_get0_md(ctx))
+#define sym_EVP_PKEY_assign_RSA(pkey, rsa) sym_EVP_PKEY_assign((pkey), EVP_PKEY_RSA, (rsa))
+#define sym_OPENSSL_free(addr) sym_CRYPTO_free((addr), OPENSSL_FILE, OPENSSL_LINE)
+#define sym_PKCS7_set_detached(p, v) sym_PKCS7_ctrl((p), PKCS7_OP_SET_DETACHED_SIGNATURE, (v), NULL)
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO_RENAME(void*, sym_OPENSSL_free, OPENSSL_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ASN1_OCTET_STRING*, sym_ASN1_OCTET_STRING_free, ASN1_OCTET_STRING_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ASN1_TIME*, sym_ASN1_TIME_free, ASN1_TIME_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BIGNUM*, sym_BN_free, BN_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BIO*, sym_BIO_free_all, BIO_free_allp, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BIO*, sym_BIO_free, BIO_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(BN_CTX*, sym_BN_CTX_free, BN_CTX_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EC_GROUP*, sym_EC_GROUP_free, EC_GROUP_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EC_POINT*, sym_EC_POINT_free, EC_POINT_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(ECDSA_SIG*, sym_ECDSA_SIG_free, ECDSA_SIG_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_CIPHER_CTX*, sym_EVP_CIPHER_CTX_free, EVP_CIPHER_CTX_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_CIPHER*, sym_EVP_CIPHER_free, EVP_CIPHER_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MAC_CTX*, sym_EVP_MAC_CTX_free, EVP_MAC_CTX_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MAC*, sym_EVP_MAC_free, EVP_MAC_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MD_CTX*, sym_EVP_MD_CTX_free, EVP_MD_CTX_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_MD*, sym_EVP_MD_free, EVP_MD_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_PKEY_CTX*, sym_EVP_PKEY_CTX_free, EVP_PKEY_CTX_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(EVP_PKEY*, sym_EVP_PKEY_free, EVP_PKEY_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(OSSL_PARAM*, sym_OSSL_PARAM_free, OSSL_PARAM_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(PKCS7_SIGNER_INFO*, sym_PKCS7_SIGNER_INFO_free, PKCS7_SIGNER_INFO_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(PKCS7*, sym_PKCS7_free, PKCS7_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(X509_NAME*, sym_X509_NAME_free, X509_NAME_freep, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(X509*, sym_X509_free, X509_freep, NULL);
+
+/* Stack-of macros that go through the dlopen'd sym_OPENSSL_sk_* variants, mirroring the sk_TYPE_OP() helpers
+ * from <openssl/x509.h> and friends. */
+#define sym_sk_X509_new_null() \
+        ((STACK_OF(X509)*) sym_OPENSSL_sk_new_null())
+#define sym_sk_X509_push(sk, ptr) \
+        sym_OPENSSL_sk_push(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))
+#define sym_sk_X509_pop_free(sk, freefunc) \
+        sym_OPENSSL_sk_pop_free(ossl_check_X509_sk_type(sk), ossl_check_X509_freefunc_type(freefunc))
+#define sym_sk_X509_ALGOR_pop_free(sk, freefunc) \
+        sym_OPENSSL_sk_pop_free(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_freefunc_type(freefunc))
+#define sym_sk_X509_ATTRIBUTE_pop_free(sk, freefunc) \
+        sym_OPENSSL_sk_pop_free(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc))
+#define sym_sk_PKCS7_SIGNER_INFO_num(sk) \
+        sym_OPENSSL_sk_num(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk))
+#define sym_sk_PKCS7_SIGNER_INFO_value(sk, idx) \
+        ((PKCS7_SIGNER_INFO*) sym_OPENSSL_sk_value(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk), (idx)))
+
+static inline STACK_OF(X509_ALGOR) *x509_algor_free_many(STACK_OF(X509_ALGOR) *attrs) {
+        if (!attrs)
+                return NULL;
+
+        sym_sk_X509_ALGOR_pop_free(attrs, sym_X509_ALGOR_free);
+        return NULL;
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ALGOR)*, x509_algor_free_many, NULL);
+
+static inline STACK_OF(X509_ATTRIBUTE) *x509_attribute_free_many(STACK_OF(X509_ATTRIBUTE) *attrs) {
+        if (!attrs)
+                return NULL;
+
+        sym_sk_X509_ATTRIBUTE_pop_free(attrs, sym_X509_ATTRIBUTE_free);
+        return NULL;
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ATTRIBUTE)*, x509_attribute_free_many, NULL);
+
+static inline void sk_X509_free_allp(STACK_OF(X509) **sk) {
+        if (!sk || !*sk)
+                return;
+
+        sym_sk_X509_pop_free(*sk, sym_X509_free);
+}
+
+int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret);
+int openssl_pubkey_to_pem(EVP_PKEY *pkey, char **ret);
+
+int openssl_digest_size(const char *digest_alg, size_t *ret_digest_size);
+
+int openssl_digest_many(const char *digest_alg, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
+
+static inline int openssl_digest(const char *digest_alg, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
+        return openssl_digest_many(digest_alg, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
+}
+
+int openssl_hmac_many(const char *digest_alg, const void *key, size_t key_size, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
+
+static inline int openssl_hmac(const char *digest_alg, const void *key, size_t key_size, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
+        return openssl_hmac_many(digest_alg, key, key_size, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
+}
+
+int openssl_cipher_many(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const struct iovec data[], size_t n_data, void **ret, size_t *ret_size);
+
+static inline int openssl_cipher(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const void *buf, size_t len, void **ret, size_t *ret_size) {
+        return openssl_cipher_many(alg, bits, mode, key, key_size, iv, iv_size, &IOVEC_MAKE((void*) buf, len), 1, ret, ret_size);
+}
+
+int kdf_ss_derive(const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, size_t derive_size, void **ret);
+
+int kdf_kb_hmac_derive(const char *mode, const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, const void *seed, size_t seed_size, size_t derive_size, void **ret);
+
+int rsa_encrypt_bytes(EVP_PKEY *pkey, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
+
+int rsa_oaep_encrypt_bytes(const EVP_PKEY *pkey, const char *digest_alg, const char *label, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
+
+int rsa_pkey_to_suitable_key_size(EVP_PKEY *pkey, size_t *ret_suitable_key_size);
+
+int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size, EVP_PKEY **ret);
+
+int rsa_pkey_to_n_e(const EVP_PKEY *pkey, void **ret_n, size_t *ret_n_size, void **ret_e, size_t *ret_e_size);
+
+int ecc_pkey_from_curve_x_y(int curve_id, const void *x, size_t x_size, const void *y, size_t y_size, EVP_PKEY **ret);
+
+int ecc_pkey_to_curve_x_y(const EVP_PKEY *pkey, int *ret_curve_id, void **ret_x, size_t *ret_x_size, void **ret_y, size_t *ret_y_size);
+
+int ecc_pkey_new(int curve_id, EVP_PKEY **ret);
+
+int ecc_ecdh(const EVP_PKEY *private_pkey, const EVP_PKEY *peer_pkey, void **ret_shared_secret, size_t *ret_shared_secret_size);
+
+int pkey_generate_volume_keys(EVP_PKEY *pkey, void **ret_decrypted_key, size_t *ret_decrypted_key_size, void **ret_saved_key, size_t *ret_saved_key_size);
+
+int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_size);
+
+int digest_and_sign(const EVP_MD *md, EVP_PKEY *privkey, const void *data, size_t size, void **ret, size_t *ret_size);
+
+int pkcs7_new(X509 *certificate, EVP_PKEY *private_key, const char *hash_algorithm, PKCS7 **ret_p7, PKCS7_SIGNER_INFO **ret_si);
+
+int string_hashsum(const char *s, size_t len, const char *md_algorithm, char **ret);
+static inline int string_hashsum_sha224(const char *s, size_t len, char **ret) {
+        return string_hashsum(s, len, "SHA224", ret);
+}
+static inline int string_hashsum_sha256(const char *s, size_t len, char **ret) {
+        return string_hashsum(s, len, "SHA256", ret);
+}
+
+int x509_fingerprint(X509 *cert, uint8_t buffer[static X509_FINGERPRINT_SIZE]);
+
+int openssl_load_x509_certificate(
+                CertificateSourceType certificate_source_type,
+                const char *certificate_source,
+                const char *certificate,
+                X509 **ret);
+
+int openssl_load_private_key(
+                KeySourceType private_key_source_type,
+                const char *private_key_source,
+                const char *private_key,
+                const AskPasswordRequest *request,
+                EVP_PKEY **ret_private_key,
+                OpenSSLAskPasswordUI **ret_user_interface);
+
+int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret);
+
+OpenSSLAskPasswordUI* openssl_ask_password_ui_free(OpenSSLAskPasswordUI *ui);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OpenSSLAskPasswordUI*, openssl_ask_password_ui_free, NULL);
+
+#endif
index 72522787688510e593263033bda47e9989e7cdce..662739ea0fe9cc2bac3a4c3d8f136ddb81741d0d 100644 (file)
@@ -6,12 +6,6 @@
 #include <sys/mount.h>
 #include <unistd.h>
 
-#if HAVE_OPENSSL
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/x509.h>
-#endif
-
 #include "sd-device.h"
 #include "sd-id128.h"
 #include "sd-json.h"
@@ -26,6 +20,7 @@
 #include "conf-files.h"
 #include "constants.h"
 #include "copy.h"
+#include "crypto-util.h"
 #include "cryptsetup-util.h"
 #include "device-private.h"
 #include "devnum-util.h"
@@ -57,7 +52,6 @@
 #include "mountpoint-util.h"
 #include "namespace-util.h"
 #include "nulstr-util.h"
-#include "openssl-util.h"
 #include "os-util.h"
 #include "path-util.h"
 #include "pcrextend-util.h"
@@ -3087,6 +3081,10 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
         assert(iovec_is_set(&verity->root_hash));
         assert(iovec_is_set(&verity->root_hash_sig));
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         /* Because installing a signature certificate into the kernel chain is so messy, let's optionally do
          * userspace validation. */
 
@@ -3099,7 +3097,7 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
         }
 
         const unsigned char *d = verity->root_hash_sig.iov_base;
-        p7 = d2i_PKCS7(NULL, &d, (long) verity->root_hash_sig.iov_len);
+        p7 = sym_d2i_PKCS7(NULL, &d, (long) verity->root_hash_sig.iov_len);
         if (!p7)
                 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse PKCS7 DER signature data.");
 
@@ -3107,11 +3105,11 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
         if (!s)
                 return log_oom_debug();
 
-        bio = BIO_new_mem_buf(s, strlen(s));
+        bio = sym_BIO_new_mem_buf(s, strlen(s));
         if (!bio)
                 return log_oom_debug();
 
-        sk = sk_X509_new_null();
+        sk = sym_sk_X509_new_null();
         if (!sk)
                 return log_oom_debug();
 
@@ -3125,23 +3123,23 @@ static int validate_signature_userspace(const VeritySettings *verity, const char
                         continue;
                 }
 
-                c = PEM_read_X509(f, NULL, NULL, NULL);
+                c = sym_PEM_read_X509(f, NULL, NULL, NULL);
                 if (!c) {
                         log_debug("Failed to load X509 certificate '%s', ignoring.", *i);
                         continue;
                 }
 
-                if (sk_X509_push(sk, c) == 0)
+                if (sym_sk_X509_push(sk, c) == 0)
                         return log_oom_debug();
 
                 TAKE_PTR(c);
         }
 
-        r = PKCS7_verify(p7, sk, NULL, bio, NULL, PKCS7_NOINTERN|PKCS7_NOVERIFY);
+        r = sym_PKCS7_verify(p7, sk, NULL, bio, NULL, PKCS7_NOINTERN|PKCS7_NOVERIFY);
         if (r)
                 log_debug("Userspace PKCS#7 validation succeeded.");
         else
-                log_debug("Userspace PKCS#7 validation failed: %s", ERR_error_string(ERR_get_error(), NULL));
+                log_debug("Userspace PKCS#7 validation failed: %s", sym_ERR_error_string(sym_ERR_get_error(), NULL));
 
         return r;
 #else
index 1ab14a5c92a22672d62715d02e02bc90c993edf5..741dbb60a451a086b570eed67e74c314558d168d 100644 (file)
@@ -51,6 +51,7 @@ shared_sources = files(
         'coredump-util.c',
         'cpu-set-util.c',
         'creds-util.c',
+        'crypto-util.c',
         'cryptsetup-fido2.c',
         'cryptsetup-tpm2.c',
         'cryptsetup-util.c',
@@ -151,7 +152,6 @@ shared_sources = files(
         'nsresource.c',
         'numa-util.c',
         'open-file.c',
-        'openssl-util.c',
         'options.c',
         'osc-context.c',
         'output-mode.c',
@@ -197,6 +197,7 @@ shared_sources = files(
         'socket-label.c',
         'socket-netlink.c',
         'specifier.c',
+        'ssl-util.c',
         'switch-root.c',
         'swtpm-util.c',
         'tar-util.c',
@@ -400,7 +401,7 @@ libshared_deps = [threads,
                   libkmod_cflags,
                   libmicrohttpd_cflags,
                   libmount_cflags,
-                  libopenssl,
+                  libopenssl_cflags,
                   libp11kit_cflags,
                   libpam_cflags,
                   libpcre2_cflags,
diff --git a/src/shared/openssl-util.h b/src/shared/openssl-util.h
deleted file mode 100644 (file)
index 218641e..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include "ask-password-api.h"
-#include "shared-forward.h"
-#include "iovec-util.h"
-#include "sha256.h"
-
-typedef enum CertificateSourceType {
-        OPENSSL_CERTIFICATE_SOURCE_FILE,
-        OPENSSL_CERTIFICATE_SOURCE_PROVIDER,
-        _OPENSSL_CERTIFICATE_SOURCE_MAX,
-        _OPENSSL_CERTIFICATE_SOURCE_INVALID = -EINVAL,
-} CertificateSourceType;
-
-typedef enum KeySourceType {
-        OPENSSL_KEY_SOURCE_FILE,
-        OPENSSL_KEY_SOURCE_ENGINE,
-        OPENSSL_KEY_SOURCE_PROVIDER,
-        _OPENSSL_KEY_SOURCE_MAX,
-        _OPENSSL_KEY_SOURCE_INVALID = -EINVAL,
-} KeySourceType;
-
-typedef struct OpenSSLAskPasswordUI OpenSSLAskPasswordUI;
-
-int parse_openssl_certificate_source_argument(const char *argument, char **certificate_source, CertificateSourceType *certificate_source_type);
-
-int parse_openssl_key_source_argument(const char *argument, char **private_key_source, KeySourceType *private_key_source_type);
-
-#define X509_FINGERPRINT_SIZE SHA256_DIGEST_SIZE
-
-#if HAVE_OPENSSL
-#  include <openssl/bio.h>              /* IWYU pragma: export */
-#  include <openssl/bn.h>               /* IWYU pragma: export */
-#  include <openssl/core_names.h>       /* IWYU pragma: export */
-#  include <openssl/crypto.h>           /* IWYU pragma: export */
-#  include <openssl/err.h>              /* IWYU pragma: export */
-#  include <openssl/evp.h>              /* IWYU pragma: export */
-#  include <openssl/kdf.h>              /* IWYU pragma: export */
-#  include <openssl/opensslv.h>         /* IWYU pragma: export */
-#  include <openssl/param_build.h>      /* IWYU pragma: export */
-#  include <openssl/pkcs7.h>            /* IWYU pragma: export */
-#  include <openssl/provider.h>         /* IWYU pragma: export */
-#  include <openssl/ssl.h>              /* IWYU pragma: export */
-#  include <openssl/store.h>            /* IWYU pragma: export */
-#  ifndef OPENSSL_NO_UI_CONSOLE
-#    include <openssl/ui.h>             /* IWYU pragma: export */
-#  endif
-#  include <openssl/x509v3.h>           /* IWYU pragma: export */
-
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(void*, OPENSSL_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ASN1_OCTET_STRING*, ASN1_OCTET_STRING_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ASN1_TIME*, ASN1_TIME_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BIO*, BIO_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BIO*, BIO_free_all, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BIGNUM*, BN_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(BN_CTX*, BN_CTX_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_GROUP*, EC_GROUP_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_POINT*, EC_POINT_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(ECDSA_SIG*, ECDSA_SIG_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER*, EVP_CIPHER_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_CIPHER_CTX*, EVP_CIPHER_CTX_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF*, EVP_KDF_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_KDF_CTX*, EVP_KDF_CTX_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC*, EVP_MAC_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MAC_CTX*, EVP_MAC_CTX_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD*, EVP_MD_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_MD_CTX*, EVP_MD_CTX_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY*, EVP_PKEY_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY_CTX*, EVP_PKEY_CTX_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM*, OSSL_PARAM_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_PARAM_BLD*, OSSL_PARAM_BLD_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_CTX*, OSSL_STORE_close, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OSSL_STORE_INFO*, OSSL_STORE_INFO_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(PKCS7*, PKCS7_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(PKCS7_SIGNER_INFO*, PKCS7_SIGNER_INFO_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(SSL*, SSL_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(X509*, X509_free, NULL);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(X509_NAME*, X509_NAME_free, NULL);
-
-static inline STACK_OF(X509_ALGOR) *x509_algor_free_many(STACK_OF(X509_ALGOR) *attrs) {
-        if (!attrs)
-                return NULL;
-
-        sk_X509_ALGOR_pop_free(attrs, X509_ALGOR_free);
-        return NULL;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ALGOR)*, x509_algor_free_many, NULL);
-
-static inline STACK_OF(X509_ATTRIBUTE) *x509_attribute_free_many(STACK_OF(X509_ATTRIBUTE) *attrs) {
-        if (!attrs)
-                return NULL;
-
-        sk_X509_ATTRIBUTE_pop_free(attrs, X509_ATTRIBUTE_free);
-        return NULL;
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(STACK_OF(X509_ATTRIBUTE)*, x509_attribute_free_many, NULL);
-
-static inline void sk_X509_free_allp(STACK_OF(X509) **sk) {
-        if (!sk || !*sk)
-                return;
-
-        sk_X509_pop_free(*sk, X509_free);
-}
-
-int openssl_pubkey_from_pem(const void *pem, size_t pem_size, EVP_PKEY **ret);
-int openssl_pubkey_to_pem(EVP_PKEY *pkey, char **ret);
-
-int openssl_digest_size(const char *digest_alg, size_t *ret_digest_size);
-
-int openssl_digest_many(const char *digest_alg, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
-
-static inline int openssl_digest(const char *digest_alg, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
-        return openssl_digest_many(digest_alg, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
-}
-
-int openssl_hmac_many(const char *digest_alg, const void *key, size_t key_size, const struct iovec data[], size_t n_data, void **ret_digest, size_t *ret_digest_size);
-
-static inline int openssl_hmac(const char *digest_alg, const void *key, size_t key_size, const void *buf, size_t len, void **ret_digest, size_t *ret_digest_size) {
-        return openssl_hmac_many(digest_alg, key, key_size, &IOVEC_MAKE((void*) buf, len), 1, ret_digest, ret_digest_size);
-}
-
-int openssl_cipher_many(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const struct iovec data[], size_t n_data, void **ret, size_t *ret_size);
-
-static inline int openssl_cipher(const char *alg, size_t bits, const char *mode, const void *key, size_t key_size, const void *iv, size_t iv_size, const void *buf, size_t len, void **ret, size_t *ret_size) {
-        return openssl_cipher_many(alg, bits, mode, key, key_size, iv, iv_size, &IOVEC_MAKE((void*) buf, len), 1, ret, ret_size);
-}
-
-int kdf_ss_derive(const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, size_t derive_size, void **ret);
-
-int kdf_kb_hmac_derive(const char *mode, const char *digest, const void *key, size_t key_size, const void *salt, size_t salt_size, const void *info, size_t info_size, const void *seed, size_t seed_size, size_t derive_size, void **ret);
-
-int rsa_encrypt_bytes(EVP_PKEY *pkey, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
-
-int rsa_oaep_encrypt_bytes(const EVP_PKEY *pkey, const char *digest_alg, const char *label, const void *decrypted_key, size_t decrypted_key_size, void **ret_encrypt_key, size_t *ret_encrypt_key_size);
-
-int rsa_pkey_to_suitable_key_size(EVP_PKEY *pkey, size_t *ret_suitable_key_size);
-
-int rsa_pkey_from_n_e(const void *n, size_t n_size, const void *e, size_t e_size, EVP_PKEY **ret);
-
-int rsa_pkey_to_n_e(const EVP_PKEY *pkey, void **ret_n, size_t *ret_n_size, void **ret_e, size_t *ret_e_size);
-
-int ecc_pkey_from_curve_x_y(int curve_id, const void *x, size_t x_size, const void *y, size_t y_size, EVP_PKEY **ret);
-
-int ecc_pkey_to_curve_x_y(const EVP_PKEY *pkey, int *ret_curve_id, void **ret_x, size_t *ret_x_size, void **ret_y, size_t *ret_y_size);
-
-int ecc_pkey_new(int curve_id, EVP_PKEY **ret);
-
-int ecc_ecdh(const EVP_PKEY *private_pkey, const EVP_PKEY *peer_pkey, void **ret_shared_secret, size_t *ret_shared_secret_size);
-
-int pkey_generate_volume_keys(EVP_PKEY *pkey, void **ret_decrypted_key, size_t *ret_decrypted_key_size, void **ret_saved_key, size_t *ret_saved_key_size);
-
-int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_size);
-
-int digest_and_sign(const EVP_MD *md, EVP_PKEY *privkey, const void *data, size_t size, void **ret, size_t *ret_size);
-
-int pkcs7_new(X509 *certificate, EVP_PKEY *private_key, const char *hash_algorithm, PKCS7 **ret_p7, PKCS7_SIGNER_INFO **ret_si);
-
-int string_hashsum(const char *s, size_t len, const char *md_algorithm, char **ret);
-static inline int string_hashsum_sha224(const char *s, size_t len, char **ret) {
-        return string_hashsum(s, len, "SHA224", ret);
-}
-static inline int string_hashsum_sha256(const char *s, size_t len, char **ret) {
-        return string_hashsum(s, len, "SHA256", ret);
-}
-
-int x509_fingerprint(X509 *cert, uint8_t buffer[static X509_FINGERPRINT_SIZE]);
-
-int openssl_load_x509_certificate(
-                CertificateSourceType certificate_source_type,
-                const char *certificate_source,
-                const char *certificate,
-                X509 **ret);
-
-int openssl_load_private_key(
-                KeySourceType private_key_source_type,
-                const char *private_key_source,
-                const char *private_key,
-                const AskPasswordRequest *request,
-                EVP_PKEY **ret_private_key,
-                OpenSSLAskPasswordUI **ret_user_interface);
-
-int openssl_extract_public_key(EVP_PKEY *private_key, EVP_PKEY **ret);
-
-struct OpenSSLAskPasswordUI {
-        AskPasswordRequest request;
-#ifndef OPENSSL_NO_UI_CONSOLE
-        UI_METHOD *method;
-#endif
-};
-
-OpenSSLAskPasswordUI* openssl_ask_password_ui_free(OpenSSLAskPasswordUI *ui);
-DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OpenSSLAskPasswordUI*, openssl_ask_password_ui_free, NULL);
-#endif
index da54428306c116f22c04a0f3086aabbfbb348c90..b4b180d70133727fc4aef55a9037f174be62dfd4 100644 (file)
@@ -4,6 +4,7 @@
 #include <unistd.h>
 
 #include "alloc-util.h"
+#include "crypto-util.h"
 #include "hexdecoct.h"
 #include "log.h"
 #include "pe-binary.h"
@@ -325,7 +326,7 @@ static int hash_file(int fd, EVP_MD_CTX *md_ctx, uint64_t offset, uint64_t size)
                 if ((size_t) n != m)
                         return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Short read while hashing.");
 
-                if (EVP_DigestUpdate(md_ctx, buffer, m) != 1)
+                if (sym_EVP_DigestUpdate(md_ctx, buffer, m) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
 
                 offset += m;
@@ -358,6 +359,10 @@ int pe_hash(int fd,
         assert(ret_hash_size);
         assert(ret_hash);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         if (fstat(fd, &st) < 0)
                 return log_debug_errno(errno, "Failed to stat file: %m");
         r = stat_verify_regular(&st);
@@ -376,11 +381,11 @@ int pe_hash(int fd,
         if (!certificate_table)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "File lacks certificate table.");
 
-        mdctx = EVP_MD_CTX_new();
+        mdctx = sym_EVP_MD_CTX_new();
         if (!mdctx)
                 return log_oom_debug();
 
-        if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
+        if (sym_EVP_DigestInit_ex(mdctx, md, NULL) != 1)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
 
         /* Everything from beginning of file to CheckSum field in PE header */
@@ -428,11 +433,11 @@ int pe_hash(int fd,
                         return r;
 
                 /* If the file size is not a multiple of 8 bytes, pad the hash with zero bytes. */
-                if (st.st_size % 8 != 0 && EVP_DigestUpdate(mdctx, (const uint8_t[8]) {}, 8 - (st.st_size % 8)) != 1)
+                if (st.st_size % 8 != 0 && sym_EVP_DigestUpdate(mdctx, (const uint8_t[8]) {}, 8 - (st.st_size % 8)) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
         }
 
-        int hsz = EVP_MD_CTX_size(mdctx);
+        int hsz = sym_EVP_MD_CTX_get_size(mdctx);
         if (hsz < 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get hash size.");
 
@@ -441,7 +446,7 @@ int pe_hash(int fd,
         if (!hash)
                 return log_oom_debug();
 
-        if (EVP_DigestFinal_ex(mdctx, hash, &hash_size) != 1)
+        if (sym_EVP_DigestFinal_ex(mdctx, hash, &hash_size) != 1)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to finalize hash function.");
 
         assert(hash_size == (unsigned) hsz);
@@ -525,6 +530,10 @@ int uki_hash(int fd,
         assert(ret_hashes);
         assert(ret_hash_size);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         r = pe_load_headers(fd, &dos_header, &pe_header);
         if (r < 0)
                 return r;
@@ -533,7 +542,7 @@ int uki_hash(int fd,
         if (r < 0)
                 return r;
 
-        int hsz = EVP_MD_size(md);
+        int hsz = sym_EVP_MD_get_size(md);
         if (hsz < 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get hash size.");
 
@@ -553,11 +562,11 @@ int uki_hash(int fd,
                 if (hashes[i])
                         return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Duplicate section");
 
-                mdctx = EVP_MD_CTX_new();
+                mdctx = sym_EVP_MD_CTX_new();
                 if (!mdctx)
                         return log_oom_debug();
 
-                if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
+                if (sym_EVP_DigestInit_ex(mdctx, md, NULL) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
 
                 r = hash_file(fd, mdctx, le32toh(section->PointerToRawData), MIN(le32toh(section->VirtualSize), le32toh(section->SizeOfRawData)));
@@ -571,7 +580,7 @@ int uki_hash(int fd,
                         while (remaining > 0) {
                                 size_t sz = MIN(sizeof(zeroes), remaining);
 
-                                if (EVP_DigestUpdate(mdctx, zeroes, sz) != 1)
+                                if (sym_EVP_DigestUpdate(mdctx, zeroes, sz) != 1)
                                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Unable to hash data.");
 
                                 remaining -= sz;
@@ -583,7 +592,7 @@ int uki_hash(int fd,
                         return log_oom_debug();
 
                 unsigned hash_size = (unsigned) hsz;
-                if (EVP_DigestFinal_ex(mdctx, hashes[i], &hash_size) != 1)
+                if (sym_EVP_DigestFinal_ex(mdctx, hashes[i], &hash_size) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to finalize hash function.");
 
                 assert(hash_size == (unsigned) hsz);
@@ -592,7 +601,7 @@ int uki_hash(int fd,
                         _cleanup_free_ char *hs = NULL;
 
                         hs = hexmem(hashes[i], hsz);
-                        log_debug("Section %s with %s is %s.", n, EVP_MD_name(md), strna(hs));
+                        log_debug("Section %s with %s is %s.", n, sym_EVP_MD_get0_name(md), strna(hs));
                 }
         }
 
index 0f748a87d7d25f2fbd17b92da384c6c0a2188592..4b5dc243fe77f7a4505d306ecde7b5133f082ccb 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#include "openssl-util.h"
 #include "sparse-endian.h"
 #include "uki.h"
 
index eea7fec8930f3cc1c35b2daf512074889c97ee30..a4c5bb83f7d9e0da87551b9d809fa73a10598bc5 100644 (file)
@@ -1,16 +1,20 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#if HAVE_OPENSSL
+#  include <openssl/core_names.h>
+#endif
+
 #include "sd-dlopen.h"
 
 #include "alloc-util.h"
 #include "ask-password-api.h"
+#include "crypto-util.h"
 #include "dlfcn-util.h"
 #include "env-util.h"
 #include "escape.h"
 #include "format-table.h"
 #include "log.h"
 #include "memory-util.h"
-#include "openssl-util.h"
 #include "pkcs11-util.h"
 #include "random-util.h"
 #include "string-util.h"
@@ -429,7 +433,7 @@ static int read_public_key_info(
                         "Failed to read CKA_PUBLIC_KEY_INFO: %s", sym_p11_kit_strerror(rv));
 
         const unsigned char *value = attribute.pValue;
-        pkey = d2i_PUBKEY(NULL, &value, attribute.ulValueLen);
+        pkey = sym_d2i_PUBKEY(NULL, &value, attribute.ulValueLen);
         if (!pkey)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse CKA_PUBLIC_KEY_INFO");
 
@@ -449,6 +453,10 @@ int pkcs11_token_read_public_key(
 
         assert(ret_pkey);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         r = read_public_key_info(m, session, object, &pkey);
         if (r >= 0) {
                 *ret_pkey = TAKE_PTR(pkey);
@@ -543,67 +551,67 @@ int pkcs11_token_read_public_key(
                 _cleanup_(ASN1_OCTET_STRING_freep) ASN1_OCTET_STRING *os = NULL;
 
                 const unsigned char *ec_params_value = ec_attributes[0].pValue;
-                group = d2i_ECPKParameters(NULL, &ec_params_value, ec_attributes[0].ulValueLen);
+                group = sym_d2i_ECPKParameters(NULL, &ec_params_value, ec_attributes[0].ulValueLen);
                 if (!group)
                         return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_PARAMS.");
 
                 const unsigned char *ec_point_value = ec_attributes[1].pValue;
-                os = d2i_ASN1_OCTET_STRING(NULL, &ec_point_value, ec_attributes[1].ulValueLen);
+                os = sym_d2i_ASN1_OCTET_STRING(NULL, &ec_point_value, ec_attributes[1].ulValueLen);
                 if (!os)
                         return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_POINT.");
 
-                _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
+                _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
                 if (!ctx)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to create an EVP_PKEY_CTX for EC.");
 
-                if (EVP_PKEY_fromdata_init(ctx) != 1)
+                if (sym_EVP_PKEY_fromdata_init(ctx) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to init an EVP_PKEY_CTX for EC.");
 
                 OSSL_PARAM ec_params[8] = {
                         /* We need to drop the const from the data param, because ec_params is
                          * modified below. But we'll not modify ec_params[0]. */
                         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
-                                                (unsigned char *) ASN1_STRING_get0_data(os),
-                                                ASN1_STRING_length(os)),
+                                                (unsigned char *) sym_ASN1_STRING_get0_data(os),
+                                                sym_ASN1_STRING_length(os)),
                 };
 
                 _cleanup_free_ void *order = NULL, *p = NULL, *a = NULL, *b = NULL, *generator = NULL;
                 size_t order_size, p_size, a_size, b_size, generator_size;
 
-                int nid = EC_GROUP_get_curve_name(group);
+                int nid = sym_EC_GROUP_get_curve_name(group);
                 if (nid != NID_undef) {
-                        const char* name = OSSL_EC_curve_nid2name(nid);
-                        ec_params[1] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, (char*)name, strlen(name));
-                        ec_params[2] = OSSL_PARAM_construct_end();
+                        const char* name = sym_OSSL_EC_curve_nid2name(nid);
+                        ec_params[1] = sym_OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, (char*)name, strlen(name));
+                        ec_params[2] = sym_OSSL_PARAM_construct_end();
                 } else {
-                        const char *field_type = EC_GROUP_get_field_type(group) == NID_X9_62_prime_field ?
+                        const char *field_type = sym_EC_GROUP_get_field_type(group) == NID_X9_62_prime_field ?
                                 "prime-field" : "characteristic-two-field";
 
-                        const BIGNUM *bn_order = EC_GROUP_get0_order(group);
+                        const BIGNUM *bn_order = sym_EC_GROUP_get0_order(group);
 
-                        _cleanup_(BN_CTX_freep) BN_CTX *bnctx = BN_CTX_new();
+                        _cleanup_(BN_CTX_freep) BN_CTX *bnctx = sym_BN_CTX_new();
                         if (!bnctx)
                                 return log_oom_debug();
 
-                        _cleanup_(BN_freep) BIGNUM *bn_p = BN_new();
+                        _cleanup_(BN_freep) BIGNUM *bn_p = sym_BN_new();
                         if (!bn_p)
                                 return log_oom_debug();
 
-                        _cleanup_(BN_freep) BIGNUM *bn_a = BN_new();
+                        _cleanup_(BN_freep) BIGNUM *bn_a = sym_BN_new();
                         if (!bn_a)
                                 return log_oom_debug();
 
-                        _cleanup_(BN_freep) BIGNUM *bn_b = BN_new();
+                        _cleanup_(BN_freep) BIGNUM *bn_b = sym_BN_new();
                         if (!bn_b)
                                 return log_oom_debug();
 
-                        if (EC_GROUP_get_curve(group, bn_p, bn_a, bn_b, bnctx) != 1)
+                        if (sym_EC_GROUP_get_curve(group, bn_p, bn_a, bn_b, bnctx) != 1)
                                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract EC parameters from EC_GROUP.");
 
-                        order_size = BN_num_bytes(bn_order);
-                        p_size = BN_num_bytes(bn_p);
-                        a_size = BN_num_bytes(bn_a);
-                        b_size = BN_num_bytes(bn_b);
+                        order_size = sym_BN_num_bytes(bn_order);
+                        p_size = sym_BN_num_bytes(bn_p);
+                        a_size = sym_BN_num_bytes(bn_a);
+                        b_size = sym_BN_num_bytes(bn_b);
 
                         order = malloc(order_size);
                         if (!order)
@@ -621,14 +629,14 @@ int pkcs11_token_read_public_key(
                         if (!b)
                                 return log_oom_debug();
 
-                        if (BN_bn2nativepad(bn_order, order, order_size) <= 0 ||
-                            BN_bn2nativepad(bn_p, p, p_size) <= 0 ||
-                            BN_bn2nativepad(bn_a, a, a_size) <= 0 ||
-                            BN_bn2nativepad(bn_b, b, b_size) <= 0 )
+                        if (sym_BN_bn2nativepad(bn_order, order, order_size) <= 0 ||
+                            sym_BN_bn2nativepad(bn_p, p, p_size) <= 0 ||
+                            sym_BN_bn2nativepad(bn_a, a, a_size) <= 0 ||
+                            sym_BN_bn2nativepad(bn_b, b, b_size) <= 0 )
                                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to store EC parameters in native byte order.");
 
-                        const EC_POINT *point_gen = EC_GROUP_get0_generator(group);
-                        generator_size = EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bnctx);
+                        const EC_POINT *point_gen = sym_EC_GROUP_get0_generator(group);
+                        generator_size = sym_EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bnctx);
                         if (generator_size == 0)
                                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine size of a EC generator.");
 
@@ -636,20 +644,20 @@ int pkcs11_token_read_public_key(
                         if (!generator)
                                 return log_oom_debug();
 
-                        generator_size = EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, generator, generator_size, bnctx);
+                        generator_size = sym_EC_POINT_point2oct(group, point_gen, POINT_CONVERSION_UNCOMPRESSED, generator, generator_size, bnctx);
                         if (generator_size == 0)
                                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert a EC generator to octet string.");
 
-                        ec_params[1] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, (char*)field_type, strlen(field_type));
-                        ec_params[2] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, generator, generator_size);
-                        ec_params[3] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_ORDER, order, order_size);
-                        ec_params[4] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_P, p, p_size);
-                        ec_params[5] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_A, a, a_size);
-                        ec_params[6] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_B, b, b_size);
-                        ec_params[7] = OSSL_PARAM_construct_end();
+                        ec_params[1] = sym_OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, (char*)field_type, strlen(field_type));
+                        ec_params[2] = sym_OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, generator, generator_size);
+                        ec_params[3] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_ORDER, order, order_size);
+                        ec_params[4] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_P, p, p_size);
+                        ec_params[5] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_A, a, a_size);
+                        ec_params[6] = sym_OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_EC_B, b, b_size);
+                        ec_params[7] = sym_OSSL_PARAM_construct_end();
                 }
 
-                if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, ec_params) != 1)
+                if (sym_EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, ec_params) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to create EVP_PKEY from EC parameters.");
                 break;
         }
@@ -695,16 +703,20 @@ int pkcs11_token_read_x509_certificate(
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                        "Failed to read X.509 certificate data off token: %s", sym_p11_kit_strerror(rv));
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         const unsigned char *p = attribute.pValue;
-        _cleanup_(X509_freep) X509 *x509 = d2i_X509(NULL, &p, attribute.ulValueLen);
+        _cleanup_(X509_freep) X509 *x509 = sym_d2i_X509(NULL, &p, attribute.ulValueLen);
         if (!x509)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse X.509 certificate.");
 
-        const X509_NAME *name = X509_get_subject_name(x509);
+        const X509_NAME *name = sym_X509_get_subject_name(x509);
         if (!name)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to acquire X.509 subject name.");
 
-        _cleanup_free_ char *t = X509_NAME_oneline(name, NULL, 0);
+        _cleanup_free_ char *t = sym_X509_NAME_oneline(name, NULL, 0);
         if (!t)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Failed to format X.509 subject name as string.");
 
@@ -1009,23 +1021,27 @@ static int ecc_convert_to_compressed(
         _cleanup_free_ void *compressed_point = NULL;
         size_t compressed_point_size;
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         const unsigned char *ec_params_value = ec_params_attr.pValue;
-        group = d2i_ECPKParameters(NULL, &ec_params_value, ec_params_attr.ulValueLen);
+        group = sym_d2i_ECPKParameters(NULL, &ec_params_value, ec_params_attr.ulValueLen);
         if (!group)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode CKA_EC_PARAMS");
 
-        point = EC_POINT_new(group);
+        point = sym_EC_POINT_new(group);
         if (!point)
                 return log_oom();
 
-        bnctx = BN_CTX_new();
+        bnctx = sym_BN_CTX_new();
         if (!bnctx)
                 return log_oom();
 
-        if (EC_POINT_oct2point(group, point, uncompressed_point, uncompressed_point_size, bnctx) != 1)
+        if (sym_EC_POINT_oct2point(group, point, uncompressed_point, uncompressed_point_size, bnctx) != 1)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unable to decode an uncompressed EC point");
 
-        compressed_point_size = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, bnctx);
+        compressed_point_size = sym_EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, NULL, 0, bnctx);
         if (compressed_point_size == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine size of a compressed EC point");
 
@@ -1033,7 +1049,7 @@ static int ecc_convert_to_compressed(
         if (!compressed_point)
                 return log_oom();
 
-        compressed_point_size = EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, compressed_point, compressed_point_size, bnctx);
+        compressed_point_size = sym_EC_POINT_point2oct(group, point, POINT_CONVERSION_COMPRESSED, compressed_point, compressed_point_size, bnctx);
         if (compressed_point_size == 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert a EC point to compressed format");
 
@@ -1521,7 +1537,8 @@ struct pkcs11_acquire_public_key_callback_data {
 
 static void pkcs11_acquire_public_key_callback_data_release(struct pkcs11_acquire_public_key_callback_data *data) {
         erase_and_free(data->pin_used);
-        EVP_PKEY_free(data->pkey);
+        if (data->pkey)
+                sym_EVP_PKEY_free(data->pkey);
 }
 
 static int pkcs11_acquire_public_key_callback(
@@ -1673,7 +1690,11 @@ static int pkcs11_acquire_public_key_callback(
                 if (r < 0)
                         return log_error_errno(r, "Failed to read a found X.509 certificate.");
 
-                pkey = X509_get_pubkey(cert);
+                r = dlopen_libcrypto(LOG_DEBUG);
+                if (r < 0)
+                        return r;
+
+                pkey = sym_X509_get_pubkey(cert);
                 if (!pkey)
                         return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate.");
         }
index 92d850b6e5008cf81e76502df8a0003d9817ee85..7864598180f627beccbf880e9a12053ed970a86b 100644 (file)
@@ -1,10 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-#if HAVE_OPENSSL
-#  include <openssl/evp.h>
-#endif
-
 #if HAVE_P11KIT
 #  include <p11-kit/p11-kit.h>  /* IWYU pragma: export */
 #  include <p11-kit/uri.h>      /* IWYU pragma: export */
index 0a0e102adf7d94f57381606624e3e43f718cd6af..4d22d90421a996da4639a2410d0f4704535d64ca 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "alloc-util.h"
-#include "openssl-util.h"
+#include "crypto-util.h"
 #include "pkcs7-util.h"
 #include "log.h"
 
@@ -28,6 +28,10 @@ int pkcs7_extract_signers(
                 Signer **ret_signers,
                 size_t *ret_n_signers) {
 
+#if HAVE_OPENSSL
+        int r;
+#endif
+
         assert(ret_signers);
         assert(ret_n_signers);
 
@@ -35,16 +39,20 @@ int pkcs7_extract_signers(
                 return -EBADMSG;
 
 #if HAVE_OPENSSL
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         const unsigned char *d = sig->iov_base;
         _cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
-        p7 = d2i_PKCS7(/* a= */ NULL, &d, (long) sig->iov_len);
+        p7 = sym_d2i_PKCS7(/* a= */ NULL, &d, (long) sig->iov_len);
         if (!p7)
                 return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Failed to parse PKCS7 DER signature data.");
 
-        STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
+        STACK_OF(PKCS7_SIGNER_INFO) *sinfos = sym_PKCS7_get_signer_info(p7);
         if (!sinfos)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "No signature information in PKCS7 signature?");
-        int n = sk_PKCS7_SIGNER_INFO_num(sinfos);
+        int n = sym_sk_PKCS7_SIGNER_INFO_num(sinfos);
         if (n == 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "No signatures in PKCS7 signature, refusing.");
         if (n > SIGNERS_MAX) /* safety net, in case people send us weirdly complex signatures */
@@ -59,17 +67,17 @@ int pkcs7_extract_signers(
         CLEANUP_ARRAY(signers, n_signers, signer_free_many);
 
         for (int i = 0; i < n; i++) {
-                PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(PKCS7_get_signer_info(p7), i);
+                PKCS7_SIGNER_INFO *si = sym_sk_PKCS7_SIGNER_INFO_value(sym_PKCS7_get_signer_info(p7), i);
                 if (!si)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get signer information.");
 
                 _cleanup_(signer_done) Signer signer = {};
 
                 _cleanup_free_ unsigned char *p = NULL;
-                int len = i2d_X509_NAME(si->issuer_and_serial->issuer, &p);
+                int len = sym_i2d_X509_NAME(si->issuer_and_serial->issuer, &p);
                 signer.issuer = IOVEC_MAKE(TAKE_PTR(p), len);
 
-                len = i2d_ASN1_INTEGER(si->issuer_and_serial->serial, &p);
+                len = sym_i2d_ASN1_INTEGER(si->issuer_and_serial->serial, &p);
                 signer.serial = IOVEC_MAKE(TAKE_PTR(p), len);
 
                 signers[n_signers++] = TAKE_STRUCT(signer);
index 38349d9dbbcc3b2cd2daf64f49cb33f50ad20aa1..1a19b42499ca5f2acc9d21d6fa2130c0995714ef 100644 (file)
@@ -45,6 +45,7 @@ typedef enum UserDBFlags UserDBFlags;
 typedef enum UserRecordLoadFlags UserRecordLoadFlags;
 typedef enum UserStorage UserStorage;
 
+typedef struct AskPasswordRequest AskPasswordRequest;
 typedef struct Bitmap Bitmap;
 typedef struct BootConfig BootConfig;
 typedef struct BPFProgram BPFProgram;
diff --git a/src/shared/ssl-util.c b/src/shared/ssl-util.c
new file mode 100644 (file)
index 0000000..82ed54d
--- /dev/null
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-dlopen.h"
+
+#include "log.h"                /* IWYU pragma: keep */
+#include "ssl-util.h"
+
+#if HAVE_OPENSSL
+
+static void *libssl_dl = NULL;
+
+DLSYM_PROTOTYPE(SSL_ctrl) = NULL;
+DLSYM_PROTOTYPE(SSL_CTX_ctrl) = NULL;
+DLSYM_PROTOTYPE(SSL_CTX_free) = NULL;
+DLSYM_PROTOTYPE(SSL_CTX_new) = NULL;
+DLSYM_PROTOTYPE(SSL_CTX_set_default_verify_paths) = NULL;
+DLSYM_PROTOTYPE(SSL_CTX_set_options) = NULL;
+DLSYM_PROTOTYPE(SSL_do_handshake) = NULL;
+DLSYM_PROTOTYPE(SSL_free) = NULL;
+DLSYM_PROTOTYPE(SSL_get_error) = NULL;
+DLSYM_PROTOTYPE(SSL_get_wbio) = NULL;
+DLSYM_PROTOTYPE(SSL_get0_param) = NULL;
+DLSYM_PROTOTYPE(SSL_get1_session) = NULL;
+DLSYM_PROTOTYPE(SSL_new) = NULL;
+DLSYM_PROTOTYPE(SSL_read) = NULL;
+DLSYM_PROTOTYPE(SSL_SESSION_free) = NULL;
+DLSYM_PROTOTYPE(SSL_set_bio) = NULL;
+DLSYM_PROTOTYPE(SSL_set_connect_state) = NULL;
+DLSYM_PROTOTYPE(SSL_set_session) = NULL;
+DLSYM_PROTOTYPE(SSL_set_verify) = NULL;
+DLSYM_PROTOTYPE(SSL_shutdown) = NULL;
+DLSYM_PROTOTYPE(SSL_write) = NULL;
+DLSYM_PROTOTYPE(TLS_client_method) = NULL;
+
+#endif
+
+int dlopen_libssl(int log_level) {
+#if HAVE_OPENSSL
+        SD_ELF_NOTE_DLOPEN(
+                        "libssl",
+                        "Support for TLS",
+                        SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+                        "libssl.so.3");
+
+        return dlopen_many_sym_or_warn(
+                        &libssl_dl,
+                        "libssl.so.3",
+                        log_level,
+                        DLSYM_ARG(SSL_ctrl),
+                        DLSYM_ARG(SSL_CTX_ctrl),
+                        DLSYM_ARG(SSL_CTX_free),
+                        DLSYM_ARG(SSL_CTX_new),
+                        DLSYM_ARG(SSL_CTX_set_default_verify_paths),
+                        DLSYM_ARG(SSL_CTX_set_options),
+                        DLSYM_ARG(SSL_do_handshake),
+                        DLSYM_ARG(SSL_free),
+                        DLSYM_ARG(SSL_get_error),
+                        DLSYM_ARG(SSL_get_wbio),
+                        DLSYM_ARG(SSL_get0_param),
+                        DLSYM_ARG(SSL_get1_session),
+                        DLSYM_ARG(SSL_new),
+                        DLSYM_ARG(SSL_read),
+                        DLSYM_ARG(SSL_SESSION_free),
+                        DLSYM_ARG(SSL_set_bio),
+                        DLSYM_ARG(SSL_set_connect_state),
+                        DLSYM_ARG(SSL_set_session),
+                        DLSYM_ARG(SSL_set_verify),
+                        DLSYM_ARG(SSL_shutdown),
+                        DLSYM_ARG(SSL_write),
+                        DLSYM_ARG(TLS_client_method));
+#else
+        return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
+                              "libssl support is not compiled in.");
+#endif
+}
diff --git a/src/shared/ssl-util.h b/src/shared/ssl-util.h
new file mode 100644 (file)
index 0000000..7deb028
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "shared-forward.h"
+
+int dlopen_libssl(int log_level);
+
+#if HAVE_OPENSSL
+
+#  include <openssl/ssl.h>              /* IWYU pragma: export */
+
+#  include "dlfcn-util.h"
+
+extern DLSYM_PROTOTYPE(SSL_ctrl);
+extern DLSYM_PROTOTYPE(SSL_CTX_ctrl);
+extern DLSYM_PROTOTYPE(SSL_CTX_free);
+extern DLSYM_PROTOTYPE(SSL_CTX_new);
+extern DLSYM_PROTOTYPE(SSL_CTX_set_default_verify_paths);
+extern DLSYM_PROTOTYPE(SSL_CTX_set_options);
+extern DLSYM_PROTOTYPE(SSL_do_handshake);
+extern DLSYM_PROTOTYPE(SSL_free);
+extern DLSYM_PROTOTYPE(SSL_get_error);
+extern DLSYM_PROTOTYPE(SSL_get_wbio);
+extern DLSYM_PROTOTYPE(SSL_get0_param);
+extern DLSYM_PROTOTYPE(SSL_get1_session);
+extern DLSYM_PROTOTYPE(SSL_new);
+extern DLSYM_PROTOTYPE(SSL_read);
+extern DLSYM_PROTOTYPE(SSL_SESSION_free);
+extern DLSYM_PROTOTYPE(SSL_set_bio);
+extern DLSYM_PROTOTYPE(SSL_set_connect_state);
+extern DLSYM_PROTOTYPE(SSL_set_session);
+extern DLSYM_PROTOTYPE(SSL_set_verify);
+extern DLSYM_PROTOTYPE(SSL_shutdown);
+extern DLSYM_PROTOTYPE(SSL_write);
+extern DLSYM_PROTOTYPE(TLS_client_method);
+
+/* Mirrors of OpenSSL macros that go through our dlopen'd sym_* variants, so we don't end up linking against
+ * libssl just for these. */
+#define sym_SSL_set_tlsext_host_name(s, name) \
+        sym_SSL_ctrl((s), SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (void *) (name))
+#define sym_SSL_CTX_set_min_proto_version(ctx, version) \
+        sym_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MIN_PROTO_VERSION, (version), NULL)
+
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(SSL*, sym_SSL_free, SSL_freep, NULL);
+
+#endif
index d972d39d76f94e9c7fc09ad09df984a962a80872..9fe3e018693fc174df0dc4beee1ee8994570dcad 100644 (file)
@@ -13,6 +13,7 @@
 #include "chase.h"
 #include "constants.h"
 #include "creds-util.h"
+#include "crypto-util.h"
 #include "cryptsetup-util.h"
 #include "device-private.h"
 #include "device-util.h"
 #include "unaligned.h"
 #include "virt.h"
 
-#if HAVE_OPENSSL
-#  include <openssl/hmac.h>
-#endif
-
 #if HAVE_TPM2
 static void *libtss2_esys_dl = NULL;
 static void *libtss2_rc_dl = NULL;
@@ -3087,11 +3084,15 @@ int tpm2_get_good_pcr_banks_strv(
 #if HAVE_OPENSSL
         _cleanup_free_ TPMI_ALG_HASH *algs = NULL;
         _cleanup_strv_free_ char **l = NULL;
-        int n_algs;
+        int n_algs, r;
 
         assert(c);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         n_algs = tpm2_get_good_pcr_banks(c, pcr_mask, &algs);
         if (n_algs < 0)
                 return n_algs;
@@ -3105,11 +3106,11 @@ int tpm2_get_good_pcr_banks_strv(
                 if (!salg)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unknown PCR algorithm, can't measure.");
 
-                implementation = EVP_get_digestbyname(salg);
+                implementation = sym_EVP_get_digestbyname(salg);
                 if (!implementation)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "TPM2 operates with unsupported PCR algorithm, can't measure.");
 
-                n = strdup(ASSERT_PTR(EVP_MD_name(implementation)));
+                n = strdup(ASSERT_PTR(sym_EVP_MD_get0_name(implementation)));
                 if (!n)
                         return log_oom_debug();
 
@@ -3783,6 +3784,10 @@ int tpm2_policy_signed_hmac_sha256(
          * specified in the hmac_key parameter. The secret key must be loaded into the TPM already and
          * referenced in hmac_key_handle. */
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         log_debug("Submitting PolicySigned policy for HMAC-SHA256.");
 
         /* Acquire the nonce from the TPM that we shall sign */
@@ -3818,7 +3823,7 @@ int tpm2_policy_signed_hmac_sha256(
         unsigned hmac_signature_size = sizeof(hmac_signature);
 
         /* And sign this with our key */
-        if (!HMAC(EVP_sha256(),
+        if (!sym_HMAC(sym_EVP_sha256(),
                   hmac_key->iov_base,
                   hmac_key->iov_len,
                   digest_to_sign.buffer,
@@ -4555,6 +4560,10 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret)
         assert(pkey);
         assert(ret);
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         TPMT_PUBLIC public = {
                 .nameAlg = TPM2_ALG_SHA256,
                 .objectAttributes = TPMA_OBJECT_DECRYPT | TPMA_OBJECT_SIGN_ENCRYPT | TPMA_OBJECT_USERWITHAUTH,
@@ -4564,7 +4573,7 @@ int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret)
                 },
         };
 
-        int key_id = EVP_PKEY_get_id(pkey);
+        int key_id = sym_EVP_PKEY_get_id(pkey);
         switch (key_id) {
         case EVP_PKEY_EC: {
                 public.type = TPM2_ALG_ECC;
@@ -4662,8 +4671,12 @@ int tpm2_tpm2b_public_to_fingerprint(
         if (r < 0)
                 return r;
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         /* Hardcode fingerprint to SHA256 */
-        return pubkey_fingerprint(pkey, EVP_sha256(), ret_fingerprint, ret_fingerprint_size);
+        return pubkey_fingerprint(pkey, sym_EVP_sha256(), ret_fingerprint, ret_fingerprint_size);
 #else
         return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
 #endif
@@ -6812,17 +6825,21 @@ static int tpm2_userspace_log(
         if (fd < 0) /* Apparently tpm2_local_log_open() failed earlier, let's not complain again */
                 return 0;
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         for (size_t i = 0; i < values->count; i++) {
                 const EVP_MD *implementation;
                 const char *a;
 
                 assert_se(a = tpm2_hash_alg_to_string(values->digests[i].hashAlg));
-                assert_se(implementation = EVP_get_digestbyname(a));
+                assert_se(implementation = sym_EVP_get_digestbyname(a));
 
                 r = sd_json_variant_append_arraybo(
                                 &array,
                                 SD_JSON_BUILD_PAIR_STRING("hashAlg", a),
-                                SD_JSON_BUILD_PAIR_HEX("digest", &values->digests[i].digest, EVP_MD_size(implementation)));
+                                SD_JSON_BUILD_PAIR_HEX("digest", &values->digests[i].digest, sym_EVP_MD_get_size(implementation)));
                 if (r < 0)
                         return log_debug_errno(r, "Failed to append digest object to JSON array: %m");
         }
@@ -6880,6 +6897,7 @@ int tpm2_pcr_extend_bytes(
         _cleanup_close_ int log_fd = -EBADF;
         TPML_DIGEST_VALUES values = {};
         TSS2_RC rc;
+        int r;
 
         assert(c);
         assert(iovec_is_valid(data));
@@ -6894,19 +6912,23 @@ int tpm2_pcr_extend_bytes(
         if (strv_isempty(banks))
                 return 0;
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         STRV_FOREACH(bank, banks) {
                 const EVP_MD *implementation;
                 int id;
 
-                assert_se(implementation = EVP_get_digestbyname(*bank));
+                assert_se(implementation = sym_EVP_get_digestbyname(*bank));
 
                 if (values.count >= ELEMENTSOF(values.digests))
                         return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
 
-                if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
+                if ((size_t) sym_EVP_MD_get_size(implementation) > sizeof(values.digests[values.count].digest))
                         return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
 
-                id = tpm2_hash_alg_from_string(EVP_MD_name(implementation));
+                id = tpm2_hash_alg_from_string(sym_EVP_MD_get0_name(implementation));
                 if (id < 0)
                         return log_debug_errno(id, "Can't map hash name to TPM2.");
 
@@ -6919,9 +6941,9 @@ int tpm2_pcr_extend_bytes(
                  * some unrelated purpose, who knows). Hence we instead measure an HMAC signature of a
                  * private non-secret string instead. */
                 if (iovec_is_set(secret) > 0) {
-                        if (!HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL))
+                        if (!sym_HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL))
                                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
-                } else if (EVP_Digest(data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
+                } else if (sym_EVP_Digest(data->iov_base, data->iov_len, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
 
                 values.count++;
@@ -7054,6 +7076,10 @@ int tpm2_nvpcr_extend_bytes(
         assert(iovec_is_valid(data));
         assert(iovec_is_valid(secret));
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         _cleanup_(nvpcr_data_done) NvPCRData p = {};
         r = nvpcr_data_load(name, &p);
         if (r < 0)
@@ -7077,10 +7103,10 @@ int tpm2_nvpcr_extend_bytes(
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported algorithm for NvPCR, refusing.");
 
         const EVP_MD *implementation;
-        assert_se(implementation = EVP_get_digestbyname(an));
+        assert_se(implementation = sym_EVP_get_digestbyname(an));
 
         _cleanup_(iovec_done) struct iovec digest = {
-                .iov_len = EVP_MD_size(implementation),
+                .iov_len = sym_EVP_MD_get_size(implementation),
         };
 
         digest.iov_base = malloc(digest.iov_len);
@@ -7091,9 +7117,9 @@ int tpm2_nvpcr_extend_bytes(
                 data = &iovec_empty;
 
         if (iovec_is_set(secret)) {
-                if (!HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, digest.iov_base, NULL))
+                if (!sym_HMAC(implementation, secret->iov_base, secret->iov_len, data->iov_base, data->iov_len, digest.iov_base, NULL))
                         return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
-        } else if (EVP_Digest(data->iov_base, data->iov_len, digest.iov_base, NULL, implementation, NULL) != 1)
+        } else if (sym_EVP_Digest(data->iov_base, data->iov_len, digest.iov_base, NULL, implementation, NULL) != 1)
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash data to measure.");
 
         _cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
@@ -7595,10 +7621,14 @@ int tpm2_nvpcr_initialize(
         if (!an)
                 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported algorithm for NvPCR, refusing.");
 
+        r = dlopen_libcrypto(LOG_DEBUG);
+        if (r < 0)
+                return r;
+
         const EVP_MD *implementation;
-        assert_se(implementation = EVP_get_digestbyname(an));
+        assert_se(implementation = sym_EVP_get_digestbyname(an));
 
-        int digest_size = EVP_MD_get_size(implementation);
+        int digest_size = sym_EVP_MD_get_size(implementation);
         assert_se(digest_size > 0);
 
         if ((size_t) digest_size > sizeof_field(TPM2B_MAX_NV_BUFFER, buffer))
@@ -7619,7 +7649,7 @@ int tpm2_nvpcr_initialize(
         CLEANUP_ERASE(buf);
 
         /* We measure HMAC(anchor_secret, name) into the NvPCR to anchor it on our secret. */
-        if (!HMAC(implementation, anchor_secret->iov_base, anchor_secret->iov_len, hmac_buffer, hmac_buffer_size, buf.buffer, NULL))
+        if (!sym_HMAC(implementation, anchor_secret->iov_base, anchor_secret->iov_len, hmac_buffer, hmac_buffer_size, buf.buffer, NULL))
                 return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to calculate HMAC of data to measure.");
 
         _cleanup_(tpm2_handle_freep) Tpm2Handle *nv_handle = NULL;
index 8576f278cf1953f4442f65ae5c6a144fa00f6201..b5a8ec1c1eaf77beb1978da72631749c0c469182 100644 (file)
@@ -2,8 +2,9 @@
 #pragma once
 
 #include "bitfield.h"
-#include "openssl-util.h"
+#include "iovec-util.h"
 #include "shared-forward.h"
+#include "sha256-fundamental.h"
 
 typedef enum TPM2Flags {
         TPM2_FLAGS_USE_PIN     = 1 << 0,
index 68ac0e14ee89c484081829b795cf747459c71cc0..3a1ee1a048c621c5f03da301dfd72dcc0ecd636e 100644 (file)
@@ -29,7 +29,7 @@ executables += [
                 'extract' : systemd_sysupdate_extract_sources,
                 'dependencies' : [
                         libfdisk_cflags,
-                        libopenssl,
+                        libopenssl_cflags,
                         threads,
                 ],
         },
index 9544c166a59280a2e3b5054e853378b25d8bad20..6f9a24eb044831e9cdd58c7bd12997a1b23a140c 100644 (file)
@@ -289,8 +289,8 @@ executables += [
                 'c_args' : ['-fno-sanitize=all', '-fno-optimize-sibling-calls', '-O1'],
         },
         test_template + {
-                'sources' : files('test-cryptolib.c'),
-                'dependencies' : libopenssl,
+                'sources' : files('test-crypto-util.c'),
+                'dependencies' : libopenssl_cflags,
                 'conditions' : ['HAVE_OPENSSL'],
         },
         test_template + {
@@ -410,14 +410,9 @@ executables += [
                 'dependencies' : libdl,
                 'conditions' : ['ENABLE_NSS'],
         },
-        test_template + {
-                'sources' : files('test-openssl.c'),
-                'dependencies' : libopenssl,
-                'conditions' : ['HAVE_OPENSSL'],
-        },
         test_template + {
                 'sources' : files('test-pkcs7-util.c'),
-                'dependencies' : libopenssl,
+                'dependencies' : libopenssl_cflags,
                 'conditions' : ['HAVE_OPENSSL'],
         },
         test_template + {
@@ -494,7 +489,7 @@ executables += [
         },
         test_template + {
                 'sources' : files('test-tpm2.c'),
-                'dependencies' : libopenssl,
+                'dependencies' : libopenssl_cflags,
                 'timeout' : 120,
         },
         test_template + {
similarity index 93%
rename from src/test/test-openssl.c
rename to src/test/test-crypto-util.c
index a09484a2ba8ad38cb541683765fe5d251ef2da22..a2fd090ed3fabf919bc7095e206c382bb66d25be 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include "openssl-util.h"
+#include "crypto-util.h"
 #include "tests.h"
 
 TEST(openssl_pkey_from_pem) {
@@ -42,16 +42,16 @@ TEST(rsa_pkey_n_e) {
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
         assert_se(rsa_pkey_from_n_e(n, n_len, &e, sizeof(e), &pkey) >= 0);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new(pkey, NULL);
         assert_se(ctx);
-        assert_se(EVP_PKEY_verify_init(ctx) == 1);
+        assert_se(sym_EVP_PKEY_verify_init(ctx) == 1);
 
         const char *msg = "this is a secret";
         DEFINE_HEX_PTR(sig, "14b53e0c6ad99a350c3d7811e8160f4ae03ad159815bb91bddb9735b833588df2eac221fbd3fc4ece0dd63bfaeddfdaf4ae67021e759f3638bc194836413414f54e8c4d01c9c37fa4488ea2ef772276b8a33822a53c97b1c35acfb4bc621cfb8fad88f0cf7d5491f05236886afbf9ed47f9469536482f50f74a20defa59d99676bed62a17b5eb98641df5a2f8080fa4b24f2749cc152fa65ba34c14022fcb27f1b36f52021950d7b9b6c3042c50b84cfb7d55a5f9235bfd58e1bf1f604eb93416c5fb5fd90cb68f1270dfa9daf67f52c604f62c2f2beee5e7e672b0e6e9833dd43dba99b77668540c850c9a81a5ea7aaf6297383e6135bd64572362333121fc7");
-        assert_se(EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
+        assert_se(sym_EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
 
         DEFINE_HEX_PTR(invalid_sig, "1234");
-        assert_se(EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
+        assert_se(sym_EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
 
         _cleanup_free_ void *n2 = NULL, *e2 = NULL;
         size_t n2_size, e2_size;
@@ -69,16 +69,16 @@ TEST(ecc_pkey_curve_x_y) {
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
         assert_se(ecc_pkey_from_curve_x_y(curveid, x, x_len, y, y_len, &pkey) >= 0);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = sym_EVP_PKEY_CTX_new(pkey, NULL);
         assert_se(ctx);
-        assert_se(EVP_PKEY_verify_init(ctx) == 1);
+        assert_se(sym_EVP_PKEY_verify_init(ctx) == 1);
 
         const char *msg = "this is a secret";
         DEFINE_HEX_PTR(sig, "3045022100f6ca10f7ed57a020679899b26dd5ac5a1079265885e2a6477f527b6a3f02b5ca02207b550eb3e7b69360aff977f7f6afac99c3f28266b6c5338ce373f6b59263000a");
-        assert_se(EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
+        assert_se(sym_EVP_PKEY_verify(ctx, sig, sig_len, (unsigned char*) msg, strlen(msg)) == 1);
 
         DEFINE_HEX_PTR(invalid_sig, "1234");
-        assert_se(EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
+        assert_se(sym_EVP_PKEY_verify(ctx, invalid_sig, invalid_sig_len, (unsigned char*) msg, strlen(msg)) != 1);
 
         _cleanup_free_ void *x2 = NULL, *y2 = NULL;
         size_t x2_size, y2_size;
@@ -465,4 +465,31 @@ TEST(ecc_ecdh) {
         assert_se(memcmp_nn(secretAC, secretAC_size, secretAB, secretAB_size) != 0);
 }
 
-DEFINE_TEST_MAIN(LOG_DEBUG);
+TEST(string_hashsum) {
+        _cleanup_free_ char *out1 = NULL, *out2 = NULL, *out3 = NULL, *out4 = NULL;
+
+        ASSERT_OK(string_hashsum("asdf", 4, "SHA224", &out1));
+        /* echo -n 'asdf' | sha224sum - */
+        ASSERT_STREQ(out1, "7872a74bcbf298a1e77d507cd95d4f8d96131cbbd4cdfc571e776c8a");
+
+        ASSERT_OK(string_hashsum("asdf", 4, "SHA256", &out2));
+        /* echo -n 'asdf' | sha256sum - */
+        ASSERT_STREQ(out2, "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b");
+
+        ASSERT_OK(string_hashsum("", 0, "SHA224", &out3));
+        /* echo -n '' | sha224sum - */
+        ASSERT_STREQ(out3, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
+
+        ASSERT_OK(string_hashsum("", 0, "SHA256", &out4));
+        /* echo -n '' | sha256sum - */
+        ASSERT_STREQ(out4, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+}
+
+static int intro(void) {
+        if (dlopen_libcrypto(LOG_DEBUG) < 0)
+                return log_tests_skipped("libcrypto is not available");
+
+        return EXIT_SUCCESS;
+}
+
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro);
diff --git a/src/test/test-cryptolib.c b/src/test/test-cryptolib.c
deleted file mode 100644 (file)
index d86236b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include "alloc-util.h"
-#include "openssl-util.h"
-#include "tests.h"
-
-TEST(string_hashsum) {
-        _cleanup_free_ char *out1 = NULL, *out2 = NULL, *out3 = NULL, *out4 = NULL;
-
-        ASSERT_OK(string_hashsum("asdf", 4, "SHA224", &out1));
-        /* echo -n 'asdf' | sha224sum - */
-        ASSERT_STREQ(out1, "7872a74bcbf298a1e77d507cd95d4f8d96131cbbd4cdfc571e776c8a");
-
-        ASSERT_OK(string_hashsum("asdf", 4, "SHA256", &out2));
-        /* echo -n 'asdf' | sha256sum - */
-        ASSERT_STREQ(out2, "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b");
-
-        ASSERT_OK(string_hashsum("", 0, "SHA224", &out3));
-        /* echo -n '' | sha224sum - */
-        ASSERT_STREQ(out3, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f");
-
-        ASSERT_OK(string_hashsum("", 0, "SHA256", &out4));
-        /* echo -n '' | sha256sum - */
-        ASSERT_STREQ(out4, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
-}
-
-DEFINE_TEST_MAIN(LOG_INFO);
index d3121981cf50ac3a0ebb51beaa6ccaba0790c886..7421a77024f1b14545e06b68828ad29cc37a2be6 100644 (file)
@@ -5,6 +5,7 @@
 #include "blkid-util.h"
 #include "bpf-dlopen.h"
 #include "compress.h"
+#include "crypto-util.h"
 #include "cryptsetup-util.h"
 #include "curl-util.h"
 #include "elf-util.h"
@@ -28,6 +29,7 @@
 #include "qrcode-util.h"
 #include "seccomp-util.h"
 #include "selinux-util.h"
+#include "ssl-util.h"
 #include "tests.h"
 #include "tpm2-util.h"
 
@@ -68,6 +70,8 @@ static int run(int argc, char **argv) {
         ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM);
         ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
         ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX);
+        ASSERT_DLOPEN(dlopen_libcrypto, HAVE_OPENSSL);
+        ASSERT_DLOPEN(dlopen_libssl, HAVE_OPENSSL);
         ASSERT_DLOPEN(dlopen_xz, HAVE_XZ);
         ASSERT_DLOPEN(dlopen_lz4, HAVE_LZ4);
         ASSERT_DLOPEN(dlopen_microhttpd, HAVE_MICROHTTPD);
index 78e2d234ab5c74bf0e8531df905442881ec3fe4d..c9a2e0a9bb80bf6ef50a6eba341fa0ac49d583d7 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "architecture.h"
+#include "crypto-util.h"
 #include "hexdecoct.h"
 #include "tests.h"
 #include "tpm2-util.h"
@@ -782,25 +783,25 @@ TEST(tpm2b_public_to_openssl_pkey) {
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey_rsa = NULL;
         assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_rsa) >= 0);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_rsa = EVP_PKEY_CTX_new(pkey_rsa, NULL);
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_rsa = sym_EVP_PKEY_CTX_new(pkey_rsa, NULL);
         assert_se(ctx_rsa);
-        assert_se(EVP_PKEY_verify_init(ctx_rsa) == 1);
-        assert_se(EVP_PKEY_CTX_set_signature_md(ctx_rsa, EVP_sha256()) > 0);
+        assert_se(sym_EVP_PKEY_verify_init(ctx_rsa) == 1);
+        assert_se(sym_EVP_PKEY_CTX_set_signature_md(ctx_rsa, sym_EVP_sha256()) > 0);
 
         DEFINE_HEX_PTR(sig_rsa, "9f70a9e68911be3ec464cae91126328307bf355872127e042d6c61e0a80982872c151033bcf727abfae5fc9500c923120011e7ef4aa5fc690a59a034697b6022c141b4b209e2df6f4b282288cd9181073fbe7158ce113c79d87623423c1f3996ff931e59cc91db74f8e8656215b1436fc93ddec0f1f8fa8510826e674b250f047e6cba94c95ff98072a286baca94646b577974a1e00d56c21944e38960d8ee90511a2f938e5cf1ac7b7cc7ff8e3ac001d321254d3e4f988b90e9f6f873c26ecd0a12a626b3474833cdbb9e9f793238f6c97ee5b75a1a89bb7a7858d34ecfa6d34ac58d95085e6c4fbbebd47a4364be2725c2c6b3fa15d916f3c0b62a66fe76ae");
-        assert_se(EVP_PKEY_verify(ctx_rsa, sig_rsa, sig_rsa_len, (unsigned char*) msg, msg_len) == 1);
+        assert_se(sym_EVP_PKEY_verify(ctx_rsa, sig_rsa, sig_rsa_len, (unsigned char*) msg, msg_len) == 1);
 
         /* ECC */
         tpm2b_public_ecc_init(&public, TPM2_ECC_NIST_P256, "6fc0ecf3645c673ab7e86d1ec5b315afb950257c5f68ab23296160006711fac2", "8dd2ef7a2c9ecede91493ba98c8fb3f893aff325c6a1e0f752c657b2d6ca1413");
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey_ecc = NULL;
         assert_se(tpm2_tpm2b_public_to_openssl_pkey(&public, &pkey_ecc) >= 0);
 
-        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_ecc = EVP_PKEY_CTX_new(pkey_ecc, NULL);
+        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx_ecc = sym_EVP_PKEY_CTX_new(pkey_ecc, NULL);
         assert_se(ctx_ecc);
-        assert_se(EVP_PKEY_verify_init(ctx_ecc) == 1);
+        assert_se(sym_EVP_PKEY_verify_init(ctx_ecc) == 1);
 
         DEFINE_HEX_PTR(sig_ecc, "304602210092447ac0b5b32e90923f79bb4aba864b9c546a9900cf193a83243d35d189a2110221009a8b4df1dfa85e225eff9c606694d4d205a7a3968c9552f50bc2790209a90001");
-        assert_se(EVP_PKEY_verify(ctx_ecc, sig_ecc, sig_ecc_len, (unsigned char*) msg, msg_len) == 1);
+        assert_se(sym_EVP_PKEY_verify(ctx_ecc, sig_ecc, sig_ecc_len, (unsigned char*) msg, msg_len) == 1);
 }
 
 static void get_tpm2b_public_from_pem(const void *pem, size_t pem_size, TPM2B_PUBLIC *ret) {
index bac29cbbdcabe20eb3199edd96665ab27e4c608d..e87a13d8e66c9316de525b277cba933c6bc536cc 100644 (file)
@@ -10,7 +10,7 @@ executables += [
                         'HAVE_TPM2',
                 ],
                 'dependencies' : [
-                        libopenssl,
+                        libopenssl_cflags,
                 ],
         },
         libexec_template + {
index 74e13219f7a27ffa372075d0076b1fd774dae67a..b779650b73384fba7bbc8fcfae10c74b8acf6d66 100644 (file)
@@ -9,6 +9,7 @@
 #include "build.h"
 #include "conf-files.h"
 #include "constants.h"
+#include "crypto-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
 #include "fileio.h"
@@ -127,7 +128,7 @@ static void public_key_data_done(struct public_key_data *d) {
         assert(d);
 
         if (d->pkey) {
-                EVP_PKEY_free(d->pkey);
+                sym_EVP_PKEY_free(d->pkey);
                 d->pkey = NULL;
         }
         if (d->public) {
@@ -148,7 +149,7 @@ static int public_key_make_fingerprint(struct public_key_data *d) {
         assert(!d->fingerprint);
         assert(!d->fingerprint_hex);
 
-        r = pubkey_fingerprint(d->pkey, EVP_sha256(), &d->fingerprint, &d->fingerprint_size);
+        r = pubkey_fingerprint(d->pkey, sym_EVP_sha256(), &d->fingerprint, &d->fingerprint_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to calculate fingerprint of public key: %m");
 
@@ -320,7 +321,7 @@ static int setup_srk(void) {
         if (r < 0)
                 return log_error_errno(r, "Failed to open SRK public key file '%s' for writing: %m", pem_path);
 
-        if (PEM_write_PUBKEY(f, tpm2_key.pkey) <= 0)
+        if (sym_PEM_write_PUBKEY(f, tpm2_key.pkey) <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write SRK public key file '%s'.", pem_path);
 
         if (fchmod(fileno(f), 0444) < 0)
@@ -504,6 +505,10 @@ static int run(int argc, char *argv[]) {
                 return EXIT_SUCCESS;
         }
 
+        r = dlopen_libcrypto(LOG_ERR);
+        if (r < 0)
+                return r;
+
         umask(0022);
 
         /* Execute both jobs, and then return unlisted errors preferably, and listed errors