]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptenroll: iovec'ify a few more things
authorLennart Poettering <lennart@poettering.net>
Tue, 27 Aug 2024 14:31:39 +0000 (16:31 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 30 Aug 2024 12:15:33 +0000 (14:15 +0200)
src/cryptenroll/cryptenroll-fido2.c
src/cryptenroll/cryptenroll-fido2.h
src/cryptenroll/cryptenroll-password.c
src/cryptenroll/cryptenroll-password.h
src/cryptenroll/cryptenroll-pkcs11.c
src/cryptenroll/cryptenroll-pkcs11.h
src/cryptenroll/cryptenroll-recovery.c
src/cryptenroll/cryptenroll-recovery.h
src/cryptenroll/cryptenroll-tpm2.c
src/cryptenroll/cryptenroll-tpm2.h
src/cryptenroll/cryptenroll.c

index 8e53b9bb47b448804b152882a590a7747f17ac06..cc1cb8eb74773329aaf8285d3dd88d51e2adf305 100644 (file)
@@ -67,8 +67,7 @@ int load_volume_key_fido2(
 
 int enroll_fido2(
                 struct crypt_device *cd,
-                const void *volume_key,
-                size_t volume_key_size,
+                const struct iovec *volume_key,
                 const char *device,
                 Fido2EnrollFlags lock_with,
                 int cred_alg,
@@ -87,8 +86,7 @@ int enroll_fido2(
         int r, keyslot;
 
         assert_se(cd);
-        assert_se(volume_key);
-        assert_se(volume_key_size > 0);
+        assert_se(iovec_is_set(volume_key));
         assert_se(device);
 
         assert_se(node = crypt_get_device_name(cd));
@@ -139,8 +137,8 @@ int enroll_fido2(
         keyslot = crypt_keyslot_add_by_volume_key(
                         cd,
                         CRYPT_ANY_SLOT,
-                        volume_key,
-                        volume_key_size,
+                        volume_key->iov_base,
+                        volume_key->iov_len,
                         base64_encoded,
                         base64_encoded_size);
         if (keyslot < 0)
index 5cb3bf6bfaf031676bf457c7b2b71ef5e893f158..0eb2a95e737082daa3d3417cb665495a6bfddc09 100644 (file)
@@ -9,7 +9,7 @@
 
 #if HAVE_LIBFIDO2
 int load_volume_key_fido2(struct crypt_device *cd, const char *cd_node, const char *device, void *ret_vk, size_t *ret_vks);
-int enroll_fido2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, Fido2EnrollFlags lock_with, int cred_alg, const char *salt_file, bool parameters_in_header);
+int enroll_fido2(struct crypt_device *cd, const struct iovec *volume_key, const char *device, Fido2EnrollFlags lock_with, int cred_alg, const char *salt_file, bool parameters_in_header);
 
 #else
 static inline int load_volume_key_fido2(struct crypt_device *cd, const char *cd_node, const char *device, void *ret_vk, size_t *ret_vks) {
@@ -17,7 +17,7 @@ static inline int load_volume_key_fido2(struct crypt_device *cd, const char *cd_
                                "FIDO2 unlocking not supported.");
 }
 
-static inline int enroll_fido2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, Fido2EnrollFlags lock_with, int cred_alg, const char *salt_file, bool parameters_in_header) {
+static inline int enroll_fido2(struct crypt_device *cd, const struct iovec *volume_key, const char *device, Fido2EnrollFlags lock_with, int cred_alg, const char *salt_file, bool parameters_in_header) {
         return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                "FIDO2 key enrollment not supported.");
 }
index a9bd8a1dd013c842909e7fc02602b3be9aa96b2f..f6b53d4a76b3b792a75e0cc07c924a086a50d3fc 100644 (file)
@@ -5,6 +5,7 @@
 #include "env-util.h"
 #include "errno-util.h"
 #include "escape.h"
+#include "iovec-util.h"
 #include "memory-util.h"
 #include "password-quality-util.h"
 #include "strv.h"
@@ -97,14 +98,16 @@ int load_volume_key_password(
 
 int enroll_password(
                 struct crypt_device *cd,
-                const void *volume_key,
-                size_t volume_key_size) {
+                const struct iovec *volume_key) {
 
         _cleanup_(erase_and_freep) char *new_password = NULL;
         _cleanup_free_ char *error = NULL;
         const char *node;
         int r, keyslot;
 
+        assert(cd);
+        assert(iovec_is_set(volume_key));
+
         assert_se(node = crypt_get_device_name(cd));
 
         r = getenv_steal_erase("NEWPASSWORD", &new_password);
@@ -187,8 +190,8 @@ int enroll_password(
         keyslot = crypt_keyslot_add_by_volume_key(
                         cd,
                         CRYPT_ANY_SLOT,
-                        volume_key,
-                        volume_key_size,
+                        volume_key->iov_base,
+                        volume_key->iov_len,
                         new_password,
                         strlen(new_password));
         if (keyslot < 0)
index aa07a6f97b8b709d677224d9e021ee171b5d5873..4eaf48acba7b96abc6ce19508053ccbf0c3b1e5a 100644 (file)
@@ -6,4 +6,4 @@
 #include "cryptsetup-util.h"
 
 int load_volume_key_password(struct crypt_device *cd, const char* cd_node, void *ret_vk, size_t *ret_vks);
-int enroll_password(struct crypt_device *cd, const void *volume_key, size_t volume_key_size);
+int enroll_password(struct crypt_device *cd, const struct iovec *volume_key);
index 7c9dfb99c86b3a8c72a495914d2c821eedc2894a..f59a48984841b6cb0a899f7f5f0bf397959d0052 100644 (file)
@@ -33,8 +33,7 @@ static int uri_set_private_class(const char *uri, char **ret_uri) {
 
 int enroll_pkcs11(
                 struct crypt_device *cd,
-                const void *volume_key,
-                size_t volume_key_size,
+                const struct iovec *volume_key,
                 const char *uri) {
 
         _cleanup_(erase_and_freep) void *decrypted_key = NULL;
@@ -49,8 +48,7 @@ int enroll_pkcs11(
         int r;
 
         assert_se(cd);
-        assert_se(volume_key);
-        assert_se(volume_key_size > 0);
+        assert_se(iovec_is_set(volume_key));
         assert_se(uri);
 
         assert_se(node = crypt_get_device_name(cd));
@@ -83,8 +81,8 @@ int enroll_pkcs11(
         int keyslot = crypt_keyslot_add_by_volume_key(
                         cd,
                         CRYPT_ANY_SLOT,
-                        volume_key,
-                        volume_key_size,
+                        volume_key->iov_base,
+                        volume_key->iov_len,
                         base64_encoded,
                         base64_encoded_size);
         if (keyslot < 0)
index b6d28bd92c5e53e46b5aded059f45f73f8552c2e..64b7361c55e0846ae6f333fc126daf61781cbb7c 100644 (file)
@@ -7,9 +7,9 @@
 #include "log.h"
 
 #if HAVE_P11KIT && HAVE_OPENSSL
-int enroll_pkcs11(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *uri);
+int enroll_pkcs11(struct crypt_device *cd, const struct iovec *volume_key, const char *uri);
 #else
-static inline int enroll_pkcs11(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *uri) {
+static inline int enroll_pkcs11(struct crypt_device *cd, const struct iovec *volume_key, const char *uri) {
         return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                "PKCS#11 key enrollment not supported.");
 }
index 0b1e380e0654dadf8835b1ea670a5d036f2ef867..0a5e9cdcbea942179a7b096a3bae5187935479df 100644 (file)
@@ -3,6 +3,7 @@
 #include "ansi-color.h"
 #include "cryptenroll-recovery.h"
 #include "glyph-util.h"
+#include "iovec-util.h"
 #include "json-util.h"
 #include "memory-util.h"
 #include "qrcode-util.h"
@@ -11,8 +12,7 @@
 
 int enroll_recovery(
                 struct crypt_device *cd,
-                const void *volume_key,
-                size_t volume_key_size) {
+                const struct iovec *volume_key) {
 
         _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
         _cleanup_(erase_and_freep) char *password = NULL;
@@ -21,8 +21,7 @@ int enroll_recovery(
         const char *node;
 
         assert_se(cd);
-        assert_se(volume_key);
-        assert_se(volume_key_size > 0);
+        assert_se(iovec_is_set(volume_key));
 
         assert_se(node = crypt_get_device_name(cd));
 
@@ -37,8 +36,8 @@ int enroll_recovery(
         keyslot = crypt_keyslot_add_by_volume_key(
                         cd,
                         CRYPT_ANY_SLOT,
-                        volume_key,
-                        volume_key_size,
+                        volume_key->iov_base,
+                        volume_key->iov_len,
                         password,
                         strlen(password));
         if (keyslot < 0)
index 9bf4f2e489ab0dbe4a64db89c47743f8854e123f..3134d3d1485b357d2296e5973f13b7b5811b686f 100644 (file)
@@ -5,4 +5,4 @@
 
 #include "cryptsetup-util.h"
 
-int enroll_recovery(struct crypt_device *cd, const void *volume_key, size_t volume_key_size);
+int enroll_recovery(struct crypt_device *cd, const struct iovec *volume_key);
index 152549a155ef6e21ef830901a9d5915aa03993fc..583259d853e50c11a3c1f7f62d3d4c4a6fad62a0 100644 (file)
 
 static int search_policy_hash(
                 struct crypt_device *cd,
-                const void *hash,
-                size_t hash_size) {
+                const struct iovec *hash) {
 
         int r;
 
         assert(cd);
-        assert(hash || hash_size == 0);
+        assert(iovec_is_valid(hash));
 
-        if (hash_size == 0)
+        if (!iovec_is_set(hash))
                 return 0;
 
         for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
@@ -59,7 +58,7 @@ static int search_policy_hash(
                 if (r < 0)
                         return log_error_errno(r, "Invalid base64 data in 'tpm2-policy-hash' field: %m");
 
-                if (memcmp_nn(hash, hash_size, thash, thash_size) == 0)
+                if (memcmp_nn(hash->iov_base, hash->iov_len, thash, thash_size) == 0)
                         return keyslot; /* Found entry with same hash. */
         }
 
@@ -242,8 +241,7 @@ int load_volume_key_tpm2(
 }
 
 int enroll_tpm2(struct crypt_device *cd,
-                const void *volume_key,
-                size_t volume_key_size,
+                const struct iovec *volume_key,
                 const char *device,
                 uint32_t seal_key_handle,
                 const char *device_key,
@@ -276,8 +274,7 @@ int enroll_tpm2(struct crypt_device *cd,
         CLEANUP_ERASE(binary_salt);
 
         assert(cd);
-        assert(volume_key);
-        assert(volume_key_size > 0);
+        assert(iovec_is_set(volume_key));
         assert(tpm2_pcr_values_valid(hash_pcr_values, n_hash_pcr_values));
         assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
         assert(ret_slot_to_wipe);
@@ -436,7 +433,7 @@ int enroll_tpm2(struct crypt_device *cd,
                 return log_error_errno(r, "Failed to seal to TPM2: %m");
 
         /* Let's see if we already have this specific PCR policy hash enrolled, if so, exit early. */
-        r = search_policy_hash(cd, policy.buffer, policy.size);
+        r = search_policy_hash(cd, &IOVEC_MAKE(policy.buffer, policy.size));
         if (r == -ENOENT)
                 log_debug_errno(r, "PCR policy hash not yet enrolled, enrolling now.");
         else if (r < 0)
@@ -487,8 +484,8 @@ int enroll_tpm2(struct crypt_device *cd,
         keyslot = crypt_keyslot_add_by_volume_key(
                         cd,
                         CRYPT_ANY_SLOT,
-                        volume_key,
-                        volume_key_size,
+                        volume_key->iov_base,
+                        volume_key->iov_len,
                         base64_encoded,
                         base64_encoded_size);
         if (keyslot < 0)
index d722ed66a0f6b39e87fea9494727a2066edb0732..efc93f1770e4833e151085e6b23cf9e64ea1908e 100644 (file)
@@ -9,14 +9,14 @@
 
 #if HAVE_TPM2
 int load_volume_key_tpm2(struct crypt_device *cd, const char *cd_node, const char *device, void *ret_vk, size_t *ret_vks);
-int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t seal_key_handle, const char *device_key, Tpm2PCRValue *hash_pcr_values, size_t n_hash_pcr_values, const char *pubkey_path, bool load_pcr_pubkey, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path, int *ret_slot_to_wipe);
+int enroll_tpm2(struct crypt_device *cd, const struct iovec *volume_key, const char *device, uint32_t seal_key_handle, const char *device_key, Tpm2PCRValue *hash_pcr_values, size_t n_hash_pcr_values, const char *pubkey_path, bool load_pcr_pubkey, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path, int *ret_slot_to_wipe);
 #else
 static inline int load_volume_key_tpm2(struct crypt_device *cd, const char *cd_node, const char *device, void *ret_vk, size_t *ret_vks) {
         return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                "TPM2 unlocking not supported.");
 }
 
-static inline int enroll_tpm2(struct crypt_device *cd, const void *volume_key, size_t volume_key_size, const char *device, uint32_t seal_key_handle, const char *device_key, Tpm2PCRValue *hash_pcr_values, size_t n_hash_pcr_values, const char *pubkey_path, bool load_pcr_pubkey, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path, int *ret_slot_to_wipe) {
+static inline int enroll_tpm2(struct crypt_device *cd, const struct iovec *volume_key, const char *device, uint32_t seal_key_handle, const char *device_key, Tpm2PCRValue *hash_pcr_values, size_t n_hash_pcr_values, const char *pubkey_path, bool load_pcr_pubkey, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path, int *ret_slot_to_wipe) {
         return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                "TPM2 key enrollment not supported.");
 }
index 035310bc33e73e966c7ad9a241983de90b3c3875..df67a5636c54e82e7b9d9a459de3e915f2a33cef 100644 (file)
@@ -771,16 +771,12 @@ static int load_volume_key_keyfile(
 
 static int prepare_luks(
                 struct crypt_device **ret_cd,
-                void **ret_volume_key,
-                size_t *ret_volume_key_size) {
+                struct iovec *ret_volume_key) {
 
         _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
-        _cleanup_(erase_and_freep) void *vk = NULL;
-        size_t vks;
         int r;
 
         assert(ret_cd);
-        assert(!ret_volume_key == !ret_volume_key_size);
 
         r = crypt_init(&cd, arg_node);
         if (r < 0)
@@ -804,28 +800,31 @@ static int prepare_luks(
         r = crypt_get_volume_key_size(cd);
         if (r <= 0)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
-        vks = (size_t) r;
 
-        vk = malloc(vks);
-        if (!vk)
+        _cleanup_(iovec_done_erase) struct iovec vk = {};
+
+        vk.iov_base = malloc(r);
+        if (!vk.iov_base)
                 return log_oom();
 
+        vk.iov_len = (size_t) r;
+
         switch (arg_unlock_type) {
 
         case UNLOCK_PASSWORD:
-                r = load_volume_key_password(cd, arg_node, vk, &vks);
+                r = load_volume_key_password(cd, arg_node, vk.iov_base, &vk.iov_len);
                 break;
 
         case UNLOCK_KEYFILE:
-                r = load_volume_key_keyfile(cd, vk, &vks);
+                r = load_volume_key_keyfile(cd, vk.iov_base, &vk.iov_len);
                 break;
 
         case UNLOCK_FIDO2:
-                r = load_volume_key_fido2(cd, arg_node, arg_unlock_fido2_device, vk, &vks);
+                r = load_volume_key_fido2(cd, arg_node, arg_unlock_fido2_device, vk.iov_base, &vk.iov_len);
                 break;
 
         case UNLOCK_TPM2:
-                r = load_volume_key_tpm2(cd, arg_node, arg_unlock_tpm2_device, vk, &vks);
+                r = load_volume_key_tpm2(cd, arg_node, arg_unlock_tpm2_device, vk.iov_base, &vk.iov_len);
                 break;
 
         default:
@@ -836,16 +835,14 @@ static int prepare_luks(
                 return r;
 
         *ret_cd = TAKE_PTR(cd);
-        *ret_volume_key = TAKE_PTR(vk);
-        *ret_volume_key_size = vks;
+        *ret_volume_key = TAKE_STRUCT(vk);
 
         return 0;
 }
 
 static int run(int argc, char *argv[]) {
         _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
-        _cleanup_(erase_and_freep) void *vk = NULL;
-        size_t vks;
+        _cleanup_(iovec_done_erase) struct iovec vk = {};
         int slot, slot_to_wipe, r;
 
         log_setup();
@@ -860,32 +857,32 @@ static int run(int argc, char *argv[]) {
         cryptsetup_enable_logging(NULL);
 
         if (arg_enroll_type < 0)
-                r = prepare_luks(&cd, NULL, NULL); /* No need to unlock device if we don't need the volume key because we don't need to enroll anything */
+                r = prepare_luks(&cd, /* ret_volume_key= */ NULL); /* No need to unlock device if we don't need the volume key because we don't need to enroll anything */
         else
-                r = prepare_luks(&cd, &vk, &vks);
+                r = prepare_luks(&cd, &vk);
         if (r < 0)
                 return r;
 
         switch (arg_enroll_type) {
 
         case ENROLL_PASSWORD:
-                slot = enroll_password(cd, vk, vks);
+                slot = enroll_password(cd, &vk);
                 break;
 
         case ENROLL_RECOVERY:
-                slot = enroll_recovery(cd, vk, vks);
+                slot = enroll_recovery(cd, &vk);
                 break;
 
         case ENROLL_PKCS11:
-                slot = enroll_pkcs11(cd, vk, vks, arg_pkcs11_token_uri);
+                slot = enroll_pkcs11(cd, &vk, arg_pkcs11_token_uri);
                 break;
 
         case ENROLL_FIDO2:
-                slot = enroll_fido2(cd, vk, vks, arg_fido2_device, arg_fido2_lock_with, arg_fido2_cred_alg, arg_fido2_salt_file, arg_fido2_parameters_in_header);
+                slot = enroll_fido2(cd, &vk, arg_fido2_device, arg_fido2_lock_with, arg_fido2_cred_alg, arg_fido2_salt_file, arg_fido2_parameters_in_header);
                 break;
 
         case ENROLL_TPM2:
-                slot = enroll_tpm2(cd, vk, vks, arg_tpm2_device, arg_tpm2_seal_key_handle, arg_tpm2_device_key, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values, arg_tpm2_public_key, arg_tpm2_load_public_key, arg_tpm2_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin, arg_tpm2_pcrlock, &slot_to_wipe);
+                slot = enroll_tpm2(cd, &vk, arg_tpm2_device, arg_tpm2_seal_key_handle, arg_tpm2_device_key, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values, arg_tpm2_public_key, arg_tpm2_load_public_key, arg_tpm2_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin, arg_tpm2_pcrlock, &slot_to_wipe);
 
                 if (slot >= 0 && slot_to_wipe >= 0) {
                         /* Updating PIN on an existing enrollment */