diff options
Diffstat (limited to 'src/libtpmtss/tpm_tss_tss2_v1.c')
-rw-r--r-- | src/libtpmtss/tpm_tss_tss2_v1.c | 137 |
1 files changed, 123 insertions, 14 deletions
diff --git a/src/libtpmtss/tpm_tss_tss2_v1.c b/src/libtpmtss/tpm_tss_tss2_v1.c index 9ed2798f7..f904442ed 100644 --- a/src/libtpmtss/tpm_tss_tss2_v1.c +++ b/src/libtpmtss/tpm_tss_tss2_v1.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2018 Tobias Brunner * Copyright (C) 2016-2018 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * @@ -24,9 +25,9 @@ #include <tpm20.h> -#ifdef TSS2_TCTI_TABRMD_V1 +#ifdef TSS2_TCTI_TABRMD #include <tcti/tcti-tabrmd.h> -#endif /* TSS2_TCTI_TABRMD_V1 */ +#endif /* TSS2_TCTI_TABRMD */ #ifdef TSS2_TCTI_SOCKET #include <tcti_socket.h> @@ -68,6 +69,12 @@ struct private_tpm_tss_tss2_t { * List of supported algorithms */ TPM_ALG_ID supported_algs[TPM_PT_ALGORITHM_SET]; + + /** + * Is TPM FIPS 186-4 compliant ? + */ + bool fips_186_4; + }; /** @@ -153,6 +160,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) TPMS_TAGGED_PROPERTY tp; TPMI_YES_NO more_data; TPM_ALG_ID alg; + bool fips_140_2 = FALSE; uint32_t rval, i, offset, revision = 0, year = 0; size_t len = BUF_LEN; char buf[BUF_LEN], manufacturer[5], vendor_string[17]; @@ -193,12 +201,25 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this) offset = 4 * (tp.property - TPM_PT_VENDOR_STRING_1); htoun32(vendor_string + offset, tp.value); break; + case TPM_PT_MODES: + if (tp.value & TPMA_MODES_FIPS_140_2) + { + this->fips_186_4 = fips_140_2 = TRUE; + } + break; default: break; } } - DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u", LABEL, manufacturer, - vendor_string, (float)revision/100, year); + + if (!fips_140_2) + { + this->fips_186_4 = lib->settings->get_bool(lib->settings, + "%s.plugins.tpm.fips_186_4", FALSE, lib->ns); + } + DBG2(DBG_PTS, "%s manufacturer: %s (%s) rev: %05.2f %u %s", LABEL, + manufacturer, vendor_string, (float)revision/100, year, + fips_140_2 ? "FIPS 140-2" : (this->fips_186_4 ? "FIPS 186-4" : "")); /* get supported algorithms */ rval = Tss2_Sys_GetCapability(this->sys_context, 0, TPM_CAP_ALGS, @@ -400,7 +421,7 @@ METHOD(tpm_tss_t, get_version_info, chunk_t, } /** - * read the public key portion of a TSS 2.0 AIK key from NVRAM + * read the public key portion of a TSS 2.0 key from NVRAM */ bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle, TPM2B_PUBLIC *public) @@ -450,9 +471,9 @@ METHOD(tpm_tss_t, get_public, chunk_t, } aik_blob = chunk_create((u_char*)&public, sizeof(public)); - DBG3(DBG_LIB, "%s AIK public key blob: %B", LABEL, &aik_blob); + DBG3(DBG_LIB, "%s public key blob: %B", LABEL, &aik_blob); - /* convert TSS 2.0 AIK public key blot into PKCS#1 format */ + /* convert TSS 2.0 public key blot into PKCS#1 format */ switch (public.t.publicArea.type) { case TPM_ALG_RSA: @@ -469,12 +490,12 @@ METHOD(tpm_tss_t, get_public, chunk_t, aik_modulus = chunk_create(rsa->t.buffer, rsa->t.size); aik_exponent = chunk_from_chars(0x01, 0x00, 0x01); - /* subjectPublicKeyInfo encoding of AIK RSA key */ + /* subjectPublicKeyInfo encoding of RSA public key */ if (!lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER, NULL, &aik_pubkey, CRED_PART_RSA_MODULUS, aik_modulus, CRED_PART_RSA_PUB_EXP, aik_exponent, CRED_PART_END)) { - DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key " + DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of public key " "failed", LABEL); return chunk_empty; } @@ -505,7 +526,7 @@ METHOD(tpm_tss_t, get_public, chunk_t, pos += ecc->x.t.size; /* copy y coordinate of ECC point */ memcpy(pos, ecc->y.t.buffer, ecc->y.t.size); - /* subjectPublicKeyInfo encoding of AIK ECC key */ + /* subjectPublicKeyInfo encoding of ECC public key */ aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm", asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(OID_EC_PUBLICKEY), @@ -515,14 +536,101 @@ METHOD(tpm_tss_t, get_public, chunk_t, break; } default: - DBG1(DBG_PTS, "%s unsupported AIK key type", LABEL); + DBG1(DBG_PTS, "%s unsupported key type", LABEL); return chunk_empty; } - DBG1(DBG_PTS, "AIK signature algorithm is %N with %N hash", + DBG1(DBG_PTS, "signature algorithm is %N with %N hash", tpm_alg_id_names, sig_alg, tpm_alg_id_names, digest_alg); return aik_pubkey; } +METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*, + private_tpm_tss_tss2_t *this, uint32_t handle) +{ + TPM2B_PUBLIC public = { { 0, } }; + hash_algorithm_t digest; + signature_params_t supported_scheme; + + if (!read_public(this, handle, &public)) + { + return enumerator_create_empty(); + } + + switch (public.t.publicArea.type) + { + case TPM_ALG_RSA: + { + TPMS_RSA_PARMS *rsa; + TPMT_RSA_SCHEME *scheme; + + rsa = &public.t.publicArea.parameters.rsaDetail; + scheme = &rsa->scheme; + digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg); + + switch (scheme->scheme) + { + case TPM_ALG_RSAPSS: + { + ssize_t salt_len; + + salt_len = this->fips_186_4 ? RSA_PSS_SALT_LEN_DEFAULT : + RSA_PSS_SALT_LEN_MAX; + rsa_pss_params_t pss_params = { + .hash = digest, + .mgf1_hash = digest, + .salt_len = salt_len, + }; + supported_scheme = (signature_params_t){ + .scheme = SIGN_RSA_EMSA_PSS, + .params = &pss_params, + }; + if (!rsa_pss_params_set_salt_len(&pss_params, rsa->keyBits)) + { + return enumerator_create_empty(); + } + break; + } + case TPM_ALG_RSASSA: + supported_scheme = (signature_params_t){ + .scheme = signature_scheme_from_oid( + hasher_signature_algorithm_to_oid(digest, + KEY_RSA)), + }; + break; + default: + return enumerator_create_empty(); + } + break; + } + case TPM_ALG_ECC: + { + TPMT_ECC_SCHEME *scheme; + + scheme = &public.t.publicArea.parameters.eccDetail.scheme; + digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg); + + switch (scheme->scheme) + { + case TPM_ALG_ECDSA: + supported_scheme = (signature_params_t){ + .scheme = signature_scheme_from_oid( + hasher_signature_algorithm_to_oid(digest, + KEY_ECDSA)), + }; + break; + default: + return enumerator_create_empty(); + } + break; + } + default: + DBG1(DBG_PTS, "%s unsupported key type", LABEL); + return enumerator_create_empty(); + } + return enumerator_create_single(signature_params_clone(&supported_scheme), + (void*)signature_params_destroy); +} + /** * Configure a PCR Selection assuming a maximum of 24 registers */ @@ -809,7 +917,7 @@ METHOD(tpm_tss_t, quote, bool, DBG1(DBG_PTS, "%s unsupported %N signature algorithm", LABEL, tpm_alg_id_names, sig.sigAlg); return FALSE; - }; + } DBG2(DBG_PTS, "PCR digest algorithm is %N", tpm_alg_id_names, hash_alg); pcr_digest_alg = hash_alg_from_tpm_alg_id(hash_alg); @@ -1036,7 +1144,7 @@ METHOD(tpm_tss_t, sign, bool, DBG1(DBG_PTS, "%s unsupported %N signature scheme", LABEL, signature_scheme_names, scheme); return FALSE; - }; + } return TRUE; } @@ -1174,6 +1282,7 @@ tpm_tss_t *tpm_tss_tss2_create() .get_version_info = _get_version_info, .generate_aik = _generate_aik, .get_public = _get_public, + .supported_signature_schemes = _supported_signature_schemes, .read_pcr = _read_pcr, .extend_pcr = _extend_pcr, .quote = _quote, |