From: Dan Streetman Date: Tue, 16 Jan 2024 15:39:06 +0000 (-0500) Subject: tpm2: If unsealing results in policy hash mismatch when using RSA pubkey, possibly... X-Git-Tag: v256-rc1~1125^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fda3e844657b61b69f8d0badffb6239840ef9e97;p=thirdparty%2Fsystemd.git tpm2: If unsealing results in policy hash mismatch when using RSA pubkey, possibly retry The commit e3acb4d24c68291376b11bea5787112978e2775f changed how we format a TPM2B_PUBLIC object from an openssl PEM RSA key if it used the TPM-defined "default" RSA exponent, to instead set the TPM2B_PUBLIC RSA exponent to the special-case value of 0. This broke backwards compatibility with previously-sealed data. The previous commit fixed our code to no longer use the "special case" exponent value of 0, while this commit adds a fallback check for any sealed data that used the exponent value of 0. Now unsealing should work for sealed data that used either method (either 0 or the actual value). --- diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 470ee683229..770a1e2b142 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -5557,11 +5557,25 @@ int tpm2_unseal(Tpm2Context *c, /* If we know the policy hash to expect, and it doesn't match, we can shortcut things here, and not * wait until the TPM2 tells us to go away. */ - if (iovec_is_set(known_policy_hash) && - memcmp_nn(policy_digest->buffer, policy_digest->size, known_policy_hash->iov_base, known_policy_hash->iov_len) != 0) + if (iovec_is_set(known_policy_hash) && memcmp_nn(policy_digest->buffer, + policy_digest->size, + known_policy_hash->iov_base, + known_policy_hash->iov_len) != 0) { +#if HAVE_OPENSSL + if (iovec_is_set(pubkey) && + pubkey_tpm2b.publicArea.type == TPM2_ALG_RSA && + pubkey_tpm2b.publicArea.parameters.rsaDetail.exponent == TPM2_RSA_DEFAULT_EXPONENT) { + /* Due to bug #30546, if using RSA pubkey with the default exponent, we may + * need to set the exponent to the TPM special-case value of 0 and retry. */ + log_debug("Policy hash mismatch, retrying with RSA pubkey exponent set to 0."); + pubkey_tpm2b.publicArea.parameters.rsaDetail.exponent = 0; + continue; + } else +#endif return log_debug_errno(SYNTHETIC_ERRNO(EPERM), "Current policy digest does not match stored policy digest, cancelling " "TPM2 authentication attempt."); + } log_debug("Unsealing HMAC key.");