]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2: allow using tpm2_get_srk_template() without tpm
authorDan Streetman <ddstreet@ieee.org>
Tue, 3 Oct 2023 14:25:19 +0000 (10:25 -0400)
committerDan Streetman <ddstreet@ieee.org>
Tue, 7 Nov 2023 15:59:44 +0000 (10:59 -0500)
The SRK templates are defined by specification, so move the check for TPM
support to the tpm2_get_best_srk_template() function, and allow anyone to get
the ECC and RSA templates.

Also add test to verify the SRK templates are correct.

src/shared/tpm2-util.c
src/shared/tpm2-util.h
src/test/test-tpm2.c

index 2cf66351ae4c9b5cb24d1f85814b4739360a43de..da69b3d174728bd204e4811fdf17ce4283a64521 100644 (file)
@@ -1122,9 +1122,8 @@ static int tpm2_get_legacy_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_templa
  * SRK-compatible). Preferably, the TPM should contain a shared SRK located at the reserved shared SRK handle
  * (see TPM2_SRK_HANDLE in tpm2-util.h, and tpm2_get_srk() below).
  *
- * The alg must be TPM2_ALG_RSA or TPM2_ALG_ECC. Returns error if the requested template is not supported on
- * this TPM. Also see tpm2_get_best_srk_template() below. */
-static int tpm2_get_srk_template(Tpm2Context *c, TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) {
+ * Returns 0 if the specified algorithm is ECC or RSA, otherwise -EOPNOTSUPP. */
+int tpm2_get_srk_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template) {
         /* The attributes are the same between ECC and RSA templates. This has the changes specified in the
          * Provisioning Guidance document, specifically:
          * TPMA_OBJECT_USERWITHAUTH is added.
@@ -1173,47 +1172,55 @@ static int tpm2_get_srk_template(Tpm2Context *c, TPMI_ALG_PUBLIC alg, TPMT_PUBLI
                 },
         };
 
-        assert(c);
         assert(ret_template);
 
-        if (alg == TPM2_ALG_ECC) {
-                if (!tpm2_supports_alg(c, TPM2_ALG_ECC))
-                        return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
-                                               "TPM does not support ECC.");
-
-                if (!tpm2_supports_ecc_curve(c, srk_ecc.parameters.eccDetail.curveID))
-                        return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
-                                               "TPM does not support ECC-NIST-P256 curve.");
-
-                if (!tpm2_supports_tpmt_public(c, &srk_ecc))
-                        return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
-                                               "TPM does not support SRK ECC template L-2.");
-
+        switch (alg) {
+        case TPM2_ALG_ECC:
                 *ret_template = srk_ecc;
                 return 0;
-        }
-
-        if (alg == TPM2_ALG_RSA) {
-                if (!tpm2_supports_alg(c, TPM2_ALG_RSA))
-                        return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
-                                               "TPM does not support RSA.");
-
-                if (!tpm2_supports_tpmt_public(c, &srk_rsa))
-                        return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE),
-                                               "TPM does not support SRK RSA template L-1.");
-
+        case TPM2_ALG_RSA:
                 *ret_template = srk_rsa;
                 return 0;
         }
 
-        return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Unsupported SRK alg: 0x%x.", alg);
+        return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "No SRK for algorithm 0x%" PRIx16, alg);
 }
 
 /* Get the best supported SRK template. ECC is preferred, then RSA. */
 static int tpm2_get_best_srk_template(Tpm2Context *c, TPMT_PUBLIC *ret_template) {
-        if (tpm2_get_srk_template(c, TPM2_ALG_ECC, ret_template) >= 0 ||
-            tpm2_get_srk_template(c, TPM2_ALG_RSA, ret_template) >= 0)
+        TPMT_PUBLIC template;
+        int r;
+
+        assert(c);
+        assert(ret_template);
+
+        r = tpm2_get_srk_template(TPM2_ALG_ECC, &template);
+        if (r < 0)
+                return r;
+
+        if (!tpm2_supports_alg(c, TPM2_ALG_ECC))
+                log_debug("TPM does not support ECC.");
+        else if (!tpm2_supports_ecc_curve(c, template.parameters.eccDetail.curveID))
+                log_debug("TPM does not support ECC-NIST-P256 curve.");
+        else if (!tpm2_supports_tpmt_public(c, &template))
+                log_debug("TPM does not support SRK ECC template L-2.");
+        else {
+                *ret_template = template;
                 return 0;
+        }
+
+        r = tpm2_get_srk_template(TPM2_ALG_RSA, &template);
+        if (r < 0)
+                return r;
+
+        if (!tpm2_supports_alg(c, TPM2_ALG_RSA))
+                log_debug("TPM does not support RSA.");
+        else if (!tpm2_supports_tpmt_public(c, &template))
+                log_debug("TPM does not support SRK RSA template L-1.");
+        else {
+                *ret_template = template;
+                return 0;
+        }
 
         return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                "TPM does not support either SRK template L-1 (RSA) or L-2 (ECC).");
index 35d851a0d086b7a9bd52f2b0a2f60eeceee62334..59763e9cf1b44268a4a7d6d91bc74e75d84caa3f 100644 (file)
@@ -269,6 +269,8 @@ int tpm2_calculate_policy_or(const TPM2B_DIGEST *branches, size_t n_branches, TP
 int tpm2_calculate_policy_super_pcr(Tpm2PCRPrediction *prediction, uint16_t algorithm, TPM2B_DIGEST *pcr_policy);
 int tpm2_calculate_sealing_policy(const Tpm2PCRValue *pcr_values, size_t n_pcr_values, const TPM2B_PUBLIC *public, bool use_pin, const Tpm2PCRLockPolicy *policy, TPM2B_DIGEST *digest);
 
+int tpm2_get_srk_template(TPMI_ALG_PUBLIC alg, TPMT_PUBLIC *ret_template);
+
 int tpm2_get_or_create_srk(Tpm2Context *c, const Tpm2Handle *session, TPM2B_PUBLIC **ret_public, TPM2B_NAME **ret_name, TPM2B_NAME **ret_qname, Tpm2Handle **ret_handle);
 
 int tpm2_seal(Tpm2Context *c, uint32_t seal_key_handle, const TPM2B_DIGEST *policy, const char *pin, void **ret_secret, size_t *ret_secret_size, void **ret_blob, size_t *ret_blob_size, uint16_t *ret_primary_alg, void **ret_srk_buf, size_t *ret_srk_buf_size);
index 7cefb0c93b7159bc9fb5852ef56d48ef71539b87..486e360f994cc0e3b39dff50b03c1b0d64cd63c8 100644 (file)
@@ -961,6 +961,31 @@ TEST(calculate_policy_pcr) {
         assert_se(digest_check(&d, "7481fd1b116078eb3ac2456e4ad542c9b46b9b8eb891335771ca8e7c8f8e4415"));
 }
 
+TEST(tpm2_get_srk_template) {
+        TPMT_PUBLIC rsa;
+        assert_se(tpm2_get_srk_template(TPM2_ALG_RSA, &rsa) >= 0);
+        assert_se(rsa.type == TPM2_ALG_RSA);
+        assert_se(rsa.nameAlg == TPM2_ALG_SHA256);
+        assert_se(rsa.objectAttributes == 0x30472);
+        assert_se(rsa.parameters.rsaDetail.symmetric.algorithm == TPM2_ALG_AES);
+        assert_se(rsa.parameters.rsaDetail.symmetric.keyBits.sym == 128);
+        assert_se(rsa.parameters.rsaDetail.symmetric.mode.sym == TPM2_ALG_CFB);
+        assert_se(rsa.parameters.rsaDetail.scheme.scheme == TPM2_ALG_NULL);
+        assert_se(rsa.parameters.rsaDetail.keyBits == 2048);
+
+        TPMT_PUBLIC ecc;
+        assert_se(tpm2_get_srk_template(TPM2_ALG_ECC, &ecc) >= 0);
+        assert_se(ecc.type == TPM2_ALG_ECC);
+        assert_se(ecc.nameAlg == TPM2_ALG_SHA256);
+        assert_se(ecc.objectAttributes == 0x30472);
+        assert_se(ecc.parameters.eccDetail.symmetric.algorithm == TPM2_ALG_AES);
+        assert_se(ecc.parameters.eccDetail.symmetric.keyBits.sym == 128);
+        assert_se(ecc.parameters.eccDetail.symmetric.mode.sym == TPM2_ALG_CFB);
+        assert_se(ecc.parameters.eccDetail.scheme.scheme == TPM2_ALG_NULL);
+        assert_se(ecc.parameters.eccDetail.kdf.scheme == TPM2_ALG_NULL);
+        assert_se(ecc.parameters.eccDetail.curveID == TPM2_ECC_NIST_P256);
+}
+
 static void check_test_parms(Tpm2Context *c) {
         assert(c);