aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2023-02-26 08:28:15 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2023-03-17 12:25:26 -0400
commit79041f47c5ca74859f30d8fad97cca25234f6376 (patch)
treeda9a230558d955a3bc49ad8e02be523a28e40907
parentf2b31105f4042f23f155502627f802aec0156552 (diff)
downloadopenssl_tpm2_engine-79041f47c5ca74859f30d8fad97cca25234f6376.tar.gz
tpm2-common: factor out elliptic curve signature and derivation
Since these will have to be shared between the engine and the provider. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--src/engine/e_tpm2-ecc.c169
-rw-r--r--src/include/ibm-tss.h4
-rw-r--r--src/include/intel-tss.h4
-rw-r--r--src/include/tpm2-common.h8
-rw-r--r--src/libcommon/tpm2-common.c153
5 files changed, 175 insertions, 163 deletions
diff --git a/src/engine/e_tpm2-ecc.c b/src/engine/e_tpm2-ecc.c
index bbc86da..a5242e9 100644
--- a/src/engine/e_tpm2-ecc.c
+++ b/src/engine/e_tpm2-ecc.c
@@ -59,28 +59,18 @@ static EC_KEY_METHOD *tpm2_eck = NULL;
static int ec_app_data = TPM2_ENGINE_EX_DATA_UNINIT;
static int active_keys = 0;
-static TPM_HANDLE tpm2_load_key_from_ecc(const EC_KEY *eck,
- TSS_CONTEXT **tssContext, char **auth,
- TPM_SE *sessionType,
- struct app_data **app_data,
- TPM_ALG_ID *nameAlg)
+static struct app_data *tpm2_ad_from_key(const EC_KEY *eck)
{
+ struct app_data *app_data;
+
#if OPENSSL_VERSION_NUMBER < 0x10100000
/* const mess up in openssl 1.0.2 */
- *app_data = ECDSA_get_ex_data((EC_KEY *)eck, ec_app_data);
+ app_data = ECDSA_get_ex_data((EC_KEY *)eck, ec_app_data);
#else
- *app_data = EC_KEY_get_ex_data(eck, ec_app_data);
+ app_data = EC_KEY_get_ex_data(eck, ec_app_data);
#endif
- if (!*app_data)
- return 0;
-
- *auth = (*app_data)->auth;
- *sessionType = (*app_data)->req_policy_session ?
- TPM_SE_POLICY : TPM_SE_HMAC;
- *nameAlg = (*app_data)->Public.publicArea.nameAlg;
-
- return tpm2_load_key(tssContext, *app_data, srk_auth, NULL);
+ return app_data;
}
void tpm2_bind_key_to_engine_ecc(ENGINE *e, EVP_PKEY *pkey, struct app_data *data)
@@ -129,157 +119,26 @@ static ECDSA_SIG *tpm2_ecdsa_sign(const unsigned char *dgst, int dgst_len,
const BIGNUM *kinv, const BIGNUM *rp,
EC_KEY *eck)
{
- TPM_RC rc;
- TPM_HANDLE keyHandle;
- DIGEST_2B digest;
- TPMT_SIG_SCHEME inScheme;
- TPMT_SIGNATURE signature;
- TSS_CONTEXT *tssContext;
- char *auth;
- TPM_HANDLE authHandle;
- TPM_SE sessionType;
- ECDSA_SIG *sig;
- BIGNUM *r, *s;
- TPM_ALG_ID nameAlg;
- struct app_data *app_data;
-
- /* The TPM insists on knowing the digest type, so
- * calculate that from the size */
- switch (dgst_len) {
- case SHA_DIGEST_LENGTH:
- inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA1;
- break;
- case SHA256_DIGEST_LENGTH:
- inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA256;
- break;
- case SHA384_DIGEST_LENGTH:
- inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA384;
- break;
-#ifdef TPM_ALG_SHA512
- case SHA512_DIGEST_LENGTH:
- inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA512;
- break;
-#endif
- default:
- printf("ECDSA signature: Unknown digest length, cannot deduce hash type for TPM\n");
- return NULL;
- }
-
- keyHandle = tpm2_load_key_from_ecc(eck, &tssContext, &auth,
- &sessionType, &app_data, &nameAlg);
- if (keyHandle == 0) {
- fprintf(stderr, "Failed to get Key Handle in TPM EC key routines\n");
- return NULL;
- }
-
- inScheme.scheme = TPM_ALG_ECDSA;
- digest.size = dgst_len;
- memcpy(digest.buffer, dgst, dgst_len);
-
- sig = NULL;
- rc = tpm2_get_session_handle(tssContext, &authHandle, 0, sessionType,
- nameAlg);
- if (rc)
- goto out;
-
- if (sessionType == TPM_SE_POLICY) {
- rc = tpm2_init_session(tssContext, authHandle,
- app_data, nameAlg);
- if (rc)
- goto out;
- }
+ struct app_data *app_data = tpm2_ad_from_key(eck);
- rc = tpm2_Sign(tssContext, keyHandle, &digest, &inScheme, &signature,
- authHandle, auth);
- if (rc) {
- tpm2_error(rc, "TPM2_Sign");
- tpm2_flush_handle(tssContext, authHandle);
- goto out;
- }
-
- sig = ECDSA_SIG_new();
- if (!sig)
- goto out;
-
- r = BN_bin2bn(VAL_2B(signature.signature.ecdsa.signatureR, buffer),
- VAL_2B(signature.signature.ecdsa.signatureR, size),
- NULL);
- s = BN_bin2bn(VAL_2B(signature.signature.ecdsa.signatureS, buffer),
- VAL_2B(signature.signature.ecdsa.signatureS, size),
- NULL);
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000
- sig->r = r;
- sig->s = s;
-#else
- ECDSA_SIG_set0(sig, r, s);
-#endif
- out:
- tpm2_unload_key(tssContext, keyHandle);
- return sig;
+ return tpm2_sign_ecc(app_data, dgst, dgst_len, srk_auth);
}
static int tpm2_ecc_compute_key(unsigned char **psec, size_t *pseclen,
const EC_POINT *pt, const EC_KEY *eck)
{
- TPM_RC rc;
- TPM_HANDLE keyHandle;
TPM2B_ECC_POINT inPoint;
- TPM2B_ECC_POINT outPoint;
- TSS_CONTEXT *tssContext;
- TPM_HANDLE authHandle;
- TPM_SE sessionType;
- char *auth;
- size_t len;
- TPM_ALG_ID nameAlg;
struct app_data *app_data;
- int ret;
- keyHandle = tpm2_load_key_from_ecc(eck, &tssContext, &auth,
- &sessionType, &app_data, &nameAlg);
- if (keyHandle == 0) {
- fprintf(stderr, "Failed to get Key Handle in TPM EC key routines\n");
+ app_data = tpm2_ad_from_key(eck);
+ if (!app_data)
return 0;
- }
- len = tpm2_get_public_point(&inPoint, EC_KEY_get0_group(eck), pt);
- if (!len)
- return 0;
-
- ret = 0;
- rc = tpm2_get_session_handle(tssContext, &authHandle, 0, sessionType,
- nameAlg);
- if (rc)
- goto out;
-
- if (sessionType == TPM_SE_POLICY) {
- rc = tpm2_init_session(tssContext, authHandle,
- app_data, nameAlg);
- if (rc)
- goto out;
- }
- rc = tpm2_ECDH_ZGen(tssContext, keyHandle, &inPoint, &outPoint,
- authHandle, auth);
- if (rc) {
- tpm2_error(rc, "TPM2_ECDH_ZGen");
- tpm2_flush_handle(tssContext, authHandle);
- goto out;
- }
+ *pseclen = tpm2_get_public_point(&inPoint, EC_KEY_get0_group(eck), pt);
+ if (!*pseclen)
+ return 0;
- *psec = OPENSSL_malloc(len);
- if (!*psec)
- goto out;
- *pseclen = len;
- memset(*psec, 0, len);
-
- /* zero pad the X point */
- memcpy(*psec + len - VAL_2B(outPoint.point.x, size),
- VAL_2B(outPoint.point.x, buffer),
- VAL_2B(outPoint.point.x, size));
- ret = 1;
- out:
- tpm2_unload_key(tssContext, keyHandle);
- return ret;
+ return tpm2_ecdh_x(app_data, psec, pseclen, &inPoint, srk_auth);
}
#if OPENSSL_VERSION_NUMBER < 0x10100000
diff --git a/src/include/ibm-tss.h b/src/include/ibm-tss.h
index b28b522..b1f6e74 100644
--- a/src/include/ibm-tss.h
+++ b/src/include/ibm-tss.h
@@ -253,7 +253,7 @@ tpm2_Sign(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle, DIGEST_2B *digest,
static inline TPM_RC
tpm2_ECDH_ZGen(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
- TPM2B_ECC_POINT *inPoint, TPM2B_ECC_POINT *outPoint,
+ const TPM2B_ECC_POINT *inPoint, TPM2B_ECC_POINT *outPoint,
TPM_HANDLE auth, const char *authVal)
{
ECDH_ZGen_In in;
@@ -455,7 +455,7 @@ tpm2_VerifySignature(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
static inline TPM_RC
tpm2_Load(TSS_CONTEXT *tssContext, TPM_HANDLE parentHandle,
- PRIVATE_2B *inPrivate, TPM2B_PUBLIC *inPublic,
+ PRIVATE_2B *inPrivate, const TPM2B_PUBLIC *inPublic,
TPM_HANDLE *objectHandle,
TPM_HANDLE auth, const char *authVal)
{
diff --git a/src/include/intel-tss.h b/src/include/intel-tss.h
index 85c4031..d5913a4 100644
--- a/src/include/intel-tss.h
+++ b/src/include/intel-tss.h
@@ -811,7 +811,7 @@ tpm2_Sign(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle, DIGEST_2B *digest,
static inline TPM_RC
tpm2_ECDH_ZGen(TSS_CONTEXT *tssContext, TPM_HANDLE keyHandle,
- TPM2B_ECC_POINT *inPoint, TPM2B_ECC_POINT *outPoint,
+ const TPM2B_ECC_POINT *inPoint, TPM2B_ECC_POINT *outPoint,
TPM_HANDLE auth, const char *authVal)
{
TPM2B_ECC_POINT *out;
@@ -909,7 +909,7 @@ tpm2_StartAuthSession(TSS_CONTEXT *tssContext, TPM_HANDLE tpmKey,
static inline TPM_RC
tpm2_Load(TSS_CONTEXT *tssContext, TPM_HANDLE parentHandle,
- PRIVATE_2B *inPrivate, TPM2B_PUBLIC *inPublic,
+ PRIVATE_2B *inPrivate, const TPM2B_PUBLIC *inPublic,
TPM_HANDLE *objectHandle,
TPM_HANDLE auth, const char *authVal)
{
diff --git a/src/include/tpm2-common.h b/src/include/tpm2-common.h
index 48dd694..2f14e83 100644
--- a/src/include/tpm2-common.h
+++ b/src/include/tpm2-common.h
@@ -61,7 +61,7 @@ TPM_RC tpm2_get_session_handle(TSS_CONTEXT *tssContext, TPM_HANDLE *handle,
TPM_HANDLE salt_key, TPM_SE sessionType,
TPM_ALG_ID name_alg);
TPM_RC tpm2_init_session(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
- struct app_data *app_data, TPM_ALG_ID name_alg);
+ const struct app_data *app_data, TPM_ALG_ID name_alg);
TPM_RC tpm2_get_bound_handle(TSS_CONTEXT *tssContext, TPM_HANDLE *handle,
TPM_HANDLE bind, const char *auth);
TPMI_ECC_CURVE tpm2_curve_name_to_TPMI(const char *name);
@@ -82,7 +82,7 @@ int tpm2_load_engine_file(const char *filename, struct app_data **app_data,
EVP_PKEY **ppkey, UI_METHOD *ui, void *cb_data,
const char *srk_auth, int get_key_auth,
int public_only);
-TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, struct app_data *app_data,
+TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, const struct app_data *app_data,
const char *srk_auth, uint32_t *psession);
void tpm2_unload_key(TSS_CONTEXT *tssContext, TPM_HANDLE key);
void tpm2_delete(struct app_data *app_data);
@@ -121,4 +121,8 @@ TPM_RC tpm2_outerwrap(EVP_PKEY *parent,
PRIVATE_2B *p,
ENCRYPTED_SECRET_2B *enc_secret);
int tpm2_load_bf(BIO *bf, struct app_data *app_data, const char *srk_auth);
+ECDSA_SIG *tpm2_sign_ecc(const struct app_data *ad, const unsigned char *dgst,
+ int dgst_len, char *srk_auth);
+int tpm2_ecdh_x(struct app_data *ad, unsigned char **psec, size_t *pseclen,
+ const TPM2B_ECC_POINT *inPoint, const char *srk_auth);
#endif
diff --git a/src/libcommon/tpm2-common.c b/src/libcommon/tpm2-common.c
index c65b2c6..e335528 100644
--- a/src/libcommon/tpm2-common.c
+++ b/src/libcommon/tpm2-common.c
@@ -573,6 +573,155 @@ struct tpm2_ECC_Curves tpm2_supported_curves[] = {
{ .name = NULL, }
};
+ECDSA_SIG *tpm2_sign_ecc(const struct app_data *ad, const unsigned char *dgst,
+ int dgst_len, char *srk_auth)
+{
+ TPM_RC rc;
+ TPM_HANDLE keyHandle;
+ DIGEST_2B digest;
+ TPMT_SIG_SCHEME inScheme;
+ TPMT_SIGNATURE signature;
+ TSS_CONTEXT *tssContext;
+ TPM_HANDLE authHandle;
+ TPM_SE sessionType;
+ ECDSA_SIG *sig;
+ BIGNUM *r, *s;
+
+ /* The TPM insists on knowing the digest type, so
+ * calculate that from the size */
+ switch (dgst_len) {
+ case SHA_DIGEST_LENGTH:
+ inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA1;
+ break;
+ case SHA256_DIGEST_LENGTH:
+ inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA256;
+ break;
+ case SHA384_DIGEST_LENGTH:
+ inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA384;
+ break;
+#ifdef TPM_ALG_SHA512
+ case SHA512_DIGEST_LENGTH:
+ inScheme.details.ecdsa.hashAlg = TPM_ALG_SHA512;
+ break;
+#endif
+ default:
+ fprintf(stderr, "ECDSA signature: Unknown digest length, cannot deduce hash type for TPM\n");
+ return NULL;
+ }
+
+ keyHandle = tpm2_load_key(&tssContext, ad, srk_auth, NULL);
+ if (keyHandle == 0)
+ return NULL;
+
+ inScheme.scheme = TPM_ALG_ECDSA;
+ digest.size = dgst_len;
+ memcpy(digest.buffer, dgst, dgst_len);
+
+ sessionType = ad->req_policy_session ? TPM_SE_POLICY : TPM_SE_HMAC;
+
+ sig = NULL;
+ rc = tpm2_get_session_handle(tssContext, &authHandle, 0, sessionType,
+ ad->Public.publicArea.nameAlg);
+ if (rc)
+ goto out;
+
+ if (sessionType == TPM_SE_POLICY) {
+ rc = tpm2_init_session(tssContext, authHandle,
+ ad, ad->Public.publicArea.nameAlg);
+ if (rc)
+ goto out;
+ }
+
+ rc = tpm2_Sign(tssContext, keyHandle, &digest, &inScheme, &signature,
+ authHandle, ad->auth);
+ if (rc) {
+ tpm2_error(rc, "TPM2_Sign");
+ tpm2_flush_handle(tssContext, authHandle);
+ goto out;
+ }
+
+ sig = ECDSA_SIG_new();
+ if (!sig)
+ goto out;
+
+ r = BN_bin2bn(VAL_2B(signature.signature.ecdsa.signatureR, buffer),
+ VAL_2B(signature.signature.ecdsa.signatureR, size),
+ NULL);
+ s = BN_bin2bn(VAL_2B(signature.signature.ecdsa.signatureS, buffer),
+ VAL_2B(signature.signature.ecdsa.signatureS, size),
+ NULL);
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000
+ sig->r = r;
+ sig->s = s;
+#else
+ ECDSA_SIG_set0(sig, r, s);
+#endif
+ out:
+ tpm2_unload_key(tssContext, keyHandle);
+ return sig;
+}
+
+int tpm2_ecdh_x(struct app_data *ad, unsigned char **psec, size_t *pseclen,
+ const TPM2B_ECC_POINT *inPoint, const char *srk_auth)
+{
+ TPM_RC rc;
+ TPM_HANDLE keyHandle;
+ TPM2B_ECC_POINT outPoint;
+ TSS_CONTEXT *tssContext;
+ TPM_HANDLE authHandle;
+ TPM_SE sessionType;
+ size_t len;
+ int ret;
+
+ keyHandle = tpm2_load_key(&tssContext, ad, srk_auth, NULL);
+ if (keyHandle == 0) {
+ fprintf(stderr, "Failed to get Key Handle in TPM EC key routines\n");
+ return 0;
+ }
+
+ ret = 0;
+ len = tpm2_curve_to_order(ad->Public.publicArea.parameters.eccDetail.curveID);
+ sessionType = ad->req_policy_session ? TPM_SE_POLICY : TPM_SE_HMAC;
+
+ rc = tpm2_get_session_handle(tssContext, &authHandle, 0, sessionType,
+ ad->Public.publicArea.nameAlg);
+ if (rc)
+ goto out;
+
+ if (sessionType == TPM_SE_POLICY) {
+ rc = tpm2_init_session(tssContext, authHandle,
+ ad, ad->Public.publicArea.nameAlg);
+ if (rc)
+ goto out;
+ }
+
+ rc = tpm2_ECDH_ZGen(tssContext, keyHandle, inPoint, &outPoint,
+ authHandle, ad->auth);
+ if (rc) {
+ tpm2_error(rc, "TPM2_ECDH_ZGen");
+ tpm2_flush_handle(tssContext, authHandle);
+ goto out;
+ }
+
+ if (!*psec) {
+ *psec = OPENSSL_malloc(len);
+ if (!*psec)
+ goto out;
+ }
+ *pseclen = len;
+ memset(*psec, 0, len);
+
+ /* zero pad the X point */
+ memcpy(*psec + len - VAL_2B(outPoint.point.x, size),
+ VAL_2B(outPoint.point.x, buffer),
+ VAL_2B(outPoint.point.x, size));
+ ret = 1;
+ out:
+ tpm2_unload_key(tssContext, keyHandle);
+ return ret;
+}
+
TPM_RC tpm2_ObjectPublic_GetName(NAME_2B *name,
TPMT_PUBLIC *tpmtPublic)
{
@@ -1096,7 +1245,7 @@ static TPM_RC tpm2_try_policy(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
}
TPM_RC tpm2_init_session(TSS_CONTEXT *tssContext, TPM_HANDLE handle,
- struct app_data *app_data, TPM_ALG_ID name_alg)
+ const struct app_data *app_data, TPM_ALG_ID name_alg)
{
int num_commands;
struct policy_command *commands;
@@ -1942,7 +2091,7 @@ void tpm2_delete(struct app_data *app_data)
OPENSSL_free(app_data);
}
-TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, struct app_data *app_data,
+TPM_HANDLE tpm2_load_key(TSS_CONTEXT **tsscp, const struct app_data *app_data,
const char *srk_auth, uint32_t *psrk)
{
TSS_CONTEXT *tssContext;