tpm2: rev164: Trivial whitespace, comment, and libtpms-unused change

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2023-08-23 19:19:31 -04:00 committed by Stefan Berger
parent 687f0de78c
commit 0de1cea8a5
13 changed files with 206 additions and 59 deletions

View File

@ -1,3 +1,4 @@
/********************************************************************************/
/* */
/* Attestation Commands */
@ -22,7 +23,7 @@
/* */
/* 2. Source Code Distribution Conditions: */
/* */
/* - Redistributions of Source Code must retain the above copyright licenses, */
/* - Redistributions of Source CoDe must retain the above copyright licenses, */
/* this list of conditions and the following disclaimers. */
/* */
/* - Redistributions in binary form must reproduce the above copyright */

View File

@ -3,7 +3,6 @@
/* Internal Global Type Definitions */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: Global.h 1658 2021-01-22 23:14:01Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +54,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
/* (c) Copyright IBM Corp. and others, 2016 - 2023 */
/* */
/********************************************************************************/
@ -222,9 +221,9 @@ typedef struct OBJECT
OBJECT_ATTRIBUTES attributes; // object attributes
TPMT_PUBLIC publicArea; // public area of an object
TPMT_SENSITIVE sensitive; // sensitive area of an object
#if ALG_RSA
#if ALG_RSA // libtpms added begin: keep
privateExponent_t privateExponent; // Additional field for the private
#endif
#endif // libtpms added end
TPM2B_NAME qualifiedName; // object qualified name
TPMI_DH_OBJECT evictHandle; // if the object is an evict object,
// the original handle is kept here.
@ -480,7 +479,7 @@ typedef UINT32 NV_REF;
typedef BYTE *NV_RAM_REF;
/* 5.9.8.3 NV_PIN */
/* This structure deals with the possible endianness differences between the canonical form of the
/* This structure deals with the possible endianess differences between the canonical form of the
TPMS_NV_PIN_COUNTER_PARAMETERS structure and the internal value. The structures allow the data in
a PIN index to be read as an 8-octet value using NvReadUINT64Data(). That function will byte swap
all the values on a little endian system. This will put the bytes with the 4-octet values in the

View File

@ -281,7 +281,7 @@ TPM2_SetPrimaryPolicy(
break;
FOR_EACH_ACT(SET_ACT_POLICY)
default:
FAIL(FATAL_ERROR_INTERNAL);
break;
@ -512,3 +512,4 @@ TPM2_HierarchyChangeAuth(
return TPM_RC_SUCCESS;
}
#endif // CC_HierarchyChangeAuth

View File

@ -1,9 +1,9 @@
/********************************************************************************/
/* */
/* */
/* Random Number Generator */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: RandomCommands.c 1490 2019-07-26 21:13:22Z kgoldman $ */
/* $Id: RandomCommands.c 1671 2021-06-03 18:30:41Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */

View File

@ -117,7 +117,7 @@ TPM2_Sign(
// Input Validation
if(!IsSigningObject(signObject))
return TPM_RCS_KEY + RC_Sign_keyHandle;
// A key that will be used for x.509 signatures can't be used in TPM2_Sign().
if(IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, x509sign))
return TPM_RCS_ATTRIBUTES + RC_Sign_keyHandle;

View File

@ -155,7 +155,9 @@ _rpc__ForceFailureMode(
void
)
{
#if SIMULATION
SetForceFailureMode();
#endif
return;
}
/* D.4.3.5. _rpc__Signal_PhysicalPresenceOn() */

View File

@ -55,7 +55,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016-2018 */
/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
/* */
/********************************************************************************/

View File

@ -72,7 +72,9 @@
extern uint32_t MarshalDataSize;
#endif
#if DEBUG
static int once = 0;
#endif
//** TpmSizeChecks()
// This function is used during the development process to make sure that the

View File

@ -3,7 +3,7 @@
/* */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: CryptPrimeSieve_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
/* $Id: CryptPrimeSieve_fp.h 809M 2021-01-21 21:40:52Z (local) $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +55,7 @@
/* 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 - 2021 */
/* */
/********************************************************************************/

View File

@ -3,7 +3,6 @@
/* Implementation of cryptographic primitives for RSA */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: CryptRsa_fp.h 1476 2019-06-10 19:32:03Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +54,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2019 */
/* (c) Copyright IBM Corp. and others, 2016 - 2023 */
/* */
/********************************************************************************/

