]> git.proxmox.com Git - libtpms.git/commitdiff
Implement EC key generation using OpenSSL functions if rand == NULL
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Mon, 20 May 2019 14:04:59 +0000 (10:04 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Mon, 10 Jun 2019 15:19:58 +0000 (11:19 -0400)
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>
configure.ac
src/tpm2/crypto/CryptEccMain_fp.h
src/tpm2/crypto/openssl/CryptEccMain.c
src/tpm2/crypto/openssl/CryptEccSignature.c
src/tpm2/crypto/openssl/Helpers.c
src/tpm2/crypto/openssl/Helpers_fp.h

index ae95200d3a896d1d57bba6f7f95c1c652978ade2..ca9c97657d4f9af11b8eeb9b1318baf7c5ff4f4d 100644 (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]),
index f58411b1d18fff2af0a6722c948c7d7113e4fbd0..c14e9fc6170fe3581012be1d2e7456dbd75e2af7 100644 (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
                );
index e78a6e62a4709af0602d92d9824fd481bdc524e5..3cc78586238ab4021a946650d60c9be6c6a8774d 100644 (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)
index 1ac6c5469d77856bcf897a65043e08048bad7ee8..b9003be57f19620a52ace0d46fa774f232305b05 100644 (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;
index b6889e4a3879c538ddfb9f1f7cfc66426c0be06e..472123e3912ed093fe7147a55ad85af60c66ce73 100644 (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
index 0d2ff13227d8344e30523647395faefae84ec1fe..5e64d388d65a7b7ebcadbd504b9c01465c0c88c4 100644 (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 */