Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cryptenroll: disable loading public key if --tpm2-public-key= is empty #32500

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 20 additions & 17 deletions src/cryptenroll/cryptenroll-tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ int enroll_tpm2(struct crypt_device *cd,
Tpm2PCRValue *hash_pcr_values,
size_t n_hash_pcr_values,
const char *pubkey_path,
bool load_pubkey,
uint32_t pubkey_pcr_mask,
const char *signature_path,
bool use_pin,
Expand Down Expand Up @@ -306,25 +307,27 @@ int enroll_tpm2(struct crypt_device *cd,
}

TPM2B_PUBLIC public = {};
r = tpm2_load_pcr_public_key(pubkey_path, &pubkey.iov_base, &pubkey.iov_len);
if (r < 0) {
if (pubkey_path || signature_path || r != -ENOENT)
return log_error_errno(r, "Failed to read TPM PCR public key: %m");

log_debug_errno(r, "Failed to read TPM2 PCR public key, proceeding without: %m");
pubkey_pcr_mask = 0;
} else {
r = tpm2_tpm2b_public_from_pem(pubkey.iov_base, pubkey.iov_len, &public);
if (r < 0)
return log_error_errno(r, "Could not convert public key to TPM2B_PUBLIC: %m");
if (load_pubkey) {
r = tpm2_load_pcr_public_key(pubkey_path, &pubkey.iov_base, &pubkey.iov_len);
if (r < 0) {
if (pubkey_path || signature_path || r != -ENOENT)
return log_error_errno(r, "Failed to read TPM PCR public key: %m");

log_debug_errno(r, "Failed to read TPM2 PCR public key, proceeding without: %m");
pubkey_pcr_mask = 0;
} else {
r = tpm2_tpm2b_public_from_pem(pubkey.iov_base, pubkey.iov_len, &public);
if (r < 0)
return log_error_errno(r, "Could not convert public key to TPM2B_PUBLIC: %m");

if (signature_path) {
/* Also try to load the signature JSON object, to verify that our enrollment will work.
* This is optional however, skip it if it's not explicitly provided. */
if (signature_path) {
/* Also try to load the signature JSON object, to verify that our enrollment will work.
* This is optional however, skip it if it's not explicitly provided. */

r = tpm2_load_pcr_signature(signature_path, &signature_json);
if (r < 0)
return log_debug_errno(r, "Failed to read TPM PCR signature: %m");
r = tpm2_load_pcr_signature(signature_path, &signature_json);
if (r < 0)
return log_debug_errno(r, "Failed to read TPM PCR signature: %m");
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/cryptenroll/cryptenroll-tpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_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);
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 disable_loading_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_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 *slot_to_wipe) {
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 disable_loading_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.");
}
Expand Down
11 changes: 10 additions & 1 deletion src/cryptenroll/cryptenroll.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static Tpm2PCRValue *arg_tpm2_hash_pcr_values = NULL;
static size_t arg_tpm2_n_hash_pcr_values = 0;
static bool arg_tpm2_pin = false;
static char *arg_tpm2_public_key = NULL;
static bool arg_tpm2_load_public_key = true;
static uint32_t arg_tpm2_public_key_pcr_mask = 0;
static char *arg_tpm2_signature = NULL;
static char *arg_tpm2_pcrlock = NULL;
Expand Down Expand Up @@ -498,9 +499,17 @@ static int parse_argv(int argc, char *argv[]) {
break;

case ARG_TPM2_PUBLIC_KEY:
/* an empty argument disables loading a public key */
if (isempty(optarg)) {
arg_tpm2_load_public_key = false;
arg_tpm2_public_key = mfree(arg_tpm2_public_key);
break;
}

r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm2_public_key);
if (r < 0)
return r;
arg_tpm2_load_public_key = true;

break;

Expand Down Expand Up @@ -834,7 +843,7 @@ static int run(int argc, char *argv[]) {
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_public_key_pcr_mask, arg_tpm2_signature, arg_tpm2_pin, arg_tpm2_pcrlock, &slot_to_wipe);
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);

if (slot >= 0 && slot_to_wipe >= 0) {
/* Updating PIN on an existing enrollment */
Expand Down