View File

@ -3,7 +3,6 @@
/* Implementation of cryptographic primitives for RSA */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: CryptRsa.c 1658 2021-01-22 23:14:01Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +54,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
/* (c) Copyright IBM Corp. and others, 2016 - 2023 */
/* */
/********************************************************************************/
@ -92,6 +91,12 @@ CryptRsaStartup(
return TRUE;
}
/* 10.2.17.4 Internal Functions */
/* 10.2.17.4.1 RsaInitializeExponent() */
/* This function initializes the bignum data structure that holds the private exponent. This
function returns the pointer to the private exponent value so that it can be used in an
initializer for a data declaration */
void
RsaInitializeExponent(
privateExponent_t *pExp
@ -102,7 +107,83 @@ RsaInitializeExponent(
BN_INIT(pExp->dQ);
BN_INIT(pExp->qInv);
}
/* 10.2.17.4.1 ComputePrivateExponent() */
#if 0 // libtpms added
/* 10.2.17.4.2 MakePgreaterThanQ() */
/* 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)
{
bigNum bnT = Z->P;
Z->P = Z->Q;
Z->Q = bnT;
}
}
/* 10.2.17.4.3 PackExponent() */
/* This function takes the bignum private exponent and converts it into TPM2B form. In this form,
the size field contains the overall size of the packed data. The buffer contains 5, equal sized
values in P, Q, dP, dQ, qInv order. For example, if a key has a 2Kb public key, then the packed
private key will contain 5, 1Kb values. This form makes it relatively easy to load and save the
values without changing the normal unmarshaling to do anything more than allow a larger TPM2B for
the private key. Also, when exporting the value, all that is needed is to change the size field
of the private key in order to save just the P value. */
/* Return Value Meaning */
/* TRUE(1) success */
/* FALSE(0) failure -- The data is too big to fit */
static BOOL
PackExponent(
TPM2B_PRIVATE_KEY_RSA *packed,
privateExponent *Z
)
{
int i;
UINT16 primeSize = (UINT16)BITS_TO_BYTES(BnMsb(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))
return FALSE;
if(pS != primeSize)
return FALSE;
return TRUE;
}
/* 10.2.17.4.4 UnpackExponent() */
/* This function unpacks the private exponent from its TPM2B form into its bignum form. */
/* Return Value Meaning */
/* TRUE(1) success */
/* 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;
//
VERIFY(b->t.size & RSA_prime_flag);
RsaInitializeExponent(Z);
VERIFY((primeSize % 5) == 0);
primeSize /= 5;
for(i = 0; i < 5; i++)
VERIFY(BnFromBytes(bn[i], &b->t.buffer[primeSize * i], primeSize)
!= NULL);
MakePgreaterThanQ(Z);
return TRUE;
Error:
return FALSE;
}
#endif // libtpms added
/* 10.2.17.4.5 ComputePrivateExponent() */
/* This function computes the private exponent from the primes. */
/* Return Value Meaning */
/* TRUE(1) success */
@ -144,7 +225,8 @@ ComputePrivateExponent(
BnSetWord(Q, 0);
return pOK && qOK;
}
/* 10.2.17.4.2 RsaPrivateKeyOp() */
/* 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 */
@ -189,7 +271,8 @@ RsaPrivateKeyOp(
Error:
return FALSE;
}
/* 10.2.17.4.3 RSAEP() */
/* 10.2.17.4.7 RSAEP() */
/* This function performs the RSAEP operation defined in PKCS#1v2.1. It is an exponentiation of a
value (m) with the public exponent (e), modulo the public (n). */
/* Error Returns Meaning */
@ -222,7 +305,8 @@ RSAEP(
key->publicArea.unique.rsa.t.size,
key->publicArea.unique.rsa.t.buffer);
}
/* 10.2.17.4.4 RSADP() */
/* 10.2.17.4.8 RSADP() */
/* This function performs the RSADP operation defined in PKCS#1v2.1. It is an exponentiation of a
value (c) with the private exponent (d), modulo the public modulus (n). The decryption is in
place. */
@ -258,7 +342,8 @@ RSADP(
Error:
return TPM_RC_FAILURE;
}
/* 10.2.17.4.5 OaepEncode() */
/* 10.2.17.4.9 OaepEncode() */
/* This function performs OAEP padding. The size of the buffer to receive the OAEP padded data must
equal the size of the modulus */
/* Error Returns Meaning */
@ -282,32 +367,40 @@ OaepEncode(
BYTE *pp;
BYTE *pm;
TPM_RC retVal = TPM_RC_SUCCESS;
pAssert(padded != NULL && message != NULL);
// A value of zero is not allowed because the KDF can't produce a result
// if the digest size is zero.
if(hLen == 0)
return TPM_RC_VALUE;
// Basic size checks
// make sure digest isn't too big for key size
if(padded->size < (2 * hLen) + 2)
ERROR_RETURN(TPM_RC_HASH);
// and that message will fit messageSize <= k - 2hLen - 2
if(message->size > (padded->size - (2 * hLen) - 2))
ERROR_RETURN(TPM_RC_VALUE);
// Hash L even if it is null
// Offset into padded leaving room for masked seed and byte of zero
pp = &padded->buffer[hLen + 1];
if(CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
hLen, pp) != hLen)
ERROR_RETURN(TPM_RC_FAILURE);
// concatenate PS of k mLen 2hLen 2
padLen = padded->size - message->size - (2 * hLen) - 2;
MemorySet(&pp[hLen], 0, padLen);
pp[hLen + padLen] = 0x01;
padLen += 1;
memcpy(&pp[hLen + padLen], message->buffer, message->size);
// 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);
@ -316,14 +409,17 @@ OaepEncode(
ERROR_RETURN(TPM_RC_FAILURE);
// mask = MGF1 (seed, nSize hLen 1)
CryptMGF_KDF(dbSize, mask, hashAlg, hLen, seed, 0);
// Create the masked db
pm = mask;
for(i = dbSize; i > 0; i--)
*pp++ ^= *pm++;
pp = &padded->buffer[hLen + 1];
// Run the masked data through MGF1
if(CryptMGF_KDF(hLen, &padded->buffer[1], hashAlg, dbSize, pp, 0) != (unsigned)hLen)
ERROR_RETURN(TPM_RC_VALUE);
// Now XOR the seed to create masked seed
pp = &padded->buffer[1];
pm = seed;
@ -334,7 +430,7 @@ OaepEncode(
Exit:
return retVal;
}
/* 10.2.17.4.6 OaepDecode() */
/* 10.2.17.4.10 OaepDecode() */
/* This function performs OAEP padding checking. The size of the buffer to receive the recovered
data. If the padding is not valid, the dSize size is set to zero and the function returns
TPM_RC_VALUE. */
@ -354,6 +450,7 @@ OaepDecode(
UINT32 i;
BYTE seedMask[MAX_DIGEST_SIZE];
UINT32 hLen = CryptHashGetDigestSize(hashAlg);
BYTE mask[MAX_RSA_KEY_BYTES];
BYTE *pp;
BYTE *pm;
@ -364,21 +461,28 @@ OaepDecode(
ERROR_RETURN(TPM_RC_VALUE);
// Use the hash size to determine what to put through MGF1 in order
// to recover the seedMask
CryptMGF_KDF(hLen, seedMask, hashAlg, padded->size - hLen - 1,
CryptMGF_KDF(hLen,
seedMask,
hashAlg,
padded->size - hLen - 1,
&padded->buffer[hLen + 1], 0);
// Recover the seed into seedMask
pAssert(hLen <= sizeof(seedMask));
pp = &padded->buffer[1];
pm = seedMask;
for(i = hLen; i > 0; i--)
*pm++ ^= *pp++;
// Use the seed to generate the data mask
CryptMGF_KDF(padded->size - hLen - 1, mask, hashAlg, hLen, seedMask, 0);
// Use the mask generated from seed to recover the padded data
pp = &padded->buffer[hLen + 1];
pm = mask;
for(i = (padded->size - hLen - 1); i > 0; i--)
*pm++ ^= *pp++;
// Make sure that the recovered data has the hash of the label
// Put trial value in the seed mask
if((CryptHashBlock(hashAlg, label->size, (BYTE *)label->buffer,
@ -386,6 +490,7 @@ OaepDecode(
FAIL(FATAL_ERROR_INTERNAL);
if(memcmp(seedMask, mask, hLen) != 0)
ERROR_RETURN(TPM_RC_VALUE);
// find the start of the data
pm = &mask[hLen];
for(i = (UINT32)padded->size - (2 * hLen) - 1; i > 0; i--)
@ -396,6 +501,7 @@ OaepDecode(
// If we ran out of data or didn't end with 0x01, then return an error
if(i == 0 || pm[-1] != 0x01)
ERROR_RETURN(TPM_RC_VALUE);
// pm should be pointing at the first part of the data
// and i is one greater than the number of bytes to move
i--;
@ -409,7 +515,8 @@ OaepDecode(
dataOut->size = 0;
return retVal;
}
/* 10.2.17.4.7 PKCS1v1_5Encode() */
/* 10.2.17.4.11 PKCS1v1_5Encode() */
/* This function performs the encoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
/* Error Returns Meaning */
/* TPM_RC_VALUE message size is too large */
@ -425,11 +532,13 @@ RSAES_PKCS1v1_5Encode(
if(message->size > padded->size - 11)
return TPM_RC_VALUE;
// move the message to the end of the buffer
memcpy(&padded->buffer[padded->size - message->size], message->buffer,
memcpy(&padded->buffer[padded->size - message->size],
message->buffer,
message->size);
// Set the first byte to 0x00 and the second to 0x02
padded->buffer[0] = 0;
padded->buffer[1] = 2;
// Fill with random bytes
DRBG_Generate(rand, &padded->buffer[2], (UINT16)ps);
if(g_inFailureMode)
@ -437,6 +546,7 @@ RSAES_PKCS1v1_5Encode(
// Set the delimiter for the random field to 0
padded->buffer[2 + ps] = 0;
// Now, the only messy part. Make sure that all the 'ps' bytes are non-zero
// In this implementation, use the value of the current index
for(ps++; ps > 1; ps--)
@ -448,7 +558,7 @@ RSAES_PKCS1v1_5Encode(
}
return TPM_RC_SUCCESS;
}
/* 10.2.17.4.8 RSAES_Decode() */
/* 10.2.17.4.12 RSAES_Decode() */
/* This function performs the decoding for RSAES-PKCS1-V1_5-ENCRYPT as defined in PKCS#1V2.1 */
/* Error Returns Meaning */
/* TPM_RC_FAIL decoding error or results would no fit into provided buffer */
@ -470,6 +580,7 @@ RSAES_Decode(
break;
}
pSize++;
// Make sure that pSize has not gone over the end and that there are at least 8
// bytes of pad data.
fail = (pSize > coded->size) | fail;
@ -486,10 +597,8 @@ RSAES_Decode(
/* This function computes the salt size used in PSS. It is broken out so that the X509 code can get
the same value that is used by the encoding function in this module. */
INT16
CryptRsaPssSaltSize(
INT16 hashSize,
INT16 outSize
)
CryptRsaPssSaltSize(INT16 hashSize,
INT16 outSize)
{
INT16 saltSize;
//
@ -505,7 +614,7 @@ CryptRsaPssSaltSize(
}
#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
/* 10.2.17.4.9 PssEncode() */
/* 10.2.17.4.14 PssEncode() */
/* This function creates an encoded block of data that is the size of modulus. The function uses the
maximum salt size that will fit in the encoded block. */
/* Returns TPM_RC_SUCCESS or goes into failure mode. */
@ -524,8 +633,10 @@ PssEncode(
BYTE *pOut;
UINT16 mLen;
HASH_STATE hashState;
// These are fatal errors indicating bad TPM firmware
pAssert(out != NULL && hLen > 0 && digest != NULL);
// Get the size of the mask
mLen = (UINT16)(out->size - hLen - 1);
@ -536,6 +647,7 @@ PssEncode(
// Set the first 8 bytes to zero
pOut = out->buffer;
memset(pOut, 0, 8);
// Get set the salt
DRBG_Generate(rand, salt, saltSize);
if(g_inFailureMode)
@ -547,24 +659,31 @@ PssEncode(
CryptDigestUpdate2B(&hashState, digest);
CryptDigestUpdate(&hashState, saltSize, salt);
CryptHashEnd(&hashState, hLen, &pOut[out->size - hLen - 1]);
// Create a mask
if(CryptMGF_KDF(mLen, pOut, hashAlg, hLen, &pOut[mLen], 0) != mLen)
FAIL(FATAL_ERROR_INTERNAL);
// Since this implementation uses key sizes that are all even multiples of
// 8, just need to make sure that the most significant bit is CLEAR
*pOut &= 0x7f;
// Before we mess up the pOut value, set the last byte to 0xbc
pOut[out->size - 1] = 0xbc;
// XOR a byte of 0x01 at the position just before where the salt will be XOR'ed
pOut = &pOut[mLen - saltSize - 1];
*pOut++ ^= 0x01;
// XOR the salt data into the buffer
for(; saltSize > 0; saltSize--)
*pOut++ ^= *ps++;
// and we are done
return TPM_RC_SUCCESS;
}
/* 10.2.17.4.10 PssDecode() */
/* 10.2.17.4.15 PssDecode() */
/* This function checks that the PSS encoded block was built from the provided digest. If the check
is successful, TPM_RC_SUCCESS is returned. Any other value indicates an error. */
/* This implementation of PSS decoding is intended for the reference TPM implementation and is not
@ -594,19 +713,25 @@ PssDecode(
// These errors are indicative of failures due to programmer error
pAssert(dIn != NULL && eIn != NULL);
pe = eIn->buffer;
// check the hash scheme
if(hLen == 0)
ERROR_RETURN(TPM_RC_SCHEME);
// most significant bit must be zero
fail = pe[0] & 0x80;
// last byte must be 0xbc
fail |= pe[eIn->size - 1] ^ 0xbc;
// Use the hLen bytes at the end of the buffer to generate a mask
// Doesn't start at the end which is a flag byte
mLen = eIn->size - hLen - 1;
CryptMGF_KDF(mLen, mask, hashAlg, hLen, &pe[mLen], 0);
// Clear the MSO of the mask to make it consistent with the encoding.
mask[0] &= 0x7F;
pAssert(mLen <= sizeof(mask));
// XOR the data into the mask to recover the salt. This sequence
// advances eIn so that it will end up pointing to the seed data
@ -640,20 +765,26 @@ PssDecode(
// i contains the salt size and pm points to the salt. Going to use the input
// hash and the seed to recreate the hash in the lower portion of eIn.
CryptHashStart(&hashState, hashAlg);
// add the pad of 8 zeros
CryptDigestUpdate(&hashState, 8, pad);
// add the provided digest value
CryptDigestUpdate(&hashState, dIn->size, dIn->buffer);
// and the salt
CryptDigestUpdate(&hashState, i, pm);
// get the result
fail |= (CryptHashEnd(&hashState, hLen, mask) != hLen);
// Compare all bytes
for(pm = mask; hLen > 0; hLen--)
// don't use fail = because that could skip the increment and compare
// operations after the first failure and that gives away timing
// information.
fail |= *pm++ ^ *pe++;
retVal = (fail != 0) ? TPM_RC_VALUE : TPM_RC_SUCCESS;
Exit:
return retVal;
@ -694,13 +825,13 @@ MakeDerTag(
buffer += oidSize;
*buffer++ = 0x05; // Add a NULL
*buffer++ = 0x00;
*buffer++ = 0x04;
*buffer++ = (BYTE)(info->digestSize);
return oidSize + 8;
Error:
return 0;
}
/* 10.2.17.4.17 RSASSA_Encode() */
@ -723,22 +854,22 @@ RSASSA_Encode(
BYTE *eOut;
INT32 fillSize;
TPM_RC retVal = TPM_RC_SUCCESS;
// Can't use this scheme if the algorithm doesn't have a DER string defined.
if(derSize == 0)
ERROR_RETURN(TPM_RC_SCHEME);
// If the digest size of 'hashAl' doesn't match the input digest size, then
// the DER will misidentify the digest so return an error
if(CryptHashGetDigestSize(hashAlg) != hIn->size)
ERROR_RETURN(TPM_RC_VALUE);
fillSize = pOut->size - derSize - hIn->size - 3;
eOut = pOut->buffer;
// Make sure that this combination will fit in the provided space
if(fillSize < 8)
ERROR_RETURN(TPM_RC_SIZE);
// Start filling
*eOut++ = 0; // initial byte of zero
*eOut++ = 1; // byte of 0x01
@ -776,21 +907,21 @@ RSASSA_Decode(
TPM_RC retVal;
BYTE *digest;
UINT16 digestSize;
pAssert(hIn != NULL && eIn != NULL);
pe = eIn->buffer;
// Can't use this scheme if the algorithm doesn't have a DER string
// defined or if the provided hash isn't the right size
if(derSize == 0 || (unsigned)hashSize != hIn->size)
ERROR_RETURN(TPM_RC_SCHEME);
// Make sure that this combination will fit in the provided space
// Since no data movement takes place, can just walk though this
// and accept nearly random values. This can only be called from
// CryptValidateSignature() so eInSize is known to be in range.
fillSize = eIn->size - derSize - hashSize - 3;
// Start checking (fail will become non-zero if any of the bytes do not have
// the expected value.
fail = *pe++; // initial byte of zero
@ -810,7 +941,7 @@ RSASSA_Decode(
}
#endif // libtpms added
/* 10.2.17.4.13 CryptRsaSelectScheme() */
/* 10.2.17.5.1 CryptRsaSelectScheme() */
/* This function is used by TPM2_RSA_Decrypt() and TPM2_RSA_Encrypt(). It sets up the rules to
select a scheme between input and object default. This function assume the RSA object is
loaded. If a default scheme is defined in object, the default scheme should be chosen, otherwise,
@ -856,7 +987,7 @@ CryptRsaSelectScheme(
// two different, incompatible schemes specified will return NULL
return retVal;
}
/* 10.2.17.4.14 CryptRsaLoadPrivateExponent() */
/* 10.2.17.5.2 CryptRsaLoadPrivateExponent() */
/* Error Returns Meaning */
/* TPM_RC_BINDING public and private parts of rsaKey are not matched */
TPM_RC
@ -891,7 +1022,8 @@ CryptRsaLoadPrivateExponent(
return retVal;
}
#if !USE_OPENSSL_FUNCTIONS_RSA // libtpms added
/* 10.2.17.4.15 CryptRsaEncrypt() */
/* 10.2.17.5.3 CryptRsaEncrypt() */
/* This is the entry point for encryption using RSA. Encryption is use of the public exponent. The
padding parameter determines what padding will be used. */
/* The cOutSize parameter must be at least as large as the size of the key. */
@ -970,7 +1102,7 @@ CryptRsaEncrypt(
Exit:
return retVal;
}
/* 10.2.17.4.16 CryptRsaDecrypt() */
/* 10.2.17.5.4 CryptRsaDecrypt() */
/* This is the entry point for decryption using RSA. Decryption is use of the private exponent. The
padType parameter determines what padding was used. */
/* Error Returns Meaning */
@ -1021,7 +1153,7 @@ CryptRsaDecrypt(
Exit:
return retVal;
}
/* 10.2.17.4.17 CryptRsaSign() */
/* 10.2.17.5.5 CryptRsaSign() */
/* This function is used to generate an RSA signature of the type indicated in scheme. */
/* Error Returns Meaning */
/* TPM_RC_SCHEME scheme or hashAlg are not supported */
@ -1066,7 +1198,7 @@ CryptRsaSign(
}
return retVal;
}
/* 10.2.17.4.18 CryptRsaValidateSignature() */
/* 10.2.17.5.6 CryptRsaValidateSignature() */
/* This function is used to validate an RSA signature. If the signature is valid TPM_RC_SUCCESS is
returned. If the signature is not valid, TPM_RC_SIGNATURE is returned. Other return codes
indicate either parameter problems or fatal errors. */
@ -1126,7 +1258,7 @@ int GetCachedRsaKey(OBJECT *key, RAND_STATE *rand);
#else
#define GET_CACHED_KEY(key, rand)
#endif
/* 10.2.17.4.19 CryptRsaGenerateKey() */
/* 10.2.17.5.7 CryptRsaGenerateKey() */
/* Generate an RSA key from a provided seed */
/* Error Returns Meaning */
/* TPM_RC_CANCELED operation was canceled */
@ -1153,7 +1285,6 @@ CryptRsaGenerateKey(
//
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
// not supported
e = publicArea->parameters.rsaDetail.exponent;
@ -1175,12 +1306,15 @@ CryptRsaGenerateKey(
|| (keySizeInBits > MAX_RSA_KEY_BITS) // this might be redundant, but...
|| (keySizeInBits == 0))
ERROR_RETURN(TPM_RC_VALUE);
// Set the prime size for instrumentation purposes
INSTRUMENT_SET(PrimeIndex, PRIME_INDEX(keySizeInBits / 2));
#if SIMULATION && USE_RSA_KEY_CACHE
if(GET_CACHED_KEY(publicArea, sensitive, rand))
return TPM_RC_SUCCESS;
#endif
// Make sure that key generation has been tested
TEST(TPM_ALG_NULL);
#if USE_OPENSSL_FUNCTIONS_RSA // libtpms added begin
@ -1189,6 +1323,7 @@ CryptRsaGenerateKey(
#endif // libtpms added end
// Need to initialize the privateExponent structure
RsaInitializeExponent(&rsaKey->privateExponent);
// The prime is computed in P. When a new prime is found, Q is checked to
// see if it is zero. If so, P is copied to Q and a new P is found.
// When both P and Q are non-zero, the modulus and
@ -1208,6 +1343,7 @@ CryptRsaGenerateKey(
goto Exit;
}
INSTRUMENT_INC(PrimeCounts[PrimeIndex]);
// If this is the second prime, make sure that it differs from the
// first prime by at least 2^100
if(BnEqualZero(bnQ))
@ -1224,6 +1360,7 @@ CryptRsaGenerateKey(
BnSub(bnD, bnP, bnQ);
if(BnMsb(bnD) < 100)
continue;
//Form the public modulus and set the unique value
BnMult(bnN, bnP, bnQ);
BnTo2B(bnN, &publicArea->unique.rsa.b,
@ -1235,6 +1372,7 @@ CryptRsaGenerateKey(
if(((publicArea->unique.rsa.t.buffer[0] & 0x80) == 0)
|| ((sensitive->sensitive.rsa.t.buffer[0] & 0x80) == 0))
FAIL(FATAL_ERROR_INTERNAL);
// Make sure that we can form the private exponent values
if(ComputePrivateExponent(bnP, bnQ, bnPubExp, &rsaKey->privateExponent) != TRUE)
{
@ -1252,6 +1390,7 @@ CryptRsaGenerateKey(
BN_RSA(temp1);
BN_RSA(temp2);
BnGenerateRandomInRange(temp1, bnN, rand);
// Encrypt with public exponent...
BnModExp(temp2, temp1, bnPubExp, bnN);
// ... then decrypt with private exponent

View File

@ -3,7 +3,6 @@
/* TPM to OpenSSL BigNum Shim Layer */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: TpmToOsslMath.h 1658 2021-01-22 23:14:01Z kgoldman $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +54,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
/* (c) Copyright IBM Corp. and others, 2016 - 2023 */
/* */
/********************************************************************************/
@ -74,15 +73,20 @@
#define SYMMETRIC_ALIGNMENT RADIX_BYTES
#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.
/*
* As of release 3.0.0, OPENSSL_VERSION_NUMBER is a combination of the
* major (M), minor (NN) and patch (PP) version into a single integer 0xMNN00PP0L
*/
#if OPENSSL_VERSION_NUMBER > 0x30100ff0L
// Check the bignum_st definition in crypto/bn/bn_lcl.h or crypto/bn/bn_local.h and either update
// the version check or provide the new definition for this version.
// Currently safe for all 3.1.x
# error Untested OpenSSL version
#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
// from crypto/bn/bn_lcl.h
struct bignum_st {
BN_ULONG *d;
int top;
int top;
int dmax;
int neg;

View File

@ -3,7 +3,7 @@
/* Splice the OpenSSL() library into the TPM code. */
/* Written by Ken Goldman */
/* IBM Thomas J. Watson Research Center */
/* $Id: TpmToOsslSym.h 1619 2020-05-19 16:51:47Z kgoldman $ */
/* $Id: TpmToOsslSym.h 1619M 2021-01-19 21:39:42Z (local) $ */
/* */
/* Licenses and Notices */
/* */
@ -55,7 +55,7 @@
/* arising in any way out of use or reliance upon this specification or any */
/* information herein. */
/* */
/* (c) Copyright IBM Corp. and others, 2016 - 2020 */
/* (c) Copyright IBM Corp. and others, 2016 - 2021 */
/* */
/********************************************************************************/