pcrlock: when unlocking try to pick up pcrlock policy from system credentials

This commit is contained in:
Lennart Poettering
2024-01-22 15:20:22 +01:00
parent 985a261701
commit d37c312b87
10 changed files with 215 additions and 29 deletions
@@ -42,7 +42,7 @@ _public_ int cryptsetup_token_open_pin(
void *usrptr /* plugin defined parameter passed to crypt_activate_by_token*() API */) {
_cleanup_(erase_and_freep) char *base64_encoded = NULL, *pin_string = NULL;
_cleanup_(iovec_done) struct iovec blob = {}, pubkey = {}, policy_hash = {}, salt = {}, srk = {};
_cleanup_(iovec_done) struct iovec blob = {}, pubkey = {}, policy_hash = {}, salt = {}, srk = {}, pcrlock_nv = {};
_cleanup_(iovec_done_erase) struct iovec decrypted_key = {};
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
uint32_t hash_pcr_mask, pubkey_pcr_mask;
@@ -88,6 +88,7 @@ _public_ int cryptsetup_token_open_pin(
&policy_hash,
&salt,
&srk,
&pcrlock_nv,
&flags);
if (r < 0)
return log_debug_open_error(cd, r);
@@ -109,6 +110,7 @@ _public_ int cryptsetup_token_open_pin(
&policy_hash,
&salt,
&srk,
&pcrlock_nv,
flags,
&decrypted_key);
if (r < 0)
@@ -166,7 +168,7 @@ _public_ void cryptsetup_token_dump(
const char *json /* validated 'systemd-tpm2' token if cryptsetup_token_validate is defined */) {
_cleanup_free_ char *hash_pcrs_str = NULL, *pubkey_pcrs_str = NULL, *blob_str = NULL, *policy_hash_str = NULL, *pubkey_str = NULL;
_cleanup_(iovec_done) struct iovec blob = {}, pubkey = {}, policy_hash = {}, salt = {}, srk = {};
_cleanup_(iovec_done) struct iovec blob = {}, pubkey = {}, policy_hash = {}, salt = {}, srk = {}, pcrlock_nv = {};
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
uint32_t hash_pcr_mask, pubkey_pcr_mask;
uint16_t pcr_bank, primary_alg;
@@ -191,6 +193,7 @@ _public_ void cryptsetup_token_dump(
&policy_hash,
&salt,
&srk,
&pcrlock_nv,
&flags);
if (r < 0)
return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " JSON fields: %m");
@@ -226,6 +229,7 @@ _public_ void cryptsetup_token_dump(
crypt_log(cd, "\ttpm2-pcrlock: %s\n", true_false(flags & TPM2_FLAGS_USE_PCRLOCK));
crypt_log(cd, "\ttpm2-salt: %s\n", true_false(iovec_is_set(&salt)));
crypt_log(cd, "\ttpm2-srk: %s\n", true_false(iovec_is_set(&srk)));
crypt_log(cd, "\ttpm2-pcrlock-nv: %s\n", true_false(iovec_is_set(&pcrlock_nv)));
}
/*
@@ -27,6 +27,7 @@ int acquire_luks2_key(
const struct iovec *policy_hash,
const struct iovec *salt,
const struct iovec *srk,
const struct iovec *pcrlock_nv,
TPM2Flags flags,
struct iovec *ret_decrypted_key) {
@@ -75,6 +76,14 @@ int acquire_luks2_key(
r = tpm2_pcrlock_policy_load(pcrlock_path, &pcrlock_policy);
if (r < 0)
return r;
if (r == 0) {
/* Not found? Then search among passed credentials */
r = tpm2_pcrlock_policy_from_credentials(srk, pcrlock_nv, &pcrlock_policy);
if (r < 0)
return r;
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Couldn't find pcrlock policy for volume.");
}
}
_cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
@@ -20,5 +20,6 @@ int acquire_luks2_key(
const struct iovec *policy_hash,
const struct iovec *salt,
const struct iovec *srk,
const struct iovec *pcrlock_nv,
TPM2Flags flags,
struct iovec *decrypted_key);
+13 -1
View File
@@ -70,6 +70,7 @@ int acquire_tpm2_key(
const struct iovec *policy_hash,
const struct iovec *salt,
const struct iovec *srk,
const struct iovec *pcrlock_nv,
TPM2Flags flags,
usec_t until,
bool headless,
@@ -128,6 +129,14 @@ int acquire_tpm2_key(
r = tpm2_pcrlock_policy_load(pcrlock_path, &pcrlock_policy);
if (r < 0)
return r;
if (r == 0) {
/* Not found? Then search among passed credentials */
r = tpm2_pcrlock_policy_from_credentials(srk, pcrlock_nv, &pcrlock_policy);
if (r < 0)
return r;
if (r == 0)
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Couldn't find pcrlock policy for volume.");
}
}
_cleanup_(tpm2_context_unrefp) Tpm2Context *tpm2_context = NULL;
@@ -219,6 +228,7 @@ int find_tpm2_auto_data(
struct iovec *ret_policy_hash,
struct iovec *ret_salt,
struct iovec *ret_srk,
struct iovec *ret_pcrlock_nv,
TPM2Flags *ret_flags,
int *ret_keyslot,
int *ret_token) {
@@ -228,7 +238,7 @@ int find_tpm2_auto_data(
assert(cd);
for (token = start_token; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
_cleanup_(iovec_done) struct iovec blob = {}, policy_hash = {}, pubkey = {}, salt = {}, srk = {};
_cleanup_(iovec_done) struct iovec blob = {}, policy_hash = {}, pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
uint32_t hash_pcr_mask, pubkey_pcr_mask;
uint16_t pcr_bank, primary_alg;
@@ -253,6 +263,7 @@ int find_tpm2_auto_data(
&policy_hash,
&salt,
&srk,
&pcrlock_nv,
&flags);
if (r == -EUCLEAN) /* Gracefully handle issues in JSON fields not owned by us */
continue;
@@ -276,6 +287,7 @@ int find_tpm2_auto_data(
*ret_keyslot = keyslot;
*ret_token = token;
*ret_srk = TAKE_STRUCT(srk);
*ret_pcrlock_nv = TAKE_STRUCT(pcrlock_nv);
*ret_flags = flags;
return 0;
}
+4
View File
@@ -28,6 +28,7 @@ int acquire_tpm2_key(
const struct iovec *policy_hash,
const struct iovec *salt,
const struct iovec *srk,
const struct iovec *pcrlock_nv,
TPM2Flags flags,
usec_t until,
bool headless,
@@ -47,6 +48,7 @@ int find_tpm2_auto_data(
struct iovec *ret_policy_hash,
struct iovec *ret_salt,
struct iovec *ret_srk,
struct iovec *ret_pcrlock_nv,
TPM2Flags *ret_flags,
int *ret_keyslot,
int *ret_token);
@@ -70,6 +72,7 @@ static inline int acquire_tpm2_key(
const struct iovec *policy_hash,
const struct iovec *salt,
const struct iovec *srk,
const struct iovec *pcrlock_nv,
TPM2Flags flags,
usec_t until,
bool headless,
@@ -93,6 +96,7 @@ static inline int find_tpm2_auto_data(
struct iovec *ret_policy_hash,
struct iovec *ret_salt,
struct iovec *ret_srk,
struct iovec *ret_pcrlock_nv,
TPM2Flags *ret_flags,
int *ret_keyslot,
int *ret_token) {
+4 -1
View File
@@ -1688,6 +1688,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
/* policy_hash= */ NULL, /* we don't know the policy hash */
/* salt= */ NULL,
/* srk= */ NULL,
/* pcrlock_nv= */ NULL,
arg_tpm2_pin ? TPM2_FLAGS_USE_PIN : 0,
until,
arg_headless,
@@ -1732,7 +1733,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
* works. */
for (;;) {
_cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {};
_cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
uint32_t hash_pcr_mask, pubkey_pcr_mask;
uint16_t pcr_bank, primary_alg;
TPM2Flags tpm2_flags;
@@ -1750,6 +1751,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
&policy_hash,
&salt,
&srk,
&pcrlock_nv,
&tpm2_flags,
&keyslot,
&token);
@@ -1784,6 +1786,7 @@ static int attach_luks_or_plain_or_bitlk_by_tpm2(
&policy_hash,
&salt,
&srk,
&pcrlock_nv,
tpm2_flags,
until,
arg_headless,