diff --git a/configure.ac b/configure.ac index ae95200d..ca9c9765 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,7 @@ AC_ARG_WITH([tpm2], use_openssl_functions_for="" use_openssl_functions_symmetric=0 +use_openssl_functions_ec=0 use_openssl_functions_ecdsa=0 AC_ARG_ENABLE(use-openssl-functions, AS_HELP_STRING([--disable-use-openssl-functions], @@ -166,6 +167,15 @@ AS_IF([test "x$enable_use_openssl_functions" != "xno"], [ use_openssl_functions_symmetric=1 use_openssl_functions_for="symmetric (AES, TDES) " fi + # Check for EC crypto support + not_found=0 + AC_CHECK_LIB([crypto], [EC_KEY_set_group],, not_found=1) + AC_CHECK_LIB([crypto], [EC_KEY_generate_key],, not_found=1) + AC_CHECK_LIB([crypto], [EC_KEY_get0_private_key],, not_found=1) + if test "x$not_found" = "x0"; then + use_openssl_functions_ec=1 + use_openssl_functions_for="${use_openssl_functions_for}general elliptic curve (EC) " + fi # Check for ECDSA crypto support not_found=0 AC_CHECK_LIB([crypto], [ECDSA_SIG_new],, not_found=1) @@ -179,6 +189,7 @@ AS_IF([test "x$enable_use_openssl_functions" != "xno"], [ fi ]) CFLAGS="$CFLAGS -DUSE_OPENSSL_FUNCTIONS_SYMMETRIC=$use_openssl_functions_symmetric" +CFLAGS="$CFLAGS -DUSE_OPENSSL_FUNCTIONS_EC=$use_openssl_functions_ec" CFLAGS="$CFLAGS -DUSE_OPENSSL_FUNCTIONS_ECDSA=$use_openssl_functions_ecdsa" AC_ARG_ENABLE([sanitizers], AS_HELP_STRING([--enable-sanitizers], [Enable address sanitizing]), diff --git a/src/tpm2/crypto/CryptEccMain_fp.h b/src/tpm2/crypto/CryptEccMain_fp.h index f58411b1..c14e9fc6 100644 --- a/src/tpm2/crypto/CryptEccMain_fp.h +++ b/src/tpm2/crypto/CryptEccMain_fp.h @@ -167,6 +167,9 @@ BOOL BnEccGetPrivate( bigNum dOut, // OUT: the qualified random value const ECC_CURVE_DATA *C, // IN: curve for which the private key +#if USE_OPENSSL_FUNCTIONS_EC + const EC_GROUP *G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL +#endif // needs to be appropriate RAND_STATE *rand // IN: state for DRBG ); diff --git a/src/tpm2/crypto/openssl/CryptEccMain.c b/src/tpm2/crypto/openssl/CryptEccMain.c index e78a6e62..3cc78586 100644 --- a/src/tpm2/crypto/openssl/CryptEccMain.c +++ b/src/tpm2/crypto/openssl/CryptEccMain.c @@ -62,6 +62,8 @@ /* 10.2.12 CryptEccMain.c */ /* 10.2.12.1 Includes and Defines */ #include "Tpm.h" +#include "Helpers_fp.h" // libtpms added +#include "TpmToOsslMath_fp.h" // libtpms added #if ALG_ECC /* This version requires that the new format for ECC data be used */ #if !USE_BN_ECC_DATA @@ -543,6 +545,7 @@ BnPointMult( Random Value Meaning */ /* TRUE success */ /* FALSE failure generating private key */ +#if !USE_OPENSSL_FUNCTIONS_EC // libtpms added BOOL BnEccGetPrivate( bigNum dOut, // OUT: the qualified random value @@ -564,7 +567,34 @@ BnEccGetPrivate( OK = OK && BnAddWord(dOut, bnExtraBits, 1); return OK; } +#else // libtpms added begin +BOOL +BnEccGetPrivate( + bigNum dOut, // OUT: the qualified random value + const ECC_CURVE_DATA *C, // IN: curve for which the private key + const EC_GROUP *G, // IN: the EC_GROUP to use; must be != NULL for rand == NULL + // needs to be appropriate + RAND_STATE *rand // IN: state for DRBG + ) +{ + bigConst order = CurveGetOrder(C); + BOOL OK; + UINT32 orderBits = BnSizeInBits(order); + UINT32 orderBytes = BITS_TO_BYTES(orderBits); + BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64); + BN_VAR(nMinus1, MAX_ECC_KEY_BITS); + if (rand == NULL) + return OpenSSLEccGetPrivate(dOut, G); + + // + OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand); + OK = OK && BnSubWord(nMinus1, order, 1); + OK = OK && BnMod(bnExtraBits, nMinus1); + OK = OK && BnAddWord(dOut, bnExtraBits, 1); + return OK; +} +#endif // USE_OPENSSL_FUNCTIONS_EC libtpms added end /* 10.2.11.2.21 BnEccGenerateKeyPair() */ /* This function gets a private scalar from the source of random bits and does the point multiply to get the public key. */ @@ -578,7 +608,11 @@ BnEccGenerateKeyPair( { BOOL OK = FALSE; // Get a private scalar +#if USE_OPENSSL_FUNCTIONS_EC // libtpms added beging + OK = BnEccGetPrivate(bnD, AccessCurveData(E), E->G, rand); +#else // libtpms added end OK = BnEccGetPrivate(bnD, AccessCurveData(E), rand); +#endif // libtpms added // Do a point multiply OK = OK && BnEccModMult(ecQ, NULL, bnD, E); if(!OK) diff --git a/src/tpm2/crypto/openssl/CryptEccSignature.c b/src/tpm2/crypto/openssl/CryptEccSignature.c index 1ac6c546..b9003be5 100644 --- a/src/tpm2/crypto/openssl/CryptEccSignature.c +++ b/src/tpm2/crypto/openssl/CryptEccSignature.c @@ -302,7 +302,11 @@ BnSignEcdaa( { // generate nonceK such that 0 < nonceK < n // use bnT as a temp. +#if USE_OPENSSL_FUNCTIONS_EC // libtpms added begin + if(!BnEccGetPrivate(bnT, AccessCurveData(E), E->G, rand)) +#else // libtpms added end if(!BnEccGetPrivate(bnT, AccessCurveData(E), rand)) +#endif // libtpms added { retVal = TPM_RC_NO_RESULT; break; diff --git a/src/tpm2/crypto/openssl/Helpers.c b/src/tpm2/crypto/openssl/Helpers.c index b6889e4a..472123e3 100644 --- a/src/tpm2/crypto/openssl/Helpers.c +++ b/src/tpm2/crypto/openssl/Helpers.c @@ -60,6 +60,7 @@ #include "Tpm.h" #include "Helpers_fp.h" +#include "TpmToOsslMath_fp.h" #include @@ -179,3 +180,35 @@ evpfunc GetEVPCipher(TPM_ALG_ID algorithm, // IN } #endif // USE_OPENSSL_FUNCTIONS_SYMMETRIC + +#if USE_OPENSSL_FUNCTIONS_EC +BOOL +OpenSSLEccGetPrivate( + bigNum dOut, // OUT: the qualified random value + const EC_GROUP *G // IN: the EC_GROUP to use + ) +{ + BOOL OK = FALSE; + const BIGNUM *D; + EC_KEY *eckey = EC_KEY_new(); + + pAssert(G != NULL); + + if (!eckey) + return FALSE; + + if (EC_KEY_set_group(eckey, G) != 1) + goto Exit; + + if (EC_KEY_generate_key(eckey) == 1) { + OK = TRUE; + D = EC_KEY_get0_private_key(eckey); + OsslToTpmBn(dOut, D); + } + + Exit: + EC_KEY_free(eckey); + + return OK; +} +#endif // USE_OPENSSL_FUNCTIONS_EC diff --git a/src/tpm2/crypto/openssl/Helpers_fp.h b/src/tpm2/crypto/openssl/Helpers_fp.h index 0d2ff132..5e64d388 100644 --- a/src/tpm2/crypto/openssl/Helpers_fp.h +++ b/src/tpm2/crypto/openssl/Helpers_fp.h @@ -71,4 +71,11 @@ evpfunc GetEVPCipher(TPM_ALG_ID algorithm, // IN UINT16 *keyToUseLen // IN/OUT ); +#if USE_OPENSSL_FUNCTIONS_EC +BOOL OpenSSLEccGetPrivate( + bigNum dOut, // OUT: the qualified random value + const EC_GROUP *G // IN: the EC_GROUP to use + ); +#endif + #endif /* HELPERS_H */