rev180: Convert rest of CrytpRsa.c to use Crypt_Int*

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2023-12-15 23:30:17 -05:00 committed by Stefan Berger
parent e703875190
commit 4fc596a724
6 changed files with 235 additions and 131 deletions

View File

@ -116,6 +116,8 @@ LIB_EXPORT Crypt_Int* ExtMath_IntFromBytes(
// Convert Crypt_Int into external format as a byte array.
LIB_EXPORT BOOL ExtMath_IntToBytes(
const Crypt_Int* value, BYTE* output, NUMBYTES* pByteCount);
// Set Crypt_Int to a given small value. Words are native format.
LIB_EXPORT Crypt_Int* ExtMath_SetWord(Crypt_Int* buffer, crypt_uword_t word);
// #################
// Copy Functions
@ -130,6 +132,10 @@ LIB_EXPORT BOOL ExtMath_Copy(Crypt_Int* out, const Crypt_Int* in);
// Ordinary Arithmetic, writ large
// ###############################
//** ExtMath_Multiply()
// Multiplies two numbers and returns the result
LIB_EXPORT BOOL ExtMath_Multiply(
Crypt_Int* result, const Crypt_Int* multiplicand, const Crypt_Int* multiplier);
//** ExtMath_Divide()
// This function divides two Crypt_Int* values. The function returns FALSE if there is
@ -140,11 +146,23 @@ LIB_EXPORT BOOL ExtMath_Divide(Crypt_Int* quotient,
const Crypt_Int* dividend,
const Crypt_Int* divisor);
//*** ExtMath_Add()
// This function adds two Crypt_Int* values. This function always returns TRUE.
LIB_EXPORT BOOL ExtMath_Add(
Crypt_Int* result, const Crypt_Int* op1, const Crypt_Int* op2);
//*** ExtMath_AddWord()
// This function adds a word value to a Crypt_Int*. This function always returns TRUE.
LIB_EXPORT BOOL ExtMath_AddWord(
Crypt_Int* result, const Crypt_Int* op, crypt_uword_t word);
//*** ExtMath_Subtract()
// This function does subtraction of two Crypt_Int* values and returns result = op1 - op2
// when op1 is greater than op2. If op2 is greater than op1, then a fault is
// generated. This function always returns TRUE.
LIB_EXPORT BOOL ExtMath_Subtract(
Crypt_Int* result, const Crypt_Int* op1, const Crypt_Int* op2);
//*** ExtMath_SubtractWord()
// This function subtracts a word value from a Crypt_Int*. This function always
// returns TRUE.
@ -161,6 +179,7 @@ LIB_EXPORT BOOL ExtMath_ModMult(Crypt_Int* result,
const Crypt_Int* op1,
const Crypt_Int* op2,
const Crypt_Int* modulus);
//** ExtMath_ModExp()
// Compute result = (number ^ exponent) mod modulus
// where ^ indicates exponentiation.
@ -170,6 +189,13 @@ LIB_EXPORT BOOL ExtMath_ModExp(Crypt_Int* result,
const Crypt_Int* exponent,
const Crypt_Int* modulus);
//** ExtMath_ModInverse()
// Compute the modular multiplicative inverse.
// result = (number ^ -1) mod modulus
// This function is only needed when the TPM implements RSA.
LIB_EXPORT BOOL ExtMath_ModInverse(
Crypt_Int* result, const Crypt_Int* number, const Crypt_Int* modulus);
//*** ExtMath_ModWord()
// compute numerator
// This function does modular division of a big number when the modulus is a
@ -204,6 +230,22 @@ LIB_EXPORT int ExtMath_UnsignedCmpWord(const Crypt_Int* op1, crypt_uword_t word)
// Return Type: BOOL
LIB_EXPORT BOOL ExtMath_IsEqualWord(const Crypt_Int* bn, crypt_uword_t word);
//*** ExtMath_IsZero()
// Compare a Crypt_Int* to zero, expected to be O(1) time.
// Return Type: BOOL
LIB_EXPORT BOOL ExtMath_IsZero(const Crypt_Int* op1);
//*** ExtMath_MostSigBitNum()
//
// This function returns the zero-based number of the MSb (Most significant bit)
// of a Crypt_Int* value.
//
// Return Type: int
//
// -1 the word was zero or 'bn' was NULL
// n the bit number of the most significant bit in the word
LIB_EXPORT int ExtMath_MostSigBitNum(const Crypt_Int* bn);
//*** ExtMath_GetLeastSignificant32bits()
//
// This function returns the least significant 32-bits of an integer value

View File

@ -77,6 +77,10 @@
// therefore we typedef here to a size 1 (smallest possible).
typedef CRYPT_INT_BUF(one, 1) Crypt_Int;
// produces bare typedef ci_<typename>_t
#define CRYPT_INT_TYPE(typename, bits) \
typedef CRYPT_INT_BUF(ci_##typename##_buf_t, bits) ci_##typename##_t
// produces allocated `Crypt_Int* varname` backed by a
// stack buffer named `<varname>_buf`. Initialization at the discretion of the
// ExtMath library.
@ -99,5 +103,8 @@ typedef CRYPT_INT_BUF(one, 1) Crypt_Int;
#define CRYPT_INT_MAX_INITIALIZED(name, initializer) \
CRYPT_INT_INITIALIZED(name, LARGEST_NUMBER_BITS, initializer)
// A single RADIX_BITS value.
#define CRYPT_INT_WORD(name) CRYPT_INT_VAR(name, RADIX_BITS)
#endif //MATH_LIBRARY_INTERFACE_TYPES_H

View File

@ -113,6 +113,10 @@ LIB_EXPORT BOOL ExtMath_IntToBytes(
return BnToBytes((bigConst)value, output, pByteCount);
}
LIB_EXPORT Crypt_Int* ExtMath_SetWord(Crypt_Int* n, crypt_uword_t w)
{
return (Crypt_Int*)BnSetWord((bigNum)n, w);
}
// #################
// Copy Functions
// #################
@ -125,6 +129,14 @@ LIB_EXPORT BOOL ExtMath_Copy(Crypt_Int* out, const Crypt_Int* in)
// Ordinary Arithmetic, writ large
// ###############################
//** ExtMath_Multiply()
// Multiplies two numbers and returns the result
LIB_EXPORT BOOL ExtMath_Multiply(
Crypt_Int* result, const Crypt_Int* multiplicand, const Crypt_Int* multiplier)
{
return BnMult((bigNum)result, (bigConst)multiplicand, (bigConst)multiplier);
}
//** ExtMath_Divide()
// This function divides two Crypt_Int* values. The function returns FALSE if there is
// an error in the operation. Quotient may be null, in which case this function returns
@ -138,6 +150,14 @@ LIB_EXPORT BOOL ExtMath_Divide(Crypt_Int* quotient,
(bigNum)quotient, (bigNum)remainder, (bigConst)dividend, (bigConst)divisor);
}
//*** ExtMath_Add()
// This function adds two Crypt_Int* values. This function always returns TRUE.
LIB_EXPORT BOOL ExtMath_Add(
Crypt_Int* result, const Crypt_Int* op1, const Crypt_Int* op2)
{
return BnAdd((bigNum)result, (bigConst)op1, (bigConst)op2);
}
//*** ExtMath_AddWord()
// This function adds a word value to a Crypt_Int*. This function always returns TRUE.
LIB_EXPORT BOOL ExtMath_AddWord(
@ -146,6 +166,16 @@ LIB_EXPORT BOOL ExtMath_AddWord(
return BnAddWord((bigNum)result, (bigConst)op, word);
}
//*** ExtMath_Subtract()
// This function does subtraction of two Crypt_Int* values and returns result = op1 - op2
// when op1 is greater than op2. If op2 is greater than op1, then a fault is
// generated. This function always returns TRUE.
LIB_EXPORT BOOL ExtMath_Subtract(
Crypt_Int* result, const Crypt_Int* op1, const Crypt_Int* op2)
{
return BnSub((bigNum)result, (bigConst)op1, (bigConst)op2);
}
//*** ExtMath_SubtractWord()
// This function subtracts a word value from a Crypt_Int*. This function always
// returns TRUE.
@ -184,6 +214,14 @@ LIB_EXPORT BOOL ExtMath_ModExp(Crypt_Int* result,
}
#endif // ALG_RSA
//** ExtMath_ModInverse()
// Modular multiplicative inverse.
LIB_EXPORT BOOL ExtMath_ModInverse(
Crypt_Int* result, const Crypt_Int* number, const Crypt_Int* modulus)
{
return BnModInverse((bigNum)result, (bigConst)number, (bigConst)modulus);
}
//*** ExtMath_ModWord()
// This function does modular division of a big number when the modulus is a
// word value.
@ -226,6 +264,21 @@ LIB_EXPORT BOOL ExtMath_IsEqualWord(const Crypt_Int* bn, crypt_uword_t word)
return BnEqualWord((bigConst)bn, word);
}
LIB_EXPORT BOOL ExtMath_IsZero(const Crypt_Int* op1)
{
return BnEqualZero((bigConst)op1);
}
//*** ExtMath_MostSigBitNum()
// This function returns the number of the MSb of a Crypt_Int* value.
// Return Type: int
// -1 the word was zero or 'bn' was NULL
// n the bit number of the most significant bit in the word
LIB_EXPORT int ExtMath_MostSigBitNum(const Crypt_Int* bn)
{
return BnMsb((bigConst)bn);
}
LIB_EXPORT uint32_t ExtMath_GetLeastSignificant32bits(const Crypt_Int* bn)
{
MUST_BE(RADIX_BITS >= 32);

View File

@ -64,14 +64,15 @@
#define _CRYPT_RSA_H
// These values are used in the Crypt_Int* representation of various RSA values.
// define ci_rsa_t as buffer containing a CRYPT_INT object with space for
// (MAX_RSA_KEY_BITS) of actual data.
CRYPT_INT_TYPE(rsa, MAX_RSA_KEY_BITS);
#define CRYPT_RSA_VAR(name) CRYPT_INT_VAR(name, MAX_RSA_KEY_BITS)
#define CRYPT_RSA_INITIALIZED(name, initializer) \
CRYPT_INT_INITIALIZED(name, MAX_RSA_KEY_BITS, initializer)
#define CRYPT_PRIME_VAR(name) CRYPT_INT_VAR(name, (MAX_RSA_KEY_BITS / 2))
BN_TYPE(rsa, MAX_RSA_KEY_BITS);
#define BN_RSA(name) BN_VAR(name, MAX_RSA_KEY_BITS)
#define BN_RSA_INITIALIZED(name, initializer) \
BN_INITIALIZED(name, MAX_RSA_KEY_BITS, initializer)
#define BN_PRIME(name) BN_VAR(name, (MAX_RSA_KEY_BITS / 2))
BN_TYPE(prime, (MAX_RSA_KEY_BITS / 2));
#define BN_PRIME_INITIALIZED(name, initializer) \
@ -83,12 +84,12 @@ BN_TYPE(prime, (MAX_RSA_KEY_BITS / 2));
typedef struct privateExponent
{
bigNum P;
bigNum Q;
bigNum dP;
bigNum dQ;
bigNum qInv;
bn_prime_t entries[5];
Crypt_Int* P;
Crypt_Int* Q;
Crypt_Int* dP;
Crypt_Int* dQ;
Crypt_Int* qInv;
bn_prime_t entries[5];
} privateExponent;
#define NEW_PRIVATE_EXPONENT(X) \
@ -130,9 +131,9 @@ RsaSetExponentOld(
)
{
// pExp->Q must be set elsewhere
BnCopy((bigNum)&pExp->dP, Z->dP);
BnCopy((bigNum)&pExp->dQ, Z->dQ);
BnCopy((bigNum)&pExp->qInv, Z->qInv);
ExtMath_Copy((Crypt_Int*)&pExp->dP, Z->dP);
ExtMath_Copy((Crypt_Int*)&pExp->dQ, Z->dQ);
ExtMath_Copy((Crypt_Int*)&pExp->qInv, Z->qInv);
}
static inline void
@ -141,10 +142,10 @@ RsaSetExponentFromOld(
privateExponent_t *pExp // IN
)
{
BnCopy(Z->Q, (bigNum)&pExp->Q);
BnCopy(Z->dP, (bigNum)&pExp->dP);
BnCopy(Z->dQ, (bigNum)&pExp->dQ);
BnCopy(Z->qInv, (bigNum)&pExp->qInv);
ExtMath_Copy(Z->Q, (Crypt_Int*)&pExp->Q);
ExtMath_Copy(Z->dP, (Crypt_Int*)&pExp->dP);
ExtMath_Copy(Z->dQ, (Crypt_Int*)&pExp->dQ);
ExtMath_Copy(Z->qInv, (Crypt_Int*)&pExp->qInv);
}
#endif // _CRYPT_RSA_H

View File

@ -68,6 +68,7 @@
// Need this define to get the 'private' defines for this function
#define CRYPT_RSA_C
#include "Tpm.h"
#include "TpmMath_Util_fp.h"
#include "Helpers_fp.h" // libtpms added
#include <assert.h> // libtpms added
@ -100,13 +101,17 @@ BOOL CryptRsaStartup(void)
static privateExponent* RsaInitializeExponent(privateExponent* Z)
{
bigNum *bn = (bigNum *)&Z->P;
int i;
// verify privateExponent packing matches the usage of the bn pointer as an
// array in below function
MUST_BE(offsetof(privateExponent, Q) == SIZEOF_MEMBER(privateExponent, P));
Crypt_Int** bn = (Crypt_Int**)&Z->P;
int i;
//
for(i = 0; i < 5; i++)
{
bn[i] = (bigNum)&Z->entries[i];
BnInit(bn[i], BYTES_TO_CRYPT_WORDS(sizeof(Z->entries[0].d)));
bn[i] = (Crypt_Int*)&(Z->entries[i]);
ExtMath_Initialize_Int(bn[i], MAX_RSA_KEY_BITS / 2);
}
return Z;
}
@ -115,11 +120,11 @@ static privateExponent* RsaInitializeExponent(privateExponent* Z)
// This function swaps the pointers for P and Q if Q happens to be larger than Q.
static void MakePgreaterThanQ(privateExponent* Z)
{
if(BnUnsignedCmp(Z->P, Z->Q) < 0)
if(ExtMath_UnsignedCmp(Z->P, Z->Q) < 0)
{
bigNum bnT = Z->P;
Z->P = Z->Q;
Z->Q = bnT;
Crypt_Int* bnT = Z->P;
Z->P = Z->Q;
Z->Q = bnT;
}
}
@ -139,13 +144,14 @@ static void MakePgreaterThanQ(privateExponent* Z)
static BOOL PackExponent(TPM2B_PRIVATE_KEY_RSA* packed, privateExponent* Z)
{
int i;
UINT16 primeSize = (UINT16)BITS_TO_BYTES(BnMsb(Z->P));
UINT16 primeSize = (UINT16)BITS_TO_BYTES(ExtMath_MostSigBitNum(Z->P));
UINT16 pS = primeSize;
//
pAssert((primeSize * 5) <= sizeof(packed->t.buffer));
packed->t.size = (primeSize * 5) + RSA_prime_flag;
for(i = 0; i < 5; i++)
if(!BnToBytes((bigNum)&Z->entries[i], &packed->t.buffer[primeSize * i], &pS))
if(!ExtMath_IntToBytes(
(Crypt_Int*)&Z->entries[i], &packed->t.buffer[primeSize * i], &pS))
return FALSE;
if(pS != primeSize)
return FALSE;
@ -160,16 +166,17 @@ static BOOL PackExponent(TPM2B_PRIVATE_KEY_RSA* packed, privateExponent* Z)
// FALSE(0) TPM2B is not the correct size
static BOOL UnpackExponent(TPM2B_PRIVATE_KEY_RSA* b, privateExponent* Z)
{
UINT16 primeSize = b->t.size & ~RSA_prime_flag;
int i;
bigNum *bn = &Z->P;
UINT16 primeSize = b->t.size & ~RSA_prime_flag;
int i;
Crypt_Int** bn = &Z->P;
//
GOTO_ERROR_UNLESS(b->t.size & RSA_prime_flag);
RsaInitializeExponent(Z);
GOTO_ERROR_UNLESS((primeSize % 5) == 0);
primeSize /= 5;
for(i = 0; i < 5; i++)
GOTO_ERROR_UNLESS(BnFromBytes(bn[i], &b->t.buffer[primeSize * i], primeSize)
GOTO_ERROR_UNLESS(
ExtMath_IntFromBytes(bn[i], &b->t.buffer[primeSize * i], primeSize)
!= NULL);
MakePgreaterThanQ(Z);
return TRUE;
@ -178,71 +185,68 @@ static BOOL UnpackExponent(TPM2B_PRIVATE_KEY_RSA* b, privateExponent* Z)
}
#endif // libtpms added
/* 10.2.17.4.5 ComputePrivateExponent() */
/* This function computes the private exponent from the primes. */
/* Return Value Meaning */
/* TRUE(1) success */
/* FALSE(0) failure */
static BOOL
ComputePrivateExponent(
bigNum pubExp, // IN: the public exponent
privateExponent *Z // IN/OUT: on input, has primes P and Q. On
// output, has P, Q, dP, dQ, and pInv
)
//*** ComputePrivateExponent()
// This function computes the private exponent from the primes.
// Return Type: BOOL
// TRUE(1) success
// FALSE(0) failure
static BOOL ComputePrivateExponent(
Crypt_Int* pubExp, // IN: the public exponent
privateExponent* Z // IN/OUT: on input, has primes P and Q. On
// output, has P, Q, dP, dQ, and pInv
)
{
BOOL pOK;
BOOL qOK;
BN_PRIME(pT);
CRYPT_PRIME_VAR(pT);
//
// make p the larger value so that m2 is always less than p
MakePgreaterThanQ(Z);
//dP = (1/e) mod (p-1)
pOK = BnSubWord(pT, Z->P, 1);
pOK = pOK && BnModInverse(Z->dP, pubExp, pT);
pOK = ExtMath_SubtractWord(pT, Z->P, 1);
pOK = pOK && ExtMath_ModInverse(Z->dP, pubExp, pT);
//dQ = (1/e) mod (q-1)
qOK = BnSubWord(pT, Z->Q, 1);
qOK = qOK && BnModInverse(Z->dQ, pubExp, pT);
qOK = ExtMath_SubtractWord(pT, Z->Q, 1);
qOK = qOK && ExtMath_ModInverse(Z->dQ, pubExp, pT);
// qInv = (1/q) mod p
if(pOK && qOK)
pOK = qOK = BnModInverse(Z->qInv, Z->Q, Z->P);
pOK = qOK = ExtMath_ModInverse(Z->qInv, Z->Q, Z->P);
if(!pOK)
BnSetWord(Z->P, 0);
ExtMath_SetWord(Z->P, 0);
if(!qOK)
BnSetWord(Z->Q, 0);
ExtMath_SetWord(Z->Q, 0);
return pOK && qOK;
}
/* 10.2.17.4.6 RsaPrivateKeyOp() */
/* This function is called to do the exponentiation with the private key. Compile options allow use
of the simple (but slow) private exponent, or the more complex but faster CRT method. */
/* Return Value Meaning */
/* TRUE(1) success */
/* FALSE(0) failure */
static BOOL
RsaPrivateKeyOp(
bigNum inOut, // IN/OUT: number to be exponentiated
privateExponent *Z
)
//*** RsaPrivateKeyOp()
// This function is called to do the exponentiation with the private key. Compile
// options allow use of the simple (but slow) private exponent, or the more complex
// but faster CRT method.
// Return Type: BOOL
// TRUE(1) success
// FALSE(0) failure
static BOOL RsaPrivateKeyOp(Crypt_Int* inOut, // IN/OUT: number to be exponentiated
privateExponent* Z)
{
BN_RSA(M1);
BN_RSA(M2);
BN_RSA(M);
BN_RSA(H);
CRYPT_RSA_VAR(M1);
CRYPT_RSA_VAR(M2);
CRYPT_RSA_VAR(M);
CRYPT_RSA_VAR(H);
//
MakePgreaterThanQ(Z);
// m1 = cdP mod p
GOTO_ERROR_UNLESS(BnModExp(M1, inOut, Z->dP, Z->P));
GOTO_ERROR_UNLESS(ExtMath_ModExp(M1, inOut, Z->dP, Z->P));
// m2 = cdQ mod q
GOTO_ERROR_UNLESS(BnModExp(M2, inOut, Z->dQ, Z->Q));
GOTO_ERROR_UNLESS(ExtMath_ModExp(M2, inOut, Z->dQ, Z->Q));
// h = qInv * (m1 - m2) mod p = qInv * (m1 + P - m2) mod P because Q < P
// so m2 < P
GOTO_ERROR_UNLESS(BnSub(H, Z->P, M2));
GOTO_ERROR_UNLESS(BnAdd(H, H, M1));
GOTO_ERROR_UNLESS(BnModMult(H, H, Z->qInv, Z->P));
GOTO_ERROR_UNLESS(ExtMath_Subtract(H, Z->P, M2));
GOTO_ERROR_UNLESS(ExtMath_Add(H, H, M1));
GOTO_ERROR_UNLESS(ExtMath_ModMult(H, H, Z->qInv, Z->P));
// m = m2 + h * q
GOTO_ERROR_UNLESS(BnMult(M, H, Z->Q));
GOTO_ERROR_UNLESS(BnAdd(inOut, M2, M));
GOTO_ERROR_UNLESS(ExtMath_Multiply(M, H, Z->Q));
GOTO_ERROR_UNLESS(ExtMath_Add(inOut, M2, M));
return TRUE;
Error:
return FALSE;
@ -299,7 +303,7 @@ static TPM_RC RSADP(TPM2B* inOut, // IN/OUT: the value to encrypt
OBJECT* key // IN: the key
)
{
BN_RSA_INITIALIZED(bnM, inOut);
CRYPT_RSA_INITIALIZED(bnM, inOut);
NEW_PRIVATE_EXPONENT(Z);
if(UnsignedCompareB(inOut->size,
inOut->buffer,
@ -317,11 +321,11 @@ static TPM_RC RSADP(TPM2B* inOut, // IN/OUT: the value to encrypt
!= TPM_RC_SUCCESS)
return TPM_RC_BINDING;
}
GOTO_ERROR_UNLESS(BnFrom2B(Z->P, &key->sensitive.sensitive.rsa.b) != NULL);
GOTO_ERROR_UNLESS(TpmMath_IntFrom2B(Z->P, &key->sensitive.sensitive.rsa.b) != NULL);
RsaSetExponentFromOld(Z, &key->privateExponent);
// GOTO_ERROR_UNLESS(UnpackExponent(&key->sensitive.sensitive.rsa, Z)); // libtpms changed end
GOTO_ERROR_UNLESS(RsaPrivateKeyOp(bnM, Z));
GOTO_ERROR_UNLESS(BnTo2B(bnM, inOut, inOut->size));
GOTO_ERROR_UNLESS(TpmMath_IntTo2B(bnM, inOut, inOut->size));
return TPM_RC_SUCCESS;
Error:
return TPM_RC_FAILURE;
@ -385,9 +389,6 @@ static TPM_RC OaepEncode(
// The total size of db = hLen + pad + mSize;
dbSize = hLen + padLen + message->size;
// If testing, then use the provided seed. Otherwise, use values
// from the RNG
CryptRandomGenerate(hLen, mySeed);
DRBG_Generate(rand, mySeed, (UINT16)hLen);
if(g_inFailureMode)
ERROR_EXIT(TPM_RC_FAILURE);
@ -997,8 +998,7 @@ TPMT_RSA_DECRYPT* CryptRsaSelectScheme(
// Return Type: TPM_RC
// TPM_RC_BINDING public and private parts of 'rsaKey' are not matched
TPM_RC
CryptRsaLoadPrivateExponent(TPMT_PUBLIC *publicArea,
TPMT_SENSITIVE *sensitive,
CryptRsaLoadPrivateExponent(TPMT_PUBLIC* publicArea, TPMT_SENSITIVE* sensitive,
OBJECT *rsaKey // libtpms added: Should only be NULL
// in case this function is called for parameter 'testing', such as by
// TPM2_Import() -> ObjectLoad().
@ -1009,30 +1009,31 @@ CryptRsaLoadPrivateExponent(TPMT_PUBLIC *publicArea,
if((sensitive->sensitive.rsa.t.size * 2) == publicArea->unique.rsa.t.size)
{
NEW_PRIVATE_EXPONENT(Z);
BN_RSA_INITIALIZED(bnN, &publicArea->unique.rsa);
BN_RSA(bnQr);
BN_VAR(bnE, RADIX_BITS);
CRYPT_RSA_INITIALIZED(bnN, &publicArea->unique.rsa);
CRYPT_RSA_VAR(bnQr);
CRYPT_INT_VAR(bnE, RADIX_BITS);
TEST(TPM_ALG_NULL);
GOTO_ERROR_UNLESS((sensitive->sensitive.rsa.t.size * 2)
== publicArea->unique.rsa.t.size);
// Initialize the exponent
BnSetWord(bnE, publicArea->parameters.rsaDetail.exponent);
if(BnEqualZero(bnE))
BnSetWord(bnE, RSA_DEFAULT_PUBLIC_EXPONENT);
ExtMath_SetWord(bnE, publicArea->parameters.rsaDetail.exponent);
if(ExtMath_IsZero(bnE))
ExtMath_SetWord(bnE, RSA_DEFAULT_PUBLIC_EXPONENT);
// Convert first prime to 2B
GOTO_ERROR_UNLESS(BnFrom2B(Z->P, &sensitive->sensitive.rsa.b) != NULL);
GOTO_ERROR_UNLESS(
TpmMath_IntFrom2B(Z->P, &sensitive->sensitive.rsa.b) != NULL);
// Find the second prime by division. This uses 'bQ' rather than Z->Q
// because the division could make the quotient larger than a prime during
// some intermediate step.
GOTO_ERROR_UNLESS(BnDiv(Z->Q, bnQr, bnN, Z->P));
GOTO_ERROR_UNLESS(BnEqualZero(bnQr));
GOTO_ERROR_UNLESS(ExtMath_Divide(Z->Q, bnQr, bnN, Z->P));
GOTO_ERROR_UNLESS(ExtMath_IsZero(bnQr));
// Compute the private exponent and return it if found
if (rsaKey) { // libtpms added begin
RsaInitializeExponentOld(&rsaKey->privateExponent);
BnCopy((bigNum)&rsaKey->privateExponent.Q, Z->Q); // preserve Q
ExtMath_Copy((Crypt_Int *)&rsaKey->privateExponent.Q, Z->Q); // preserve Q
} // libtpms added end
GOTO_ERROR_UNLESS(ComputePrivateExponent(bnE, Z));
// GOTO_ERROR_UNLESS(PackExponent(&sensitive->sensitive.rsa, Z)); // libtpms: never pack/unpack
@ -1316,9 +1317,10 @@ LIB_EXPORT TPM_RC CryptRsaValidateSignature(
# if SIMULATION && USE_RSA_KEY_CACHE
extern int s_rsaKeyCacheEnabled;
int GetCachedRsaKey(OBJECT *key, RAND_STATE *rand);
# define GET_CACHED_KEY(key, rand) \
(s_rsaKeyCacheEnabled && GetCachedRsaKey(key, rand))
int GetCachedRsaKey(
TPMT_PUBLIC* publicArea, TPMT_SENSITIVE* sensitive, RAND_STATE* rand);
# define GET_CACHED_KEY(publicArea, sensitive, rand) \
(s_rsaKeyCacheEnabled && GetCachedRsaKey(publicArea, sensitive, rand))
# else
# define GET_CACHED_KEY(key, rand)
# endif
@ -1365,15 +1367,15 @@ LIB_EXPORT TPM_RC CryptRsaGenerateKey(
)
{
UINT32 i;
BN_RSA(bnD);
BN_RSA(bnN);
BN_WORD(bnPubExp);
CRYPT_RSA_VAR(bnD);
CRYPT_RSA_VAR(bnN);
CRYPT_INT_WORD(bnPubExp);
UINT32 e = publicArea->parameters.rsaDetail.exponent;
int keySizeInBits;
TPM_RC retVal = TPM_RC_NO_RESULT;
NEW_PRIVATE_EXPONENT(Z);
//
pAssert(BnEqualZero(Z->Q)); // libtpms added: Z->Q must be Zero
pAssert(ExtMath_IsZero(Z->Q)); // libtpms added: Z->Q must be Zero
pAssert(publicArea == &rsaKey->publicArea && sensitive == &rsaKey->sensitive); // libtpms added: consistency check
// Need to make sure that the caller did not specify an exponent that is
@ -1389,7 +1391,7 @@ LIB_EXPORT TPM_RC CryptRsaGenerateKey(
if(!IsPrimeInt(e))
ERROR_EXIT(TPM_RC_RANGE);
}
BnSetWord(bnPubExp, e);
ExtMath_SetWord(bnPubExp, e);
// check for supported key size.
keySizeInBits = publicArea->parameters.rsaDetail.keyBits;
@ -1428,7 +1430,7 @@ LIB_EXPORT TPM_RC CryptRsaGenerateKey(
if(_plat__IsCanceled())
ERROR_EXIT(TPM_RC_CANCELED);
if(TpmRsa_GeneratePrimeForRSA((Crypt_Int*)Z->P, keySizeInBits / 2, e, rand)
if(TpmRsa_GeneratePrimeForRSA(Z->P, keySizeInBits / 2, e, rand)
== TPM_RC_FAILURE)
{
retVal = TPM_RC_FAILURE;
@ -1439,25 +1441,25 @@ LIB_EXPORT TPM_RC CryptRsaGenerateKey(
// If this is the second prime, make sure that it differs from the
// first prime by at least 2^100
if(BnEqualZero(Z->Q))
if(ExtMath_IsZero(Z->Q))
{
// copy p to q and compute another prime in p
BnCopy(Z->Q, Z->P);
ExtMath_Copy(Z->Q, Z->P);
continue;
}
// Make sure that the difference is at least 100 bits. Need to do it this
// way because the big numbers are only positive values
if(BnUnsignedCmp(Z->P, Z->Q) < 0)
BnSub(bnD, Z->Q, Z->P);
if(ExtMath_UnsignedCmp(Z->P, Z->Q) < 0)
ExtMath_Subtract(bnD, Z->Q, Z->P);
else
BnSub(bnD, Z->P, Z->Q);
if(BnMsb(bnD) < 100)
ExtMath_Subtract(bnD, Z->P, Z->Q);
if(ExtMath_MostSigBitNum(bnD) < 100)
continue;
//Form the public modulus and set the unique value
BnMult(bnN, Z->P, Z->Q);
BnTo2B(bnN, &publicArea->unique.rsa.b,
(NUMBYTES)BITS_TO_BYTES(keySizeInBits));
ExtMath_Multiply(bnN, Z->P, Z->Q);
TpmMath_IntTo2B(
bnN, &publicArea->unique.rsa.b, (NUMBYTES)BITS_TO_BYTES(keySizeInBits));
// Make sure everything came out right. The MSb of the values must be one
if(((publicArea->unique.rsa.t.buffer[0] & 0x80) == 0)
|| (publicArea->unique.rsa.t.size
@ -1465,25 +1467,24 @@ LIB_EXPORT TPM_RC CryptRsaGenerateKey(
FAIL(FATAL_ERROR_INTERNAL);
// Add the prime to the sensitive area // libtpms added begin
BnTo2B(Z->P, &sensitive->sensitive.rsa.b,
(NUMBYTES)BITS_TO_BYTES(keySizeInBits) / 2); // libtpms added end
TpmMath_IntTo2B(Z->P, &sensitive->sensitive.rsa.b,
(NUMBYTES)BITS_TO_BYTES(keySizeInBits) / 2); // libtpms added end
BnCopy((bigNum)&rsaKey->privateExponent.Q, Z->Q); // libtpms added: preserve Q
ExtMath_Copy((Crypt_Int*)&rsaKey->privateExponent.Q, Z->Q); // libtpms added: preserve Q
// Make sure that we can form the private exponent values
if(ComputePrivateExponent(bnPubExp, Z) != TRUE)
{
// If ComputePrivateExponent could not find an inverse for
// Q, then copy P and recompute P. This might
// cause both to be recomputed if P is also zero
if(BnEqualZero(Z->Q))
BnCopy(Z->Q, Z->P);
if(ExtMath_IsZero(Z->Q))
ExtMath_Copy(Z->Q, Z->P);
continue;
}
RsaSetExponentOld(&rsaKey->privateExponent, Z); // libtpms added: preserve dP, dQ, qInv
// Pack the private exponent into the sensitive area
// PackExponent(&sensitive->sensitive.rsa, Z); // libtpms changed: never pack
// Make sure everything came out right. The MSb of the values must be one
if(((publicArea->unique.rsa.t.buffer[0] & 0x80) == 0)
|| ((sensitive->sensitive.rsa.t.buffer[0] & 0x80) == 0))
@ -1493,20 +1494,20 @@ LIB_EXPORT TPM_RC CryptRsaGenerateKey(
// Do a trial encryption decryption if this is a signing key
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
{
BN_RSA(temp1);
BN_RSA(temp2);
BnGenerateRandomInRange(temp1, bnN, rand);
CRYPT_RSA_VAR(temp1);
CRYPT_RSA_VAR(temp2);
BnGenerateRandomInRange((bigNum)temp1, (bigConst)bnN, rand);
// Encrypt with public exponent...
BnModExp(temp2, temp1, bnPubExp, bnN);
ExtMath_ModExp(temp2, temp1, bnPubExp, bnN);
// ... then decrypt with private exponent
RsaPrivateKeyOp(temp2, Z);
// If the starting and ending values are not the same,
// start over )-;
if(BnUnsignedCmp(temp2, temp1) != 0)
if(ExtMath_UnsignedCmp(temp2, temp1) != 0)
{
BnSetWord(Z->Q, 0);
ExtMath_SetWord(Z->Q, 0);
retVal = TPM_RC_NO_RESULT;
}
}

View File

@ -944,7 +944,7 @@ OpenSSLCryptRsaGenerateKey(
OSSL_PARAM_BLD *bld = NULL;
OSSL_PARAM *params = NULL;
EVP_PKEY *pkey = NULL;
BN_RSA(tmp);
CRYPT_RSA_VAR(tmp);
if (bnE == NULL || BN_set_word(bnE, e) != 1)
ERROR_EXIT(TPM_RC_FAILURE);
@ -964,14 +964,14 @@ OpenSSLCryptRsaGenerateKey(
if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &bnN) != 1)
ERROR_EXIT(TPM_RC_FAILURE);
OsslToTpmBn(tmp, bnN);
BnTo2B((bigNum)tmp, &publicArea->unique.rsa.b, 0);
OsslToTpmBn((bigNum)tmp, bnN);
TpmMath_IntTo2B(tmp, &publicArea->unique.rsa.b, 0);
if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &bnP) != 1)
ERROR_EXIT(TPM_RC_FAILURE);
OsslToTpmBn(tmp, bnP);
BnTo2B((bigNum)tmp, &sensitive->sensitive.rsa.b, 0);
OsslToTpmBn((bigNum)tmp, bnP);
TpmMath_IntTo2B(tmp, &sensitive->sensitive.rsa.b, 0);
// CryptRsaGenerateKey calls ComputePrivateExponent; we have to call
// it via CryptRsaLoadPrivateExponent
@ -1008,7 +1008,7 @@ OpenSSLCryptRsaGenerateKey(
const BIGNUM *bnP = NULL;
const BIGNUM *bnN = NULL;
BIGNUM *bnE = BN_new();
BN_RSA(tmp);
CRYPT_RSA_VAR(tmp);
if (bnE == NULL || BN_set_word(bnE, e) != 1)
ERROR_EXIT(TPM_RC_FAILURE);
@ -1024,11 +1024,11 @@ OpenSSLCryptRsaGenerateKey(
RSA_get0_key(rsa, &bnN, NULL, NULL);
RSA_get0_factors(rsa, &bnP, NULL);
OsslToTpmBn(tmp, bnN);
BnTo2B((bigNum)tmp, &publicArea->unique.rsa.b, 0);
OsslToTpmBn((bigNum)tmp, bnN);
TpmMath_IntTo2B(tmp, &publicArea->unique.rsa.b, 0);
OsslToTpmBn(tmp, bnP);
BnTo2B((bigNum)tmp, &sensitive->sensitive.rsa.b, 0);
OsslToTpmBn((bigNum)tmp, bnP);
TpmMath_IntTo2B(tmp, &sensitive->sensitive.rsa.b, 0);
// CryptRsaGenerateKey calls ComputePrivateExponent; we have to call
// it via CryptRsaLoadPrivateExponent