}
}
+/* Be careful before changing anything in this function, as the TPM key "name" is calculated using the entire
+ * TPMT_PUBLIC (after marshalling), and that "name" is used (for example) to calculate the policy hash for
+ * the Authorize policy. So we must ensure this conversion of a PEM to TPM2B_PUBLIC does not change the
+ * "name", because it would break unsealing of previously-sealed objects that used (for example)
+ * tpm2_calculate_policy_authorize(). See bug #30546. */
int tpm2_tpm2b_public_from_openssl_pkey(const EVP_PKEY *pkey, TPM2B_PUBLIC *ret) {
int key_id, r;
uint32_t exponent = 0;
memcpy(&exponent, e, e_size);
exponent = be32toh(exponent) >> (32 - e_size * 8);
- if (exponent == TPM2_RSA_DEFAULT_EXPONENT)
- exponent = 0;
+
+ /* TPM specification Part 2 ("Structures") section for TPMS_RSA_PARAMS states "An exponent of
+ * zero indicates that the exponent is the default of 2^16 + 1". However, we have no reason
+ * to special case it in our PEM->TPM2B_PUBLIC conversion, and doing so could break backwards
+ * compatibility, so even if it is the "default" value of 0x10001, we do not set it to 0. */
public.parameters.rsaDetail.exponent = exponent;
break;
assert_se(p->parameters.rsaDetail.keyBits == expected_n_len * 8);
- assert_se(p->parameters.rsaDetail.exponent == 0);
+ assert_se(p->parameters.rsaDetail.exponent == 0x10001);
check_tpm2b_public_fingerprint(&public, "d9186d13a7fd5b3644cee05448f49ad3574e82a2942ff93cf89598d36cca78a9");
}