Implement EC key generation using OpenSSL functions if rand == NULL

Use OpenSSL functions to create EC keys only for the case that
rand == NULL in which case no KDF is being used and where we can
create a truly random key. This doesn't break the upgrade path.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2019-05-20 10:04:59 -04:00 committed by Stefan Berger
parent d175ee918b
commit afbb327423
6 changed files with 92 additions and 0 deletions

View File

@ -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]),

View File

@ -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
);

View File

@ -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)

View File

@ -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;

View File

@ -60,6 +60,7 @@
#include "Tpm.h"
#include "Helpers_fp.h"
#include "TpmToOsslMath_fp.h"
#include <openssl/evp.h>
@ -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

View File

@ -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 */