tpm2: Add BIGUM parameter to BigInitialized and use VERIFY in TpmToOsslMath.c

The original TPM 2 version of BIG_INITIALIZED uses a BIGNUM
on the stack and uses the internals of the BIGNUM's data structure
to initialize it. We don't do this here but use only the API
functions and therefor have tp free the BIGNMs create with
BIG_INITIALIZED().

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2019-11-17 15:43:57 -05:00 committed by Stefan Berger
parent e180ef05f7
commit 0be25cbb22
5 changed files with 161 additions and 140 deletions

View File

@ -224,7 +224,9 @@ BnSignEcdsa(
int retVal;
const BIGNUM *r;
const BIGNUM *s;
BIGNUM *d = BigInitialized(bnD);
BIGNUM *d = BN_new();
d = BigInitialized(d, bnD);
eckey = EC_KEY_new();
@ -688,10 +690,13 @@ BnValidateSignatureEcdsa(
int rc;
ECDSA_SIG *sig = NULL;
EC_KEY *eckey = NULL;
BIGNUM *r = BigInitialized(bnR);
BIGNUM *s = BigInitialized(bnS);
BIGNUM *r = BN_new();
BIGNUM *s = BN_new();
EC_POINT *q = EcPointInitialized(ecQ, E);
r = BigInitialized(r, bnR);
s = BigInitialized(s, bnS);
sig = ECDSA_SIG_new();
eckey = EC_KEY_new();

View File

@ -373,9 +373,9 @@ InitOpenSSLRSAPrivateKey(OBJECT *rsaKey, // IN
BIGNUM *Qr = NULL;
BIGNUM *D = NULL;
#if CRT_FORMAT_RSA == YES
BIGNUM *dP = NULL;
BIGNUM *dQ = NULL;
BIGNUM *qInv = NULL;
BIGNUM *dP = BN_new();
BIGNUM *dQ = BN_new();
BIGNUM *qInv = BN_new();
#endif
RSA *key;
BN_CTX *ctx = NULL;
@ -413,9 +413,9 @@ InitOpenSSLRSAPrivateKey(OBJECT *rsaKey, // IN
#if CRT_FORMAT_RSA == YES
/* CRT parameters are not absolutely needed but may speed up ops */
dP = BigInitialized((bigConst)&rsaKey->privateExponent.dP);
dQ = BigInitialized((bigConst)&rsaKey->privateExponent.dQ);
qInv = BigInitialized((bigConst)&rsaKey->privateExponent.qInv);
dP = BigInitialized(dP, (bigConst)&rsaKey->privateExponent.dP);
dQ = BigInitialized(dQ, (bigConst)&rsaKey->privateExponent.dQ);
qInv = BigInitialized(qInv, (bigConst)&rsaKey->privateExponent.qInv);
if (dP == NULL || dQ == NULL || qInv == NULL ||
RSA_set0_crt_params(key, dP, dQ, qInv) != 1)
ERROR_RETURN(TPM_RC_FAILURE);

View File

@ -128,18 +128,33 @@ OsslToTpmBn(
BnNewVariable(). */
BIGNUM *
BigInitialized(
BIGNUM *toInit,
bigConst initializer
)
{
BIGNUM *toInit = NULL;
#if 1 // libtpms added begin
BIGNUM *_toInit;
unsigned char buffer[LARGEST_NUMBER + 1];
NUMBYTES buffer_len = (NUMBYTES )sizeof(buffer);
if (initializer == NULL) {
#endif // libtpms added end
if(initializer == NULL)
FAIL(FATAL_ERROR_PARAMETER);
if(toInit == NULL || initializer == NULL)
return NULL;
}
#if 1 // libtpms added begin
BnToBytes(initializer, buffer, &buffer_len); /* TPM to bin */
toInit = BN_bin2bn(buffer, buffer_len, NULL); /* bin to ossl */
_toInit = BN_bin2bn(buffer, buffer_len, NULL); /* bin to ossl */
BN_copy(toInit, _toInit);
BN_clear_free(_toInit);
#else // libtpms added end
toInit->d = (BN_ULONG *)&initializer->d[0];
toInit->dmax = (int)initializer->allocated;
toInit->top = (int)initializer->size;
toInit->neg = 0;
toInit->flags = 0;
#endif
return toInit;
}
@ -193,7 +208,6 @@ void BIGNUM_print(
/* B.2.3.2.3.4. BnNewVariable() */
/* This function allocates a new variable in the provided context. If the context does not exist or
the allocation fails, it is a catastrophic failure. */
#if 0
static BIGNUM *
BnNewVariable(
BN_CTX *CTX
@ -207,7 +221,6 @@ BnNewVariable(
FAIL(FATAL_ERROR_ALLOCATION);
return new;
}
#endif
#if LIBRARY_COMPATIBILITY_CHECK
void
@ -252,26 +265,23 @@ BnModMult(
)
{
OSSL_ENTER();
BIG_INITIALIZED(bnResult, result);
BOOL OK = TRUE;
BIGNUM *bnResult = BN_NEW();
BIGNUM *bnTemp = BN_NEW();
BIG_INITIALIZED(bnOp1, op1);
BIG_INITIALIZED(bnOp2, op2);
BIG_INITIALIZED(bnMod, modulus);
BIG_VAR(bnTemp, (LARGEST_NUMBER_BITS * 4));
BOOL OK;
pAssert(BnGetAllocated(result) >= BnGetSize(modulus));
OK = BN_mul(bnTemp, bnOp1, bnOp2, CTX);
OK = OK && BN_div(NULL, bnResult, bnTemp, bnMod, CTX);
if(OK)
{
result->size = DIV_UP(BN_num_bytes(bnResult),
sizeof(crypt_uword_t));
OsslToTpmBn(result, bnResult);
}
BN_clear_free(bnTemp);
BN_clear_free(bnMod);
BN_clear_free(bnOp2);
BN_clear_free(bnOp1);
BN_clear_free(bnResult);
//
VERIFY(BN_mul(bnTemp, bnOp1, bnOp2, CTX));
VERIFY(BN_div(NULL, bnResult, bnTemp, bnMod, CTX));
VERIFY(OsslToTpmBn(result, bnResult));
goto Exit;
Error:
OK = FALSE;
Exit:
BN_clear_free(bnMod); // libtpms added
BN_clear_free(bnOp2); // libtpms added
BN_clear_free(bnOp1); // libtpms added
OSSL_LEAVE();
return OK;
}
@ -290,23 +300,19 @@ BnMult(
)
{
OSSL_ENTER();
BN_VAR(temp, (LARGEST_NUMBER_BITS * 2));
BIG_INITIALIZED(bnTemp, temp);
BIGNUM *bnTemp = BN_NEW();
BOOL OK = TRUE;
BIG_INITIALIZED(bnA, multiplicand);
BIG_INITIALIZED(bnB, multiplier);
BOOL OK;
pAssert(result->allocated >=
(BITS_TO_CRYPT_WORDS(BnSizeInBits(multiplicand)
+ BnSizeInBits(multiplier))));
OK = BN_mul(bnTemp, bnA, bnB, CTX);
if(OK)
{
OsslToTpmBn(temp, bnTemp);
BnCopy(result, temp);
}
BN_clear_free(bnB);
BN_clear_free(bnA);
BN_clear_free(bnTemp);
//
VERIFY(BN_mul(bnTemp, bnA, bnB, CTX));
VERIFY(OsslToTpmBn(result, bnTemp));
goto Exit;
Error:
OK = FALSE;
Exit:
BN_clear_free(bnB); // libtpms added
BN_clear_free(bnA); // libtpms added
OSSL_LEAVE();
return OK;
}
@ -327,43 +333,28 @@ BnDiv(
)
{
OSSL_ENTER();
BIG_INITIALIZED(bnQ, quotient);
BIG_INITIALIZED(bnR, remainder);
BIGNUM *bnQ = BN_NEW();
BIGNUM *bnR = BN_NEW();
BOOL OK = TRUE;
BIG_INITIALIZED(bnDend, dividend);
BIG_INITIALIZED(bnSor, divisor);
BOOL OK;
pAssert(!BnEqualZero(divisor));
if(BnGetSize(dividend) < BnGetSize(divisor))
{
if(quotient)
BnSetWord(quotient, 0);
if(remainder)
BnCopy(remainder, dividend);
OK = TRUE;
}
else
{
pAssert((quotient == NULL)
|| (quotient->allocated >= (unsigned)(dividend->size
- divisor->size)));
pAssert((remainder == NULL)
|| (remainder->allocated >= divisor->size));
OK = BN_div(bnQ, bnR, bnDend, bnSor, CTX);
if(OK)
{
OsslToTpmBn(quotient, bnQ);
OsslToTpmBn(remainder, bnR);
}
}
//
if(BnEqualZero(divisor))
FAIL(FATAL_ERROR_DIVIDE_ZERO);
VERIFY(BN_div(bnQ, bnR, bnDend, bnSor, CTX));
VERIFY(OsslToTpmBn(quotient, bnQ));
VERIFY(OsslToTpmBn(remainder, bnR));
DEBUG_PRINT("In BnDiv:\n");
BIGNUM_PRINT(" bnDividend: ", bnDend, TRUE);
BIGNUM_PRINT(" bnDivisor: ", bnSor, TRUE);
BIGNUM_PRINT(" bnQuotient: ", bnQ, TRUE);
BIGNUM_PRINT(" bnRemainder: ", bnR, TRUE);
BN_clear_free(bnSor);
BN_clear_free(bnDend);
BN_clear_free(bnR);
BN_clear_free(bnQ);
goto Exit;
Error:
OK = FALSE;
Exit:
BN_clear_free(bnSor); // libtpms added
BN_clear_free(bnDend); // libtpms added
OSSL_LEAVE();
return OK;
}
@ -383,20 +374,19 @@ BnGcd(
)
{
OSSL_ENTER();
BIG_INITIALIZED(bnGcd, gcd);
BIGNUM *bnGcd = BN_NEW();
BOOL OK = TRUE;
BIG_INITIALIZED(bn1, number1);
BIG_INITIALIZED(bn2, number2);
BOOL OK;
pAssert(gcd != NULL);
OK = BN_gcd(bnGcd, bn1, bn2, CTX);
if(OK)
{
OsslToTpmBn(gcd, bnGcd);
gcd->size = DIV_UP(BN_num_bytes(bnGcd), sizeof(crypt_uword_t));
}
BN_clear_free(bn2);
BN_clear_free(bn1);
BN_clear_free(bnGcd);
//
VERIFY(BN_gcd(bnGcd, bn1, bn2, CTX));
VERIFY(OsslToTpmBn(gcd, bnGcd));
goto Exit;
Error:
OK = FALSE;
Exit:
BN_clear_free(bn2); // libtpms added
BN_clear_free(bn1); // libtpms added
OSSL_LEAVE();
return OK;
}
@ -417,21 +407,21 @@ BnModExp(
)
{
OSSL_ENTER();
BIG_INITIALIZED(bnResult, result);
BIGNUM *bnResult = BN_NEW();
BOOL OK = TRUE;
BIG_INITIALIZED(bnN, number);
BIG_INITIALIZED(bnE, exponent);
BIG_INITIALIZED(bnM, modulus);
BOOL OK;
//
OK = BN_mod_exp(bnResult, bnN, bnE, bnM, CTX);
if(OK)
{
OsslToTpmBn(result, bnResult);
}
BN_clear_free(bnM);
BN_clear_free(bnE);
BN_clear_free(bnN);
BN_clear_free(bnResult);
VERIFY(BN_mod_exp(bnResult, bnN, bnE, bnM, CTX));
VERIFY(OsslToTpmBn(result, bnResult));
goto Exit;
Error:
OK = FALSE;
Exit:
BN_clear_free(bnM); // libtpms added
BN_clear_free(bnE); // libtpms added
BN_clear_free(bnN); // libtpms added
OSSL_LEAVE();
return OK;
}
@ -450,18 +440,19 @@ BnModInverse(
)
{
OSSL_ENTER();
BIG_INITIALIZED(bnResult, result);
BIGNUM *bnResult = BN_NEW();
BOOL OK = TRUE;
BIG_INITIALIZED(bnN, number);
BIG_INITIALIZED(bnM, modulus);
BOOL OK;
OK = (BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL);
if(OK)
{
OsslToTpmBn(result, bnResult);
}
BN_clear_free(bnM);
BN_clear_free(bnN);
BN_clear_free(bnResult);
//
VERIFY(BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL);
VERIFY(OsslToTpmBn(result, bnResult));
goto Exit;
Error:
OK = FALSE;
Exit:
BN_clear_free(bnM); // libtpms added
BN_clear_free(bnN); // libtpms added
OSSL_LEAVE();
return OK;
}
@ -517,19 +508,24 @@ EcPointInitialized(
bigCurve E
)
{
BIG_INITIALIZED(bnX, (initializer != NULL) ? initializer->x : NULL);
BIG_INITIALIZED(bnY, (initializer != NULL) ? initializer->y : NULL);
EC_POINT *P = (initializer != NULL && E != NULL)
? EC_POINT_new(E->G) : NULL;
pAssert(E != NULL);
if(P != NULL)
#if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10200000L
EC_POINT_set_affine_coordinates(E->G, P, bnX, bnY, E->CTX);
#else
EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX);
#endif
BN_clear_free(bnY);
BN_clear_free(bnX);
EC_POINT *P = NULL;
if(initializer != NULL)
{
BIG_INITIALIZED(bnX, initializer->x);
BIG_INITIALIZED(bnY, initializer->y);
if(E == NULL) // libtpms changed begin (check E before accessing)
FAIL(FATAL_ERROR_ALLOCATION);
P = EC_POINT_new(E->G); // libtpms changed end
#if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10200000L // libtpms added begin
if(!EC_POINT_set_affine_coordinates(E->G, P, bnX, bnY, E->CTX))
#else // libtpms added end
if(!EC_POINT_set_affine_coordinates_GFp(E->G, P, bnX, bnY, E->CTX))
#endif // libtpms added
P = NULL;
BN_clear_free(bnX); // libtpms added
BN_clear_free(bnY); // libtpms added
}
return P;
}
@ -625,7 +621,7 @@ BnEccModMult(
PointFromOssl(R, pR, E);
EC_POINT_clear_free(pR);
EC_POINT_clear_free(pS);
BN_clear_free(bnD);
BN_clear_free(bnD); // libtpms added
return !BnEqualZero(R->z);
}
@ -665,8 +661,9 @@ BnEccModMult2(
EC_POINT_clear_free(pR);
EC_POINT_clear_free(pS);
EC_POINT_clear_free(pQ);
BN_clear_free(bnD);
BN_clear_free(bnU);
BN_clear_free(bnD); // libtpms added
BN_clear_free(bnU); // libtpms added
return !BnEqualZero(R->z);
}

View File

@ -70,11 +70,24 @@
#define MATH_LIB_OSSL
#include <openssl/evp.h>
#include <openssl/ec.h>
#if 0
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#include <openssl/bn_lcl.h>
#endif
#endif
#if 0 // libtpms added
#if OPENSSL_VERSION_NUMBER >= 0x10200000L
// Check the bignum_st definition in crypto/bn/bn_lcl.h and either update the
// version check or provide the new definition for this version.
# error Untested OpenSSL version
#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
// from crypto/bn/bn_lcl.h
struct bignum_st {
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit
* chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
#endif // OPENSSL_VERSION_NUMBER
#endif // libtpms added
#include <openssl/bn.h>
#if USE_OPENSSL_FUNCTIONS_ECDSA // libtpms added begin
#include <openssl/ecdsa.h>
@ -93,18 +106,21 @@
# error Ossl library is using different radix
#endif
/* Allocate a local BIGNUM value. For the allocation, a bigNum structure is created as is a
local BIGNUM. The bigNum is initialized and then the BIGNUM is set to reference the local
value. */
/* Allocate a local BIGNUM value. For the allocation, a bigNum structure is created as is a local
BIGNUM. The bigNum is initialized and then the BIGNUM is set to reference the local value. */
#define BIG_VAR(name, bits) \
BN_VAR(name##Bn, (bits)); \
BIGNUM *name = BigInitialized(BnInit(name##Bn, \
BIGNUM *_##name = BN_new(); /* libtpms */ \
BIGNUM *name = BigInitialized(_##name, /* libtpms */ \
BnInit(name##Bn, \
BYTES_TO_CRYPT_WORDS(sizeof(_##name##Bn.d))))
/* Allocate a BIGNUM and initialize with the values in a bigNum initializer */
#define BIG_INITIALIZED(name, initializer) \
BIGNUM *name = BigInitialized(initializer)
BIGNUM *_##name = BN_new(); /* libtpms */ \
BIGNUM *name = BigInitialized(_##name, initializer) /* libtpms */
typedef struct
{

View File

@ -1,9 +1,9 @@
/********************************************************************************/
/* */
/* */
/* TPM to OpenSSL BigNum Shim Layer */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: TpmToOsslMath_fp.h 1108 2017-12-12 19:07:15Z kgoldman $ */
/* $Id: TpmToOsslMath_fp.h 1519 2019-11-15 20:43:51Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,13 +55,15 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 */
/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
/* */
/********************************************************************************/
#ifndef TPMTOOSSLMATH_FP_H
#define TPMTOOSSLMATH_FP_H
#include <openssl/bn.h>
BOOL
OsslToTpmBn(
bigNum bn,
@ -69,6 +71,7 @@ OsslToTpmBn(
);
BIGNUM *
BigInitialized(
BIGNUM *toInit,
bigConst initializer
);
// libtpms added begin