]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptenroll: disable loading public key if --tpm2-public-key= is empty
authorSam Leonard <sam.leonard@codethink.co.uk>
Fri, 26 Apr 2024 12:35:05 +0000 (13:35 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 2 May 2024 14:34:09 +0000 (16:34 +0200)
src/cryptenroll/cryptenroll-tpm2.c
src/cryptenroll/cryptenroll-tpm2.h
src/cryptenroll/cryptenroll.c

index 83a2f4420f5380edbcc472013ca6b001c8daa5aa..1656dc1e83453df53d8f7eb924c66d4a79b154e6 100644 (file)
@@ -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,
@@ -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");
+                        }
                 }
         }
 
index 634d7637b9087d7ce229b863f4a580bc7fd6b6f9..4522b0b5950f2b963514b4f815e841237d2c773f 100644 (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_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.");
 }
index 9c618ad28a55842c3b37c99e299bd295134ac084..6e700d30143871a7dd1cf1ff557b38cc77e55df3 100644 (file)
@@ -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;
@@ -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;
 
@@ -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 */