summaryrefslogtreecommitdiff
path: root/src/libtpmtss
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2019-01-02 10:45:36 +0100
committerYves-Alexis Perez <corsac@debian.org>2019-01-02 11:07:05 +0100
commit918094fde55fa0dbfd59a5f88d576efb513a88db (patch)
tree61e31656c60a6cc928c50cd633568043673e2cbd /src/libtpmtss
parent69bc96f6b0b388d35e983f8d27224fa49d92918c (diff)
downloadvyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.tar.gz
vyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.zip
New upstream version 5.7.2
Diffstat (limited to 'src/libtpmtss')
-rw-r--r--src/libtpmtss/plugins/tpm/tpm_private_key.c10
-rw-r--r--src/libtpmtss/tpm_tss.h12
-rw-r--r--src/libtpmtss/tpm_tss_trousers.c7
-rw-r--r--src/libtpmtss/tpm_tss_tss2_v1.c137
-rw-r--r--src/libtpmtss/tpm_tss_tss2_v2.c133
5 files changed, 271 insertions, 28 deletions
diff --git a/src/libtpmtss/plugins/tpm/tpm_private_key.c b/src/libtpmtss/plugins/tpm/tpm_private_key.c
index 3b7582ae3..d946fbe56 100644
--- a/src/libtpmtss/plugins/tpm/tpm_private_key.c
+++ b/src/libtpmtss/plugins/tpm/tpm_private_key.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2017 Andreas Steffen
+ * Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2017-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -75,6 +76,12 @@ METHOD(private_key_t, get_keysize, int,
return this->pubkey->get_keysize(this->pubkey);
}
+METHOD(private_key_t, supported_signature_schemes, enumerator_t*,
+ private_tpm_private_key_t *this)
+{
+ return this->tpm->supported_signature_schemes(this->tpm, this->handle);
+}
+
METHOD(private_key_t, sign, bool,
private_tpm_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
@@ -201,6 +208,7 @@ tpm_private_key_t *tpm_private_key_connect(key_type_t type, va_list args)
.sign = _sign,
.decrypt = _decrypt,
.get_keysize = _get_keysize,
+ .supported_signature_schemes = _supported_signature_schemes,
.get_public_key = _get_public_key,
.equals = private_key_equals,
.belongs_to = private_key_belongs_to,
diff --git a/src/libtpmtss/tpm_tss.h b/src/libtpmtss/tpm_tss.h
index 11e4a7c15..aab7a4d6c 100644
--- a/src/libtpmtss/tpm_tss.h
+++ b/src/libtpmtss/tpm_tss.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2016 Andreas Steffen
+ * Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2016-2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -80,6 +81,15 @@ struct tpm_tss_t {
chunk_t (*get_public)(tpm_tss_t *this, uint32_t handle);
/**
+ * Return signature schemes supported by the given key (TPM 2.0 only)
+ *
+ * @param handle key object handle
+ * @return enumerator over signature_params_t*
+ */
+ enumerator_t *(*supported_signature_schemes)(tpm_tss_t *this,
+ uint32_t handle);
+
+ /**
* Retrieve the current value of a PCR register in a given PCR bank
*
* @param pcr_num PCR number
diff --git a/src/libtpmtss/tpm_tss_trousers.c b/src/libtpmtss/tpm_tss_trousers.c
index 81e542d02..937373354 100644
--- a/src/libtpmtss/tpm_tss_trousers.c
+++ b/src/libtpmtss/tpm_tss_trousers.c
@@ -390,6 +390,12 @@ METHOD(tpm_tss_t, get_public, chunk_t,
return aik_pubkey;
}
+METHOD(tpm_tss_t, supported_signature_schemes, enumerator_t*,
+ private_tpm_tss_trousers_t *this, uint32_t handle)
+{
+ return enumerator_create_empty();
+}
+
METHOD(tpm_tss_t, read_pcr, bool,
private_tpm_tss_trousers_t *this, uint32_t pcr_num, chunk_t *pcr_value,
hash_algorithm_t alg)
@@ -642,6 +648,7 @@ tpm_tss_t *tpm_tss_trousers_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,
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,
diff --git a/src/libtpmtss/tpm_tss_tss2_v2.c b/src/libtpmtss/tpm_tss_tss2_v2.c
index 7cb0d48a9..6bbbce238 100644
--- a/src/libtpmtss/tpm_tss_tss2_v2.c
+++ b/src/libtpmtss/tpm_tss_tss2_v2.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2018 Tobias Brunner
* Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
@@ -64,6 +65,12 @@ struct private_tpm_tss_tss2_t {
* List of supported algorithms
*/
TPM2_ALG_ID supported_algs[TPM2_PT_ALGORITHM_SET];
+
+ /**
+ * Is TPM FIPS 186-4 compliant ?
+ */
+ bool fips_186_4;
+
};
/**
@@ -152,6 +159,7 @@ static bool get_algs_capability(private_tpm_tss_tss2_t *this)
TPMS_TAGGED_PROPERTY tp;
TPMI_YES_NO more_data;
TPM2_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 - TPM2_PT_VENDOR_STRING_1);
htoun32(vendor_string + offset, tp.value);
break;
+ case TPM2_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, TPM2_CAP_ALGS,
@@ -360,7 +381,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)
@@ -404,9 +425,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.publicArea.type)
{
case TPM2_ALG_RSA:
@@ -423,12 +444,12 @@ METHOD(tpm_tss_t, get_public, chunk_t,
aik_modulus = chunk_create(rsa->buffer, rsa->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;
}
@@ -459,7 +480,7 @@ METHOD(tpm_tss_t, get_public, chunk_t,
pos += ecc->x.size;
/* copy y coordinate of ECC point */
memcpy(pos, ecc->y.buffer, ecc->y.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),
@@ -469,14 +490,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.publicArea.type)
+ {
+ case TPM2_ALG_RSA:
+ {
+ TPMS_RSA_PARMS *rsa;
+ TPMT_RSA_SCHEME *scheme;
+
+ rsa = &public.publicArea.parameters.rsaDetail;
+ scheme = &rsa->scheme;
+ digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
+
+ switch (scheme->scheme)
+ {
+ case TPM2_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 TPM2_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 TPM2_ALG_ECC:
+ {
+ TPMT_ECC_SCHEME *scheme;
+
+ scheme = &public.publicArea.parameters.eccDetail.scheme;
+ digest = hash_alg_from_tpm_alg_id(scheme->details.anySig.hashAlg);
+
+ switch (scheme->scheme)
+ {
+ case TPM2_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
*/
@@ -729,7 +837,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);
@@ -940,7 +1048,7 @@ METHOD(tpm_tss_t, sign, bool,
DBG1(DBG_PTS, "%s unsupported %N signature scheme",
LABEL, signature_scheme_names, scheme);
return FALSE;
- };
+ }
return TRUE;
}
@@ -1061,6 +1169,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,