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,
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));
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)
#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) {
"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.");
}
#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"
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);
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)
#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);
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;
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));
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)
#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.");
}
#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"
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;
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));
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)
#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);
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++) {
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. */
}
}
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,
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);
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)
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)
#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.");
}
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)
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:
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();
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 */