From 549c1a99d469d9d1ec42ddfccba26724dea0d28a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 27 Aug 2024 16:31:39 +0200 Subject: [PATCH] cryptenroll: iovec'ify a few more things --- src/cryptenroll/cryptenroll-fido2.c | 10 +++--- src/cryptenroll/cryptenroll-fido2.h | 4 +-- src/cryptenroll/cryptenroll-password.c | 11 ++++--- src/cryptenroll/cryptenroll-password.h | 2 +- src/cryptenroll/cryptenroll-pkcs11.c | 10 +++--- src/cryptenroll/cryptenroll-pkcs11.h | 4 +-- src/cryptenroll/cryptenroll-recovery.c | 11 +++---- src/cryptenroll/cryptenroll-recovery.h | 2 +- src/cryptenroll/cryptenroll-tpm2.c | 21 ++++++------- src/cryptenroll/cryptenroll-tpm2.h | 4 +-- src/cryptenroll/cryptenroll.c | 43 ++++++++++++-------------- 11 files changed, 57 insertions(+), 65 deletions(-) diff --git a/src/cryptenroll/cryptenroll-fido2.c b/src/cryptenroll/cryptenroll-fido2.c index 8e53b9bb47b..cc1cb8eb747 100644 --- a/src/cryptenroll/cryptenroll-fido2.c +++ b/src/cryptenroll/cryptenroll-fido2.c @@ -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) diff --git a/src/cryptenroll/cryptenroll-fido2.h b/src/cryptenroll/cryptenroll-fido2.h index 5cb3bf6bfaf..0eb2a95e737 100644 --- a/src/cryptenroll/cryptenroll-fido2.h +++ b/src/cryptenroll/cryptenroll-fido2.h @@ -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."); } diff --git a/src/cryptenroll/cryptenroll-password.c b/src/cryptenroll/cryptenroll-password.c index a9bd8a1dd01..f6b53d4a76b 100644 --- a/src/cryptenroll/cryptenroll-password.c +++ b/src/cryptenroll/cryptenroll-password.c @@ -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) diff --git a/src/cryptenroll/cryptenroll-password.h b/src/cryptenroll/cryptenroll-password.h index aa07a6f97b8..4eaf48acba7 100644 --- a/src/cryptenroll/cryptenroll-password.h +++ b/src/cryptenroll/cryptenroll-password.h @@ -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); diff --git a/src/cryptenroll/cryptenroll-pkcs11.c b/src/cryptenroll/cryptenroll-pkcs11.c index 7c9dfb99c86..f59a4898484 100644 --- a/src/cryptenroll/cryptenroll-pkcs11.c +++ b/src/cryptenroll/cryptenroll-pkcs11.c @@ -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) diff --git a/src/cryptenroll/cryptenroll-pkcs11.h b/src/cryptenroll/cryptenroll-pkcs11.h index b6d28bd92c5..64b7361c55e 100644 --- a/src/cryptenroll/cryptenroll-pkcs11.h +++ b/src/cryptenroll/cryptenroll-pkcs11.h @@ -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."); } diff --git a/src/cryptenroll/cryptenroll-recovery.c b/src/cryptenroll/cryptenroll-recovery.c index 0b1e380e065..0a5e9cdcbea 100644 --- a/src/cryptenroll/cryptenroll-recovery.c +++ b/src/cryptenroll/cryptenroll-recovery.c @@ -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) diff --git a/src/cryptenroll/cryptenroll-recovery.h b/src/cryptenroll/cryptenroll-recovery.h index 9bf4f2e489a..3134d3d1485 100644 --- a/src/cryptenroll/cryptenroll-recovery.h +++ b/src/cryptenroll/cryptenroll-recovery.h @@ -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); diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 152549a155e..583259d853e 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -18,15 +18,14 @@ 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) diff --git a/src/cryptenroll/cryptenroll-tpm2.h b/src/cryptenroll/cryptenroll-tpm2.h index d722ed66a0f..efc93f1770e 100644 --- a/src/cryptenroll/cryptenroll-tpm2.h +++ b/src/cryptenroll/cryptenroll-tpm2.h @@ -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."); } diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index 035310bc33e..df67a5636c5 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -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 */ -- 2.47.3