]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2: If unsealing results in policy hash mismatch when using RSA pubkey, possibly... 30971/head
authorDan Streetman <ddstreet@ieee.org>
Tue, 16 Jan 2024 15:39:06 +0000 (10:39 -0500)
committerDan Streetman <ddstreet@ieee.org>
Tue, 16 Jan 2024 20:57:08 +0000 (15:57 -0500)
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).

src/shared/tpm2-util.c

index 470ee683229ecc088d24421d291747fc3923ec9c..770a1e2b1429322566620a22c40e8d4ccc0dc838 100644 (file)
@@ -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.");