diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2023-02-26 08:28:15 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2023-03-17 12:25:26 -0400 |
commit | 79041f47c5ca74859f30d8fad97cca25234f6376 (patch) | |
tree | da9a230558d955a3bc49ad8e02be523a28e40907 | |
parent | f2b31105f4042f23f155502627f802aec0156552 (diff) | |
download | openssl_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.c | 169 | ||||
-rw-r--r-- | src/include/ibm-tss.h | 4 | ||||
-rw-r--r-- | src/include/intel-tss.h | 4 | ||||
-rw-r--r-- | src/include/tpm2-common.h | 8 | ||||
-rw-r--r-- | src/libcommon/tpm2-common.c | 153 |
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; |