From 7911b6ca12a046e7c1f89c1cbbe6a387a1b4daf0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Nov 2023 20:57:29 +0100 Subject: [PATCH 1/6] repart,cryptenroll: bring tpm2 switches/--help/handling in a single, canonical order Let's define the same switches and their backing variables in the same order, and let's make sure the enums and switches are named the same. No actual code changes. --- src/cryptenroll/cryptenroll.c | 38 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index d2915ad7ee..5a7f7c3bff 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -137,10 +137,10 @@ static int help(void) { "\n%3$sTPM2 Enrollment:%4$s\n" " --tpm2-device=PATH\n" " Enroll a TPM2 device\n" - " --tpm2-seal-key-handle=HANDLE\n" - " Specify handle of key to use for sealing\n" " --tpm2-device-key=PATH\n" " Enroll a TPM2 device using its public key\n" + " --tpm2-seal-key-handle=HANDLE\n" + " Specify handle of key to use for sealing\n" " --tpm2-pcrs=PCR1+PCR2+PCR3+…\n" " Specify TPM2 PCRs to seal against\n" " --tpm2-public-key=PATH\n" @@ -175,14 +175,14 @@ static int parse_argv(int argc, char *argv[]) { ARG_PKCS11_TOKEN_URI, ARG_FIDO2_DEVICE, ARG_TPM2_DEVICE, - ARG_TPM2_SEAL_KEY_HANDLE, ARG_TPM2_DEVICE_KEY, + ARG_TPM2_SEAL_KEY_HANDLE, ARG_TPM2_PCRS, ARG_TPM2_PUBLIC_KEY, ARG_TPM2_PUBLIC_KEY_PCRS, ARG_TPM2_SIGNATURE, - ARG_TPM2_PIN, ARG_TPM2_PCRLOCK, + ARG_TPM2_WITH_PIN, ARG_WIPE_SLOT, ARG_FIDO2_WITH_PIN, ARG_FIDO2_WITH_UP, @@ -204,14 +204,14 @@ static int parse_argv(int argc, char *argv[]) { { "fido2-with-user-presence", required_argument, NULL, ARG_FIDO2_WITH_UP }, { "fido2-with-user-verification", required_argument, NULL, ARG_FIDO2_WITH_UV }, { "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE }, - { "tpm2-seal-key-handle", required_argument, NULL, ARG_TPM2_SEAL_KEY_HANDLE }, { "tpm2-device-key", required_argument, NULL, ARG_TPM2_DEVICE_KEY }, + { "tpm2-seal-key-handle", required_argument, NULL, ARG_TPM2_SEAL_KEY_HANDLE }, { "tpm2-pcrs", required_argument, NULL, ARG_TPM2_PCRS }, { "tpm2-public-key", required_argument, NULL, ARG_TPM2_PUBLIC_KEY }, { "tpm2-public-key-pcrs", required_argument, NULL, ARG_TPM2_PUBLIC_KEY_PCRS }, { "tpm2-signature", required_argument, NULL, ARG_TPM2_SIGNATURE }, - { "tpm2-with-pin", required_argument, NULL, ARG_TPM2_PIN }, { "tpm2-pcrlock", required_argument, NULL, ARG_TPM2_PCRLOCK }, + { "tpm2-with-pin", required_argument, NULL, ARG_TPM2_WITH_PIN }, { "wipe-slot", required_argument, NULL, ARG_WIPE_SLOT }, {} }; @@ -380,13 +380,6 @@ static int parse_argv(int argc, char *argv[]) { break; } - case ARG_TPM2_SEAL_KEY_HANDLE: - r = safe_atou32_full(optarg, 16, &arg_tpm2_seal_key_handle); - if (r < 0) - return log_error_errno(r, "Could not parse TPM2 seal key handle index '%s': %m", optarg); - - break; - case ARG_TPM2_DEVICE_KEY: if (arg_enroll_type >= 0 || arg_tpm2_device_key) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -400,16 +393,16 @@ static int parse_argv(int argc, char *argv[]) { arg_enroll_type = ENROLL_TPM2; break; - case ARG_TPM2_PCRS: - auto_hash_pcr_values = false; - r = tpm2_parse_pcr_argument_append(optarg, &arg_tpm2_hash_pcr_values, &arg_tpm2_n_hash_pcr_values); + case ARG_TPM2_SEAL_KEY_HANDLE: + r = safe_atou32_full(optarg, 16, &arg_tpm2_seal_key_handle); if (r < 0) - return r; + return log_error_errno(r, "Could not parse TPM2 seal key handle index '%s': %m", optarg); break; - case ARG_TPM2_PIN: - r = parse_boolean_argument("--tpm2-with-pin=", optarg, &arg_tpm2_pin); + case ARG_TPM2_PCRS: + auto_hash_pcr_values = false; + r = tpm2_parse_pcr_argument_append(optarg, &arg_tpm2_hash_pcr_values, &arg_tpm2_n_hash_pcr_values); if (r < 0) return r; @@ -445,6 +438,13 @@ static int parse_argv(int argc, char *argv[]) { auto_pcrlock = false; break; + case ARG_TPM2_WITH_PIN: + r = parse_boolean_argument("--tpm2-with-pin=", optarg, &arg_tpm2_pin); + if (r < 0) + return r; + + break; + case ARG_WIPE_SLOT: { const char *p = optarg; From a8d8d34bfca293e7941b2af4351f72a47c74655c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Nov 2023 21:31:45 +0100 Subject: [PATCH 2/6] tpm2-util: move loading of TPM2B_PUBLIC from disk into tpm2-util.c No change in behaviour, let's just move this over so that we can reuse this in repart later (and don't have to export the ugly `sym_` function pointer for it) --- src/cryptenroll/cryptenroll-tpm2.c | 27 ++------------------ src/shared/tpm2-util.c | 40 +++++++++++++++++++++++++++++- src/shared/tpm2-util.h | 4 +-- 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 4b9f6b2d07..3b8b8ae2e0 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -224,32 +224,9 @@ int enroll_tpm2(struct crypt_device *cd, _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL; TPM2B_PUBLIC device_key_public = {}; if (device_key) { - _cleanup_free_ char *device_key_buffer = NULL; - size_t device_key_buffer_size; - r = read_full_file(device_key, &device_key_buffer, &device_key_buffer_size); + r = tpm2_load_public_key_file(device_key, &device_key_public); if (r < 0) - return log_error_errno(r, "Failed to read device key from file: %m"); - - r = dlopen_tpm2(); - if (r < 0) - return log_debug_errno(r, "TPM2 support not installed: %m"); - - TSS2_RC rc; - size_t offset = 0; - rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal( - (uint8_t*) device_key_buffer, - device_key_buffer_size, - &offset, - &device_key_public); - if (rc != TSS2_RC_SUCCESS) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Could not unmarshal public key from file."); - - assert(offset <= device_key_buffer_size); - if (offset != device_key_buffer_size) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Found %zu bytes of trailing garbage in public key file.", - device_key_buffer_size - offset); + return r; if (!tpm2_pcr_values_has_all_values(hash_pcr_values, n_hash_pcr_values)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index f3712c8496..11e0ae4723 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -88,7 +88,7 @@ static TSS2_RC (*sym_Tss2_MU_TPM2B_NAME_Marshal)(TPM2B_NAME const *src, uint8_t static TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Marshal)(TPM2B_PRIVATE const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL; static TSS2_RC (*sym_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PRIVATE *dest) = NULL; static TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Marshal)(TPM2B_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL; -TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest) = NULL; +static TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest) = NULL; static TSS2_RC (*sym_Tss2_MU_TPM2B_SENSITIVE_Marshal)(TPM2B_SENSITIVE const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL; static TSS2_RC (*sym_Tss2_MU_TPML_PCR_SELECTION_Marshal)(TPML_PCR_SELECTION const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL; static TSS2_RC (*sym_Tss2_MU_TPMS_NV_PUBLIC_Marshal)(TPMS_NV_PUBLIC const *src, uint8_t buffer[], size_t buffer_size, size_t *offset) = NULL; @@ -6845,6 +6845,44 @@ int tpm2_pcrlock_policy_load( *ret_policy = TAKE_STRUCT(policy); return 1; } + +int tpm2_load_public_key_file(const char *path, TPM2B_PUBLIC *ret) { + _cleanup_free_ char *device_key_buffer = NULL; + TPM2B_PUBLIC device_key_public = {}; + size_t device_key_buffer_size; + TSS2_RC rc; + int r; + + assert(path); + assert(ret); + + r = dlopen_tpm2(); + if (r < 0) + return log_debug_errno(r, "TPM2 support not installed: %m"); + + r = read_full_file(path, &device_key_buffer, &device_key_buffer_size); + if (r < 0) + return log_error_errno(r, "Failed to read device key from file '%s': %m", path); + + size_t offset = 0; + rc = sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal( + (uint8_t*) device_key_buffer, + device_key_buffer_size, + &offset, + &device_key_public); + if (rc != TSS2_RC_SUCCESS) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Could not unmarshal public key from file."); + + assert(offset <= device_key_buffer_size); + if (offset != device_key_buffer_size) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Found %zu bytes of trailing garbage in public key file.", + device_key_buffer_size - offset); + + *ret = device_key_public; + return 0; +} #endif char *tpm2_pcr_mask_to_string(uint32_t mask) { diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index e867976369..9f4f1f6d58 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -305,6 +305,8 @@ int tpm2_unseal_data(Tpm2Context *c, const struct iovec *public, const struct io int tpm2_serialize(Tpm2Context *c, const Tpm2Handle *handle, void **ret_serialized, size_t *ret_serialized_size); int tpm2_deserialize(Tpm2Context *c, const void *serialized, size_t serialized_size, Tpm2Handle **ret_handle); +int tpm2_load_public_key_file(const char *path, TPM2B_PUBLIC *ret); + /* The tpm2-tss library has many structs that are simply a combination of an array (or object) and * size. These macros allow easily initializing or assigning instances of such structs from an existing * buffer/object and size, while also checking the size for safety with the struct buffer/object size. If the @@ -361,8 +363,6 @@ int tpm2_deserialize(Tpm2Context *c, const void *serialized, size_t serialized_s 0; \ }) -extern TSS2_RC (*sym_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], size_t buffer_size, size_t *offset, TPM2B_PUBLIC *dest); - #else /* HAVE_TPM2 */ typedef struct {} Tpm2Context; typedef struct {} Tpm2Handle; From a4e9f3d3e8c9400d32ac2554067676feb19c0772 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Nov 2023 22:37:37 +0100 Subject: [PATCH 3/6] cryptenroll: slightly reorder things The tpm2_tpm2b_public_from_pem() invocation only makes sense when we succeed to load the file from disk, hence we might do this together and safe a conditionalization. --- src/cryptenroll/cryptenroll-tpm2.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cryptenroll/cryptenroll-tpm2.c b/src/cryptenroll/cryptenroll-tpm2.c index 3b8b8ae2e0..653ad4452a 100644 --- a/src/cryptenroll/cryptenroll-tpm2.c +++ b/src/cryptenroll/cryptenroll-tpm2.c @@ -193,6 +193,7 @@ int enroll_tpm2(struct crypt_device *cd, return log_error_errno(base64_encoded_size, "Failed to base64 encode salted pin: %m"); } + TPM2B_PUBLIC public = {}; r = tpm2_load_pcr_public_key(pubkey_path, &pubkey, &pubkey_size); if (r < 0) { if (pubkey_path || signature_path || r != -ENOENT) @@ -200,13 +201,19 @@ int enroll_tpm2(struct crypt_device *cd, log_debug_errno(r, "Failed to read TPM2 PCR public key, proceeding without: %m"); pubkey_pcr_mask = 0; - } else 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); + } else { + r = tpm2_tpm2b_public_from_pem(pubkey, pubkey_size, &public); if (r < 0) - return log_debug_errno(r, "Failed to read TPM PCR signature: %m"); + 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. */ + + r = tpm2_load_pcr_signature(signature_path, &signature_json); + if (r < 0) + return log_debug_errno(r, "Failed to read TPM PCR signature: %m"); + } } bool any_pcr_value_specified = tpm2_pcr_values_has_any_values(hash_pcr_values, n_hash_pcr_values); @@ -260,13 +267,6 @@ int enroll_tpm2(struct crypt_device *cd, return log_error_errno(r, "Could not get hash mask: %m"); } - TPM2B_PUBLIC public; - if (pubkey) { - r = tpm2_tpm2b_public_from_pem(pubkey, pubkey_size, &public); - if (r < 0) - return log_error_errno(r, "Could not convert public key to TPM2B_PUBLIC: %m"); - } - TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE); r = tpm2_calculate_sealing_policy( hash_pcr_values, From 78fdf0f68b07b0539305b128a00d0f8428a055cd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 8 Nov 2023 22:42:51 +0100 Subject: [PATCH 4/6] repart: add --tpm2-device-key= to repart, too This adds what was added to systemd-cryptenroll recently to systemd-repart too. Follow-up for: c3a2a681bed77ce4f9218cd28405994ab5263077 --- man/systemd-repart.xml | 11 +++++ src/partition/repart.c | 105 +++++++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 26 deletions(-) diff --git a/man/systemd-repart.xml b/man/systemd-repart.xml index 70f8346e80..5cd4c1ccad 100644 --- a/man/systemd-repart.xml +++ b/man/systemd-repart.xml @@ -377,6 +377,17 @@ + + PATH + HANDLE + + Configures a TPM2 SRK key to bind encryption to. See + systemd-cryptenroll1 + for details on this option. + + + + PATH PCR diff --git a/src/partition/repart.c b/src/partition/repart.c index 01cfc46f1c..45a214bcc8 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -148,6 +148,8 @@ static size_t arg_key_size = 0; static EVP_PKEY *arg_private_key = NULL; static X509 *arg_certificate = NULL; static char *arg_tpm2_device = NULL; +static uint32_t arg_tpm2_seal_key_handle = 0; +static char *arg_tpm2_device_key = NULL; static Tpm2PCRValue *arg_tpm2_hash_pcr_values = NULL; static size_t arg_tpm2_n_hash_pcr_values = 0; static char *arg_tpm2_public_key = NULL; @@ -174,6 +176,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_key, erase_and_freep); STATIC_DESTRUCTOR_REGISTER(arg_private_key, EVP_PKEY_freep); STATIC_DESTRUCTOR_REGISTER(arg_certificate, X509_freep); STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep); +STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device_key, freep); STATIC_DESTRUCTOR_REGISTER(arg_tpm2_hash_pcr_values, freep); STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep); STATIC_DESTRUCTOR_REGISTER(arg_tpm2_pcrlock, freep); @@ -3684,6 +3687,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta _cleanup_free_ char *hp = NULL, *vol = NULL, *dm_name = NULL; const char *passphrase = NULL; size_t passphrase_size = 0; + TPM2Flags flags = 0; const char *vt; int r; @@ -3790,11 +3794,6 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta } } - _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL; - r = tpm2_context_new(arg_tpm2_device, &tpm2_context); - if (r < 0) - return log_error_errno(r, "Failed to create TPM2 context: %m"); - TPM2B_PUBLIC public; if (pubkey) { r = tpm2_tpm2b_public_from_pem(pubkey, pubkey_size, &public); @@ -3802,9 +3801,36 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta return log_error_errno(r, "Could not convert public key to TPM2B_PUBLIC: %m"); } - r = tpm2_pcr_read_missing_values(tpm2_context, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values); - if (r < 0) - return log_error_errno(r, "Could not read pcr values: %m"); + _cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy pcrlock_policy = {}; + if (arg_tpm2_pcrlock) { + r = tpm2_pcrlock_policy_load(arg_tpm2_pcrlock, &pcrlock_policy); + if (r < 0) + return r; + + flags |= TPM2_FLAGS_USE_PCRLOCK; + } + + _cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL; + TPM2B_PUBLIC device_key_public = {}; + if (arg_tpm2_device_key) { + r = tpm2_load_public_key_file(arg_tpm2_device_key, &device_key_public); + if (r < 0) + return r; + + if (!tpm2_pcr_values_has_all_values(arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Must provide all PCR values when using TPM2 device key."); + } else { + r = tpm2_context_new(arg_tpm2_device, &tpm2_context); + if (r < 0) + return log_error_errno(r, "Failed to create TPM2 context: %m"); + + if (!tpm2_pcr_values_has_all_values(arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values)) { + r = tpm2_pcr_read_missing_values(tpm2_context, arg_tpm2_hash_pcr_values, arg_tpm2_n_hash_pcr_values); + if (r < 0) + return log_error_errno(r, "Could not read pcr values: %m"); + } + } uint16_t hash_pcr_bank = 0; uint32_t hash_pcr_mask = 0; @@ -3823,13 +3849,6 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta return log_error_errno(r, "Could not get hash mask: %m"); } - _cleanup_(tpm2_pcrlock_policy_done) Tpm2PCRLockPolicy pcrlock_policy = {}; - if (arg_tpm2_pcrlock) { - r = tpm2_pcrlock_policy_load(arg_tpm2_pcrlock, &pcrlock_policy); - if (r < 0) - return r; - } - TPM2B_DIGEST policy = TPM2B_DIGEST_MAKE(NULL, TPM2_SHA256_DIGEST_SIZE); r = tpm2_calculate_sealing_policy( arg_tpm2_hash_pcr_values, @@ -3841,14 +3860,26 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta if (r < 0) return log_error_errno(r, "Could not calculate sealing policy digest: %m"); - r = tpm2_seal(tpm2_context, - /* seal_key_handle= */ 0, - &policy, - /* pin= */ NULL, - &secret, &secret_size, - &blob, &blob_size, - /* ret_primary_alg= */ NULL, - &srk_buf, &srk_buf_size); + if (arg_tpm2_device_key) + r = tpm2_calculate_seal( + arg_tpm2_seal_key_handle, + &device_key_public, + /* attributes= */ NULL, + /* secret= */ NULL, /* secret_size= */ 0, + &policy, + /* pin= */ NULL, + &secret, &secret_size, + &blob, &blob_size, + &srk_buf, &srk_buf_size); + else + r = tpm2_seal(tpm2_context, + arg_tpm2_seal_key_handle, + &policy, + /* pin= */ NULL, + &secret, &secret_size, + &blob, &blob_size, + /* ret_primary_alg= */ NULL, + &srk_buf, &srk_buf_size); if (r < 0) return log_error_errno(r, "Failed to seal to TPM2: %m"); @@ -3863,8 +3894,8 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta keyslot = sym_crypt_keyslot_add_by_volume_key( cd, CRYPT_ANY_SLOT, - NULL, - VOLUME_KEY_SIZE, + /* volume_key= */ NULL, + /* volume_key_size= */ VOLUME_KEY_SIZE, base64_encoded, base64_encoded_size); if (keyslot < 0) @@ -3881,7 +3912,7 @@ static int partition_encrypt(Context *context, Partition *p, PartitionTarget *ta policy.buffer, policy.size, NULL, 0, /* no salt because tpm2_seal has no pin */ srk_buf, srk_buf_size, - 0, + flags, &v); if (r < 0) return log_error_errno(r, "Failed to prepare TPM2 JSON token object: %m"); @@ -6389,6 +6420,10 @@ static int help(void) { " --certificate=PATH PEM certificate to use when generating verity\n" " roothash signatures\n" " --tpm2-device=PATH Path to TPM2 device node to use\n" + " --tpm2-device-key=PATH\n" + " Enroll a TPM2 device using its public key\n" + " --tpm2-seal-key-handle=HANDLE\n" + " Specify handle of key to use for sealing\n" " --tpm2-pcrs=PCR1+PCR2+PCR3+…\n" " TPM2 PCR indexes to use for TPM2 enrollment\n" " --tpm2-public-key=PATH\n" @@ -6447,6 +6482,8 @@ static int parse_argv(int argc, char *argv[]) { ARG_PRIVATE_KEY, ARG_CERTIFICATE, ARG_TPM2_DEVICE, + ARG_TPM2_DEVICE_KEY, + ARG_TPM2_SEAL_KEY_HANDLE, ARG_TPM2_PCRS, ARG_TPM2_PUBLIC_KEY, ARG_TPM2_PUBLIC_KEY_PCRS, @@ -6485,6 +6522,8 @@ static int parse_argv(int argc, char *argv[]) { { "private-key", required_argument, NULL, ARG_PRIVATE_KEY }, { "certificate", required_argument, NULL, ARG_CERTIFICATE }, { "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE }, + { "tpm2-device-key", required_argument, NULL, ARG_TPM2_DEVICE_KEY }, + { "tpm2-seal-key-handle", required_argument, NULL, ARG_TPM2_SEAL_KEY_HANDLE }, { "tpm2-pcrs", required_argument, NULL, ARG_TPM2_PCRS }, { "tpm2-public-key", required_argument, NULL, ARG_TPM2_PUBLIC_KEY }, { "tpm2-public-key-pcrs", required_argument, NULL, ARG_TPM2_PUBLIC_KEY_PCRS }, @@ -6722,6 +6761,20 @@ static int parse_argv(int argc, char *argv[]) { break; } + case ARG_TPM2_DEVICE_KEY: + r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_tpm2_device_key); + if (r < 0) + return r; + + break; + + case ARG_TPM2_SEAL_KEY_HANDLE: + r = safe_atou32_full(optarg, 16, &arg_tpm2_seal_key_handle); + if (r < 0) + return log_error_errno(r, "Could not parse TPM2 seal key handle index '%s': %m", optarg); + + break; + case ARG_TPM2_PCRS: auto_hash_pcr_values = false; r = tpm2_parse_pcr_argument_append(optarg, &arg_tpm2_hash_pcr_values, &arg_tpm2_n_hash_pcr_values); From 6528563e6490886d4fcb70f9a2167260f8fa019d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Nov 2023 12:25:07 +0100 Subject: [PATCH 5/6] test: make sure --tpm2-device-key= works correctly in repart, too --- test/units/testsuite-70.cryptsetup.sh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/units/testsuite-70.cryptsetup.sh b/test/units/testsuite-70.cryptsetup.sh index a1c6035e45..0a52fbbe6e 100755 --- a/test/units/testsuite-70.cryptsetup.sh +++ b/test/units/testsuite-70.cryptsetup.sh @@ -189,4 +189,26 @@ PASSWORD=passphrase systemd-cryptenroll --tpm2-device=auto --tpm2-seal-key-handl systemd-cryptsetup attach test-volume "$IMAGE" - tpm2-device=auto,headless=1 systemd-cryptsetup detach test-volume +# Make sure that --tpm2-device-key= also works with systemd-repart +tpm2_readpublic -c 0x81000001 -o /tmp/srk.pub +mkdir /tmp/dditest +cat > /tmp/dditest/50-root.conf < Date: Thu, 9 Nov 2023 10:59:06 +0100 Subject: [PATCH 6/6] update TODO --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 7a734ef25d..7ad7c77310 100644 --- a/TODO +++ b/TODO @@ -133,6 +133,10 @@ Deprecations and removals: Features: +* repart + cryptsetup: support file systems that are encrypted and use verity + on top. Usecase: confexts that shall be signed by the admin but also be + confidential. Then, add a new --make-ddi=confext-encrypted for this. + * systemd-pcrextend: - support measuring to nvindex with PCR update semantics ("fake PCRs") - add api for "allocating" such an nvindex