cryptenroll: Support rotating PIN on an existing TPM2 enrollment
This commit is contained in:
@@ -252,7 +252,8 @@ int enroll_tpm2(struct crypt_device *cd,
|
|||||||
uint32_t pubkey_pcr_mask,
|
uint32_t pubkey_pcr_mask,
|
||||||
const char *signature_path,
|
const char *signature_path,
|
||||||
bool use_pin,
|
bool use_pin,
|
||||||
const char *pcrlock_path) {
|
const char *pcrlock_path,
|
||||||
|
int *ret_slot_to_wipe) {
|
||||||
|
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *signature_json = NULL;
|
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *signature_json = NULL;
|
||||||
_cleanup_(erase_and_freep) char *base64_encoded = NULL;
|
_cleanup_(erase_and_freep) char *base64_encoded = NULL;
|
||||||
@@ -261,7 +262,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
|||||||
const char *node;
|
const char *node;
|
||||||
_cleanup_(erase_and_freep) char *pin_str = NULL;
|
_cleanup_(erase_and_freep) char *pin_str = NULL;
|
||||||
ssize_t base64_encoded_size;
|
ssize_t base64_encoded_size;
|
||||||
int r, keyslot;
|
int r, keyslot, slot_to_wipe = -1;
|
||||||
TPM2Flags flags = 0;
|
TPM2Flags flags = 0;
|
||||||
uint8_t binary_salt[SHA256_DIGEST_SIZE] = {};
|
uint8_t binary_salt[SHA256_DIGEST_SIZE] = {};
|
||||||
/*
|
/*
|
||||||
@@ -277,6 +278,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
|||||||
assert(volume_key_size > 0);
|
assert(volume_key_size > 0);
|
||||||
assert(tpm2_pcr_values_valid(hash_pcr_values, n_hash_pcr_values));
|
assert(tpm2_pcr_values_valid(hash_pcr_values, n_hash_pcr_values));
|
||||||
assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
|
assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
|
||||||
|
assert(ret_slot_to_wipe);
|
||||||
|
|
||||||
assert_se(node = crypt_get_device_name(cd));
|
assert_se(node = crypt_get_device_name(cd));
|
||||||
|
|
||||||
@@ -416,8 +418,12 @@ int enroll_tpm2(struct crypt_device *cd,
|
|||||||
log_debug_errno(r, "PCR policy hash not yet enrolled, enrolling now.");
|
log_debug_errno(r, "PCR policy hash not yet enrolled, enrolling now.");
|
||||||
else if (r < 0)
|
else if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
else {
|
else if (use_pin) {
|
||||||
|
log_debug("This PCR set is already enrolled, re-enrolling anyway to update PIN.");
|
||||||
|
slot_to_wipe = r;
|
||||||
|
} else {
|
||||||
log_info("This PCR set is already enrolled, executing no operation.");
|
log_info("This PCR set is already enrolled, executing no operation.");
|
||||||
|
*ret_slot_to_wipe = slot_to_wipe;
|
||||||
return r; /* return existing keyslot, so that wiping won't kill it */
|
return r; /* return existing keyslot, so that wiping won't kill it */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,5 +493,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
|||||||
return log_error_errno(r, "Failed to add TPM2 JSON token to LUKS2 header: %m");
|
return log_error_errno(r, "Failed to add TPM2 JSON token to LUKS2 header: %m");
|
||||||
|
|
||||||
log_info("New TPM2 token enrolled as key slot %i.", keyslot);
|
log_info("New TPM2 token enrolled as key slot %i.", keyslot);
|
||||||
|
|
||||||
|
*ret_slot_to_wipe = slot_to_wipe;
|
||||||
return keyslot;
|
return keyslot;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#if HAVE_TPM2
|
#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 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_pcrs, size_t n_hash_pcrs, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path);
|
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_pcrs, size_t n_hash_pcrs, const char *pubkey_path, uint32_t pubkey_pcr_mask, const char *signature_path, bool use_pin, const char *pcrlock_path, int *ret_slot_to_wipe);
|
||||||
#else
|
#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) {
|
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),
|
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||||
|
|||||||
@@ -727,7 +727,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
||||||
_cleanup_(erase_and_freep) void *vk = NULL;
|
_cleanup_(erase_and_freep) void *vk = NULL;
|
||||||
size_t vks;
|
size_t vks;
|
||||||
int slot, r;
|
int slot, slot_to_wipe, r;
|
||||||
|
|
||||||
log_show_color(true);
|
log_show_color(true);
|
||||||
log_parse_environment();
|
log_parse_environment();
|
||||||
@@ -768,9 +768,21 @@ static int run(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ENROLL_TPM2:
|
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_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin, arg_tpm2_pcrlock);
|
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_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin, arg_tpm2_pcrlock, &slot_to_wipe);
|
||||||
break;
|
|
||||||
|
|
||||||
|
if (slot >= 0 && slot_to_wipe >= 0) {
|
||||||
|
/* Updating PIN on an existing enrollment */
|
||||||
|
r = wipe_slots(
|
||||||
|
cd,
|
||||||
|
&slot_to_wipe,
|
||||||
|
/* n_explicit_slots= */ 1,
|
||||||
|
WIPE_EXPLICIT,
|
||||||
|
/* by_mask= */ 0,
|
||||||
|
/* except_slot= */ -1);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case _ENROLL_TYPE_INVALID:
|
case _ENROLL_TYPE_INVALID:
|
||||||
/* List enrolled slots if we are called without anything to enroll or wipe */
|
/* List enrolled slots if we are called without anything to enroll or wipe */
|
||||||
if (!wipe_requested())
|
if (!wipe_requested())
|
||||||
|
|||||||
@@ -64,6 +64,13 @@ PASSWORD=foo systemd-cryptenroll --tpm2-device=auto "$IMAGE"
|
|||||||
systemd-cryptenroll --unlock-tpm2-device=auto --recovery-key "$IMAGE"
|
systemd-cryptenroll --unlock-tpm2-device=auto --recovery-key "$IMAGE"
|
||||||
systemd-cryptenroll --unlock-tpm2-device=auto --tpm2-device=auto --wipe-slot=tpm2 "$IMAGE"
|
systemd-cryptenroll --unlock-tpm2-device=auto --tpm2-device=auto --wipe-slot=tpm2 "$IMAGE"
|
||||||
|
|
||||||
|
# Add PIN to TPM2 enrollment
|
||||||
|
NEWPIN=1234 systemd-cryptenroll --unlock-tpm2-device=auto --tpm2-device=auto --tpm2-with-pin=yes "$IMAGE"
|
||||||
|
|
||||||
|
# Change PIN on TPM2 enrollment
|
||||||
|
PIN=1234 NEWPIN=4321 systemd-cryptenroll --unlock-tpm2-device=auto --tpm2-device=auto --tpm2-with-pin=yes "$IMAGE"
|
||||||
|
PIN=4321 systemd-cryptenroll --unlock-tpm2-device=auto --recovery-key "$IMAGE"
|
||||||
|
|
||||||
(! systemd-cryptenroll --fido2-with-client-pin=false)
|
(! systemd-cryptenroll --fido2-with-client-pin=false)
|
||||||
(! systemd-cryptenroll --fido2-with-user-presence=f "$IMAGE" /tmp/foo)
|
(! systemd-cryptenroll --fido2-with-user-presence=f "$IMAGE" /tmp/foo)
|
||||||
(! systemd-cryptenroll --fido2-with-client-pin=1234 "$IMAGE")
|
(! systemd-cryptenroll --fido2-with-client-pin=1234 "$IMAGE")
|
||||||
|
|||||||
Reference in New Issue
Block a user