1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-14 04:58:28 +03:00

cryptenroll: iovec'ify a few more things

This commit is contained in:
Lennart Poettering 2024-08-27 16:31:39 +02:00
parent c08ffe5b12
commit 549c1a99d4
11 changed files with 57 additions and 65 deletions

View 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)

View 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.");
}

View 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)

View 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);

View 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)

View 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.");
}

View 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)

View 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);

View File

@ -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)

View 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.");
}

View 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 */