mirror of
https://github.com/stefanberger/libtpms
synced 2026-01-07 11:09:06 +00:00
Upgrade from rev 142 to rev 146
This is the diff patch between rev 142 and 146. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
ccce8b5f49
commit
992a5bfad8
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: AlgorithmCap.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: AlgorithmCap.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -76,100 +76,103 @@ static const ALGORITHM s_algorithms[] =
|
||||
// need to be full (gaps are allowed). One day, a tool might exist to fill in the
|
||||
// table from the TPM_ALG description
|
||||
#ifdef TPM_ALG_RSA
|
||||
{TPM_ALG_RSA, {1, 0, 0, 1, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_RSA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_TDES
|
||||
{TPM_ALG_TDES, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_TDES, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA1
|
||||
{TPM_ALG_SHA1, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SHA1, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
{TPM_ALG_HMAC, {0, 0, 1, 0, 0, 1, 0, 0, 0}},
|
||||
{TPM_ALG_HMAC, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 1, 0, 0, 0)},
|
||||
#ifdef TPM_ALG_AES
|
||||
{TPM_ALG_AES, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_AES, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_MGF1
|
||||
{TPM_ALG_MGF1, {0, 0, 1, 0, 0, 0, 0, 1, 0}},
|
||||
{TPM_ALG_MGF1, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
|
||||
#endif
|
||||
{TPM_ALG_KEYEDHASH, {0, 0, 1, 1, 0, 1, 1, 0, 0}},
|
||||
{TPM_ALG_KEYEDHASH, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 1, 0, 1, 1, 0, 0)},
|
||||
#ifdef TPM_ALG_XOR
|
||||
{TPM_ALG_XOR, {0, 1, 1, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_XOR, TPMA_ALGORITHM_INITIALIZER(0, 1, 1, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA256
|
||||
{TPM_ALG_SHA256, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SHA256, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA384
|
||||
{TPM_ALG_SHA384, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SHA384, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA512
|
||||
{TPM_ALG_SHA512, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SHA512, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM3_256
|
||||
{TPM_ALG_SM3_256, {0, 0, 1, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SM3_256, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM4
|
||||
{TPM_ALG_SM4, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SM4, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_RSASSA
|
||||
{TPM_ALG_RSASSA, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
|
||||
{TPM_ALG_RSASSA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_RSAES
|
||||
{TPM_ALG_RSAES, {1, 0, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_RSAES, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_RSAPSS
|
||||
{TPM_ALG_RSAPSS, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
|
||||
{TPM_ALG_RSAPSS, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_OAEP
|
||||
{TPM_ALG_OAEP, {1, 0, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_OAEP, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECDSA
|
||||
{TPM_ALG_ECDSA, {1, 0, 0, 0, 0, 1, 0, 1, 0}},
|
||||
{TPM_ALG_ECDSA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECDH
|
||||
{TPM_ALG_ECDH, {1, 0, 0, 0, 0, 0, 0, 1, 0}},
|
||||
{TPM_ALG_ECDH, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECDAA
|
||||
{TPM_ALG_ECDAA, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
|
||||
{TPM_ALG_ECDAA, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM2
|
||||
{TPM_ALG_SM2, {1, 0, 0, 0, 0, 1, 0, 1, 0}},
|
||||
{TPM_ALG_SM2, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECSCHNORR
|
||||
{TPM_ALG_ECSCHNORR, {1, 0, 0, 0, 0, 1, 0, 0, 0}},
|
||||
{TPM_ALG_ECSCHNORR, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 1, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECMQV
|
||||
{TPM_ALG_ECMQV, {1, 0, 0, 0, 0, 0, 0, 1, 0}},
|
||||
{TPM_ALG_ECMQV, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 0, 0, 0, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_KDF1_SP800_56A
|
||||
{TPM_ALG_KDF1_SP800_56A,{0, 0, 1, 0, 0, 0, 0, 1, 0}},
|
||||
{TPM_ALG_KDF1_SP800_56A, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_KDF2
|
||||
{TPM_ALG_KDF2, {0, 0, 1, 0, 0, 0, 0, 1, 0}},
|
||||
{TPM_ALG_KDF2, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_KDF1_SP800_108
|
||||
{TPM_ALG_KDF1_SP800_108,{0, 0, 1, 0, 0, 0, 0, 1, 0}},
|
||||
{TPM_ALG_KDF1_SP800_108, TPMA_ALGORITHM_INITIALIZER(0, 0, 1, 0, 0, 0, 0, 1, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECC
|
||||
{TPM_ALG_ECC, {1, 0, 0, 1, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_ECC, TPMA_ALGORITHM_INITIALIZER(1, 0, 0, 1, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
{TPM_ALG_SYMCIPHER, {0, 0, 0, 1, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_SYMCIPHER, TPMA_ALGORITHM_INITIALIZER(0, 0, 0, 1, 0, 0, 0, 0, 0)},
|
||||
#ifdef TPM_ALG_CAMELLIA
|
||||
{TPM_ALG_CAMELLIA, {0, 1, 0, 0, 0, 0, 0, 0, 0}},
|
||||
{TPM_ALG_CAMELLIA, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_CMAC
|
||||
{TPM_ALG_CMAC, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 1, 0, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_CTR
|
||||
{TPM_ALG_CTR, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_CTR, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_OFB
|
||||
{TPM_ALG_OFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_OFB, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_CBC
|
||||
{TPM_ALG_CBC, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_CBC, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_CFB
|
||||
{TPM_ALG_CFB, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_CFB, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECB
|
||||
{TPM_ALG_ECB, {0, 1, 0, 0, 0, 0, 1, 0, 0}},
|
||||
{TPM_ALG_ECB, TPMA_ALGORITHM_INITIALIZER(0, 1, 0, 0, 0, 0, 1, 0, 0)},
|
||||
#endif
|
||||
};
|
||||
/* 9.1.3 AlgorithmCapGetImplemented() */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Code to perform the various self-test functions. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: AlgorithmTests.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: AlgorithmTests.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -319,7 +319,7 @@ TestSymmetric(
|
||||
/* The tests are for public key only operations and for private key operations. Signature
|
||||
verification and encryption are public key operations. They are tested by using a KVT. For
|
||||
signature verification, this means that a known good signature is checked by
|
||||
_cpri_ValidateSignatureRSA(). If it fails, then the TPM enters failure mode. For encryption, the
|
||||
CryptRsaValidateSignature(). If it fails, then the TPM enters failure mode. For encryption, the
|
||||
TPM encrypts known values using the selected scheme and checks that the returned value matches
|
||||
the expected value. */
|
||||
/* For private key operations, a full scheme check is used. For a signing key, a known key is used
|
||||
@ -751,12 +751,15 @@ TestEcc(
|
||||
}
|
||||
#endif // TPM_ALG_ECC
|
||||
/* 10.2.1.6.4 TestAlgorithm() */
|
||||
/* Dispatches to the correct test function for the algorithm. If algorithm is not If toTest is not
|
||||
NULL, then the test decisions are based on the algorithm selections in toTest. Otherwise,
|
||||
g_toTest is used. When bits are clear in g_toTest they will also be cleared toTest. If there
|
||||
doesn't happen to be a test for the algorithm, its associated bit quietly cleared. If alg is zero
|
||||
(TPM_ALG_ERROR), then the toTest vector is cleared of any bits for which there is a test (i.e. no
|
||||
tests are actually run but the vector is cleared. */
|
||||
/* Dispatches to the correct test function for the algorithm or get a list of testable
|
||||
algorithms. */
|
||||
/* If toTest is not NULL, then the test decisions are based on the algorithm selections in
|
||||
toTest. Otherwise, g_toTest is used. When bits are clear in g_toTest they will also be cleared
|
||||
toTest. */
|
||||
/* If there doesn't happen to be a test for the algorithm, its associated bit is quietly
|
||||
cleared. */
|
||||
/* If alg is zero (TPM_ALG_ERROR), then the toTest vector is cleared of any bits for which there is
|
||||
no test (i.e. no tests are actually run but the vector is cleared). */
|
||||
/* NOTE: toTest will only ever have bits set for implemented algorithms but alg can be anything. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SUCCESS test complete */
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Asymmetric Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: AsymmetricCommands.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: AsymmetricCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -78,7 +78,7 @@ TPM2_RSA_Encrypt(
|
||||
if(rsaKey->publicArea.type != TPM_ALG_RSA)
|
||||
return TPM_RCS_KEY + RC_RSA_Encrypt_keyHandle;
|
||||
// selected key must have the decryption attribute
|
||||
if(rsaKey->publicArea.objectAttributes.decrypt != SET)
|
||||
if(!IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + RC_RSA_Encrypt_keyHandle;
|
||||
// Is there a label?
|
||||
if(!IsLabelProperlyFormatted(&in->label.b))
|
||||
@ -116,8 +116,8 @@ TPM2_RSA_Decrypt(
|
||||
if(rsaKey->publicArea.type != TPM_ALG_RSA)
|
||||
return TPM_RCS_KEY + RC_RSA_Decrypt_keyHandle;
|
||||
// The selected key must be an unrestricted decryption key
|
||||
if(rsaKey->publicArea.objectAttributes.restricted == SET
|
||||
|| rsaKey->publicArea.objectAttributes.decrypt == CLEAR)
|
||||
if(IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
|
||||
|| !IS_ATTRIBUTE(rsaKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + RC_RSA_Decrypt_keyHandle;
|
||||
// NOTE: Proper operation of this command requires that the sensitive area
|
||||
// of the key is loaded. This is assured because authorization is required
|
||||
@ -207,8 +207,8 @@ TPM2_ECDH_ZGen(
|
||||
if(eccKey->publicArea.type != TPM_ALG_ECC)
|
||||
return TPM_RCS_KEY + RC_ECDH_ZGen_keyHandle;
|
||||
// Selected key needs to be unrestricted with the 'decrypt' attribute
|
||||
if(eccKey->publicArea.objectAttributes.restricted == SET
|
||||
|| eccKey->publicArea.objectAttributes.decrypt != SET)
|
||||
if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
|
||||
|| !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + RC_ECDH_ZGen_keyHandle;
|
||||
// Make sure the scheme allows this use
|
||||
if(eccKey->publicArea.parameters.eccDetail.scheme.scheme != TPM_ALG_ECDH
|
||||
@ -265,9 +265,8 @@ TPM2_ZGen_2Phase(
|
||||
if(eccKey->publicArea.type != TPM_ALG_ECC)
|
||||
return TPM_RCS_KEY + RC_ZGen_2Phase_keyA;
|
||||
// keyA must not be restricted and must be a decrypt key
|
||||
if(eccKey->publicArea.objectAttributes.restricted == SET
|
||||
|| eccKey->publicArea.objectAttributes.decrypt != SET
|
||||
)
|
||||
if(IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, restricted)
|
||||
|| !IS_ATTRIBUTE(eccKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + RC_ZGen_2Phase_keyA;
|
||||
// if the scheme of keyA is TPM_ALG_NULL, then use the input scheme; otherwise
|
||||
// the input scheme must be the same as the scheme of keyA
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Attest_spt.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Attest_spt.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -202,6 +202,7 @@ IsSigningObject(
|
||||
OBJECT *object // IN:
|
||||
)
|
||||
{
|
||||
return ((object == NULL) || ((object->publicArea.objectAttributes.sign == SET)
|
||||
&& object->publicArea.type != TPM_ALG_SYMCIPHER));
|
||||
return ((object == NULL) || ((IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, sign)
|
||||
&& object->publicArea.type != TPM_ALG_SYMCIPHER)));
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* conversion functions that will convert TPM2B to/from internal format */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: BnConvert.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: BnConvert.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -160,7 +160,7 @@ BnFromHex(
|
||||
if(i == 1)
|
||||
*d = FromHex(*p);
|
||||
}
|
||||
#if BIG_ENDIAN_TPM == NO
|
||||
#if !BIG_ENDIAN_TPM
|
||||
for(i = 0; i < wordCount; i++)
|
||||
bn->d[i] = SWAP_CRYPT_WORD(bn->d[i]);
|
||||
#endif // BIG_ENDIAN_TPM
|
||||
@ -173,6 +173,9 @@ BnFromHex(
|
||||
string and sets size to the normalized value. If size is an input 0, then the receiving buffer is
|
||||
guaranteed to be large enough for the result and the size will be set to the size required for
|
||||
bigNum (leading zeros suppressed). */
|
||||
/* The conversion for a little-endian machine simply requires that all significant bytes of the
|
||||
bigNum be reversed. For a big-endian machine, rather than process unpack each word individually,
|
||||
the bigNum is converted to little-endian words, copied, and then converted back to big-endian. */
|
||||
LIB_EXPORT BOOL
|
||||
BnToBytes(
|
||||
bigConst bn,
|
||||
@ -198,27 +201,32 @@ BnToBytes(
|
||||
}
|
||||
else
|
||||
{
|
||||
#if BIG_ENDIAN_TPM
|
||||
// Copy the constant input value into a modifiable value
|
||||
BN_VAR(bnL, LARGEST_NUMBER_BITS * 2);
|
||||
BnCopy(bnL, bn);
|
||||
// byte swap the words in the local value to make them little-endian
|
||||
for(count = 0; count < bnL->size; count++)
|
||||
bnL->d[count] = SWAP_CRYPT_WORD(bnL->d[count]);
|
||||
bn = (bigConst)bnL;
|
||||
#endif
|
||||
if(*size == 0)
|
||||
*size = (NUMBYTES)requiredSize;
|
||||
pAssert(requiredSize <= *size);
|
||||
#if BIG_ENDIAN_TPM
|
||||
// byte swap the words to make them little-endian
|
||||
for(count = 0; count < bn->size; count++)
|
||||
bn->d[count] = SWAP_CRYPT_WORD(bn->d[count]);
|
||||
#endif
|
||||
// Byte swap the number (not words but the whole value)
|
||||
count = *size;
|
||||
// Start from the least significant word and offset to the most significant
|
||||
// byte which is in some high word
|
||||
pFrom = (BYTE *)(&bn->d[0]) + requiredSize - 1;
|
||||
pTo = buffer;
|
||||
// If the number of output bytes is larger than the number bytes required
|
||||
// for the input number, pad with zeros
|
||||
for(count = *size; count > requiredSize; count--)
|
||||
*pTo++ = 0;
|
||||
// Move the most significant byte at the end of the BigNum to the next most
|
||||
// significant byte position of the 2B and repeat for all significant bytes.
|
||||
for(; requiredSize > 0; requiredSize--)
|
||||
*pTo++ = *pFrom--;
|
||||
#if BIG_ENDIAN_TPM
|
||||
// Put the input back into big-endian format
|
||||
for(count = 0; count < bn->size; count++)
|
||||
bn->d[count] = SWAP_CRYPT_WORD(bn->d[count]);
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: BnEccData.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: BnEccData.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -55,15 +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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* 10.2.3 BnEccData.c */
|
||||
#include "Tpm.h"
|
||||
/* both the new, refactored code and the old code (this is necessary so that errata can be
|
||||
/* both the new, re-factored code and the old code (this is necessary so that errata can be
|
||||
handled). Another script (BnEccData().pl) does the conversion and generates BnEccData.c for use
|
||||
in the refactored code. */
|
||||
in the re-factored code. */
|
||||
#if defined TPM_ALG_ECC && !defined USE_2B_ECC_DATA
|
||||
const struct {
|
||||
crypt_uword_t allocated;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: BnMath.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: BnMath.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -489,14 +489,21 @@ BnGetRandomBits(
|
||||
RAND_STATE *rand
|
||||
)
|
||||
{
|
||||
TPM2B_TYPE(LARGEST, LARGEST_NUMBER);
|
||||
TPM2B_LARGEST large;
|
||||
// Since this could be used for ECC key generation using the extra bits method,
|
||||
// make sure that the value is large enough
|
||||
TPM2B_TYPE(LARGEST, LARGEST_NUMBER + 8);
|
||||
TPM2B_LARGEST large;
|
||||
//
|
||||
large.b.size = (UINT16)BITS_TO_BYTES(bits);
|
||||
DRBG_Generate(rand, large.t.buffer, large.t.size);
|
||||
BnFrom2B(n, &large.b);
|
||||
BnMaskBits(n, bits);
|
||||
return TRUE;
|
||||
if(DRBG_Generate(rand, large.t.buffer, large.t.size) == large.t.size)
|
||||
{
|
||||
if(BnFrom2B(n, &large.b) != NULL)
|
||||
{
|
||||
if(BnMaskBits(n, bits))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
/* 10.2.4.3.21 BnGenerateRandomInRange() */
|
||||
/* Function to generate a random number r in the range 1 <= r < limit. The function gets a random
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Number of capability values that will fit into the largest data buffer */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Capabilities.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Capabilities.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -61,6 +61,7 @@
|
||||
|
||||
#ifndef _CAPABILITIES_H
|
||||
#define _CAPABILITIES_H
|
||||
|
||||
#define MAX_CAP_DATA (MAX_CAP_BUFFER - sizeof(TPM_CAP)-sizeof(UINT32))
|
||||
#define MAX_CAP_ALGS (MAX_CAP_DATA / sizeof(TPMS_ALG_PROPERTY))
|
||||
#define MAX_CAP_HANDLES (MAX_CAP_DATA / sizeof(TPM_HANDLE))
|
||||
@ -69,9 +70,6 @@
|
||||
#define MAX_PCR_PROPERTIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_PCR_SELECT))
|
||||
#define MAX_ECC_CURVES (MAX_CAP_DATA / sizeof(TPM_ECC_CURVE))
|
||||
#define MAX_TAGGED_POLICIES (MAX_CAP_DATA / sizeof(TPMS_TAGGED_POLICY))
|
||||
#define MAX_AC_CAPABILITIES (MAX_CAP_DATA / sizeof(TPMS_AC_OUTPUT))
|
||||
|
||||
#ifdef TPM_CC_AC_GetCapability
|
||||
/* This is #defined because TPMA_AC_CAPABILITIES might not be defined */
|
||||
# define MAX_AC_CAPABILITIES (MAX_CAP_DATA / sizeof(TPMS_AC_OUTPUT))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Used by the simulator to mimic a hardware clock */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Clock.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Clock.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -115,7 +115,8 @@ static uint64_t tpmclock(void)
|
||||
hardware events. */
|
||||
/* C.3.3.2. _plat__TimerReset() */
|
||||
/* This function sets current system clock time as t0 for counting TPM time. This function is called
|
||||
at a power on event to reset the clock. */
|
||||
at a power on event to reset the clock. When the clock is reset, the indication that the clock
|
||||
was stopped is also set. */
|
||||
LIB_EXPORT void
|
||||
_plat__TimerReset(
|
||||
void
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CommandAudit.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CommandAudit.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -214,8 +214,9 @@ CommandAuditCapGetCCList(
|
||||
{
|
||||
// If we have not filled up the return list, add this command
|
||||
// code to its
|
||||
TPM_CC cc = s_ccAttr[commandIndex].commandIndex;
|
||||
if(s_ccAttr[commandIndex].V)
|
||||
TPM_CC cc = GET_ATTRIBUTE(s_ccAttr[commandIndex],
|
||||
TPMA_CC, commandIndex);
|
||||
if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
|
||||
cc += (1 << 29);
|
||||
commandList->commandCodes[commandList->count] = cc;
|
||||
commandList->count++;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Functions for testing various command properties */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CommandCodeAttributes.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CommandCodeAttributes.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -134,14 +134,16 @@ GetClosestCommandIndex(
|
||||
// entry.
|
||||
// Note: Put this check first so that the typical case of only one vendor-
|
||||
// specific command doesn't waste any more time.
|
||||
if(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE].commandIndex >= searchIndex)
|
||||
if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE], TPMA_CC,
|
||||
commandIndex) >= searchIndex)
|
||||
{
|
||||
// the vendor array is always assumed to be packed so there is
|
||||
// no need to check to see if the command is implemented
|
||||
return LIBRARY_COMMAND_ARRAY_SIZE;
|
||||
}
|
||||
// See if this is out of range on the top
|
||||
if(s_ccAttr[COMMAND_COUNT - 1].commandIndex < searchIndex)
|
||||
if(GET_ATTRIBUTE(s_ccAttr[COMMAND_COUNT - 1], TPMA_CC, commandIndex)
|
||||
< searchIndex)
|
||||
{
|
||||
return UNIMPLEMENTED_COMMAND_INDEX;
|
||||
}
|
||||
@ -154,7 +156,8 @@ GetClosestCommandIndex(
|
||||
while(min <= max)
|
||||
{
|
||||
commandIndex = (min + max + 1) / 2;
|
||||
diff = s_ccAttr[commandIndex].commandIndex - searchIndex;
|
||||
diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)
|
||||
- searchIndex;
|
||||
if(diff == 0)
|
||||
return commandIndex;
|
||||
if(diff > 0)
|
||||
@ -180,7 +183,8 @@ GetClosestCommandIndex(
|
||||
#endif
|
||||
}
|
||||
// Get here if the V-Bit was not set in 'commandCode'
|
||||
if(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE - 1].commandIndex < searchIndex)
|
||||
if(GET_ATTRIBUTE(s_ccAttr[LIBRARY_COMMAND_ARRAY_SIZE - 1], TPMA_CC,
|
||||
commandIndex) < searchIndex)
|
||||
{
|
||||
// requested index is out of the range to the top
|
||||
#if VENDOR_COMMAND_ARRAY_SIZE > 0
|
||||
@ -199,7 +203,7 @@ GetClosestCommandIndex(
|
||||
}
|
||||
// If the request is lower than any value in the array, then return
|
||||
// the lowest value (needs to be an index for an implemented command
|
||||
if(s_ccAttr[0].commandIndex >= searchIndex)
|
||||
if(GET_ATTRIBUTE(s_ccAttr[0], TPMA_CC, commandIndex) >= searchIndex)
|
||||
{
|
||||
return NextImplementedIndex(0);
|
||||
}
|
||||
@ -221,7 +225,8 @@ GetClosestCommandIndex(
|
||||
while(min <= max)
|
||||
{
|
||||
commandIndex = (min + max + 1) / 2;
|
||||
diff = s_ccAttr[commandIndex].commandIndex - searchIndex;
|
||||
diff = GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC,
|
||||
commandIndex) - searchIndex;
|
||||
if(diff == 0)
|
||||
return commandIndex;
|
||||
if(diff > 0)
|
||||
@ -283,9 +288,9 @@ CommandCodeToCommandIndex(
|
||||
// requested, then the command is not implemented.
|
||||
if(commandIndex != UNIMPLEMENTED_COMMAND_INDEX)
|
||||
{
|
||||
if((s_ccAttr[commandIndex].commandIndex != searchIndex)
|
||||
|| ((s_ccAttr[commandIndex].V == SET) && !vendor)
|
||||
|| ((s_ccAttr[commandIndex].V == CLEAR) && vendor))
|
||||
if((GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex)
|
||||
!= searchIndex)
|
||||
|| (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V)) != vendor)
|
||||
commandIndex = UNIMPLEMENTED_COMMAND_INDEX;
|
||||
}
|
||||
return commandIndex;
|
||||
@ -316,8 +321,9 @@ GetCommandCode(
|
||||
COMMAND_INDEX commandIndex // IN: the command index
|
||||
)
|
||||
{
|
||||
TPM_CC commandCode = s_ccAttr[commandIndex].commandIndex;
|
||||
if(s_ccAttr[commandIndex].V)
|
||||
TPM_CC commandCode = GET_ATTRIBUTE(s_ccAttr[commandIndex],
|
||||
TPMA_CC, commandIndex);
|
||||
if(IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
|
||||
commandCode += CC_VEND;
|
||||
return commandCode;
|
||||
}
|
||||
@ -423,9 +429,9 @@ IsWriteOperation(
|
||||
#ifdef WRITE_LOCK
|
||||
return ((s_commandAttributes[commandIndex] & WRITE_LOCK) != 0);
|
||||
#else
|
||||
if(!s_ccAttr[commandIndex].V)
|
||||
if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
|
||||
{
|
||||
switch(s_ccAttr[commandIndex].commandIndex)
|
||||
switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex))
|
||||
{
|
||||
case TPM_CC_NV_Write:
|
||||
#if CC_NV_Increment
|
||||
@ -463,9 +469,9 @@ IsReadOperation(
|
||||
#ifdef READ_LOCK
|
||||
return ((s_commandAttributes[commandIndex] & READ_LOCK) != 0);
|
||||
#else
|
||||
if(!s_ccAttr[commandIndex].V)
|
||||
if(!IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V))
|
||||
{
|
||||
switch(s_ccAttr[commandIndex].commandIndex)
|
||||
switch(GET_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, commandIndex))
|
||||
{
|
||||
case TPM_CC_NV_Read:
|
||||
case TPM_CC_PolicyNV:
|
||||
@ -537,6 +543,6 @@ IsVendorCommand(
|
||||
COMMAND_INDEX commandIndex // IN: command index to check
|
||||
)
|
||||
{
|
||||
return (s_ccAttr[commandIndex].V == SET);
|
||||
return (IS_ATTRIBUTE(s_ccAttr[commandIndex], TPMA_CC, V));
|
||||
}
|
||||
#endif // INLINE_FUNCTIONS
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CommandDispatchData.h 828 2016-11-18 21:19:43Z kgoldman $ */
|
||||
/* $Id: CommandDispatchData.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -68,6 +68,10 @@
|
||||
const UNMARSHAL_t UnmarshalArray[] = {
|
||||
#define TPMI_DH_CONTEXT_H_UNMARSHAL 0
|
||||
(UNMARSHAL_t)TPMI_DH_CONTEXT_Unmarshal,
|
||||
#if 0
|
||||
#define TPMI_RH_AC_H_UNMARSHAL (TPMI_DH_CONTEXT_H_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_RH_AC_Unmarshal,
|
||||
#endif
|
||||
#define TPMI_RH_CLEAR_H_UNMARSHAL (TPMI_DH_CONTEXT_H_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_RH_CLEAR_Unmarshal,
|
||||
#define TPMI_RH_HIERARCHY_AUTH_H_UNMARSHAL (TPMI_RH_CLEAR_H_UNMARSHAL + 1)
|
||||
@ -140,7 +144,9 @@ const UNMARSHAL_t UnmarshalArray[] = {
|
||||
(UNMARSHAL_t)TPM2B_SENSITIVE_DATA_Unmarshal,
|
||||
#define TPM2B_TEMPLATE_P_UNMARSHAL (TPM2B_SENSITIVE_DATA_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPM2B_TEMPLATE_Unmarshal,
|
||||
#define UINT8_P_UNMARSHAL (TPM2B_TEMPLATE_P_UNMARSHAL + 1)
|
||||
#define TPM2B_TIMEOUT_P_UNMARSHAL (TPM2B_TEMPLATE_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPM2B_TIMEOUT_Unmarshal,
|
||||
#define UINT8_P_UNMARSHAL (TPM2B_TIMEOUT_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)UINT8_Unmarshal,
|
||||
#define TPMI_DH_CONTEXT_P_UNMARSHAL (UINT8_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_DH_CONTEXT_Unmarshal,
|
||||
@ -172,6 +178,10 @@ const UNMARSHAL_t UnmarshalArray[] = {
|
||||
(UNMARSHAL_t)TPMT_TK_HASHCHECK_Unmarshal,
|
||||
#define TPMT_TK_VERIFIED_P_UNMARSHAL (TPMT_TK_HASHCHECK_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMT_TK_VERIFIED_Unmarshal,
|
||||
#if 0
|
||||
#define TPM_AT_P_UNMARSHAL (TPMT_TK_VERIFIED_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPM_AT_Unmarshal,
|
||||
#endif
|
||||
#define TPM_CAP_P_UNMARSHAL (TPMT_TK_VERIFIED_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPM_CAP_Unmarshal,
|
||||
#define TPM_CLOCK_ADJUST_P_UNMARSHAL (TPM_CAP_P_UNMARSHAL + 1)
|
||||
@ -190,11 +200,13 @@ const UNMARSHAL_t UnmarshalArray[] = {
|
||||
#define PARAMETER_FIRST_FLAG_TYPE (UINT64_P_UNMARSHAL + 1)
|
||||
#define TPM2B_PUBLIC_P_UNMARSHAL (UINT64_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPM2B_PUBLIC_Unmarshal,
|
||||
#define TPMI_ALG_HASH_P_UNMARSHAL (TPM2B_PUBLIC_P_UNMARSHAL + 1)
|
||||
#define TPMI_ALG_CIPHER_MODE_P_UNMARSHAL (TPM2B_PUBLIC_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_ALG_CIPHER_MODE_Unmarshal,
|
||||
#define TPMI_ALG_HASH_P_UNMARSHAL (TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_ALG_HASH_Unmarshal,
|
||||
#define TPMI_ALG_SYM_MODE_P_UNMARSHAL (TPMI_ALG_HASH_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_ALG_SYM_MODE_Unmarshal,
|
||||
#define TPMI_DH_PCR_P_UNMARSHAL (TPMI_ALG_SYM_MODE_P_UNMARSHAL + 1)
|
||||
#define TPMI_ALG_MAC_SCHEME_P_UNMARSHAL (TPMI_ALG_HASH_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_ALG_MAC_SCHEME_Unmarshal,
|
||||
#define TPMI_DH_PCR_P_UNMARSHAL (TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_DH_PCR_Unmarshal,
|
||||
#define TPMI_ECC_KEY_EXCHANGE_P_UNMARSHAL (TPMI_DH_PCR_P_UNMARSHAL + 1)
|
||||
(UNMARSHAL_t)TPMI_ECC_KEY_EXCHANGE_Unmarshal,
|
||||
@ -253,8 +265,14 @@ const MARSHAL_t MarshalArray[] = {
|
||||
(MARSHAL_t)TPM2B_PUBLIC_KEY_RSA_Marshal,
|
||||
#define TPM2B_SENSITIVE_DATA_P_MARSHAL (TPM2B_PUBLIC_KEY_RSA_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPM2B_SENSITIVE_DATA_Marshal,
|
||||
#define UINT8_P_MARSHAL (TPM2B_SENSITIVE_DATA_P_MARSHAL + 1)
|
||||
#define TPM2B_TIMEOUT_P_MARSHAL (TPM2B_SENSITIVE_DATA_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPM2B_TIMEOUT_Marshal,
|
||||
#define UINT8_P_MARSHAL (TPM2B_TIMEOUT_P_MARSHAL + 1)
|
||||
(MARSHAL_t)UINT8_Marshal,
|
||||
#if 0
|
||||
#define TPML_AC_CAPABILITIES_P_MARSHAL (UINT8_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPML_AC_CAPABILITIES_Marshal,
|
||||
#endif
|
||||
#define TPML_ALG_P_MARSHAL (UINT8_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPML_ALG_Marshal,
|
||||
#define TPML_DIGEST_P_MARSHAL (TPML_ALG_P_MARSHAL + 1)
|
||||
@ -263,6 +281,10 @@ const MARSHAL_t MarshalArray[] = {
|
||||
(MARSHAL_t)TPML_DIGEST_VALUES_Marshal,
|
||||
#define TPML_PCR_SELECTION_P_MARSHAL (TPML_DIGEST_VALUES_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPML_PCR_SELECTION_Marshal,
|
||||
#if 0
|
||||
#define TPMS_AC_OUTPUT_P_MARSHAL (TPML_PCR_SELECTION_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPMS_AC_OUTPUT_Marshal,
|
||||
#endif
|
||||
#define TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL (TPML_PCR_SELECTION_P_MARSHAL + 1)
|
||||
(MARSHAL_t)TPMS_ALGORITHM_DETAIL_ECC_Marshal,
|
||||
#define TPMS_CAPABILITY_DATA_P_MARSHAL (TPMS_ALGORITHM_DETAIL_ECC_P_MARSHAL + 1)
|
||||
@ -288,9 +310,7 @@ const MARSHAL_t MarshalArray[] = {
|
||||
#define UINT16_P_MARSHAL (UINT32_P_MARSHAL + 1)
|
||||
(MARSHAL_t)UINT16_Marshal,
|
||||
|
||||
|
||||
#define RESPONSE_PARAMETER_LAST_TYPE (UINT16_P_MARSHAL)
|
||||
|
||||
};
|
||||
#if CC_Startup == YES
|
||||
#include "Startup_fp.h"
|
||||
@ -1138,7 +1158,7 @@ EncryptDecrypt_COMMAND_DESCRIPTOR_t _EncryptDecryptData = {
|
||||
(UINT16)(offsetof(EncryptDecrypt_Out, ivOut))},
|
||||
/* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
|
||||
TPMI_YES_NO_P_UNMARSHAL,
|
||||
TPMI_ALG_SYM_MODE_P_UNMARSHAL + ADD_FLAG,
|
||||
TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + ADD_FLAG,
|
||||
TPM2B_IV_P_UNMARSHAL,
|
||||
TPM2B_MAX_BUFFER_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
@ -1177,7 +1197,7 @@ EncryptDecrypt2_COMMAND_DESCRIPTOR_t _EncryptDecrypt2Data = {
|
||||
/* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
|
||||
TPM2B_MAX_BUFFER_P_UNMARSHAL,
|
||||
TPMI_YES_NO_P_UNMARSHAL,
|
||||
TPMI_ALG_SYM_MODE_P_UNMARSHAL + ADD_FLAG,
|
||||
TPMI_ALG_CIPHER_MODE_P_UNMARSHAL + ADD_FLAG,
|
||||
TPM2B_IV_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
TPM2B_MAX_BUFFER_P_MARSHAL,
|
||||
@ -1254,6 +1274,38 @@ HMAC_COMMAND_DESCRIPTOR_t _HMACData = {
|
||||
#else
|
||||
#define _HMACDataAddress 0
|
||||
#endif
|
||||
#if CC_MAC == YES
|
||||
#include "MAC_fp.h"
|
||||
typedef TPM_RC (MAC_Entry)(
|
||||
MAC_In *in,
|
||||
MAC_Out *out
|
||||
);
|
||||
typedef const struct {
|
||||
MAC_Entry *entry;
|
||||
UINT16 inSize;
|
||||
UINT16 outSize;
|
||||
UINT16 offsetOfTypes;
|
||||
UINT16 paramOffsets[2];
|
||||
BYTE types[6];
|
||||
} MAC_COMMAND_DESCRIPTOR_t;
|
||||
MAC_COMMAND_DESCRIPTOR_t _MACData = {
|
||||
/* entry */ &TPM2_MAC,
|
||||
/* inSize */ (UINT16)(sizeof(MAC_In)),
|
||||
/* outSize */ (UINT16)(sizeof(MAC_Out)),
|
||||
/* offsetOfTypes */ offsetof(MAC_COMMAND_DESCRIPTOR_t, types),
|
||||
/* offsets */ {(UINT16)(offsetof(MAC_In, buffer)),
|
||||
(UINT16)(offsetof(MAC_In, inScheme))},
|
||||
/* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
|
||||
TPM2B_MAX_BUFFER_P_UNMARSHAL,
|
||||
TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + ADD_FLAG,
|
||||
END_OF_LIST,
|
||||
TPM2B_DIGEST_P_MARSHAL,
|
||||
END_OF_LIST}
|
||||
};
|
||||
#define _MACDataAddress (&_MACData)
|
||||
#else
|
||||
#define _MACDataAddress 0
|
||||
#endif
|
||||
#if CC_GetRandom == YES
|
||||
#include "GetRandom_fp.h"
|
||||
typedef TPM_RC (GetRandom_Entry)(
|
||||
@ -1340,6 +1392,38 @@ HMAC_Start_COMMAND_DESCRIPTOR_t _HMAC_StartData = {
|
||||
#else
|
||||
#define _HMAC_StartDataAddress 0
|
||||
#endif
|
||||
#if CC_MAC_Start == YES
|
||||
#include "MAC_Start_fp.h"
|
||||
typedef TPM_RC (MAC_Start_Entry)(
|
||||
MAC_Start_In *in,
|
||||
MAC_Start_Out *out
|
||||
);
|
||||
typedef const struct {
|
||||
MAC_Start_Entry *entry;
|
||||
UINT16 inSize;
|
||||
UINT16 outSize;
|
||||
UINT16 offsetOfTypes;
|
||||
UINT16 paramOffsets[2];
|
||||
BYTE types[6];
|
||||
} MAC_Start_COMMAND_DESCRIPTOR_t;
|
||||
MAC_Start_COMMAND_DESCRIPTOR_t _MAC_StartData = {
|
||||
/* entry */ &TPM2_MAC_Start,
|
||||
/* inSize */ (UINT16)(sizeof(MAC_Start_In)),
|
||||
/* outSize */ (UINT16)(sizeof(MAC_Start_Out)),
|
||||
/* offsetOfTypes */ offsetof(MAC_Start_COMMAND_DESCRIPTOR_t, types),
|
||||
/* offsets */ {(UINT16)(offsetof(MAC_Start_In, auth)),
|
||||
(UINT16)(offsetof(MAC_Start_In, inScheme))},
|
||||
/* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
|
||||
TPM2B_DIGEST_P_UNMARSHAL,
|
||||
TPMI_ALG_MAC_SCHEME_P_UNMARSHAL + ADD_FLAG,
|
||||
END_OF_LIST,
|
||||
UINT32_H_MARSHAL,
|
||||
END_OF_LIST}
|
||||
};
|
||||
#define _MAC_StartDataAddress (&_MAC_StartData)
|
||||
#else
|
||||
#define _MAC_StartDataAddress 0
|
||||
#endif
|
||||
#if CC_HashSequenceStart == YES
|
||||
#include "HashSequenceStart_fp.h"
|
||||
typedef TPM_RC (HashSequenceStart_Entry)(
|
||||
@ -2100,7 +2184,7 @@ PolicySigned_COMMAND_DESCRIPTOR_t _PolicySignedData = {
|
||||
UINT32_P_UNMARSHAL,
|
||||
TPMT_SIGNATURE_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
TPM2B_DIGEST_P_MARSHAL,
|
||||
TPM2B_TIMEOUT_P_MARSHAL,
|
||||
TPMT_TK_AUTH_P_MARSHAL,
|
||||
END_OF_LIST}
|
||||
};
|
||||
@ -2140,7 +2224,7 @@ PolicySecret_COMMAND_DESCRIPTOR_t _PolicySecretData = {
|
||||
TPM2B_DIGEST_P_UNMARSHAL,
|
||||
UINT32_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
TPM2B_DIGEST_P_MARSHAL,
|
||||
TPM2B_TIMEOUT_P_MARSHAL,
|
||||
TPMT_TK_AUTH_P_MARSHAL,
|
||||
END_OF_LIST}
|
||||
};
|
||||
@ -2172,7 +2256,7 @@ PolicyTicket_COMMAND_DESCRIPTOR_t _PolicyTicketData = {
|
||||
(UINT16)(offsetof(PolicyTicket_In, authName)),
|
||||
(UINT16)(offsetof(PolicyTicket_In, ticket))},
|
||||
/* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
|
||||
TPM2B_DIGEST_P_UNMARSHAL,
|
||||
TPM2B_TIMEOUT_P_UNMARSHAL,
|
||||
TPM2B_DIGEST_P_UNMARSHAL,
|
||||
TPM2B_DIGEST_P_UNMARSHAL,
|
||||
TPM2B_NAME_P_UNMARSHAL,
|
||||
@ -3802,6 +3886,108 @@ NV_Certify_COMMAND_DESCRIPTOR_t _NV_CertifyData = {
|
||||
#else
|
||||
#define _NV_CertifyDataAddress 0
|
||||
#endif
|
||||
#if CC_AC_GetCapability == YES
|
||||
#include "AC_GetCapability_fp.h"
|
||||
typedef TPM_RC (AC_GetCapability_Entry)(
|
||||
AC_GetCapability_In *in,
|
||||
AC_GetCapability_Out *out
|
||||
);
|
||||
typedef const struct {
|
||||
AC_GetCapability_Entry *entry;
|
||||
UINT16 inSize;
|
||||
UINT16 outSize;
|
||||
UINT16 offsetOfTypes;
|
||||
UINT16 paramOffsets[3];
|
||||
BYTE types[7];
|
||||
} AC_GetCapability_COMMAND_DESCRIPTOR_t;
|
||||
AC_GetCapability_COMMAND_DESCRIPTOR_t _AC_GetCapabilityData = {
|
||||
/* entry */ &TPM2_AC_GetCapability,
|
||||
/* inSize */ (UINT16)(sizeof(AC_GetCapability_In)),
|
||||
/* outSize */ (UINT16)(sizeof(AC_GetCapability_Out)),
|
||||
/* offsetOfTypes */ offsetof(AC_GetCapability_COMMAND_DESCRIPTOR_t, types),
|
||||
/* offsets */ {(UINT16)(offsetof(AC_GetCapability_In, capability)),
|
||||
(UINT16)(offsetof(AC_GetCapability_In, count)),
|
||||
(UINT16)(offsetof(AC_GetCapability_Out, capabilitiesData))},
|
||||
/* types */ {TPMI_RH_AC_H_UNMARSHAL,
|
||||
TPM_AT_P_UNMARSHAL,
|
||||
UINT32_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
UINT8_P_MARSHAL,
|
||||
TPML_AC_CAPABILITIES_P_MARSHAL,
|
||||
END_OF_LIST}
|
||||
};
|
||||
#define _AC_GetCapabilityDataAddress (&_AC_GetCapabilityData)
|
||||
#else
|
||||
#define _AC_GetCapabilityDataAddress 0
|
||||
#endif
|
||||
#if CC_AC_Send == YES
|
||||
#include "AC_Send_fp.h"
|
||||
typedef TPM_RC (AC_Send_Entry)(
|
||||
AC_Send_In *in,
|
||||
AC_Send_Out *out
|
||||
);
|
||||
typedef const struct {
|
||||
AC_Send_Entry *entry;
|
||||
UINT16 inSize;
|
||||
UINT16 outSize;
|
||||
UINT16 offsetOfTypes;
|
||||
UINT16 paramOffsets[3];
|
||||
BYTE types[7];
|
||||
} AC_Send_COMMAND_DESCRIPTOR_t;
|
||||
AC_Send_COMMAND_DESCRIPTOR_t _AC_SendData = {
|
||||
/* entry */ &TPM2_AC_Send,
|
||||
/* inSize */ (UINT16)(sizeof(AC_Send_In)),
|
||||
/* outSize */ (UINT16)(sizeof(AC_Send_Out)),
|
||||
/* offsetOfTypes */ offsetof(AC_Send_COMMAND_DESCRIPTOR_t, types),
|
||||
/* offsets */ {(UINT16)(offsetof(AC_Send_In, authHandle)),
|
||||
(UINT16)(offsetof(AC_Send_In, ac)),
|
||||
(UINT16)(offsetof(AC_Send_In, acDataIn))},
|
||||
/* types */ {TPMI_DH_OBJECT_H_UNMARSHAL,
|
||||
TPMI_RH_NV_AUTH_H_UNMARSHAL,
|
||||
TPMI_RH_AC_H_UNMARSHAL,
|
||||
TPM2B_MAX_BUFFER_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
TPMS_AC_OUTPUT_P_MARSHAL,
|
||||
END_OF_LIST}
|
||||
};
|
||||
#define _AC_SendDataAddress (&_AC_SendData)
|
||||
#else
|
||||
#define _AC_SendDataAddress 0
|
||||
#endif
|
||||
#if CC_Policy_AC_SendSelect == YES
|
||||
#include "Policy_AC_SendSelect_fp.h"
|
||||
typedef TPM_RC (Policy_AC_SendSelect_Entry)(
|
||||
Policy_AC_SendSelect_In *in
|
||||
);
|
||||
typedef const struct {
|
||||
Policy_AC_SendSelect_Entry *entry;
|
||||
UINT16 inSize;
|
||||
UINT16 outSize;
|
||||
UINT16 offsetOfTypes;
|
||||
UINT16 paramOffsets[4];
|
||||
BYTE types[7];
|
||||
} Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t;
|
||||
Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t _Policy_AC_SendSelectData = {
|
||||
/* entry */ &TPM2_Policy_AC_SendSelect,
|
||||
/* inSize */ (UINT16)(sizeof(Policy_AC_SendSelect_In)),
|
||||
/* outSize */ 0,
|
||||
/* offsetOfTypes */ offsetof(Policy_AC_SendSelect_COMMAND_DESCRIPTOR_t, types),
|
||||
/* offsets */ {(UINT16)(offsetof(Policy_AC_SendSelect_In, objectName)),
|
||||
(UINT16)(offsetof(Policy_AC_SendSelect_In, authHandleName)),
|
||||
(UINT16)(offsetof(Policy_AC_SendSelect_In, acName)),
|
||||
(UINT16)(offsetof(Policy_AC_SendSelect_In, includeObject))},
|
||||
/* types */ {TPMI_SH_POLICY_H_UNMARSHAL,
|
||||
TPM2B_NAME_P_UNMARSHAL,
|
||||
TPM2B_NAME_P_UNMARSHAL,
|
||||
TPM2B_NAME_P_UNMARSHAL,
|
||||
TPMI_YES_NO_P_UNMARSHAL,
|
||||
END_OF_LIST,
|
||||
END_OF_LIST}
|
||||
};
|
||||
#define _Policy_AC_SendSelectDataAddress (&_Policy_AC_SendSelectData)
|
||||
#else
|
||||
#define _Policy_AC_SendSelectDataAddress 0
|
||||
#endif
|
||||
#if CC_Vendor_TCG_Test == YES
|
||||
#include "Vendor_TCG_Test_fp.h"
|
||||
typedef TPM_RC (Vendor_TCG_Test_Entry)(
|
||||
@ -3994,9 +4180,17 @@ COMMAND_DESCRIPTOR_t *s_CommandDataArray[] = {
|
||||
#if (PAD_LIST || CC_ECDH_ZGen)
|
||||
(COMMAND_DESCRIPTOR_t *)_ECDH_ZGenDataAddress,
|
||||
#endif
|
||||
#if (PAD_LIST || CC_HMAC)
|
||||
#if (PAD_LIST || (CC_HMAC || CC_MAC))
|
||||
# if CC_HMAC
|
||||
(COMMAND_DESCRIPTOR_t *)_HMACDataAddress,
|
||||
#endif
|
||||
# endif
|
||||
# if CC_MAC
|
||||
(COMMAND_DESCRIPTOR_t *)_MACDataAddress,
|
||||
# endif
|
||||
# if (CC_HMAC || CC_MAC) > 1
|
||||
# error "More than one aliased command defined"
|
||||
# endif
|
||||
#endif // CC_HMAC CC_MAC
|
||||
#if (PAD_LIST || CC_Import)
|
||||
(COMMAND_DESCRIPTOR_t *)_ImportDataAddress,
|
||||
#endif
|
||||
@ -4012,9 +4206,17 @@ COMMAND_DESCRIPTOR_t *s_CommandDataArray[] = {
|
||||
#if (PAD_LIST)
|
||||
(COMMAND_DESCRIPTOR_t *)0,
|
||||
#endif
|
||||
#if (PAD_LIST || CC_HMAC_Start)
|
||||
#if (PAD_LIST || (CC_HMAC_Start || CC_MAC_Start))
|
||||
# if CC_HMAC_Start
|
||||
(COMMAND_DESCRIPTOR_t *)_HMAC_StartDataAddress,
|
||||
#endif
|
||||
# endif
|
||||
# if CC_MAC_Start
|
||||
(COMMAND_DESCRIPTOR_t *)_MAC_StartDataAddress,
|
||||
# endif
|
||||
# if (CC_HMAC_Start || CC_MAC_Start) > 1
|
||||
# error "More than one aliased command defined"
|
||||
# endif
|
||||
#endif // CC_HMAC_Start CC_MAC_Start
|
||||
#if (PAD_LIST || CC_SequenceUpdate)
|
||||
(COMMAND_DESCRIPTOR_t *)_SequenceUpdateDataAddress,
|
||||
#endif
|
||||
@ -4183,6 +4385,15 @@ COMMAND_DESCRIPTOR_t *s_CommandDataArray[] = {
|
||||
#if (PAD_LIST || CC_EncryptDecrypt2)
|
||||
(COMMAND_DESCRIPTOR_t *)_EncryptDecrypt2DataAddress,
|
||||
#endif
|
||||
#if (PAD_LIST || CC_AC_GetCapability)
|
||||
(COMMAND_DESCRIPTOR_t *)_AC_GetCapabilityDataAddress,
|
||||
#endif // CC_AC_GetCapability
|
||||
#if (PAD_LIST || CC_AC_Send)
|
||||
(COMMAND_DESCRIPTOR_t *)_AC_SendDataAddress,
|
||||
#endif // CC_AC_Send
|
||||
#if (PAD_LIST || CC_Policy_AC_SendSelect)
|
||||
(COMMAND_DESCRIPTOR_t *)_Policy_AC_SendSelectDataAddress,
|
||||
#endif // CC_Policy_AC_SendSelect
|
||||
#if (PAD_LIST || CC_Vendor_TCG_Test)
|
||||
(COMMAND_DESCRIPTOR_t *)_Vendor_TCG_TestDataAddress,
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CompilerDependencies.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CompilerDependencies.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2016 */
|
||||
/* (c) Copyright IBM Corp. and others, 2016, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Context Management */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: ContextCommands.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: ContextCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -63,6 +63,9 @@
|
||||
#include "ContextSave_fp.h"
|
||||
#ifdef TPM_CC_ContextSave // Conditional expansion of this file
|
||||
#include "Context_spt_fp.h"
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_CONTEXT_GAP a contextID could not be assigned for a session context save */
|
||||
/* TPM_RC_TOO_MANY_CONTEXTS no more contexts can be saved as the counter has maxed out */
|
||||
TPM_RC
|
||||
TPM2_ContextSave(
|
||||
ContextSave_In *in, // IN: input parameter list
|
||||
@ -82,7 +85,18 @@ TPM2_ContextSave(
|
||||
// the update of state reset data. If the state is orderly and
|
||||
// cannot be changed, exit early.
|
||||
RETURN_IF_ORDERLY;
|
||||
|
||||
// Internal Data Update
|
||||
|
||||
// This implementation does not do things in quite the same way as described in
|
||||
// Part 2 of the specification. In Part 2, it indicates that the
|
||||
// TPMS_CONTEXT_DATA contains two TPM2B values. That is not how this is
|
||||
// implemented. Rather, the size field of the TPM2B_CONTEXT_DATA is used to
|
||||
// determine the amount of data in the encrypted data. That part is not
|
||||
// independently sized. This makes the actual size 2 bytes smaller than
|
||||
// calculated using Part 2. Since this is opaque to the caller, it is not
|
||||
// necessary to fix. The actual size is returned by TPM2_GetCapabilties().
|
||||
|
||||
// Initialize output handle. At the end of command action, the output
|
||||
// handle of an object will be replaced, while the output handle
|
||||
// for a session will be the same as input
|
||||
@ -215,7 +229,6 @@ TPM2_ContextLoad(
|
||||
ContextLoad_Out *out // OUT: output parameter list
|
||||
)
|
||||
{
|
||||
// Local Variables
|
||||
TPM_RC result;
|
||||
TPM2B_DIGEST integrityToCompare;
|
||||
TPM2B_DIGEST integrity;
|
||||
@ -225,6 +238,9 @@ TPM2_ContextLoad(
|
||||
TPM2B_SYM_KEY symKey;
|
||||
TPM2B_IV iv;
|
||||
// Input Validation
|
||||
|
||||
// See discussion about the context format in TPM2_ContextSave Detailed Actions
|
||||
|
||||
// IF this is a session context, make sure that the sequence number is
|
||||
// consistent with the version in the slot
|
||||
// Check context blob size
|
||||
@ -297,7 +313,7 @@ TPM2_ContextLoad(
|
||||
RETURN_IF_ORDERLY;
|
||||
// Check if input handle points to a valid saved session and that the
|
||||
// sequence number makes sense
|
||||
if(!SequenceNumbereForSavedContextIsValid(&in->context))
|
||||
if(!SequenceNumberForSavedContextIsValid(&in->context))
|
||||
return TPM_RCS_HANDLE + RC_ContextLoad_context;
|
||||
// Restore session. A TPM_RC_SESSION_MEMORY, TPM_RC_CONTEXT_GAP error
|
||||
// may be returned at this point
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Context_spt.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Context_spt.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -75,7 +75,7 @@ ComputeContextProtectionKey(
|
||||
{
|
||||
UINT16 symKeyBits; // number of bits in the parent's
|
||||
// symmetric key
|
||||
TPM2B_AUTH *proof = NULL; // the proof value to use. Is null for
|
||||
TPM2B_PROOF *proof = NULL; // the proof value to use. Is null for
|
||||
// everything but a primary object in
|
||||
// the Endorsement Hierarchy
|
||||
BYTE kdfResult[sizeof(TPMU_HA) * 2];// Value produced by the KDF
|
||||
@ -119,7 +119,7 @@ ComputeContextIntegrity(
|
||||
)
|
||||
{
|
||||
HMAC_STATE hmacState;
|
||||
TPM2B_AUTH *proof;
|
||||
TPM2B_PROOF *proof;
|
||||
UINT16 integritySize;
|
||||
// Get proof value
|
||||
proof = HierarchyGetProof(contextBlob->hierarchy);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptSelfTest.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptSelfTest.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -189,7 +189,7 @@ CryptInitializeToTest(
|
||||
}
|
||||
/* 10.2.7.2.5 CryptTestAlgorithm() */
|
||||
/* Only point of contact with the actual self tests. If a self-test fails, there is no return and
|
||||
the TPM goes into failure mode. The call to TestAlgorithm() uses an algorithms selector and a bit
|
||||
the TPM goes into failure mode. The call to TestAlgorithm() uses an algorithm selector and a bit
|
||||
vector. When the test is run, the corresponding bit in toTest and in g_toTest is CLEAR. If toTest
|
||||
is NULL, then only the bit in g_toTest is CLEAR. There is a special case for the call to
|
||||
TestAlgorithm(). When alg is TPM_ALG_ERROR, TestAlgorithm() will CLEAR any bit in toTest for
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Interfaces to the CryptoEngine() */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptUtil.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptUtil.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -129,6 +129,7 @@ CryptHMACVerifySignature(
|
||||
/* 10.2.6.3.3 CryptGenerateKeyedHash() */
|
||||
/* This function creates a keyedHash object. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_NO_RESULT cannot get values from random number generator */
|
||||
/* TPM_RC_SIZE sensitive data size is larger than allowed for the scheme */
|
||||
static TPM_RC
|
||||
CryptGenerateKeyedHash(
|
||||
@ -163,8 +164,8 @@ CryptGenerateKeyedHash(
|
||||
//If the user provided the key, check that it is a proper size
|
||||
if(sensitiveCreate->data.t.size != 0)
|
||||
{
|
||||
if(publicArea->objectAttributes.decrypt
|
||||
|| publicArea->objectAttributes.sign)
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
|
||||
|| IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
{
|
||||
if(sensitiveCreate->data.t.size > hashBlockSize)
|
||||
return TPM_RC_SIZE;
|
||||
@ -180,12 +181,12 @@ CryptGenerateKeyedHash(
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the TPM is going to generate the data, then set the size to be the
|
||||
// The TPM is going to generate the data, so set the size to be the
|
||||
// size of the digest of the algorithm
|
||||
int sizeInBits = digestSize * 8;
|
||||
TPM2B_SENSITIVE_DATA *key = &sensitive->sensitive.bits;
|
||||
key->t.size = CryptRandMinMax(key->t.buffer, sizeInBits, sizeInBits / 2,
|
||||
rand);
|
||||
sensitive->sensitive.bits.t.size =
|
||||
DRBG_Generate(rand, sensitive->sensitive.bits.t.buffer, digestSize);
|
||||
if(sensitive->sensitive.bits.t.size == 0)
|
||||
return TPM_RC_NO_RESULT;
|
||||
}
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
@ -240,7 +241,7 @@ void
|
||||
ParmEncryptSym(
|
||||
TPM_ALG_ID symAlg, // IN: symmetric algorithm
|
||||
TPM_ALG_ID hash, // IN: hash algorithm for KDFa
|
||||
UINT16 keySizeInBits, // IN: AES key size in bits
|
||||
UINT16 keySizeInBits, // IN: AES symmetric key size in bits
|
||||
TPM2B *key, // IN: KDF HMAC key
|
||||
TPM2B *nonceCaller, // IN: nonce caller
|
||||
TPM2B *nonceTpm, // IN: nonce TPM
|
||||
@ -271,9 +272,10 @@ ParmEncryptSym(
|
||||
/* This function generates a symmetric cipher key. The derivation process is determined by the type
|
||||
of the provided rand */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RCS_KEY_SIZE key size in the public area does not match the size in the sensitive creation
|
||||
/* TPM_RC_NO_RESULT cannot get a random value */
|
||||
/* TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive creation
|
||||
area */
|
||||
/* TPM_RCS_KEY provided key value is not allowed */
|
||||
/* TPM_RC_KEY provided key value is not allowed */
|
||||
static TPM_RC
|
||||
CryptGenerateKeySymmetric(
|
||||
TPMT_PUBLIC *publicArea, // IN/OUT: The public area template
|
||||
@ -307,9 +309,13 @@ CryptGenerateKeySymmetric(
|
||||
#endif
|
||||
else
|
||||
{
|
||||
sensitive->sensitive.sym.t.size = CryptRandMinMax(
|
||||
sensitive->sensitive.sym.t.buffer, keyBits, keyBits / 2, rand);
|
||||
result = TPM_RC_SUCCESS;
|
||||
{
|
||||
sensitive->sensitive.sym.t.size =
|
||||
DRBG_Generate(rand, sensitive->sensitive.sym.t.buffer,
|
||||
BITS_TO_BYTES(keyBits));
|
||||
result = (sensitive->sensitive.sym.t.size == 0)
|
||||
? TPM_RC_NO_RESULT : TPM_RC_SUCCESS;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -475,7 +481,7 @@ CryptSecretEncrypt(
|
||||
// The encryption scheme is OAEP using the nameAlg of the encrypt key.
|
||||
scheme.scheme = TPM_ALG_OAEP;
|
||||
scheme.details.anySig.hashAlg = encryptKey->publicArea.nameAlg;
|
||||
if(encryptKey->publicArea.objectAttributes.decrypt != SET)
|
||||
if(!IS_ATTRIBUTE(encryptKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
|
||||
return TPM_RC_ATTRIBUTES;
|
||||
switch(encryptKey->publicArea.type)
|
||||
{
|
||||
@ -678,8 +684,7 @@ CryptSecretDecrypt(
|
||||
// seed = XOR(secret, hash, key, nonceCaller, nullNonce)
|
||||
// where:
|
||||
// secret the secret parameter from the TPM2_StartAuthHMAC
|
||||
// command
|
||||
// which contains the seed value
|
||||
// command that contains the seed value
|
||||
// hash nameAlg of tpmKey
|
||||
// key the key or data value in the object referenced by
|
||||
// entityHandle in the TPM2_StartAuthHMAC command
|
||||
@ -779,7 +784,7 @@ CryptParameterEncryption(
|
||||
{
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
}
|
||||
// Compute encryption key by concatenating sessionAuth with extra key
|
||||
// Compute encryption key by concatenating sessionKey with extra key
|
||||
MemoryCopy2B(&key.b, &session->sessionKey.b, sizeof(key.t.buffer));
|
||||
MemoryConcat2B(&key.b, &extraKey->b, sizeof(key.t.buffer));
|
||||
if(session->symmetric.algorithm == TPM_ALG_XOR)
|
||||
@ -869,8 +874,8 @@ CryptComputeSymmetricUnique(
|
||||
{
|
||||
// For parents (symmetric and derivation), use an HMAC to compute
|
||||
// the 'unique' field
|
||||
if(publicArea->objectAttributes.restricted
|
||||
&& publicArea->objectAttributes.decrypt)
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
|
||||
&& IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
// Unique field is HMAC(sensitive->seedValue, sensitive->sensitive)
|
||||
HMAC_STATE hmacState;
|
||||
@ -906,12 +911,13 @@ CryptComputeSymmetricUnique(
|
||||
use seed, label and context with context being the hash of the template. If the Primary Object is
|
||||
in the Endorsement hierarchy, it will also populate proof with ehProof. */
|
||||
/* For derived keys, seed will be the secret value from the parent, label and context will be set
|
||||
according to the parameters of TPM2_Derive() and hashAlg will be set which causes the RAND_STATE
|
||||
according to the parameters of TPM2_CreateLoaded() and hashAlg will be set which causes the RAND_STATE
|
||||
to be a KDF generator. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_KEY a provided key is not an allowed value */
|
||||
/* TPM_RC_KEY_SIZE key size in the public area does not match the size in the sensitive creation
|
||||
area for a symmetric key */
|
||||
/* TPM_RC_NO_RESULT unable to get random values (only in derivation) */
|
||||
/* TPM_RC_RANGE for an RSA key, the exponent is not supported */
|
||||
/* TPM_RC_SIZE sensitive data size is larger than allowed for the scheme for a keyed hash object */
|
||||
/* TPM_RC_VALUE exponent is not prime or could not find a prime using the provided parameters for an
|
||||
@ -933,7 +939,8 @@ CryptCreateObject(
|
||||
object->sensitive.authValue = sensitiveCreate->userAuth;
|
||||
// If the TPM is the source of the data, set the size of the provided data to
|
||||
// zero so that there's no confusion about what to do.
|
||||
if(object->publicArea.objectAttributes.sensitiveDataOrigin)
|
||||
if(IS_ATTRIBUTE(object->publicArea.objectAttributes,
|
||||
TPMA_OBJECT, sensitiveDataOrigin))
|
||||
sensitiveCreate->data.t.size = 0;
|
||||
// Generate the key and unique fields for the asymmetric keys and just the
|
||||
// sensitive value for symmetric object
|
||||
@ -971,18 +978,20 @@ CryptCreateObject(
|
||||
return result;
|
||||
// Create the sensitive seed value
|
||||
// If this is a primary key in the endorsement hierarchy, stir the DRBG state
|
||||
// This implementation uses the proof of the storage hierarchy but the
|
||||
// proof of the endorsement hierarchy would also work
|
||||
// This implementation uses both shProof and ehProof to make sure that there
|
||||
// is no leakage of either.
|
||||
if(object->attributes.primary && object->attributes.epsHierarchy)
|
||||
DRBG_AdditionalData((DRBG_STATE *)rand, &gp.shProof.b);
|
||||
// Set the seed value to the size of the digest produced by the nameAlg
|
||||
object->sensitive.seedValue.b.size
|
||||
= CryptHashGetDigestSize(publicArea->nameAlg);
|
||||
object->sensitive.seedValue.t.size = CryptRandMinMax(
|
||||
object->sensitive.seedValue.t.buffer,
|
||||
object->sensitive.seedValue.t.size * 8,
|
||||
object->sensitive.seedValue.t.size * 8 / 2, rand);
|
||||
// For symmetric values, need to compute the unique value
|
||||
{
|
||||
DRBG_AdditionalData((DRBG_STATE *)rand, &gp.shProof.b);
|
||||
DRBG_AdditionalData((DRBG_STATE *)rand, &gp.ehProof.b);
|
||||
}
|
||||
// Generate a seedValue that is the size of the digest produced by nameAlg
|
||||
object->sensitive.seedValue.t.size =
|
||||
DRBG_Generate(rand, object->sensitive.seedValue.t.buffer,
|
||||
CryptHashGetDigestSize(publicArea->nameAlg));
|
||||
if(object->sensitive.seedValue.t.size == 0)
|
||||
return TPM_RC_NO_RESULT;
|
||||
// For symmetric objects, need to compute the unique value for the public area
|
||||
if(publicArea->type == TPM_ALG_SYMCIPHER
|
||||
|| publicArea->type == TPM_ALG_KEYEDHASH)
|
||||
{
|
||||
@ -992,9 +1001,9 @@ CryptCreateObject(
|
||||
else
|
||||
{
|
||||
// if this is an asymmetric key and it isn't a parent, then
|
||||
// can get rid of the seed.
|
||||
if(publicArea->objectAttributes.sign
|
||||
|| !publicArea->objectAttributes.restricted)
|
||||
// get rid of the seed.
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
|
||||
|| !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
|
||||
memset(&object->sensitive.seedValue, 0,
|
||||
sizeof(object->sensitive.seedValue));
|
||||
}
|
||||
@ -1648,8 +1657,13 @@ CryptValidateKeys(
|
||||
if(publicArea->nameAlg != TPM_ALG_NULL)
|
||||
{
|
||||
TPM2B_DIGEST compare;
|
||||
#if 1
|
||||
if(sensitive->seedValue.t.size != digestSize)
|
||||
return TPM_RCS_KEY_SIZE;
|
||||
#else
|
||||
if((sensitive->seedValue.t.size > digestSize)
|
||||
|| (sensitive->seedValue.t.size < digestSize/2))
|
||||
#endif
|
||||
return TPM_RCS_KEY_SIZE;
|
||||
CryptComputeSymmetricUnique(publicArea, sensitive, &compare);
|
||||
if(!MemoryEqual2B(&unique->sym.b, &compare.b))
|
||||
return TPM_RC_BINDING;
|
||||
@ -1659,8 +1673,8 @@ CryptValidateKeys(
|
||||
}
|
||||
// For a parent, need to check that the seedValue is the correct size for
|
||||
// protections. It should be at least half the size of the nameAlg
|
||||
if(publicArea->objectAttributes.restricted
|
||||
&& publicArea->objectAttributes.decrypt
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
|
||||
&& IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
|
||||
&& sensitive != NULL
|
||||
&& publicArea->nameAlg != TPM_ALG_NULL)
|
||||
{
|
||||
@ -1682,3 +1696,140 @@ CryptAlgsSetImplemented(
|
||||
{
|
||||
AlgorithmGetImplementedVector(&g_implementedAlgorithms);
|
||||
}
|
||||
/* 10.2.6.6.21 CryptSelectMac() */
|
||||
/* This function is used to set the MAC scheme based on the key parameters and the input scheme. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SCHEME the scheme is not a valid mac scheme */
|
||||
/* TPM_RC_TYPE the input key is not a type that supports a mac */
|
||||
/* TPM_RC_VALUE the input scheme and the key scheme are not compatible */
|
||||
TPM_RC
|
||||
CryptSelectMac(
|
||||
TPMT_PUBLIC *publicArea,
|
||||
TPMI_ALG_MAC_SCHEME *inMac
|
||||
)
|
||||
{
|
||||
TPM_ALG_ID macAlg = TPM_ALG_NULL;
|
||||
switch(publicArea->type)
|
||||
{
|
||||
case TPM_ALG_KEYEDHASH:
|
||||
{
|
||||
// Local value to keep lines from getting too long
|
||||
TPMT_KEYEDHASH_SCHEME *scheme;
|
||||
scheme = &publicArea->parameters.keyedHashDetail.scheme;
|
||||
// Expect that the scheme is either HMAC or NULL
|
||||
if(scheme->scheme != TPM_ALG_NULL)
|
||||
macAlg = scheme->details.hmac.hashAlg;
|
||||
break;
|
||||
}
|
||||
case TPM_ALG_SYMCIPHER:
|
||||
{
|
||||
TPMT_SYM_DEF_OBJECT *scheme;
|
||||
scheme = &publicArea->parameters.symDetail.sym;
|
||||
// Expect that the scheme is either valid symmetric cipher or NULL
|
||||
if(scheme->algorithm != TPM_ALG_NULL)
|
||||
macAlg = scheme->mode.sym;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return TPM_RCS_TYPE;
|
||||
}
|
||||
// If the input value is not TPM_ALG_NULL ...
|
||||
if(*inMac != TPM_ALG_NULL)
|
||||
{
|
||||
// ... then either the scheme in the key must be TPM_ALG_NULL or the input
|
||||
// value must match
|
||||
if((macAlg != TPM_ALG_NULL) && (*inMac != macAlg))
|
||||
return TPM_RCS_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since the input value is TPM_ALG_NULL, then the key value can't be
|
||||
// TPM_ALG_NULL
|
||||
if(macAlg == TPM_ALG_NULL)
|
||||
return TPM_RCS_VALUE;
|
||||
*inMac = macAlg;
|
||||
}
|
||||
if(!CryptMacIsValidForKey(publicArea->type, *inMac, FALSE))
|
||||
return TPM_RCS_SCHEME;
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
/* 10.2.6.6.22 CryptMacIsValidForKey() */
|
||||
/* Check to see if the key type is compatible with the mac type */
|
||||
BOOL
|
||||
CryptMacIsValidForKey(
|
||||
TPM_ALG_ID keyType,
|
||||
TPM_ALG_ID macAlg,
|
||||
BOOL flag
|
||||
)
|
||||
{
|
||||
switch(keyType)
|
||||
{
|
||||
case TPM_ALG_KEYEDHASH:
|
||||
return CryptHashIsValidAlg(macAlg, flag);
|
||||
break;
|
||||
case TPM_ALG_SYMCIPHER:
|
||||
return CryptSmacIsValidAlg(macAlg, flag);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
/* 10.2.6.6.23 CryptSmacIsValidAlg() */
|
||||
/* This function is used to test if an algorithm is a supported SMAC algorithm. It needs to be
|
||||
updated as new algorithms are added. */
|
||||
BOOL
|
||||
CryptSmacIsValidAlg(
|
||||
TPM_ALG_ID alg,
|
||||
BOOL FLAG // IN: Indicates if TPM_ALG_NULL is valid
|
||||
)
|
||||
{
|
||||
switch (alg)
|
||||
{
|
||||
#ifdef TPM_ALG_CMAC
|
||||
case TPM_ALG_CMAC:
|
||||
return TRUE;
|
||||
break;
|
||||
#endif
|
||||
case TPM_ALG_NULL:
|
||||
return FLAG;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* 10.2.6.6.24 CryptSymModeIsValid() */
|
||||
/* Function checks to see if an algorithm ID is a valid, symmetric block cipher mode for the TPM. If
|
||||
flag is SET, them TPM_ALG_NULL is a valid mode. not include the modes used for SMAC */
|
||||
BOOL
|
||||
CryptSymModeIsValid(
|
||||
TPM_ALG_ID mode,
|
||||
BOOL flag
|
||||
)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
#if ALG_CTR
|
||||
case TPM_ALG_CTR:
|
||||
#endif // ALG_CTR
|
||||
#if ALG_OFB
|
||||
case TPM_ALG_OFB:
|
||||
#endif // ALG_OFB
|
||||
#if ALG_CBC
|
||||
case TPM_ALG_CBC:
|
||||
#endif // ALG_CBC
|
||||
#if ALG_CFB
|
||||
case TPM_ALG_CFB:
|
||||
#endif // ALG_CFB
|
||||
#if ALG_ECB
|
||||
case TPM_ALG_ECB:
|
||||
#endif // ALG_ECB
|
||||
return TRUE;
|
||||
case TPM_ALG_NULL:
|
||||
return flag;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptUtil_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptUtil_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -220,6 +220,26 @@ void
|
||||
CryptAlgsSetImplemented(
|
||||
void
|
||||
);
|
||||
|
||||
TPM_RC
|
||||
CryptSelectMac(
|
||||
TPMT_PUBLIC *publicArea,
|
||||
TPMI_ALG_MAC_SCHEME *inMac
|
||||
);
|
||||
BOOL
|
||||
CryptMacIsValidForKey(
|
||||
TPM_ALG_ID keyType,
|
||||
TPM_ALG_ID macAlg,
|
||||
BOOL flag
|
||||
);
|
||||
BOOL
|
||||
CryptSmacIsValidAlg(
|
||||
TPM_ALG_ID alg,
|
||||
BOOL FLAG // IN: Indicates if TPM_ALG_NULL is valid
|
||||
);
|
||||
BOOL
|
||||
CryptSymModeIsValid(
|
||||
TPM_ALG_ID mode,
|
||||
BOOL flag
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Dictionary Attack Logic. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: DA.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: DA.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -89,7 +89,7 @@ DAPreInstall_Init(
|
||||
NV_SYNC_PERSISTENT(lockOutAuthEnabled);
|
||||
return;
|
||||
}
|
||||
/* 8.2.3.3 DAStartup() */
|
||||
/* 8.2.3.2 DAStartup() */
|
||||
/* This function is called by TPM2_Startup() to initialize the DA parameters. In the case of
|
||||
Startup(CLEAR), use of lockoutAuth will be enabled if the lockout recovery time is 0. Otherwise,
|
||||
lockoutAuth will not be enabled until the TPM has been continuously powered for the
|
||||
@ -153,7 +153,7 @@ DAStartup(
|
||||
TimeUpdate();
|
||||
return;
|
||||
}
|
||||
/* 8.2.3.4 DARegisterFailure() */
|
||||
/* 8.2.3.3 DARegisterFailure() */
|
||||
/* This function is called when a authorization failure occurs on an entity that is subject to
|
||||
dictionary-attack protection. When a DA failure is triggered, register the failure by resetting
|
||||
the relevant self-healing timer to the current time. */
|
||||
@ -169,7 +169,7 @@ DARegisterFailure(
|
||||
s_selfHealTimer = g_time;
|
||||
return;
|
||||
}
|
||||
/* 8.2.3.5 DASelfHeal() */
|
||||
/* 8.2.3.4 DASelfHeal() */
|
||||
/* This function is called to check if sufficient time has passed to allow decrement of failedTries
|
||||
or to re-enable use of lockoutAuth. */
|
||||
/* This function should be called when the time interval is updated. */
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Duplication Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: DuplicationCommands.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: DuplicationCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -81,7 +81,7 @@ TPM2_Duplicate(
|
||||
// Get new parent
|
||||
newParent = HandleToObject(in->newParentHandle);
|
||||
// duplicate key must have fixParent bit CLEAR.
|
||||
if(object->publicArea.objectAttributes.fixedParent == SET)
|
||||
if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, fixedParent))
|
||||
return TPM_RCS_ATTRIBUTES + RC_Duplicate_objectHandle;
|
||||
// Do not duplicate object with NULL nameAlg
|
||||
if(object->publicArea.nameAlg == TPM_ALG_NULL)
|
||||
@ -92,7 +92,8 @@ TPM2_Duplicate(
|
||||
return TPM_RCS_TYPE + RC_Duplicate_newParentHandle;
|
||||
// If the duplicated object has encryptedDuplication SET, then there must be
|
||||
// an inner wrapper and the new parent may not be TPM_RH_NULL
|
||||
if(object->publicArea.objectAttributes.encryptedDuplication == SET)
|
||||
if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT,
|
||||
encryptedDuplication))
|
||||
{
|
||||
if(in->symmetricAlg.algorithm == TPM_ALG_NULL)
|
||||
return TPM_RCS_SYMMETRIC + RC_Duplicate_symmetricAlg;
|
||||
@ -167,7 +168,7 @@ TPM2_Rewrap(
|
||||
return TPM_RCS_HANDLE + RC_Rewrap_oldParent;
|
||||
if(in->oldParent != TPM_RH_NULL)
|
||||
{
|
||||
OBJECT *oldParent = HandleToObject(in->oldParent);;
|
||||
OBJECT *oldParent = HandleToObject(in->oldParent);
|
||||
// old parent key must be a storage object
|
||||
if(!ObjectIsStorage(in->oldParent))
|
||||
return TPM_RCS_TYPE + RC_Rewrap_oldParent;
|
||||
@ -260,12 +261,15 @@ TPM2_Import(
|
||||
TPM2B_DATA data; // symmetric key
|
||||
TPMT_SENSITIVE sensitive;
|
||||
TPM2B_NAME name;
|
||||
TPMA_OBJECT attributes;
|
||||
UINT16 innerKeySize = 0; // encrypt key size for inner
|
||||
// wrapper
|
||||
// Input Validation
|
||||
// to save typing
|
||||
attributes = in->objectPublic.publicArea.objectAttributes;
|
||||
// FixedTPM and fixedParent must be CLEAR
|
||||
if(in->objectPublic.publicArea.objectAttributes.fixedTPM == SET
|
||||
|| in->objectPublic.publicArea.objectAttributes.fixedParent == SET)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM)
|
||||
|| IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent))
|
||||
return TPM_RCS_ATTRIBUTES + RC_Import_objectPublic;
|
||||
// Get parent pointer
|
||||
parentObject = HandleToObject(in->parentHandle);
|
||||
@ -287,7 +291,7 @@ TPM2_Import(
|
||||
return TPM_RCS_SIZE + RC_Import_encryptionKey;
|
||||
// If encryptedDuplication is SET, then the object must have an inner
|
||||
// wrapper
|
||||
if(in->objectPublic.publicArea.objectAttributes.encryptedDuplication)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication))
|
||||
return TPM_RCS_ATTRIBUTES + RC_Import_encryptionKey;
|
||||
}
|
||||
// See if there is an outer wrapper
|
||||
@ -310,7 +314,7 @@ TPM2_Import(
|
||||
{
|
||||
// If encrytpedDuplication is set, then the object must have an outer
|
||||
// wrapper
|
||||
if(in->objectPublic.publicArea.objectAttributes.encryptedDuplication)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication))
|
||||
return TPM_RCS_ATTRIBUTES + RC_Import_inSymSeed;
|
||||
data.t.size = 0;
|
||||
}
|
||||
@ -329,7 +333,7 @@ TPM2_Import(
|
||||
// If the parent of this object has fixedTPM SET, then validate this
|
||||
// object as if it were being loaded so that validation can be skipped
|
||||
// when it is actually loaded.
|
||||
if(parentObject->publicArea.objectAttributes.fixedTPM == SET)
|
||||
if(IS_ATTRIBUTE(parentObject->publicArea.objectAttributes, TPMA_OBJECT, fixedTPM))
|
||||
{
|
||||
result = ObjectLoad(NULL, NULL, &in->objectPublic.publicArea,
|
||||
&sensitive, RC_Import_objectPublic, RC_Import_duplicate,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Enhanced Authorization Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: EACommands.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: EACommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -155,18 +155,23 @@ TPM2_PolicySigned(
|
||||
&& session->attributes.isTrialPolicy == CLEAR)
|
||||
{
|
||||
BOOL expiresOnReset = (in->nonceTPM.t.size == 0);
|
||||
// Generate timeout buffer. The format of output timeout buffer is
|
||||
// TPM-specific.
|
||||
// In this implementation, the timeout parameter is the timeout relative
|
||||
// to g_time with a one byte flag to indicate if the ticket will expire on
|
||||
// TPM Reset
|
||||
out->timeout.t.size = sizeof(authTimeout) + 1;
|
||||
UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
|
||||
out->timeout.t.buffer[sizeof(authTimeout)] = (BYTE)expiresOnReset;
|
||||
// Compute policy ticket
|
||||
authTimeout &= ~EXPIRATION_BIT;
|
||||
TicketComputeAuth(TPM_ST_AUTH_SIGNED, EntityGetHierarchy(in->authObject),
|
||||
authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef,
|
||||
&entityName, &out->policyTicket);
|
||||
// Generate timeout buffer. The format of output timeout buffer is
|
||||
// TPM-specific.
|
||||
// Note: In this implementation, the timeout buffer value is computed after
|
||||
// the ticket is produced so, when the ticket is checked, the expiration
|
||||
// flag needs to be extracted before the ticket is checked.
|
||||
// In the Windows compatible version, the least-significant bit of the
|
||||
// timeout value is used as a flag to indicate if the authorization expires
|
||||
// on reset. The flag is the MSb.
|
||||
out->timeout.t.size = sizeof(authTimeout);
|
||||
if(expiresOnReset)
|
||||
authTimeout |= EXPIRATION_BIT;
|
||||
UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -231,18 +236,23 @@ TPM2_PolicySecret(
|
||||
&& !NvIsPinPassIndex(in->authHandle))
|
||||
{
|
||||
BOOL expiresOnReset = (in->nonceTPM.t.size == 0);
|
||||
// Generate timeout buffer. The format of output timeout buffer is
|
||||
// TPM-specific.
|
||||
// In this implementation, the timeout parameter is the timeout relative
|
||||
// to g_time with a one byte flag to indicate if the ticket will expire on
|
||||
// TPM Reset
|
||||
out->timeout.t.size = sizeof(authTimeout) + 1;
|
||||
UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
|
||||
out->timeout.t.buffer[sizeof(authTimeout)] = (BYTE)expiresOnReset;
|
||||
// Compute policy ticket
|
||||
authTimeout &= ~EXPIRATION_BIT;
|
||||
TicketComputeAuth(TPM_ST_AUTH_SECRET, EntityGetHierarchy(in->authHandle),
|
||||
authTimeout, expiresOnReset, &in->cpHashA, &in->policyRef,
|
||||
&entityName, &out->policyTicket);
|
||||
// Generate timeout buffer. The format of output timeout buffer is
|
||||
// TPM-specific.
|
||||
// Note: In this implementation, the timeout buffer value is computed after
|
||||
// the ticket is produced so, when the ticket is checked, the expiration
|
||||
// flag needs to be extracted before the ticket is checked.
|
||||
out->timeout.t.size = sizeof(authTimeout);
|
||||
// In the Windows compatible version, the least-significant bit of the
|
||||
// timeout value is used as a flag to indicate if the authorization expires
|
||||
// on reset. The flag is the MSb.
|
||||
if(expiresOnReset)
|
||||
authTimeout |= EXPIRATION_BIT;
|
||||
UINT64_TO_BYTE_ARRAY(authTimeout, out->timeout.t.buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -287,12 +297,16 @@ TPM2_PolicyTicket(
|
||||
if(session->attributes.isTrialPolicy)
|
||||
return TPM_RCS_ATTRIBUTES + RC_PolicyTicket_policySession;
|
||||
// Restore timeout data. The format of timeout buffer is TPM-specific.
|
||||
// In this implementation, we simply copy the value of timeout to the
|
||||
// buffer.
|
||||
if(in->timeout.t.size != sizeof(UINT64) + 1)
|
||||
// In this implementation, the most significant bit of the timeout value is
|
||||
// used as the flag to indicate that the ticket expires on TPM Reset or
|
||||
// TPM Restart. The flag has to be removed before the parameters and ticket
|
||||
// are checked.
|
||||
if(in->timeout.t.size != sizeof(UINT64))
|
||||
return TPM_RCS_SIZE + RC_PolicyTicket_timeout;
|
||||
authTimeout = BYTE_ARRAY_TO_UINT64(in->timeout.t.buffer);
|
||||
expiresOnReset = in->timeout.t.buffer[sizeof(authTimeout)];
|
||||
// extract the flag
|
||||
expiresOnReset = (authTimeout & EXPIRATION_BIT) != 0;
|
||||
authTimeout &= ~EXPIRATION_BIT;
|
||||
// Do the normal checks on the cpHashA and timeout values
|
||||
result = PolicyParameterChecks(session, authTimeout,
|
||||
&in->cpHashA,
|
||||
@ -898,7 +912,7 @@ TPM2_PolicyAuthorize(
|
||||
hashAlg = BYTE_ARRAY_TO_UINT16(in->keySign.t.name);
|
||||
// 'keySign' parameter needs to use a supported hash algorithm, otherwise
|
||||
// can't tell how large the digest should be
|
||||
if(!CryptHashIsImplemented(hashAlg, 0))
|
||||
if(!CryptHashIsValidAlg(hashAlg, FALSE))
|
||||
return TPM_RCS_HASH + RC_PolicyAuthorize_keySign;
|
||||
digestSize = CryptHashGetDigestSize(hashAlg);
|
||||
if(digestSize != (in->keySign.t.size - 2))
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: EncryptDecrypt2_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: EncryptDecrypt2_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -59,17 +59,17 @@
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* rev 134 */
|
||||
/* rev 146 */
|
||||
|
||||
#ifndef ENCRYPTDECRYPT2_FP_H
|
||||
#define ENCRYPTDECRYPT2_FP_H
|
||||
|
||||
typedef struct {
|
||||
TPMI_DH_OBJECT keyHandle;
|
||||
TPM2B_MAX_BUFFER inData;
|
||||
TPMI_YES_NO decrypt;
|
||||
TPMI_ALG_SYM_MODE mode;
|
||||
TPM2B_IV ivIn;
|
||||
TPMI_DH_OBJECT keyHandle;
|
||||
TPM2B_MAX_BUFFER inData;
|
||||
TPMI_YES_NO decrypt;
|
||||
TPMI_ALG_CIPHER_MODE mode;
|
||||
TPM2B_IV ivIn;
|
||||
} EncryptDecrypt2_In;
|
||||
|
||||
#define RC_EncryptDecrypt2_keyHandle (TPM_RC_H + TPM_RC_1)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: EncryptDecrypt_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: EncryptDecrypt_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -65,11 +65,11 @@
|
||||
#define ENCRYPTDECRYPT_FP_H
|
||||
|
||||
typedef struct {
|
||||
TPMI_DH_OBJECT keyHandle;
|
||||
TPMI_YES_NO decrypt;
|
||||
TPMI_ALG_SYM_MODE mode;
|
||||
TPM2B_IV ivIn;
|
||||
TPM2B_MAX_BUFFER inData;
|
||||
TPMI_DH_OBJECT keyHandle;
|
||||
TPMI_YES_NO decrypt;
|
||||
TPMI_ALG_CIPHER_MODE mode;
|
||||
TPM2B_IV ivIn;
|
||||
TPM2B_MAX_BUFFER inData;
|
||||
} EncryptDecrypt_In;
|
||||
|
||||
#define RC_EncryptDecrypt_keyHandle (TPM_RC_H + TPM_RC_1)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Encrypt Decrypt Support */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: EncryptDecrypt_spt.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: EncryptDecrypt_spt.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -94,13 +94,19 @@ EncryptDecryptShared(
|
||||
if(symKey->publicArea.type != TPM_ALG_SYMCIPHER)
|
||||
return TPM_RCS_KEY + RC_EncryptDecrypt_keyHandle;
|
||||
// The key must be unrestricted and allow the selected operation
|
||||
OK = symKey->publicArea.objectAttributes.restricted != SET;
|
||||
OK = !IS_ATTRIBUTE(symKey->publicArea.objectAttributes,
|
||||
TPMA_OBJECT, restricted);
|
||||
if(YES == decryptIn)
|
||||
OK = OK && symKey->publicArea.objectAttributes.decrypt == SET;
|
||||
OK = OK && IS_ATTRIBUTE(symKey->publicArea.objectAttributes,
|
||||
TPMA_OBJECT, decrypt);
|
||||
else
|
||||
OK = OK && symKey->publicArea.objectAttributes.sign == SET;
|
||||
OK = OK && IS_ATTRIBUTE(symKey->publicArea.objectAttributes,
|
||||
TPMA_OBJECT, sign);
|
||||
if(!OK)
|
||||
return TPM_RCS_ATTRIBUTES + RC_EncryptDecrypt_keyHandle;
|
||||
// Make sure that key is an encrypt/decrypt key and not SMAC
|
||||
if(!CryptSymModeIsValid(mode, TRUE))
|
||||
return TPM_RCS_MODE + RC_EncryptDecrypt_keyHandle;
|
||||
// If the key mode is not TPM_ALG_NULL...
|
||||
// or TPM_ALG_NULL
|
||||
if(mode != TPM_ALG_NULL)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Accessing properties for handles of various types */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Entity.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Entity.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -448,7 +448,8 @@ EntityGetHierarchy(
|
||||
// If only the platform can delete the index, then it is
|
||||
// considered to be in the platform hierarchy, otherwise it
|
||||
// is in the owner hierarchy.
|
||||
if(IsNv_TPMA_NV_PLATFORMCREATE(nvIndex->publicArea.attributes))
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV,
|
||||
PLATFORMCREATE))
|
||||
hierarchy = TPM_RH_PLATFORM;
|
||||
else
|
||||
hierarchy = TPM_RH_OWNER;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* TPM variables that are not stack allocated */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Global.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Global.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -79,7 +79,6 @@ UINT64 g_time;
|
||||
#ifdef CLOCK_STOPS
|
||||
CLOCK_NONCE g_timeEpoch;
|
||||
#endif
|
||||
BOOL g_timeNewEpochNeeded;
|
||||
BOOL g_pcrReConfig;
|
||||
TPMI_DH_OBJECT g_DRTMHandle;
|
||||
BOOL g_DrtmPreStartup;
|
||||
@ -94,6 +93,15 @@ UPDATE_TYPE g_updateNV;
|
||||
BOOL g_nvOk;
|
||||
TPM_RC g_NvStatus;
|
||||
TPM2B_AUTH g_platformUniqueDetails;
|
||||
ALGORITHM_VECTOR g_implementedAlgorithms;
|
||||
ALGORITHM_VECTOR g_toTest;
|
||||
CRYPTO_SELF_TEST_STATE g_cryptoSelfTestState; // This structure contains the
|
||||
// cryptographic self-test
|
||||
#ifdef SIMULATION
|
||||
BOOL g_forceFailureMode;
|
||||
#endif
|
||||
BOOL g_inFailureMode;
|
||||
// cryptographic self-test
|
||||
STATE_CLEAR_DATA gc;
|
||||
STATE_RESET_DATA gr;
|
||||
PERSISTENT_DATA gp;
|
||||
@ -127,9 +135,11 @@ UINT64 s_maxCounter;
|
||||
NV_REF s_evictNvEnd;
|
||||
TPM_RC g_NvStatus;
|
||||
BYTE s_indexOrderlyRam[RAM_INDEX_SPACE];
|
||||
#ifndef __IGNORE_STATE__ // DO NOT DEFINE THIS VALUE
|
||||
NV_INDEX s_cachedNvIndex;
|
||||
NV_REF s_cachedNvRef;
|
||||
BYTE *s_cachedNvRamRef;
|
||||
#endif // __IGNORE_STATE__
|
||||
/* 9.5.4.4 Object.c */
|
||||
OBJECT s_objects[MAX_LOADED_OBJECTS];
|
||||
/* 9.5.4.5 PCR.c */
|
||||
@ -146,27 +156,11 @@ int s_freeSessionSlots;
|
||||
UINT32 s_actionInputBuffer[1024]; // action input buffer
|
||||
UINT32 s_actionOutputBuffer[1024]; // action output buffer
|
||||
#endif
|
||||
/* 9.5.4.8 SelfTest.c */
|
||||
ALGORITHM_VECTOR g_implementedAlgorithms;
|
||||
ALGORITHM_VECTOR g_toTest;
|
||||
/* 9.5.4.9 g_cryptoSelfTestState */
|
||||
/* This structure contains the cryptographic self-test state values. */
|
||||
CRYPTO_SELF_TEST_STATE g_cryptoSelfTestState;
|
||||
ALGORITHM_VECTOR AlgToTest;
|
||||
/* 9.5.4.10 TpmFail.c */
|
||||
#ifdef SIMULATION
|
||||
BOOL g_forceFailureMode;
|
||||
#endif
|
||||
BOOL g_inFailureMode;
|
||||
UINT32 s_failFunction;
|
||||
UINT32 s_failLine;
|
||||
UINT32 s_failCode;
|
||||
#if 0
|
||||
#ifdef TPM_ALG_ECC
|
||||
/* 9.5.4.11 ECC Curves */
|
||||
ECC_CURVE c_curves[ECC_CURVE_COUNT];
|
||||
#endif
|
||||
#endif // 0
|
||||
/* 9.5.5.9 CryptRand.c */
|
||||
/* This is the state used when the library uses a random number generator. A special function is
|
||||
installed for the library to call. That function picks up the state from this location and uses
|
||||
it for the generation of the random number. */
|
||||
@ -180,7 +174,7 @@ BOOL g_manufactured = FALSE;
|
||||
/* This is here for the same reason that g_manufactured is here. Both of these values can be
|
||||
provided by the actual platform-specific code or by hardware indications. */
|
||||
BOOL g_initialized;
|
||||
/* 9.5.4.14 Purpose String Constants */
|
||||
/* 9.5.4.14 Purpose-specific String Constants */
|
||||
/* These string constants are shared across functions to make sure that they are all using
|
||||
consistent sting values. */
|
||||
TPM2B_STRING(PRIMARY_OBJECT_CREATION, "Primary Object Creation");
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Internal Global Type Definitions */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Global.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Global.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -59,10 +59,11 @@
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* 5.12 Global.h */
|
||||
/* 5.10 Global.h */
|
||||
/* 5.10.2 Includes */
|
||||
|
||||
#if !defined _TPM_H_
|
||||
#error "Should not be called"
|
||||
#error "Should only be instanced in TPM.h"
|
||||
#endif
|
||||
|
||||
#ifndef GLOBAL_H
|
||||
@ -70,7 +71,6 @@
|
||||
//#define SELF_TEST
|
||||
_REDUCE_WARNING_LEVEL_(2)
|
||||
#include <string.h>
|
||||
//#include <setjmp.h>
|
||||
#include <stddef.h>
|
||||
_NORMAL_WARNING_LEVEL_
|
||||
#ifdef SIMULATION
|
||||
@ -83,6 +83,7 @@ _NORMAL_WARNING_LEVEL_
|
||||
#include "CryptTest.h"
|
||||
#include "BnValues.h"
|
||||
#include "CryptHash.h"
|
||||
#include "CryptSym.h"
|
||||
#include "CryptRand.h"
|
||||
#include "CryptEcc.h"
|
||||
#include "CryptRsa.h"
|
||||
@ -105,6 +106,10 @@ typedef BYTE AUTH_VALUE[sizeof(TPMU_HA)];
|
||||
typedef BYTE TIME_INFO[sizeof(TPMS_TIME_INFO)];
|
||||
/* A NAME is a BYTE array that can contain a TPMU_NAME */
|
||||
typedef BYTE NAME[sizeof(TPMU_NAME)];
|
||||
/* Definition for a PROOF value */
|
||||
TPM2B_TYPE(PROOF, PROOF_SIZE);
|
||||
/* Definition for a Primary Seed value */
|
||||
TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE);
|
||||
/* A CLOCK_NONCE is used to tag the time value in the authorization session and in the ticket
|
||||
computation so that the ticket expires when there is a time discontinuity. When the clock stops
|
||||
during normal operation, the nonce is 64-bit value kept in RAM but it is a 32-bit counter when
|
||||
@ -139,7 +144,7 @@ typedef struct
|
||||
unsigned primary : 1; //5) SET for a primary object
|
||||
unsigned temporary : 1; //6) SET for a temporary object
|
||||
unsigned stClear : 1; //7) SET for an stClear object
|
||||
unsigned hmacSeq : 1; //8) SET for an HMAC sequence object
|
||||
unsigned hmacSeq : 1; //8) SET for an HMAC or MAC sequence object
|
||||
unsigned hashSeq : 1; //9) SET for a hash sequence object
|
||||
unsigned eventSeq : 1; //10) SET for an event sequence object
|
||||
unsigned ticketSafe : 1; //11) SET if a ticket is safe to create
|
||||
@ -388,7 +393,7 @@ typedef BYTE *NV_RAM_REF;
|
||||
all the values on a little endian system. This will put the bytes with the 4-octet values in the
|
||||
correct order but will swap the pinLimit and pinCount values. When written, the PIN index is
|
||||
simply handled as a normal index with the octets in canonical order. */
|
||||
#if BIG_ENDIAN_TPM == YES
|
||||
#if BIG_ENDIAN_TPM
|
||||
typedef struct
|
||||
{
|
||||
UINT32 pinCount;
|
||||
@ -422,7 +427,9 @@ extern const UINT16 g_rcIndex[15];
|
||||
exclusive audit session, the location is set to TPM_RH_UNASSIGNED. */
|
||||
extern TPM_HANDLE g_exclusiveAuditSession;
|
||||
/* This is the value in which we keep the current command time. This is initialized at the start of
|
||||
each command. The time is in mS. */
|
||||
each command. The time is the accumulated time since the last time that the TPM's timer was
|
||||
last powered up. Clock is the accumulated time since the last time that the TPM was
|
||||
cleared. g_time is in mS. */
|
||||
extern UINT64 g_time;
|
||||
/* This value contains the current clock Epoch. It changes when there is a clock discontinuity. It
|
||||
may be necessary to place this in NV should the timer be able to run across a power down of the
|
||||
@ -433,42 +440,42 @@ extern CLOCK_NONCE g_timeEpoch;
|
||||
#else
|
||||
#define g_timeEpoch gp.timeEpoch
|
||||
#endif
|
||||
/* 5.12.10.7 g_phEnable */
|
||||
/* 5.10.10.7 g_phEnable */
|
||||
/* This is the platform hierarchy control and determines if the platform hierarchy is
|
||||
available. This value is SET on each TPM2_Startup(). The default value is SET. */
|
||||
extern BOOL g_phEnable;
|
||||
/* 5.12.10.8 g_pcrReConfig */
|
||||
/* 5.10.10.8 g_pcrReConfig */
|
||||
/* This value is SET if a TPM2_PCR_Allocate() command successfully executed since the last
|
||||
TPM2_Startup(). If so, then the next shutdown is required to be Shutdown(CLEAR). */
|
||||
extern BOOL g_pcrReConfig;
|
||||
/* 5.12.10.9 g_DRTMHandle */
|
||||
/* 5.10.10.9 g_DRTMHandle */
|
||||
/* This location indicates the sequence object handle that holds the DRTM sequence data. When not
|
||||
used, it is set to TPM_RH_UNASSIGNED. A sequence DRTM sequence is started on either _TPM_Init()
|
||||
or _TPM_Hash_Start(). */
|
||||
extern TPMI_DH_OBJECT g_DRTMHandle;
|
||||
/* 5.12.10.10 g_DrtmPreStartup */
|
||||
/* 5.10.10.10 g_DrtmPreStartup */
|
||||
/* This value indicates that an H-CRTM occurred after _TPM_Init() but before TPM2_Startup(). The
|
||||
define for PRE_STARTUP_FLAG is used to add the g_DrtmPreStartup value to gp_orderlyState at
|
||||
shutdown. This hack is to avoid adding another NV variable. */
|
||||
extern BOOL g_DrtmPreStartup;
|
||||
/* 5.12.10.11 g_StartupLocality3 */
|
||||
/* 5.10.10.11 g_StartupLocality3 */
|
||||
/* This value indicates that a TPM2_Startup() occurred at locality 3. Otherwise, it at locality
|
||||
0. The define for STARTUP_LOCALITY_3 is to indicate that the startup was not at locality 0. This
|
||||
hack is to avoid adding another NV variable. */
|
||||
extern BOOL g_StartupLocality3;
|
||||
/* 5.12.10.12 TPM_SU_NONE */
|
||||
/* 5.10.10.12 TPM_SU_NONE */
|
||||
/* Part 2 defines the two shutdown/startup types that may be used in TPM2_Shutdown() and
|
||||
TPM2_Starup(). This additional define is used by the TPM to indicate that no shutdown was
|
||||
received. */
|
||||
/* NOTE: This is a reserved value. */
|
||||
#define SU_NONE_VALUE (0xFFFF)
|
||||
#define TPM_SU_NONE (TPM_SU)(SU_NONE_VALUE)
|
||||
/* 5.12.10.13 TPM_SU_DA_USED */
|
||||
/* 5.10.10.13 TPM_SU_DA_USED */
|
||||
/* As with TPM_SU_NONE, this value is added to allow indication that the shutdown was not orderly
|
||||
and that a DA=protected object was reference during the previous cycle. */
|
||||
#define SU_DA_USED_VALUE (SU_NONE_VALUE - 1)
|
||||
#define TPM_SU_DA_USED (TPM_SU)(SU_DA_USED_VALUE)
|
||||
/* 5.12.10.14 Startup Flags */
|
||||
/* 5.10.10.14 Startup Flags */
|
||||
/* These flags are included in gp.orderlyState. These are hacks and are being used to avoid having
|
||||
to change the layout of gp. The PRE_STARTUP_FLAG indicates that a
|
||||
_TPM_Hash_Start()/_Data()/_End() sequence was received after _TPM_Init() but before
|
||||
@ -477,13 +484,13 @@ extern BOOL g_StartupLocality3;
|
||||
#define PRE_STARTUP_FLAG 0x8000
|
||||
#define STARTUP_LOCALITY_3 0x4000
|
||||
#ifdef USE_DA_USED
|
||||
/* 5.12.10.15 g_daUsed */
|
||||
/* 5.10.10.15 g_daUsed */
|
||||
/* This location indicates if a DA-protected value is accessed during a boot cycle. If none has,
|
||||
then there is no need to increment failedTries on the next non-orderly startup. This bit is
|
||||
merged with gp.orderlyState when that gp.orderly is set to SU_NONE_VALUE */
|
||||
extern BOOL g_daUsed;
|
||||
#endif
|
||||
/* 5.12.10.16 g_updateNV */
|
||||
/* 5.10.10.16 g_updateNV */
|
||||
/* This flag indicates if NV should be updated at the end of a command. This flag is set to UT_NONE
|
||||
at the beginning of each command in ExecuteCommand(). This flag is checked in ExecuteCommand()
|
||||
after the detailed actions of a command complete. If the command execution was successful and
|
||||
@ -494,7 +501,7 @@ typedef BYTE UPDATE_TYPE;
|
||||
#define UT_NV (UPDATE_TYPE)1
|
||||
#define UT_ORDERLY (UPDATE_TYPE)(UT_NV + 2)
|
||||
extern UPDATE_TYPE g_updateNV;
|
||||
/* 5.12.10.17 g_powerWasLost */
|
||||
/* 5.10.10.17 g_powerWasLost */
|
||||
/* This flag is used to indicate if the power was lost. It is SET in _TPM__Init(). This flag is
|
||||
cleared by TPM2_Startup() after all power-lost activities are completed. */
|
||||
/* NOTE: When power is applied, this value can come up as anything. However, _plat__WasPowerLost()
|
||||
@ -502,19 +509,19 @@ extern UPDATE_TYPE g_updateNV;
|
||||
correct answer. When power was not lost, but the power-lost processing has not been completed
|
||||
before the next _TPM_Init(), then the TPM still does the correct thing. */
|
||||
extern BOOL g_powerWasLost;
|
||||
/* 5.12.10.18 g_clearOrderly */
|
||||
/* 5.10.10.18 g_clearOrderly */
|
||||
/* This flag indicates if the execution of a command should cause the orderly state to be cleared.
|
||||
This flag is set to FALSE at the beginning of each command in ExecuteCommand() and is checked in
|
||||
ExecuteCommand() after the detailed actions of a command complete but before the check of
|
||||
g_updateNV. If this flag is TRUE, and the orderly state is not SU_NONE_VALUE, then the orderly
|
||||
state in NV memory will be changed to SU_NONE_VALUE or SU_DA_USED_VALUE. */
|
||||
extern BOOL g_clearOrderly;
|
||||
/* 5.12.10.19 g_prevOrderlyState */
|
||||
/* 5.10.10.19 g_prevOrderlyState */
|
||||
/* This location indicates how the TPM was shut down before the most recent TPM2_Startup(). This
|
||||
value, along with the startup type, determines if the TPM should do a TPM Reset, TPM Restart, or
|
||||
TPM Resume. */
|
||||
extern TPM_SU g_prevOrderlyState;
|
||||
/* 5.12.10.20 g_nvOk */
|
||||
/* 5.10.10.20 g_nvOk */
|
||||
/* This value indicates if the NV integrity check was successful or not. If not and the failure was
|
||||
severe, then the TPM would have been put into failure mode after it had been re-manufactured. If
|
||||
the NV failure was in the area where the state-save data is kept, then this variable will have a
|
||||
@ -523,7 +530,7 @@ extern BOOL g_nvOk;
|
||||
/* NV availability is sampled as the start of each command and stored here so that its value remains
|
||||
consistent during the command execution */
|
||||
extern TPM_RC g_NvStatus;
|
||||
/* 5.12.10.21 g_platformUnique */
|
||||
/* 5.10.10.21 g_platformUnique */
|
||||
/* This location contains the unique value(s) used to identify the TPM. It is loaded on every
|
||||
_TPM2_Startup() The first value is used to seed the RNG. The second value is used as a vendor
|
||||
authValue. The value used by the RNG would be the value derived from the chip unique value (such
|
||||
@ -563,9 +570,9 @@ typedef struct
|
||||
TPM2B_SEED PPSeed;
|
||||
// Note there is a nullSeed in the state_reset memory.
|
||||
// Hierarchy proofs
|
||||
TPM2B_AUTH phProof;
|
||||
TPM2B_AUTH shProof;
|
||||
TPM2B_AUTH ehProof;
|
||||
TPM2B_PROOF phProof;
|
||||
TPM2B_PROOF shProof;
|
||||
TPM2B_PROOF ehProof;
|
||||
// Note there is a nullProof in the state_reset memory.
|
||||
//*********************************************************************************
|
||||
// Reset Events
|
||||
@ -665,7 +672,7 @@ typedef struct
|
||||
#endif
|
||||
} PERSISTENT_DATA;
|
||||
extern PERSISTENT_DATA gp;
|
||||
/* 5.12.11.3
|
||||
/* 5.10.11.3
|
||||
ORDERLY_DATA */
|
||||
/* The data in this structure is saved to NV on each TPM2_Shutdown(). */
|
||||
typedef struct orderly_data
|
||||
@ -689,8 +696,6 @@ typedef struct orderly_data
|
||||
// of entropy. By keeping the old state and adding entropy, the entropy will
|
||||
// accumulate.
|
||||
DRBG_STATE drbgState;
|
||||
|
||||
|
||||
// These values allow the accumulation of self-healing time across orderly shutdown
|
||||
// of the TPM.
|
||||
#ifdef ACCUMULATE_SELF_HEAL_TIMER
|
||||
@ -705,8 +710,8 @@ typedef struct orderly_data
|
||||
#endif // ACCUMULATE_SELF_HEAL_TIMER
|
||||
# define drbgDefault go.drbgState
|
||||
extern ORDERLY_DATA go;
|
||||
|
||||
/* 5.12.11.4 STATE_CLEAR_DATA */
|
||||
|
||||
/* 5.10.11.4 STATE_CLEAR_DATA */
|
||||
/* This structure contains the data that is saved on Shutdown(STATE). and restored on
|
||||
Startup(STATE). The values are set to their default settings on any Startup(Clear). In other
|
||||
words the data is only persistent across TPM Resume. */
|
||||
@ -736,7 +741,7 @@ typedef struct state_clear_data
|
||||
PCR_AUTHVALUE pcrAuthValues;
|
||||
} STATE_CLEAR_DATA;
|
||||
extern STATE_CLEAR_DATA gc;
|
||||
/* 5.12.11.5
|
||||
/* 5.10.11.5
|
||||
State
|
||||
Reset
|
||||
Data */
|
||||
@ -748,7 +753,7 @@ typedef struct state_reset_data
|
||||
//*****************************************************************************
|
||||
// Hierarchy Control
|
||||
//*****************************************************************************
|
||||
TPM2B_AUTH nullProof; // The proof value associated with
|
||||
TPM2B_PROOF nullProof; // The proof value associated with
|
||||
// the TPM_RH_NULL hierarchy. The
|
||||
// default reset value is from the RNG.
|
||||
TPM2B_SEED nullSeed; // The seed value for the TPM_RN_NULL
|
||||
@ -824,7 +829,7 @@ typedef struct state_reset_data
|
||||
#endif //TPM_ALG_ECC
|
||||
} STATE_RESET_DATA;
|
||||
extern STATE_RESET_DATA gr;
|
||||
/* 5.12.12
|
||||
/* 5.10.12
|
||||
NV
|
||||
Layout */
|
||||
/* The NV data organization is */
|
||||
@ -840,7 +845,7 @@ extern STATE_RESET_DATA gr;
|
||||
#define NV_INDEX_RAM_DATA (NV_ORDERLY_DATA + sizeof(ORDERLY_DATA))
|
||||
#define NV_USER_DYNAMIC (NV_INDEX_RAM_DATA + sizeof(s_indexOrderlyRam))
|
||||
#define NV_USER_DYNAMIC_END NV_MEMORY_SIZE
|
||||
/* 5.12.13 Global Macro Definitions */
|
||||
/* 5.10.13 Global Macro Definitions */
|
||||
/* The NV_READ_PERSISTENT and NV_WRITE_PERSISTENT macros are used to access members of the
|
||||
PERSISTENT_DATA structure in NV. */
|
||||
#define NV_READ_PERSISTENT(to, from) \
|
||||
@ -930,7 +935,7 @@ extern BOOL g_manufactured;
|
||||
This flag is maintained in power simulation module because this is the only place that may
|
||||
reliably set this flag to FALSE. */
|
||||
extern BOOL g_initialized;
|
||||
/* 5.12.14 Private data */
|
||||
/* 5.10.14 Private data */
|
||||
#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
|
||||
/* From SessionProcess.c */
|
||||
/* The following arrays are used to save command sessions information so that the command
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* This file is a collection of miscellaneous macros. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: GpMacros.h 960 2017-03-10 19:08:17Z kgoldman $ */
|
||||
/* $Id: GpMacros.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -62,15 +62,14 @@
|
||||
#ifndef GPMACROS_H
|
||||
#define GPMACROS_H
|
||||
|
||||
/* 5.11 GpMacros.h */
|
||||
|
||||
/* 5.11.1 Introduction */
|
||||
/* This file is a collection of miscellaneous macros. */
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#include "swap.h"
|
||||
#include "VendorString.h"
|
||||
/* 5.13.2 For Self-test */
|
||||
/* 5.11.2 For Self-test */
|
||||
/* These macros are used in CryptUtil() to invoke the incremental self test. */
|
||||
#ifdef SELF_TEST
|
||||
# define TEST(alg) if(TEST_BIT(alg, g_toTest)) CryptTestAlgorithm(alg, NULL)
|
||||
@ -84,22 +83,14 @@
|
||||
# define TEST(alg)
|
||||
# define TEST_HASH(alg)
|
||||
#endif // SELF_TEST
|
||||
/* 5.13.3 For Failures */
|
||||
#if 0
|
||||
/* 5.11.3 For Failures */
|
||||
#if defined _POSIX_
|
||||
# define FUNCTION_NAME 0
|
||||
#else
|
||||
# define FUNCTION_NAME __FUNCTION__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined ( WIN32 )
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
# define FUNCTION_NAME __func__
|
||||
|
||||
#ifdef NO_FAIL_TRACE
|
||||
# define FAIL(errorCode) (TpmFail(errorCode))
|
||||
# define FAIL(errorCode) (TpmFail(errorCode))
|
||||
#else
|
||||
# define FAIL(errorCode) (TpmFail(FUNCTION_NAME, __LINE__, errorCode))
|
||||
#endif
|
||||
@ -119,26 +110,26 @@
|
||||
#define REQUIRE(condition, errorCode, returnCode) \
|
||||
{ \
|
||||
if(!!(condition)) \
|
||||
{ \
|
||||
FAIL(FATAL_ERROR_errorCode); \
|
||||
FAIL_RETURN(returnCode); \
|
||||
} \
|
||||
{ \
|
||||
FAIL(FATAL_ERROR_errorCode); \
|
||||
FAIL_RETURN(returnCode); \
|
||||
} \
|
||||
}
|
||||
#define PARAMETER_CHECK(condition, returnCode) \
|
||||
REQUIRE((condition), PARAMETER, returnCode)
|
||||
#if defined(EMPTY_ASSERT)
|
||||
#if defined EMPTY_ASSERT
|
||||
# define pAssert(a) ((void)0)
|
||||
#else
|
||||
# define pAssert(a) {if(!(a)) FAIL(FATAL_ERROR_PARAMETER);}
|
||||
#endif
|
||||
/* 5.13.4 Derived from Vendor-specific values */
|
||||
/* 5.11.4 Derived from Vendor-specific values */
|
||||
/* Values derived from vendor specific settings in Implementation.h */
|
||||
#define PCR_SELECT_MIN ((PLATFORM_PCR+7)/8)
|
||||
#define PCR_SELECT_MAX ((IMPLEMENTATION_PCR+7)/8)
|
||||
#define MAX_ORDERLY_COUNT ((1 << ORDERLY_BITS) - 1)
|
||||
#define PRIVATE_VENDOR_SPECIFIC_BYTES \
|
||||
((MAX_RSA_KEY_BYTES/2) * (3 + CRT_FORMAT_RSA * 2))
|
||||
/* 5.13.5 Compile-time Checks */
|
||||
/* 5.11.5 Compile-time Checks */
|
||||
/* In some cases, the relationship between two values may be dependent on things that change based
|
||||
on various selections like the chosen cryptographic libraries. It is possible that these
|
||||
selections will result in incompatible settings. These are often detectable by the compiler but
|
||||
@ -192,6 +183,10 @@
|
||||
# define DEBUG YES
|
||||
#endif
|
||||
#define STD_RESPONSE_HEADER (sizeof(TPM_ST) + sizeof(UINT32) + sizeof(TPM_RC))
|
||||
#define JOIN(x,y) x##y
|
||||
#define CONCAT(x,y) JOIN(x, y)
|
||||
/* If CONTEXT_INTEGRITY_HASH_ALG is defined, then the vendor is using the old style
|
||||
table. Otherwise, pick the strongest implemented hash algorithm as the context hash. */
|
||||
#ifndef CONTEXT_HASH_ALGORITHM
|
||||
# if defined ALG_SHA512 && ALG_SHA512 == YES
|
||||
# define CONTEXT_HASH_ALGORITHM SHA512
|
||||
@ -202,32 +197,97 @@
|
||||
# elif defined ALG_SM3_256 && ALG_SM3_256 == YES
|
||||
# define CONTEXT_HASH_ALGORITHM SM3_256
|
||||
# elif defined ALG_SHA1 && ALG_SHA1 == YES
|
||||
# define CONTEXT_HASH_ALGORITHM SHA1
|
||||
# define CONTEXT_HASH_ALGORITHM SHA1
|
||||
# endif
|
||||
# define CONTEXT_INTEGRITY_HASH_ALG CONCAT(TPM_ALG_, CONTEXT_HASH_ALGORITHM)
|
||||
#endif
|
||||
#ifndef CONTEXT_INTEGRITY_HASH_SIZE
|
||||
#define CONTEXT_INTEGRITY_HASH_SIZE CONCAT(CONTEXT_HASH_ALGORITHM, _DIGEST_SIZE)
|
||||
#endif
|
||||
#ifdef TPM_ALG_RSA
|
||||
#define RSA_SECURITY_STRENGTH (MAX_RSA_KEY_BITS >= 15360 ? 256 : \
|
||||
(MAX_RSA_KEY_BITS >= 7680 ? 192 : \
|
||||
(MAX_RSA_KEY_BITS >= 3072 ? 128 : \
|
||||
(MAX_RSA_KEY_BITS >= 2048 ? 112 : \
|
||||
(MAX_RSA_KEY_BITS >= 1024 ? 80 : 0)))))
|
||||
#else
|
||||
#define RSA_SECURITY_STRENGTH 0
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECC
|
||||
#define ECC_SECURITY_STRENGTH (MAX_ECC_KEY_BITS >= 521 ? 256 : \
|
||||
(MAX_ECC_KEY_BITS >= 384 ? 192 : \
|
||||
(MAX_ECC_KEY_BITS >= 256 ? 128 : 0)))
|
||||
#else
|
||||
#define ECC_SECURITY_STRENGTH 0
|
||||
#endif // TPM_AGL_ECC
|
||||
#define MAX_ASYM_SECURITY_STRENGTH \
|
||||
MAX(RSA_SECURITY_STRENGTH, ECC_SECURITY_STRENGTH)
|
||||
#define MAX_HASH_SECURITY_STRENGTH ((CONTEXT_INTEGRITY_HASH_SIZE * 8) / 2)
|
||||
/* Unless some algorithm is broken... */
|
||||
#define MAX_SYM_SECURITY_STRENGTH MAX_SYM_KEY_BITS
|
||||
#define MAX_SECURITY_STRENGTH_BITS \
|
||||
MAX(MAX_ASYM_SECURITY_STRENGTH, \
|
||||
MAX(MAX_SYM_SECURITY_STRENGTH, \
|
||||
MAX_HASH_SECURITY_STRENGTH))
|
||||
/* This is the size that was used before the 1.38 errata requiring that P1.14.4 be followed */
|
||||
#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE
|
||||
/* As required by P1.14.4 */
|
||||
#define COMPLIANT_PROOF_SIZE \
|
||||
(MAX(CONTEXT_INTEGRITY_HASH_SIZE, (2 * MAX_SYM_KEY_BYTES)))
|
||||
/* As required by P1.14.3.1 */
|
||||
#define COMPLIANT_PRIMARY_SEED_SIZE \
|
||||
BITS_TO_BYTES(MAX_SECURITY_STRENGTH_BITS * 2)
|
||||
/* This is the pre-errata version */
|
||||
#ifndef PRIMARY_SEED_SIZE
|
||||
# define PRIMARY_SEED_SIZE PROOF_SIZE
|
||||
#endif
|
||||
#ifdef USE_SPEC_COMPLIANT_PROOFS
|
||||
# undef PROOF_SIZE
|
||||
# define PROOF_SIZE COMPLIANT_PROOF_SIZE
|
||||
# undef PRIMARY_SEED_SIZE
|
||||
# define PRIMARY_SEED_SIZE COMPLIANT_PRIMARY_SEED_SIZE
|
||||
#endif // USE_SPEC_COMPLIANT_PROOFS || !defined PRIMARY_SEED_SIZE
|
||||
#ifndef SKIP_PROOF_ERRORS
|
||||
# if PROOF_SIZE < COMPLIANT_PROOF_SIZE
|
||||
# error "PROOF_SIZE is not compliant with TPM specification"
|
||||
# endif
|
||||
# if PRIMARY_SEED_SIZE < COMPLIANT_PRIMARY_SEED_SIZE
|
||||
# error "Implementation.h specifies a non-compliant PRIMARY_SEED_SIZE"
|
||||
# endif
|
||||
#endif
|
||||
#define JOIN(x,y) x##y
|
||||
#define CONCAT(x,y) JOIN(x, y)
|
||||
|
||||
/* If CONTEXT_INTEGRITY_HASH_ALG is defined, then the vendor is using the old style table */
|
||||
|
||||
#ifndef CONTEXT_INTEGRITY_HASH_ALG
|
||||
#define CONTEXT_INTEGRITY_HASH_ALG CONCAT(TPM_ALG_, CONTEXT_HASH_ALGORITHM)
|
||||
#define CONTEXT_INTEGRITY_HASH_SIZE CONCAT(CONTEXT_HASH_ALGORITHM, _DIGEST_SIZE)
|
||||
#endif
|
||||
#define PROOF_SIZE CONTEXT_INTEGRITY_HASH_SIZE
|
||||
|
||||
/* If CONTEXT_ENCRYP_ALG is defined, then the vendor is using the old style table */
|
||||
|
||||
#ifndef CONTEXT_ENCRYPT_ALG
|
||||
#define CONTEXT_ENCRYPT_ALG CONCAT(TPM_ALG_, CONTEXT_ENCRYPT_ALGORITHM)
|
||||
#define CONTEXT_ENCRYPT_KEY_BITS \
|
||||
CONCAT(CONCAT(MAX_, CONTEXT_ENCRYPT_ALGORITHM), _KEY_BITS)
|
||||
#define CONTEXT_ENCRYPT_KEY_BYTES ((CONTEXT_ENCRYPT_KEY_BITS+7)/8)
|
||||
#endif
|
||||
#if ALG_ECC
|
||||
# define LABEL_MAX_BUFFER MAX_ECC_KEY_BYTES
|
||||
#else
|
||||
# define LABEL_MAX_BUFFER MAX_DIGEST_SIZE
|
||||
/* This is updated to follow the requirement of P2 that the label not be larger than 32 bytes. */
|
||||
#ifndef LABEL_MAX_BUFFER
|
||||
#define LABEL_MAX_BUFFER MIN(32, MIN(MAX_ECC_KEY_BYTES, MAX_DIGEST_SIZE))
|
||||
#endif
|
||||
/* This bit is used to indicate that an authorization ticket expires on TPM Reset and TPM Restart.It
|
||||
is added to the timeout value returned by TPM2_PoliySigned() and TPM2_PolicySecret() and used by
|
||||
TPM2_PolicyTicket(). The timeout value is relative to Time (g_time). Time is reset whenever the
|
||||
TPM loses power and cannot be moved forward by the user (as can Clock). g_time is a 64-bit value
|
||||
expressing time in ms. Sealing the MSb() for a flag means that the TPM needs to be reset at least
|
||||
once every 292,471,208 years rather than once every 584,942,417 years. */
|
||||
#define EXPIRATION_BIT ((UINT64)1 << 63)
|
||||
/* Check for consistency of the bit ordering an bit fields */
|
||||
#if BIG_ENDIAN_TPM && MOST_SIGNIFICANT_BIT_0 && !defined NO_BIT_FIELD_STRUCTURES
|
||||
# error "Settings not consistent"
|
||||
#endif
|
||||
/* These macros are used to handle the variation in handling of bit fields. If */
|
||||
#ifndef NO_BIT_FIELD_STRUCTURES // The default, old version, with bit fields
|
||||
# define IS_ATTRIBUTE(a, type, b) ((a.b != 0))
|
||||
# define SET_ATTRIBUTE(a, type, b) (a.b = SET)
|
||||
# define CLEAR_ATTRIBUTE(a, type, b) (a.b = CLEAR)
|
||||
# define GET_ATTRIBUTE(a, type, b) (a.b)
|
||||
#else
|
||||
# define IS_ATTRIBUTE(a, type, b) ((a & type##_##b) != 0)
|
||||
# define SET_ATTRIBUTE(a, type, b) (a |= type##_##b)
|
||||
# define CLEAR_ATTRIBUTE(a, type, b) (a &= ~type##_##b)
|
||||
# define GET_ATTRIBUTE(a, type, b) \
|
||||
(type)((a & type##_##b) >> type##_##b##_SHIFT)
|
||||
#endif
|
||||
|
||||
#endif // GP_MACROS_H
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* fUnctions that return the type of a handle. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Handle.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Handle.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -79,7 +79,6 @@ HandleGetType(
|
||||
/* This function returns the permanent handle that is equal to the input value or is the next higher
|
||||
value. If there is no handle with the input value and there is no next higher value, it returns
|
||||
0: */
|
||||
/* Return Values Meaning */
|
||||
TPM_HANDLE
|
||||
NextPermanentHandle(
|
||||
TPM_HANDLE inHandle // IN: the handle to check
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: HashCommands.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: HashCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -79,10 +79,12 @@ TPM2_HMAC_Start(
|
||||
if(publicArea->type != TPM_ALG_KEYEDHASH)
|
||||
return TPM_RCS_TYPE + RC_HMAC_Start_handle;
|
||||
// and that it is unrestricted
|
||||
if(publicArea->objectAttributes.restricted == SET)
|
||||
if (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
|
||||
//if(publicArea->objectAttributes.restricted == SET) kgold
|
||||
return TPM_RCS_ATTRIBUTES + RC_HMAC_Start_handle;
|
||||
// and that it is a signing key
|
||||
if(publicArea->objectAttributes.sign != SET)
|
||||
if (!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
// if(publicArea->objectAttributes.sign != SET) kgold
|
||||
return TPM_RCS_KEY + RC_HMAC_Start_handle;
|
||||
// See if the key has a default
|
||||
if(publicArea->parameters.keyedHashDetail.scheme.scheme == TPM_ALG_NULL)
|
||||
@ -110,6 +112,53 @@ TPM2_HMAC_Start(
|
||||
}
|
||||
#endif // CC_HMAC_Start
|
||||
#include "Tpm.h"
|
||||
#include "MAC_Start_fp.h"
|
||||
#ifdef TPM_CC_MAC_Start // Conditional expansion of this file
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_ATTRIBUTES key referenced by handle is not a signing key or is restricted */
|
||||
/* TPM_RC_OBJECT_MEMORY no space to create an internal object */
|
||||
/* TPM_RC_KEY key referenced by handle is not an HMAC key */
|
||||
/* TPM_RC_VALUE hashAlg is not compatible with the hash algorithm of the scheme of the object
|
||||
referenced by handle */
|
||||
TPM_RC
|
||||
TPM2_MAC_Start(
|
||||
MAC_Start_In *in, // IN: input parameter list
|
||||
MAC_Start_Out *out // OUT: output parameter list
|
||||
)
|
||||
{
|
||||
OBJECT *keyObject;
|
||||
TPMT_PUBLIC *publicArea;
|
||||
TPM_RC result;
|
||||
// Input Validation
|
||||
// Get HMAC key object and public area pointers
|
||||
keyObject = HandleToObject(in->handle);
|
||||
publicArea = &keyObject->publicArea;
|
||||
// Make sure that the key can do what is required
|
||||
result = CryptSelectMac(publicArea, &in->inScheme);
|
||||
// If the key is not able to do a MAC, indicate that the handle selects an
|
||||
// object that can't do a MAC
|
||||
if(result == TPM_RCS_TYPE)
|
||||
return TPM_RCS_TYPE + RC_MAC_Start_handle;
|
||||
// If there is another error type, indicate that the scheme and key are not
|
||||
// compatible
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return RcSafeAddToResult(result, RC_MAC_Start_inScheme);
|
||||
// Make sure that the key is not restricted
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
|
||||
return TPM_RCS_ATTRIBUTES + RC_MAC_Start_handle;
|
||||
// and that it is a signing key
|
||||
if(!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
return TPM_RCS_KEY + RC_MAC_Start_handle;
|
||||
// Internal Data Update
|
||||
// Create a HMAC sequence object. A TPM_RC_OBJECT_MEMORY error may be
|
||||
// returned at this point
|
||||
return ObjectCreateHMACSequence(in->inScheme,
|
||||
keyObject,
|
||||
&in->auth,
|
||||
&out->sequenceHandle);
|
||||
}
|
||||
#endif // CC_MAC_Start
|
||||
#include "Tpm.h"
|
||||
#include "HashSequenceStart_fp.h"
|
||||
#ifdef TPM_CC_HashSequenceStart // Conditional expansion of this file
|
||||
TPM_RC
|
||||
@ -177,7 +226,7 @@ TPM2_SequenceUpdate(
|
||||
}
|
||||
else if(object->attributes.hmacSeq == SET)
|
||||
{
|
||||
// Update sequence object hash/HMAC stack
|
||||
// Update sequence object HMAC stack
|
||||
CryptDigestUpdate2B(&hashObject->state.hmacState.hashState,
|
||||
&in->buffer.b);
|
||||
}
|
||||
@ -188,72 +237,77 @@ TPM2_SequenceUpdate(
|
||||
#include "Tpm.h"
|
||||
#include "SequenceComplete_fp.h"
|
||||
#ifdef TPM_CC_SequenceComplete // Conditional expansion of this file
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_MODE sequenceHandle does not reference a hash or HMAC sequence object */
|
||||
TPM_RC
|
||||
TPM2_SequenceComplete(
|
||||
SequenceComplete_In *in, // IN: input parameter list
|
||||
SequenceComplete_Out *out // OUT: output parameter list
|
||||
)
|
||||
{
|
||||
OBJECT *object;
|
||||
HASH_OBJECT *hashObject;
|
||||
// Input validation
|
||||
// Get hash object pointer
|
||||
object = HandleToObject(in->sequenceHandle);
|
||||
hashObject = (HASH_OBJECT *)HandleToObject(in->sequenceHandle);
|
||||
// input handle must be a hash or HMAC sequence object.
|
||||
if(object->attributes.hashSeq == CLEAR
|
||||
&& object->attributes.hmacSeq == CLEAR)
|
||||
if(hashObject->attributes.hashSeq == CLEAR
|
||||
&& hashObject->attributes.hmacSeq == CLEAR)
|
||||
return TPM_RCS_MODE + RC_SequenceComplete_sequenceHandle;
|
||||
// Command Output
|
||||
if(object->attributes.hashSeq == SET) // sequence object for hash
|
||||
if(hashObject->attributes.hashSeq == SET) // sequence object for hash
|
||||
{
|
||||
// Update last piece of data
|
||||
HASH_OBJECT *hashObject = (HASH_OBJECT *)object;
|
||||
// Get the hash algorithm before the algorithm is lost in CryptHashEnd
|
||||
TPM_ALG_ID hashAlg = hashObject->state.hashState[0].hashAlg;
|
||||
// Update last piece of the data
|
||||
CryptDigestUpdate2B(&hashObject->state.hashState[0], &in->buffer.b);
|
||||
// Complete hash
|
||||
out->result.t.size
|
||||
= CryptHashGetDigestSize(
|
||||
CryptHashGetContextAlg(&hashObject->state.hashState[0]));
|
||||
CryptHashEnd2B(&hashObject->state.hashState[0], &out->result.b);
|
||||
out->result.t.size = CryptHashEnd(&hashObject->state.hashState[0],
|
||||
sizeof(out->result.t.buffer),
|
||||
out->result.t.buffer);
|
||||
// Check if the first block of the sequence has been received
|
||||
if(hashObject->attributes.firstBlock == CLEAR)
|
||||
{
|
||||
// If not, then this is the first block so see if it is 'safe'
|
||||
// to sign.
|
||||
if(TicketIsSafe(&in->buffer.b))
|
||||
hashObject->attributes.ticketSafe = SET;
|
||||
}
|
||||
{
|
||||
// If not, then this is the first block so see if it is 'safe'
|
||||
// to sign.
|
||||
if(TicketIsSafe(&in->buffer.b))
|
||||
hashObject->attributes.ticketSafe = SET;
|
||||
}
|
||||
// Output ticket
|
||||
out->validation.tag = TPM_ST_HASHCHECK;
|
||||
out->validation.hierarchy = in->hierarchy;
|
||||
if(in->hierarchy == TPM_RH_NULL)
|
||||
{
|
||||
// Ticket is not required
|
||||
out->validation.digest.t.size = 0;
|
||||
}
|
||||
else if(object->attributes.ticketSafe == CLEAR)
|
||||
{
|
||||
// Ticket is not safe to generate
|
||||
out->validation.hierarchy = TPM_RH_NULL;
|
||||
out->validation.digest.t.size = 0;
|
||||
}
|
||||
{
|
||||
// Ticket is not required
|
||||
out->validation.digest.t.size = 0;
|
||||
}
|
||||
else if(hashObject->attributes.ticketSafe == CLEAR)
|
||||
{
|
||||
// Ticket is not safe to generate
|
||||
out->validation.hierarchy = TPM_RH_NULL;
|
||||
out->validation.digest.t.size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Compute ticket
|
||||
TicketComputeHashCheck(out->validation.hierarchy, hashAlg,
|
||||
&out->result, &out->validation);
|
||||
}
|
||||
{
|
||||
// Compute ticket
|
||||
TicketComputeHashCheck(out->validation.hierarchy, hashAlg,
|
||||
&out->result, &out->validation);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HASH_OBJECT *hashObject = (HASH_OBJECT *)object;
|
||||
// Update last piece of data
|
||||
CryptDigestUpdate2B(&hashObject->state.hmacState.hashState, &in->buffer.b);
|
||||
// Complete hash/HMAC
|
||||
out->result.t.size =
|
||||
CryptHashGetDigestSize(
|
||||
CryptHashGetContextAlg(&hashObject->state.hmacState.hashState));
|
||||
CryptHmacEnd2B(&(hashObject->state.hmacState), &out->result.b);
|
||||
#ifndef SMAC_IMPLEMENTED
|
||||
// Complete HMAC
|
||||
out->result.t.size = CryptHmacEnd(&(hashObject->state.hmacState),
|
||||
sizeof(out->result.t.buffer),
|
||||
out->result.t.buffer);
|
||||
#else
|
||||
// Complete the MAC
|
||||
out->result.t.size = CryptMacEnd(&hashObject->state.hmacState,
|
||||
sizeof(out->result.t.buffer),
|
||||
out->result.t.buffer);
|
||||
#endif
|
||||
// No ticket is generated for HMAC sequence
|
||||
out->validation.tag = TPM_ST_HASHCHECK;
|
||||
out->validation.hierarchy = TPM_RH_NULL;
|
||||
@ -261,7 +315,7 @@ TPM2_SequenceComplete(
|
||||
}
|
||||
// Internal Data Update
|
||||
// mark sequence object as evict so it will be flushed on the way out
|
||||
object->attributes.evict = SET;
|
||||
hashObject->attributes.evict = SET;
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif // CC_SequenceComplete
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Hierarchy.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Hierarchy.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
/* 8.3 Hierarchy.c */
|
||||
@ -76,15 +76,15 @@ HierarchyPreInstall_Init(
|
||||
// Allow lockout clear command
|
||||
gp.disableClear = FALSE;
|
||||
// Initialize Primary Seeds
|
||||
gp.EPSeed.t.size = PRIMARY_SEED_SIZE;
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer);
|
||||
gp.SPSeed.t.size = PRIMARY_SEED_SIZE;
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.SPSeed.t.buffer);
|
||||
gp.PPSeed.t.size = PRIMARY_SEED_SIZE;
|
||||
gp.EPSeed.t.size = sizeof(gp.EPSeed.t.buffer);
|
||||
gp.SPSeed.t.size = sizeof(gp.SPSeed.t.buffer);
|
||||
gp.PPSeed.t.size = sizeof(gp.PPSeed.t.buffer);
|
||||
CryptRandomGenerate(gp.EPSeed.t.size, gp.EPSeed.t.buffer);
|
||||
CryptRandomGenerate(gp.SPSeed.t.size, gp.SPSeed.t.buffer);
|
||||
#ifdef USE_PLATFORM_EPS
|
||||
_plat__GetEPS(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer);
|
||||
_plat__GetEPS(gp.PPSeed.t.size, gp.EPSeed.t.buffer);
|
||||
#else
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.PPSeed.t.buffer);
|
||||
CryptRandomGenerate(gp.PPSeed.t.size, gp.PPSeed.t.buffer);
|
||||
#endif
|
||||
// Initialize owner, endorsement and lockout auth
|
||||
gp.ownerAuth.t.size = 0;
|
||||
@ -98,9 +98,9 @@ HierarchyPreInstall_Init(
|
||||
gp.lockoutAlg = TPM_ALG_NULL;
|
||||
gp.lockoutPolicy.t.size = 0;
|
||||
// Initialize ehProof, shProof and phProof
|
||||
gp.phProof.t.size = PROOF_SIZE;
|
||||
gp.shProof.t.size = PROOF_SIZE;
|
||||
gp.ehProof.t.size = PROOF_SIZE;
|
||||
gp.phProof.t.size = sizeof(gp.phProof.t.buffer);
|
||||
gp.shProof.t.size = sizeof(gp.shProof.t.buffer);
|
||||
gp.ehProof.t.size = sizeof(gp.ehProof.t.buffer);
|
||||
CryptRandomGenerate(gp.phProof.t.size, gp.phProof.t.buffer);
|
||||
CryptRandomGenerate(gp.shProof.t.size, gp.shProof.t.buffer);
|
||||
CryptRandomGenerate(gp.ehProof.t.size, gp.ehProof.t.buffer);
|
||||
@ -144,46 +144,45 @@ HierarchyStartup(
|
||||
// nullProof and nullSeed are updated at every TPM_RESET
|
||||
if((type != SU_RESTART) && (type != SU_RESUME))
|
||||
{
|
||||
gr.nullProof.t.size = PROOF_SIZE;
|
||||
CryptRandomGenerate(gr.nullProof.t.size,
|
||||
gr.nullProof.t.buffer);
|
||||
gr.nullSeed.t.size = PRIMARY_SEED_SIZE;
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gr.nullSeed.t.buffer);
|
||||
gr.nullProof.t.size = sizeof(gr.nullProof.t.buffer);
|
||||
CryptRandomGenerate(gr.nullProof.t.size, gr.nullProof.t.buffer);
|
||||
gr.nullSeed.t.size = sizeof(gr.nullProof.t.buffer);
|
||||
CryptRandomGenerate(gr.nullProof.t.size, gr.nullSeed.t.buffer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* 8.3.3.3 HierarchyGetProof() */
|
||||
/* This function finds the proof value associated with a hierarchy.It returns a pointer to the proof
|
||||
value. */
|
||||
TPM2B_AUTH *
|
||||
TPM2B_PROOF *
|
||||
HierarchyGetProof(
|
||||
TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant
|
||||
)
|
||||
{
|
||||
TPM2B_AUTH *auth = NULL;
|
||||
TPM2B_PROOF *proof = NULL;
|
||||
switch(hierarchy)
|
||||
{
|
||||
case TPM_RH_PLATFORM:
|
||||
// phProof for TPM_RH_PLATFORM
|
||||
auth = &gp.phProof;
|
||||
proof = &gp.phProof;
|
||||
break;
|
||||
case TPM_RH_ENDORSEMENT:
|
||||
// ehProof for TPM_RH_ENDORSEMENT
|
||||
auth = &gp.ehProof;
|
||||
proof = &gp.ehProof;
|
||||
break;
|
||||
case TPM_RH_OWNER:
|
||||
// shProof for TPM_RH_OWNER
|
||||
auth = &gp.shProof;
|
||||
proof = &gp.shProof;
|
||||
break;
|
||||
case TPM_RH_NULL:
|
||||
// nullProof for TPM_RH_NULL
|
||||
auth = &gr.nullProof;
|
||||
proof = &gr.nullProof;
|
||||
break;
|
||||
default:
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
break;
|
||||
}
|
||||
return auth;
|
||||
return proof;
|
||||
}
|
||||
/* 8.3.3.4 HierarchyGetPrimarySeed() */
|
||||
/* This function returns the primary seed of a hierarchy. */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Hierarchy Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: HierarchyCommands.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: HierarchyCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -68,7 +68,6 @@ TPM2_CreatePrimary(
|
||||
CreatePrimary_Out *out // OUT: output parameter list
|
||||
)
|
||||
{
|
||||
// Local variables
|
||||
TPM_RC result = TPM_RC_SUCCESS;
|
||||
TPMT_PUBLIC *publicArea;
|
||||
DRBG_STATE rand;
|
||||
@ -289,13 +288,12 @@ TPM2_ChangePPS(
|
||||
RETURN_IF_NV_IS_NOT_AVAILABLE;
|
||||
// Input parameter is not reference in command action
|
||||
NOT_REFERENCED(in);
|
||||
// in = NULL; kgold
|
||||
// Internal Data Update
|
||||
// Reset platform hierarchy seed from RNG
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.PPSeed.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.PPSeed.t.buffer), gp.PPSeed.t.buffer);
|
||||
// Create a new phProof value from RNG to prevent the saved platform
|
||||
// hierarchy contexts being loaded
|
||||
CryptRandomGenerate(PROOF_SIZE, gp.phProof.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.phProof.t.buffer), gp.phProof.t.buffer);
|
||||
// Set platform authPolicy to null
|
||||
gc.platformAlg = TPM_ALG_NULL;
|
||||
gc.platformPolicy.t.size = 0;
|
||||
@ -336,9 +334,9 @@ TPM2_ChangeEPS(
|
||||
NOT_REFERENCED(in);
|
||||
// Internal Data Update
|
||||
// Reset endorsement hierarchy seed from RNG
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.EPSeed.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.EPSeed.t.buffer), gp.EPSeed.t.buffer);
|
||||
// Create new ehProof value from RNG
|
||||
CryptRandomGenerate(PROOF_SIZE, gp.ehProof.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.ehProof.t.buffer), gp.ehProof.t.buffer);
|
||||
// Enable endorsement hierarchy
|
||||
gc.ehEnable = TRUE;
|
||||
// set authValue buffer to zeros
|
||||
@ -383,10 +381,10 @@ TPM2_Clear(
|
||||
return TPM_RC_DISABLED;
|
||||
// Internal Data Update
|
||||
// Reset storage hierarchy seed from RNG
|
||||
CryptRandomGenerate(PRIMARY_SEED_SIZE, gp.SPSeed.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.SPSeed.t.buffer), gp.SPSeed.t.buffer);
|
||||
// Create new shProof and ehProof value from RNG
|
||||
CryptRandomGenerate(PROOF_SIZE, gp.shProof.t.buffer);
|
||||
CryptRandomGenerate(PROOF_SIZE, gp.ehProof.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.shProof.t.buffer), gp.shProof.t.buffer);
|
||||
CryptRandomGenerate(sizeof(gp.ehProof.t.buffer), gp.ehProof.t.buffer);
|
||||
// Enable storage and endorsement hierarchy
|
||||
gc.shEnable = gc.ehEnable = TRUE;
|
||||
// set the authValue buffers to zero
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Hierarchy_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Hierarchy_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -70,7 +70,7 @@ void
|
||||
HierarchyStartup(
|
||||
STARTUP_TYPE type // IN: start up type
|
||||
);
|
||||
TPM2B_AUTH *
|
||||
TPM2B_PROOF *
|
||||
HierarchyGetProof(
|
||||
TPMI_RH_HIERARCHY hierarchy // IN: hierarchy constant
|
||||
);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Implementation.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Implementation.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -81,14 +81,18 @@
|
||||
#define SET 1
|
||||
#define CLEAR 0
|
||||
/* From Vendor-Specific: Table 1 - Defines for Processor Values */
|
||||
#ifndef BIG_ENDIAN_TPM
|
||||
#define BIG_ENDIAN_TPM NO
|
||||
#define LITTLE_ENDIAN_TPM YES
|
||||
#define AUTO_ALIGN NO
|
||||
#endif
|
||||
#define LITTLE_ENDIAN_TPM !BIG_ENDIAN_TPM
|
||||
#define MOST_SIGNIFICANT_BIT_0 NO
|
||||
#define LEAST_SIGNIFICANT_BIT_0 !MOST_SIGNIFICANT_BIT_0
|
||||
#define AUTO_ALIGN NO
|
||||
/* From Vendor-Specific: Table 2 - Defines for Implemented Algorithms */
|
||||
#define ALG_RSA ALG_YES
|
||||
#define ALG_SHA1 ALG_YES
|
||||
#define ALG_HMAC ALG_YES
|
||||
#define ALG_TDES ALG_YES
|
||||
#define ALG_TDES ALG_NO
|
||||
#define ALG_AES ALG_YES
|
||||
#define ALG_MGF1 ALG_YES
|
||||
#define ALG_XOR ALG_YES
|
||||
@ -113,6 +117,7 @@
|
||||
#define ALG_KDF1_SP800_56A (ALG_YES*ALG_ECC)
|
||||
#define ALG_KDF2 ALG_NO
|
||||
#define ALG_KDF1_SP800_108 ALG_YES
|
||||
#define ALG_CMAC ALG_NO
|
||||
#define ALG_CTR ALG_YES
|
||||
#define ALG_OFB ALG_YES
|
||||
#define ALG_CBC ALG_YES
|
||||
@ -213,8 +218,10 @@
|
||||
#define CC_HashSequenceStart CC_YES
|
||||
#define CC_HierarchyChangeAuth CC_YES
|
||||
#define CC_HierarchyControl CC_YES
|
||||
#define CC_HMAC CC_YES
|
||||
#define CC_HMAC_Start CC_YES
|
||||
#define CC_HMAC (CC_YES^ALG_CMAC)
|
||||
#define CC_MAC (CC_NO^ALG_CMAC)
|
||||
#define CC_HMAC_Start (CC_YES^ALG_CMAC)
|
||||
#define CC_MAC_Start (CC_NO^ALG_CMAC)
|
||||
#define CC_Import CC_YES
|
||||
#define CC_IncrementalSelfTest CC_YES
|
||||
#define CC_Load CC_YES
|
||||
@ -353,6 +360,7 @@
|
||||
#define CRT_FORMAT_RSA YES
|
||||
#define VENDOR_COMMAND_COUNT 0
|
||||
#define MAX_VENDOR_BUFFER_SIZE 1024
|
||||
#define TPM_MAX_DERIVATION_BITS 8192
|
||||
/* From TCG Algorithm Registry: Table 2 - Definition of TPM_ALG_ID Constants */
|
||||
typedef UINT16 TPM_ALG_ID;
|
||||
#define ALG_ERROR_VALUE 0x0000
|
||||
@ -479,6 +487,10 @@ typedef UINT16 TPM_ALG_ID;
|
||||
#if defined ALG_CAMELLIA && ALG_CAMELLIA == YES
|
||||
#define TPM_ALG_CAMELLIA (TPM_ALG_ID)(ALG_CAMELLIA_VALUE)
|
||||
#endif
|
||||
#define ALG_CMAC_VALUE 0x003F
|
||||
#if defined ALG_CMAC && ALG_CMAC == YES
|
||||
#define TPM_ALG_CMAC (TPM_ALG_ID)(ALG_CMAC_VALUE)
|
||||
#endif
|
||||
#define ALG_CTR_VALUE 0x0040
|
||||
#if defined ALG_CTR && ALG_CTR == YES
|
||||
#define TPM_ALG_CTR (TPM_ALG_ID)(ALG_CTR_VALUE)
|
||||
@ -913,6 +925,12 @@ typedef UINT32 TPM_CC;
|
||||
#if CC_HMAC == YES
|
||||
#define TPM_CC_HMAC (TPM_CC)(0x00000155)
|
||||
#endif
|
||||
#ifndef CC_MAC
|
||||
# define CC_MAC NO
|
||||
#endif
|
||||
#if CC_MAC == YES
|
||||
#define TPM_CC_MAC (TPM_CC)(0x00000155)
|
||||
#endif
|
||||
#ifndef CC_Import
|
||||
# define CC_Import NO
|
||||
#endif
|
||||
@ -943,6 +961,12 @@ typedef UINT32 TPM_CC;
|
||||
#if CC_HMAC_Start == YES
|
||||
#define TPM_CC_HMAC_Start (TPM_CC)(0x0000015b)
|
||||
#endif
|
||||
#ifndef CC_MAC_Start
|
||||
# define CC_MAC_Start NO
|
||||
#endif
|
||||
#if CC_MAC_Start == YES
|
||||
#define TPM_CC_MAC_Start (TPM_CC)(0x0000015b)
|
||||
#endif
|
||||
#ifndef CC_SequenceUpdate
|
||||
# define CC_SequenceUpdate NO
|
||||
#endif
|
||||
@ -1261,6 +1285,12 @@ typedef UINT32 TPM_CC;
|
||||
#if CC_EncryptDecrypt2 == YES
|
||||
#define TPM_CC_EncryptDecrypt2 (TPM_CC)(0x00000193)
|
||||
#endif
|
||||
#ifndef CC_AC_GetCapability
|
||||
# define CC_AC_GetCapability NO
|
||||
#endif
|
||||
#if CC_AC_GetCapability == YES
|
||||
#define TPM_CC_AC_GetCapability (TPM_CC)(0x00000194)
|
||||
#endif
|
||||
#ifndef CC_AC_Send
|
||||
# define CC_AC_Send NO
|
||||
#endif
|
||||
@ -1273,12 +1303,6 @@ typedef UINT32 TPM_CC;
|
||||
#if CC_Policy_AC_SendSelect == YES
|
||||
#define TPM_CC_Policy_AC_SendSelect (TPM_CC)(0x00000196)
|
||||
#endif
|
||||
#ifndef CC_SMAC
|
||||
# define CC_SMAC NO
|
||||
#endif
|
||||
#if CC_SMAC == YES
|
||||
#define TPM_CC_SMAC (TPM_CC)(0x00000197)
|
||||
#endif
|
||||
#define CC_VEND (TPM_CC)(0x20000000)
|
||||
#ifndef CC_Vendor_TCG_Test
|
||||
# define CC_Vendor_TCG_Test NO
|
||||
@ -1349,13 +1373,13 @@ typedef UINT32 TPM_CC;
|
||||
+ (ADD_FILL || CC_Rewrap) /* 0x00000152 */ \
|
||||
+ (ADD_FILL || CC_Create) /* 0x00000153 */ \
|
||||
+ (ADD_FILL || CC_ECDH_ZGen) /* 0x00000154 */ \
|
||||
+ (ADD_FILL || CC_HMAC) /* 0x00000155 */ \
|
||||
+ (ADD_FILL || CC_HMAC || CC_MAC) /* 0x00000155 */ \
|
||||
+ (ADD_FILL || CC_Import) /* 0x00000156 */ \
|
||||
+ (ADD_FILL || CC_Load) /* 0x00000157 */ \
|
||||
+ (ADD_FILL || CC_Quote) /* 0x00000158 */ \
|
||||
+ (ADD_FILL || CC_RSA_Decrypt) /* 0x00000159 */ \
|
||||
+ ADD_FILL /* 0x0000015a */ \
|
||||
+ (ADD_FILL || CC_HMAC_Start) /* 0x0000015b */ \
|
||||
+ (ADD_FILL || CC_HMAC_Start || CC_MAC_Start) /* 0x0000015b */ \
|
||||
+ (ADD_FILL || CC_SequenceUpdate) /* 0x0000015c */ \
|
||||
+ (ADD_FILL || CC_Sign) /* 0x0000015d */ \
|
||||
+ (ADD_FILL || CC_Unseal) /* 0x0000015e */ \
|
||||
@ -1417,7 +1441,6 @@ typedef UINT32 TPM_CC;
|
||||
+ (ADD_FILL || CC_Policy_AC_SendSelect) /* 0x00000196 */ \
|
||||
+ ADD_FILL /* 0x00000197 */ \
|
||||
)
|
||||
|
||||
#define VENDOR_COMMAND_ARRAY_SIZE ( 0 \
|
||||
+ CC_Vendor_TCG_Test \
|
||||
)
|
||||
@ -1496,6 +1519,4 @@ typedef TPM2B_MAX_HASH_BLOCK TPM2B_HASH_BLOCK;
|
||||
#if MAX_SYM_KEY_BITS == 0 || MAX_SYM_BLOCK_SIZE == 0
|
||||
# error Bad size for MAX_SYM_KEY_BITS or MAX_SYM_BLOCK_SIZE
|
||||
#endif
|
||||
/* Define the 2B structure for a seed */
|
||||
TPM2B_TYPE(SEED, PRIMARY_SEED_SIZE);
|
||||
#endif // _IMPLEMENTATION_H_
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Include Headers for Internal Routines */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: InternalRoutines.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: InternalRoutines.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -106,7 +106,7 @@
|
||||
#include "IoBuffers_fp.h"
|
||||
#include "Memory_fp.h"
|
||||
#include "ResponseCodeProcessing_fp.h"
|
||||
/* Internal crypto functions */
|
||||
/* Internal cryptographic functions */
|
||||
#include "BnConvert_fp.h"
|
||||
#include "BnMath_fp.h"
|
||||
#include "BnMemory_fp.h"
|
||||
@ -130,6 +130,12 @@
|
||||
#include "CryptEccSignature_fp.h"
|
||||
#include "CryptEccKeyExchange_fp.h"
|
||||
#endif
|
||||
#if defined TPM_CC_MAC || defined TPM_CC_MAC_Start
|
||||
# include "CryptSmac_fp.h"
|
||||
# ifdef TPM_ALG_CMAC
|
||||
# include "CryptCmac_fp.h"
|
||||
# endif
|
||||
#endif
|
||||
/* Support library */
|
||||
#include "SupportLibraryFunctionPrototypes_fp.h"
|
||||
/* Linkage to platform functions */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: IoBuffers.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: IoBuffers.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Locality.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Locality.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -76,19 +76,19 @@ LocalityGetAttributes(
|
||||
switch(locality)
|
||||
{
|
||||
case 0:
|
||||
locality_attributes.TPM_LOC_ZERO = SET;
|
||||
SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_ZERO);
|
||||
break;
|
||||
case 1:
|
||||
locality_attributes.TPM_LOC_ONE = SET;
|
||||
SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_ONE);
|
||||
break;
|
||||
case 2:
|
||||
locality_attributes.TPM_LOC_TWO = SET;
|
||||
SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_TWO);
|
||||
break;
|
||||
case 3:
|
||||
locality_attributes.TPM_LOC_THREE = SET;
|
||||
SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_THREE);
|
||||
break;
|
||||
case 4:
|
||||
locality_attributes.TPM_LOC_FOUR = SET;
|
||||
SET_ATTRIBUTE(locality_attributes, TPMA_LOCALITY, TPM_LOC_FOUR);
|
||||
break;
|
||||
default:
|
||||
pAssert(locality > 31);
|
||||
|
||||
88
src/tpm2/MAC_Start_fp.h
Normal file
88
src/tpm2/MAC_Start_fp.h
Normal file
@ -0,0 +1,88 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: MAC_Start_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - 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 */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* rev 146 */
|
||||
|
||||
#ifndef MAC_START_FP_H
|
||||
#define MAC_START_FP_H
|
||||
|
||||
typedef struct {
|
||||
TPMI_DH_OBJECT handle;
|
||||
TPM2B_AUTH auth;
|
||||
TPMI_ALG_MAC_SCHEME inScheme;
|
||||
} MAC_Start_In;
|
||||
|
||||
typedef struct {
|
||||
TPMI_DH_OBJECT sequenceHandle;
|
||||
} MAC_Start_Out;
|
||||
|
||||
#define RC_MAC_Start_handle (TPM_RC_H + TPM_RC_1)
|
||||
#define RC_MAC_Start_auth (TPM_RC_P + TPM_RC_1)
|
||||
#define RC_MAC_Start_inScheme (TPM_RC_P + TPM_RC_2)
|
||||
|
||||
TPM_RC
|
||||
TPM2_MAC_Start(
|
||||
MAC_Start_In *in, // IN: input parameter list
|
||||
MAC_Start_Out *out // OUT: output parameter list
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
88
src/tpm2/MAC_fp.h
Normal file
88
src/tpm2/MAC_fp.h
Normal file
@ -0,0 +1,88 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: MAC_fp.h 1049 2017-07-20 21:00:18Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - 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 */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2012-2015 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* rev 119 */
|
||||
|
||||
#ifndef MAC_FP_H
|
||||
#define MAC_FP_H
|
||||
|
||||
typedef struct {
|
||||
TPMI_DH_OBJECT handle;
|
||||
TPM2B_MAX_BUFFER buffer;
|
||||
TPMI_ALG_MAC_SCHEME inScheme;
|
||||
} Mac_In;
|
||||
|
||||
#define RC_Mac_handle (TPM_RC_H + TPM_RC_1)
|
||||
#define RC_Mac_buffer (TPM_RC_P + TPM_RC_1)
|
||||
#define RC_Mac_inScheme (TPM_RC_P + TPM_RC_2)
|
||||
|
||||
typedef struct {
|
||||
TPM2B_MAX_BUFFER outMac;
|
||||
} Mac_Out;
|
||||
|
||||
TPM_RC
|
||||
TPM2_Mac(
|
||||
Mac_In *in, // IN: input parameter list
|
||||
Mac_Out *out // OUT: output parameter list
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Parameter Marshaling */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Marshal.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Marshal.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -335,7 +335,7 @@ UINT16
|
||||
TPMA_SESSION_Marshal(TPMA_SESSION *source, BYTE **buffer, INT32 *size)
|
||||
{
|
||||
UINT16 written = 0;
|
||||
written += UINT8_Marshal(&source->val, buffer, size);
|
||||
written += UINT8_Marshal(source, buffer, size);
|
||||
return written;
|
||||
}
|
||||
|
||||
@ -345,7 +345,7 @@ UINT16
|
||||
TPMA_LOCALITY_Marshal(TPMA_LOCALITY *source, BYTE **buffer, INT32 *size)
|
||||
{
|
||||
UINT16 written = 0;
|
||||
written += UINT8_Marshal(&source->val, buffer, size);
|
||||
written += UINT8_Marshal(source, buffer, size);
|
||||
return written;
|
||||
}
|
||||
|
||||
@ -561,6 +561,15 @@ TPM2B_MAX_NV_BUFFER_Marshal(TPM2B_MAX_NV_BUFFER *source, BYTE **buffer, INT32 *s
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Table 80 - Definition of TPM2B_TIMEOUT Structure <IN/OUT> */
|
||||
UINT16
|
||||
TPM2B_TIMEOUT_Marshal(TPM2B_TIMEOUT *source, BYTE **buffer, INT32 *size)
|
||||
{
|
||||
UINT16 written = 0;
|
||||
written += TPM2B_Marshal(&source->b, buffer, size);
|
||||
return written;
|
||||
}
|
||||
|
||||
/* Table 2:82 - Definition of TPM2B_IV Structure (StructuresTable()) */
|
||||
|
||||
UINT16
|
||||
@ -1690,8 +1699,8 @@ TPMS_ALGORITHM_DETAIL_ECC_Marshal(TPMS_ALGORITHM_DETAIL_ECC *source, BYTE **buff
|
||||
|
||||
written += TPM_ECC_CURVE_Marshal(&source->curveID, buffer, size);
|
||||
written += UINT16_Marshal(&source->keySize, buffer, size);
|
||||
written += TPMT_KDF_SCHEME_Marshal(&source->kdf, buffer, size);;
|
||||
written += TPMT_ECC_SCHEME_Marshal(&source->sign, buffer, size);;
|
||||
written += TPMT_KDF_SCHEME_Marshal(&source->kdf, buffer, size);
|
||||
written += TPMT_ECC_SCHEME_Marshal(&source->sign, buffer, size);
|
||||
written += TPM2B_ECC_PARAMETER_Marshal(&source->p, buffer, size);
|
||||
written += TPM2B_ECC_PARAMETER_Marshal(&source->a, buffer, size);
|
||||
written += TPM2B_ECC_PARAMETER_Marshal(&source->b, buffer, size);
|
||||
@ -2079,7 +2088,7 @@ UINT16
|
||||
TPMA_NV_Marshal(TPMA_NV *source, BYTE **buffer, INT32 *size)
|
||||
{
|
||||
UINT16 written = 0;
|
||||
written += UINT32_Marshal(&source->val, buffer, size);
|
||||
written += UINT32_Marshal(source, buffer, size);
|
||||
return written;
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Parameter Marshaling */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Marshal_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Marshal_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -153,6 +153,8 @@ extern "C" {
|
||||
UINT16
|
||||
TPM2B_MAX_NV_BUFFER_Marshal(TPM2B_MAX_NV_BUFFER *source, BYTE **buffer, INT32 *size);
|
||||
UINT16
|
||||
TPM2B_TIMEOUT_Marshal(TPM2B_TIMEOUT *source, BYTE **buffer, INT32 *size);
|
||||
UINT16
|
||||
TPM2B_IV_Marshal(TPM2B_IV *source, BYTE **buffer, INT32 *size);
|
||||
UINT16
|
||||
TPM2B_NAME_Marshal(TPM2B_NAME *source, BYTE **buffer, INT32 *size);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Math functions performed with canonical integers in byte buffers */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: MathOnByteBuffers.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: MathOnByteBuffers.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
/* This file contains implementation of the math functions that are performed with canonical
|
||||
integers in byte buffers. The canonical integer is big-endian bytes. */
|
||||
#include "Tpm.h"
|
||||
/* 9.11.1.1 UnsignedCmpB */
|
||||
/* 9.11.2.1 UnsignedCmpB */
|
||||
/* This function compare two unsigned values. The values are byte-aligned, big-endian numbers (e.g,
|
||||
a hash). */
|
||||
/* Return Values Meaning */
|
||||
@ -94,7 +94,7 @@ UnsignedCompareB(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* 9.11.1.2 SignedCompareB() */
|
||||
/* 9.11.2.2 SignedCompareB() */
|
||||
/* Compare two signed integers: */
|
||||
/* Return Values Meaning */
|
||||
/* 1 if a > b */
|
||||
@ -126,7 +126,7 @@ SignedCompareB(
|
||||
// do unsigned compare the other way
|
||||
return 0 - UnsignedCompareB(aSize, a, bSize, b);
|
||||
}
|
||||
/* 9.11.1.3 ModExpB */
|
||||
/* 9.11.3.3 ModExpB */
|
||||
/* This function is used to do modular exponentiation in support of RSA. The most typical uses are:
|
||||
c = m^e mod n (RSA encrypt) and m = c^d mod n (RSA decrypt). When doing decryption, the e
|
||||
parameter of the function will contain the private exponent d instead of the public exponent
|
||||
@ -174,7 +174,7 @@ ModExpB(
|
||||
Exit:
|
||||
return retVal;
|
||||
}
|
||||
/* 9.11.1.4 DivideB() */
|
||||
/* 9.11.2.4 DivideB() */
|
||||
/* Divide an integer (n) by an integer (d) producing a quotient (q) and a remainder (r). If q or r
|
||||
is not needed, then the pointer to them may be set to NULL. */
|
||||
/* Error Returns Meaning */
|
||||
@ -205,7 +205,7 @@ DivideB(
|
||||
return TPM_RC_NO_RESULT;
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
/* 9.11.1.5 AdjustNumberB() */
|
||||
/* 9.11.2.5 AdjustNumberB() */
|
||||
/* Remove/add leading zeros from a number in a TPM2B. Will try to make the number by adding or
|
||||
removing leading zeros. If the number is larger than the requested size, it will make the number
|
||||
as small as possible. Setting requestedSize to zero is equivalent to requesting that the number
|
||||
@ -242,3 +242,24 @@ AdjustNumberB(
|
||||
}
|
||||
return num->size;
|
||||
}
|
||||
|
||||
/* 9.11.2.6 ShiftLeft() */
|
||||
/* This function shifts a byte buffer (a TPM2B) one byte to the left. That is, the most significant
|
||||
bit of the most significant byte is lost. */
|
||||
TPM2B *
|
||||
ShiftLeft(
|
||||
TPM2B *value // IN/OUT: value to shift and shifted value out
|
||||
)
|
||||
{
|
||||
UINT16 count = value->size;
|
||||
BYTE *buffer = value->buffer;
|
||||
if(count > 0)
|
||||
{
|
||||
for(count -= 1; count > 0; buffer++, count--)
|
||||
{
|
||||
buffer[0] = (buffer[0] << 1) + ((buffer[1] & 0x80) ? 1 : 0);
|
||||
}
|
||||
*buffer <<= 1;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Math functions performed with canonical integers in byte buffers */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: MathOnByteBuffers_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: MathOnByteBuffers_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -102,6 +102,9 @@ AdjustNumberB(
|
||||
TPM2B *num,
|
||||
UINT16 requestedSize
|
||||
);
|
||||
|
||||
TPM2B *
|
||||
ShiftLeft(
|
||||
TPM2B *value // IN/OUT: value to shift and shifted value out
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: NV.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: NV.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -62,53 +62,43 @@
|
||||
#ifndef NV_H
|
||||
#define NV_H
|
||||
|
||||
/* 5.14.1 Index Type Definitions */
|
||||
/* These definitions allow the same code to be used pre and post 1.21. The main action is to
|
||||
redefine the index type values from the bit values. Use TPM_NT_ORDINARY to indicate if the TPM_NT
|
||||
type is defined */
|
||||
#ifdef TPM_NT_ORDINARY
|
||||
# define NV_ATTRIBUTES_TO_TYPE(attributes) (attributes.TPM_NT)
|
||||
/* If TPM_NT_ORDINARY is defined, then the TPM_NT field is present in a TPMA_NV */
|
||||
# define GET_TPM_NT(attributes) GET_ATTRIBUTE(attributes, TPMA_NV, TPM_NT)
|
||||
#else
|
||||
# define NV_ATTRIBUTES_TO_TYPE(attributes) \
|
||||
( attributes.TPMA_NV_COUNTER \
|
||||
+ (attributes.TPMA_NV_BITS << 1) \
|
||||
+ (attributes.TPMA_NV_EXTEND << 2) \
|
||||
/* If TPM_NT_ORDINARY is not defined, then need to synthesize it from the attributes */
|
||||
# define GetNv_TPM_NV(attributes) \
|
||||
( IS_ATTRIBUTE(attributes, TPMA_NV, COUNTER) \
|
||||
+ (IS_ATTRIBUTE(attributes, TPMA_NV, BITS) << 1) \
|
||||
+ (IS_ATTRIBUTE(attributes, TPMA_NV, EXTEND) << 2) \
|
||||
)
|
||||
# define TPM_NT_ORDINARY (0)
|
||||
# define TPM_NT_COUNTER (1)
|
||||
# define TPM_NT_BITS (2)
|
||||
# define TPM_NT_EXTEND (4)
|
||||
#endif
|
||||
/* 5.17.2 Attribute Macros */
|
||||
/* 5.14.2 Attribute Macros */
|
||||
/* These macros are used to isolate the differences in the way that the index type changed in
|
||||
version 1.21 of the specification */
|
||||
#ifdef TPM_NT_ORDINARY
|
||||
# define IsNvOrdinaryIndex(attributes) (attributes.TPM_NT == TPM_NT_ORDINARY)
|
||||
#else
|
||||
# define IsNvOrdinaryIndex(attributes) \
|
||||
((attributes.TPMA_NV_COUNTER == CLEAR) \
|
||||
&& (attributes.TPMA_NV_BITS == CLEAR) \
|
||||
&& (attributes.TPMA_NV_EXTEND == CLEAR)
|
||||
# define TPM_NT_ORDINARY (0)
|
||||
#endif
|
||||
#ifdef TPM_NT_COUNTER
|
||||
# define IsNvCounterIndex(attributes) (attributes.TPM_NT == TPM_NT_COUNTER)
|
||||
#else
|
||||
# define IsNvCounterIndex(attributes) (attributes.TPMA_NV_COUNTER == SET)
|
||||
# define TPM_NT_COUNTER (1)
|
||||
#endif
|
||||
#ifdef TPM_NT_BITS
|
||||
# define IsNvBitsIndex(attributes) (attributes.TPM_NT == TPM_NT_BITS)
|
||||
#else
|
||||
# define IsNvBitsIndex(attributes) (attributes.TPMA_NV_BITS == SET)
|
||||
# define TPM_NT_BITS (2)
|
||||
#endif
|
||||
#ifdef TPM_NT_EXTEND
|
||||
# define IsNvExtendIndex(attributes) (attributes.TPM_NT == TPM_NT_EXTEND)
|
||||
#else
|
||||
# define IsNvExtendIndex(attributes) (attributes.TPMA_NV_EXTEND == SET)
|
||||
# define TPM_NT_EXTEND (4)
|
||||
#endif
|
||||
(GET_TPM_NT(attributes) == TPM_NT_ORDINARY)
|
||||
# define IsNvCounterIndex(attributes) \
|
||||
(GET_TPM_NT(attributes) == TPM_NT_COUNTER)
|
||||
# define IsNvBitsIndex(attributes) \
|
||||
(GET_TPM_NT(attributes) == TPM_NT_BITS)
|
||||
# define IsNvExtendIndex(attributes) \
|
||||
(GET_TPM_NT(attributes) == TPM_NT_EXTEND)
|
||||
#ifdef TPM_NT_PIN_PASS
|
||||
# define IsNvPinPassIndex(attributes) (attributes.TPM_NT == TPM_NT_PIN_PASS)
|
||||
# define IsNvPinPassIndex(attributes) \
|
||||
(GET_TPM_NT(attributes) == TPM_NT_PIN_PASS)
|
||||
#endif
|
||||
#ifdef TPM_NT_PIN_FAIL
|
||||
# define IsNvPinFailIndex(attributes) (attributes.TPM_NT == TPM_NT_PIN_FAIL)
|
||||
# define IsNvPinFailIndex(attributes) \
|
||||
(GET_TPM_NT(attributes) == TPM_NT_PIN_FAIL)
|
||||
#endif
|
||||
typedef struct {
|
||||
UINT32 size;
|
||||
@ -118,7 +108,7 @@ typedef struct {
|
||||
(sizeof(UINT32) + sizeof(TPM_HANDLE) + sizeof(OBJECT))
|
||||
#define NV_INDEX_COUNTER_SIZE \
|
||||
(sizeof(UINT32) + sizeof(NV_INDEX) + sizeof(UINT64))
|
||||
#define NV_RAM_INDEX_COUNTER_SIZE \
|
||||
#define NV_RAM_INDEX_COUNTER_SIZE \
|
||||
(sizeof(NV_RAM_HEADER) + sizeof(UINT64))
|
||||
typedef struct {
|
||||
UINT32 size;
|
||||
@ -130,22 +120,20 @@ typedef struct {
|
||||
UINT32 values so that there is no padding between the UINT32 list end marker and the UIT64m()
|
||||
maxCounter value. */
|
||||
typedef UINT32 NV_LIST_TERMINATOR[3];
|
||||
|
||||
/* 5.15.3 Orderly RAM Values */
|
||||
|
||||
/* 5.14.3 Orderly RAM Values */
|
||||
/* The following defines are for accessing orderly RAM values. This is the initialize for the RAM
|
||||
reference iterator. */
|
||||
#define NV_RAM_REF_INIT 0
|
||||
/* This is the starting address of the RAM space used for orderly data */
|
||||
#define RAM_ORDERLY_START \
|
||||
(&s_indexOrderlyRam[0])
|
||||
#define RAM_ORDERLY_START \
|
||||
(&s_indexOrderlyRam[0])
|
||||
/* This is the offset within NV that is used to save the orderly data on an orderly shutdown. */
|
||||
#define NV_ORDERLY_START \
|
||||
(NV_INDEX_RAM_DATA)
|
||||
#define NV_ORDERLY_START \
|
||||
(NV_INDEX_RAM_DATA)
|
||||
/* This is the end of the orderly RAM space. It is actually the first byte after the last byte of
|
||||
orderly RAM data */
|
||||
#define RAM_ORDERLY_END \
|
||||
(RAM_ORDERLY_START + sizeof(s_indexOrderlyRam))
|
||||
(RAM_ORDERLY_START + sizeof(s_indexOrderlyRam))
|
||||
/* This is the end of the orderly space in NV memory. As with RAM_ORDERLY_END, it is actually the
|
||||
offset of the first byte after the end of the NV orderly data. */
|
||||
#define NV_ORDERLY_END \
|
||||
@ -153,17 +141,17 @@ typedef UINT32 NV_LIST_TERMINATOR[3];
|
||||
/* Macro to check that an orderly RAM address is with range. */
|
||||
#define ORDERLY_RAM_ADDRESS_OK(start, offset) \
|
||||
((start >= RAM_ORDERLY_START) && ((start + offset - 1) < RAM_ORDERLY_END))
|
||||
#define RETURN_IF_NV_IS_NOT_AVAILABLE \
|
||||
{ \
|
||||
if(g_NvStatus != TPM_RC_SUCCESS) \
|
||||
return g_NvStatus; \
|
||||
#define RETURN_IF_NV_IS_NOT_AVAILABLE \
|
||||
{ \
|
||||
if(g_NvStatus != TPM_RC_SUCCESS) \
|
||||
return g_NvStatus; \
|
||||
}
|
||||
/* Routinely have to clear the orderly flag and fail if the NV is not available so that it can be
|
||||
cleared. */
|
||||
#define RETURN_IF_ORDERLY \
|
||||
{ \
|
||||
if(NvClearOrderly() != TPM_RC_SUCCESS) \
|
||||
return g_NvStatus; \
|
||||
#define RETURN_IF_ORDERLY \
|
||||
{ \
|
||||
if(NvClearOrderly() != TPM_RC_SUCCESS) \
|
||||
return g_NvStatus; \
|
||||
}
|
||||
#define NV_IS_AVAILABLE (g_NvStatus == TPM_RC_SUCCESS)
|
||||
#define IS_ORDERLY(value) (value < SU_DA_USED_VALUE)
|
||||
@ -171,5 +159,4 @@ typedef UINT32 NV_LIST_TERMINATOR[3];
|
||||
/* Macro to set the NV UPDATE_TYPE. This deals with the fact that the update is possibly a
|
||||
combination of UT_NV and UT_ORDERLY. */
|
||||
#define SET_NV_UPDATE(type) g_updateNV |= (type)
|
||||
|
||||
#endif
|
||||
#endif // _NV_H_
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Non-Volatile Storage */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: NVCommands.c 847 2016-11-29 21:17:44Z kgoldman $ */
|
||||
/* $Id: NVCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -75,7 +75,7 @@ TPM2_NV_DefineSpace(
|
||||
// If the UndefineSpaceSpecial command is not implemented, then can't have
|
||||
// an index that can only be deleted with policy
|
||||
#if CC_NV_UndefineSpaceSpecial == NO
|
||||
if(IsNv_TPMA_NV_POLICY_DELETE(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, POLICY_DELETE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
#endif
|
||||
// check that the authPolicy consistent with hash algorithm
|
||||
@ -94,7 +94,7 @@ TPM2_NV_DefineSpace(
|
||||
return TPM_RCS_HIERARCHY + RC_NV_DefineSpace_authHandle;
|
||||
// Attribute checks
|
||||
// Eliminate the unsupported types
|
||||
switch(NV_ATTRIBUTES_TO_TYPE(attributes))
|
||||
switch(GET_TPM_NT(attributes))
|
||||
{
|
||||
#if CC_NV_Increment == YES
|
||||
case TPM_NT_COUNTER:
|
||||
@ -105,7 +105,7 @@ TPM2_NV_DefineSpace(
|
||||
#if CC_NV_Extend == YES
|
||||
case TPM_NT_EXTEND:
|
||||
#endif
|
||||
#if CC_PolicySigned == YES && defined TPM_NT_PIN_PASS
|
||||
#if CC_PolicySecret == YES && defined TPM_NT_PIN_PASS
|
||||
case TPM_NT_PIN_PASS:
|
||||
case TPM_NT_PIN_FAIL:
|
||||
#endif
|
||||
@ -116,7 +116,7 @@ TPM2_NV_DefineSpace(
|
||||
break;
|
||||
}
|
||||
// Check that the sizes are OK based on the type
|
||||
switch(NV_ATTRIBUTES_TO_TYPE(attributes))
|
||||
switch(GET_TPM_NT(attributes))
|
||||
{
|
||||
case TPM_NT_ORDINARY:
|
||||
// Can't exceed the allowed size for the implementation
|
||||
@ -134,11 +134,11 @@ TPM2_NV_DefineSpace(
|
||||
break;
|
||||
}
|
||||
// Handle other specifics
|
||||
switch(NV_ATTRIBUTES_TO_TYPE(attributes))
|
||||
switch(GET_TPM_NT(attributes))
|
||||
{
|
||||
case TPM_NT_COUNTER:
|
||||
// Counter can't have TPMA_NV_CLEAR_STCLEAR SET (don't clear counters)
|
||||
if(IsNv_TPMA_NV_CLEAR_STCLEAR(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
break;
|
||||
#ifdef TPM_NT_PIN_FAIL
|
||||
@ -153,15 +153,15 @@ TPM2_NV_DefineSpace(
|
||||
// (i.e., with platform authorization , owner authorization,
|
||||
// or with policyAuth.)
|
||||
// It is not allowed to create a PIN Index that can't be modified.
|
||||
if(!IsNv_TPMA_NV_NO_DA(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, NO_DA))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
#endif
|
||||
#ifdef TPM_NT_PIN_PASS
|
||||
case TPM_NT_PIN_PASS:
|
||||
// AUTHWRITE must be CLEAR (see note above to TPM_NT_PIN_FAIL)
|
||||
if(IsNv_TPMA_NV_AUTHWRITE(attributes)
|
||||
|| IsNv_TPMA_NV_GLOBALLOCK(attributes)
|
||||
|| IsNv_TPMA_NV_WRITEDEFINE(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, AUTHWRITE)
|
||||
|| IS_ATTRIBUTE(attributes, TPMA_NV, GLOBALLOCK)
|
||||
|| IS_ATTRIBUTE(attributes, TPMA_NV, WRITEDEFINE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
#endif // this comes before break because PIN_FAIL falls through
|
||||
break;
|
||||
@ -169,41 +169,41 @@ TPM2_NV_DefineSpace(
|
||||
break;
|
||||
}
|
||||
// Locks may not be SET and written cannot be SET
|
||||
if(IsNv_TPMA_NV_WRITTEN(attributes)
|
||||
|| IsNv_TPMA_NV_WRITELOCKED(attributes)
|
||||
|| IsNv_TPMA_NV_READLOCKED(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, WRITTEN)
|
||||
|| IS_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED)
|
||||
|| IS_ATTRIBUTE(attributes, TPMA_NV, READLOCKED))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
// There must be a way to read the index.
|
||||
if(!IsNv_TPMA_NV_OWNERREAD(attributes)
|
||||
&& !IsNv_TPMA_NV_PPREAD(attributes)
|
||||
&& !IsNv_TPMA_NV_AUTHREAD(attributes)
|
||||
&& !IsNv_TPMA_NV_POLICYREAD(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERREAD)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_NV, PPREAD)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_NV, AUTHREAD)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_NV, POLICYREAD))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
// There must be a way to write the index
|
||||
if(!IsNv_TPMA_NV_OWNERWRITE(attributes)
|
||||
&& !IsNv_TPMA_NV_PPWRITE(attributes)
|
||||
&& !IsNv_TPMA_NV_AUTHWRITE(attributes)
|
||||
&& !IsNv_TPMA_NV_POLICYWRITE(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERWRITE)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_NV, PPWRITE)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_NV, AUTHWRITE)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_NV, POLICYWRITE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
// An index with TPMA_NV_CLEAR_STCLEAR can't have TPMA_NV_WRITEDEFINE SET
|
||||
if(IsNv_TPMA_NV_CLEAR_STCLEAR(attributes)
|
||||
&& IsNv_TPMA_NV_WRITEDEFINE(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR)
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_NV, WRITEDEFINE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
// Make sure that the creator of the index can delete the index
|
||||
if((IsNv_TPMA_NV_PLATFORMCREATE(attributes)
|
||||
if((IS_ATTRIBUTE(attributes, TPMA_NV, PLATFORMCREATE)
|
||||
&& in->authHandle == TPM_RH_OWNER)
|
||||
|| (!IsNv_TPMA_NV_PLATFORMCREATE(attributes)
|
||||
|| (!IS_ATTRIBUTE(attributes, TPMA_NV, PLATFORMCREATE)
|
||||
&& in->authHandle == TPM_RH_PLATFORM))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_authHandle;
|
||||
// If TPMA_NV_POLICY_DELETE is SET, then the index must be defined by
|
||||
// the platform
|
||||
if(IsNv_TPMA_NV_POLICY_DELETE(attributes)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, POLICY_DELETE)
|
||||
&& TPM_RH_PLATFORM != in->authHandle)
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
// Make sure that the TPMA_NV_WRITEALL is not set if the index size is larger
|
||||
// than the allowed NV buffer size.
|
||||
if(in->publicInfo.nvPublic.dataSize > MAX_NV_BUFFER_SIZE
|
||||
&& IsNv_TPMA_NV_WRITEALL(attributes))
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_NV, WRITEALL))
|
||||
return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
|
||||
// And finally, see if the index is already defined.
|
||||
if(NvIndexIsDefined(in->publicInfo.nvPublic.nvIndex))
|
||||
@ -225,12 +225,12 @@ TPM2_NV_UndefineSpace(
|
||||
NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
|
||||
// Input Validation
|
||||
// This command can't be used to delete an index with TPMA_NV_POLICY_DELETE SET
|
||||
if(IsNv_TPMA_NV_POLICY_DELETE(nvIndex->publicArea.attributes))
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, POLICY_DELETE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_UndefineSpace_nvIndex;
|
||||
// The owner may only delete an index that was defined with ownerAuth. The
|
||||
// platform may delete an index that was created with either authorization.
|
||||
if(in->authHandle == TPM_RH_OWNER
|
||||
&& IsNv_TPMA_NV_PLATFORMCREATE(nvIndex->publicArea.attributes))
|
||||
&& IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, PLATFORMCREATE))
|
||||
return TPM_RC_NV_AUTHORIZATION;
|
||||
// Internal Data Update
|
||||
// Call implementation dependent internal routine to delete NV index
|
||||
@ -251,7 +251,7 @@ TPM2_NV_UndefineSpaceSpecial(
|
||||
NV_INDEX *nvIndex = NvGetIndexInfo(in->nvIndex, &locator);
|
||||
// Input Validation
|
||||
// This operation only applies when the TPMA_NV_POLICY_DELETE attribute is SET
|
||||
if(!IsNv_TPMA_NV_POLICY_DELETE(nvIndex->publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, POLICY_DELETE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_UndefineSpaceSpecial_nvIndex;
|
||||
// Internal Data Update
|
||||
// Call implementation dependent internal routine to delete NV index
|
||||
@ -317,7 +317,7 @@ TPM2_NV_Write(
|
||||
// full sized.
|
||||
// Note: if the requested size is the same as the Index data size, then offset
|
||||
// will have to be zero. Otherwise, the range check above would have failed.
|
||||
if(IsNv_TPMA_NV_WRITEALL(attributes)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, WRITEALL)
|
||||
&& in->data.t.size < nvIndex->publicArea.dataSize)
|
||||
return TPM_RC_NV_RANGE;
|
||||
// Internal Data Update
|
||||
@ -353,7 +353,7 @@ TPM2_NV_Increment(
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_Increment_nvIndex;
|
||||
// Internal Data Update
|
||||
// If counter index is not been written, initialize it
|
||||
if(!IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
|
||||
countValue = NvReadMaxCount();
|
||||
else
|
||||
// Read NV data in native format for TPM CPU.
|
||||
@ -369,12 +369,12 @@ TPM2_NV_Increment(
|
||||
// If a counter just rolled over, then force the NV update.
|
||||
// Note, if this is an orderly counter, then the write-back needs to be
|
||||
// forced, for other counters, the write-back will happen anyway
|
||||
if(IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes)
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY)
|
||||
&& (countValue & MAX_ORDERLY_COUNT) == 0 )
|
||||
{
|
||||
// Need to force an NV update of orderly data
|
||||
SET_NV_UPDATE(UT_ORDERLY);
|
||||
}
|
||||
{
|
||||
// Need to force an NV update of orderly data
|
||||
SET_NV_UPDATE(UT_ORDERLY);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -408,7 +408,7 @@ TPM2_NV_Extend(
|
||||
// Perform the write.
|
||||
oldDigest.t.size = CryptHashGetDigestSize(nvIndex->publicArea.nameAlg);
|
||||
pAssert(oldDigest.t.size <= sizeof(oldDigest.t.buffer));
|
||||
if(IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes))
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
|
||||
{
|
||||
NvGetIndexData(nvIndex, locator, 0, oldDigest.t.size, oldDigest.t.buffer);
|
||||
}
|
||||
@ -454,7 +454,7 @@ TPM2_NV_SetBits(
|
||||
if(!IsNvBitsIndex(nvIndex->publicArea.attributes))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_SetBits_nvIndex;
|
||||
// If index is not been written, initialize it
|
||||
if(!IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
|
||||
oldValue = 0;
|
||||
else
|
||||
// Read index data
|
||||
@ -491,14 +491,14 @@ TPM2_NV_WriteLock(
|
||||
}
|
||||
// if neither TPMA_NV_WRITEDEFINE nor TPMA_NV_WRITE_STCLEAR is set, the index
|
||||
// can not be write-locked
|
||||
if(nvAttributes.TPMA_NV_WRITEDEFINE == CLEAR
|
||||
&& nvAttributes.TPMA_NV_WRITE_STCLEAR == CLEAR)
|
||||
if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITEDEFINE)
|
||||
&& !IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITE_STCLEAR))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_WriteLock_nvIndex;
|
||||
// Internal Data Update
|
||||
// Set the WRITELOCK attribute.
|
||||
// Note: if TPMA_NV_WRITELOCKED were already SET, then the write access check
|
||||
// above would have failed and this code isn't executed.
|
||||
nvAttributes.TPMA_NV_WRITELOCKED = SET;
|
||||
SET_ATTRIBUTE(nvAttributes, TPMA_NV, WRITELOCKED);
|
||||
// Write index info back
|
||||
return NvWriteIndexAttributes(nvIndex->publicArea.nvIndex, locator,
|
||||
nvAttributes);
|
||||
@ -522,6 +522,13 @@ TPM2_NV_GlobalWriteLock(
|
||||
#include "Tpm.h"
|
||||
#include "NV_Read_fp.h"
|
||||
#ifdef TPM_CC_NV_Read // Conditional expansion of this file
|
||||
/* TPM_RC_NV_AUTHORIZATION the authorization was valid but the authorizing entity (authHandle) is
|
||||
not allowed to read from the Index referenced by nvIndex */
|
||||
/* TPM_RC_NV_LOCKED the Index referenced by nvIndex is read locked */
|
||||
/* TPM_RC_NV_RANGE read range defined by size and offset is outside the range of the Index
|
||||
referenced by nvIndex */
|
||||
/* TPM_RC_NV_UNINITIALIZED the Index referenced by nvIndex has not been initialized (written) */
|
||||
/* TPM_RC_VALUE the read size is larger than the MAX_NV_BUFFER_SIZE */
|
||||
TPM_RC
|
||||
TPM2_NV_Read(
|
||||
NV_Read_In *in, // IN: input parameter list
|
||||
@ -583,11 +590,11 @@ TPM2_NV_ReadLock(
|
||||
// If NvReadAccessChecks return TPM_RC_NV_UNINITALIZED, then continue.
|
||||
// It is not an error to read lock an uninitialized Index.
|
||||
// if TPMA_NV_READ_STCLEAR is not set, the index can not be read-locked
|
||||
if(nvAttributes.TPMA_NV_READ_STCLEAR == CLEAR)
|
||||
if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, READ_STCLEAR))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_ReadLock_nvIndex;
|
||||
// Internal Data Update
|
||||
// Set the READLOCK attribute
|
||||
nvAttributes.TPMA_NV_READLOCKED = SET;
|
||||
SET_ATTRIBUTE(nvAttributes, TPMA_NV, READLOCKED);
|
||||
// Write NV info back
|
||||
return NvWriteIndexAttributes(nvIndex->publicArea.nvIndex,
|
||||
locator,
|
||||
@ -646,6 +653,10 @@ TPM2_NV_Certify(
|
||||
if((UINT32)in->size + (UINT32)in->offset > (UINT32)nvIndex->publicArea.dataSize)
|
||||
return TPM_RC_NV_RANGE;
|
||||
// Make sure the data will fit the return buffer
|
||||
// NOTE: This check may be modified if the output buffer will not hold the
|
||||
// maximum sized NV buffer as part of the certified data. The difference in
|
||||
// size could be substantial if the signature scheme was produced a large
|
||||
// signature (e.g., RSA 4096).
|
||||
if(in->size > MAX_NV_BUFFER_SIZE)
|
||||
return TPM_RCS_VALUE + RC_NV_Certify_size;
|
||||
// Command Output
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Dynamic space for user defined NV */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: NVDynamic.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: NVDynamic.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -64,6 +64,7 @@
|
||||
#define NV_C
|
||||
#include "Tpm.h"
|
||||
#include "PlatformData.h"
|
||||
#include "NVDynamic_fp.h"
|
||||
/* 8.4.3 Local Functions */
|
||||
/* 8.4.3.1 NvNext() */
|
||||
/* This function provides a method to traverse every data entry in NV dynamic area. */
|
||||
@ -200,7 +201,7 @@ NvTestSpace(
|
||||
reserved += (MIN_EVICT_OBJECTS - persistentNum) * NV_EVICT_OBJECT_SIZE;
|
||||
}
|
||||
// If this is not an index or is not a counter, reserve space for the
|
||||
// required number of counter indices
|
||||
// required number of counter indexes
|
||||
if(!isIndex || !isCounter)
|
||||
{
|
||||
// Get the number of counters
|
||||
@ -223,12 +224,16 @@ NvWriteNvListEnd(
|
||||
NV_REF end
|
||||
)
|
||||
{
|
||||
// Marker is initialized with zeros
|
||||
BYTE listEndMarker[sizeof(NV_LIST_TERMINATOR)] = {0};
|
||||
UINT64 maxCount = NvReadMaxCount();
|
||||
//
|
||||
// This is a constant check that can be resolved at compile time.
|
||||
cAssert(sizeof(UINT64) <= sizeof(NV_LIST_TERMINATOR) - sizeof(UINT32));
|
||||
// Copy the maxCount value to the marker buffer
|
||||
MemoryCopy(&listEndMarker[sizeof(UINT32)], &maxCount, sizeof(UINT64));
|
||||
pAssert(end + sizeof(NV_LIST_TERMINATOR) <= s_evictNvEnd);
|
||||
// Write it to memory
|
||||
NvWrite(end, sizeof(NV_LIST_TERMINATOR), &listEndMarker);
|
||||
return end + sizeof(NV_LIST_TERMINATOR);
|
||||
}
|
||||
@ -256,7 +261,7 @@ NvAdd(
|
||||
newAddr = NvGetEnd();
|
||||
// Step over the forward pointer
|
||||
nextAddr = newAddr + sizeof(UINT32);
|
||||
// Optionally write the handle. For indices, the handle is TPM_RH_UNASSIGNED
|
||||
// Optionally write the handle. For indexes, the handle is TPM_RH_UNASSIGNED
|
||||
// so that the handle in the nvIndex is used instead of writing this value
|
||||
if(handle != TPM_RH_UNASSIGNED)
|
||||
{
|
||||
@ -477,7 +482,7 @@ NvDeleteRAM(
|
||||
SET_NV_UPDATE(UT_ORDERLY);
|
||||
return;
|
||||
}
|
||||
/* 8.4.4.8 NvReadIndex() */
|
||||
/* 8.4.4.9 NvReadIndex() */
|
||||
/* This function is used to read the NV Index NV_INDEX. This is used so that the index information
|
||||
can be compressed and only this function would be needed to decompress it. Mostly, compression
|
||||
would only be able to save the space needed by the policy. */
|
||||
@ -489,6 +494,7 @@ NvReadNvIndexInfo(
|
||||
{
|
||||
pAssert(nvIndex != NULL);
|
||||
NvRead(nvIndex, ref, sizeof(NV_INDEX));
|
||||
return;
|
||||
}
|
||||
/* 8.4.4.9 NvReadObject() */
|
||||
/* This function is used to read a persistent object. This is used so that the object information
|
||||
@ -500,6 +506,7 @@ NvReadObject(
|
||||
)
|
||||
{
|
||||
NvRead(object, (ref + sizeof(TPM_HANDLE)), sizeof(OBJECT));
|
||||
return;
|
||||
}
|
||||
/* 8.4.4.10 NvFindEvict() */
|
||||
/* This function will return the NV offset of an evict object */
|
||||
@ -603,6 +610,7 @@ NvWriteRamIndexAttributes(
|
||||
{
|
||||
MemoryCopy(ref + offsetof(NV_RAM_HEADER, attributes), &attributes,
|
||||
sizeof(TPMA_NV));
|
||||
return;
|
||||
}
|
||||
/* 8.4.5 Externally Accessible Functions */
|
||||
/* 8.4.5.1 NvIsPlatformPersistentHandle() */
|
||||
@ -648,6 +656,7 @@ NvIndexIsAccessible(
|
||||
)
|
||||
{
|
||||
NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
|
||||
//
|
||||
if(nvIndex == NULL)
|
||||
// If index is not found, return TPM_RC_HANDLE
|
||||
return TPM_RC_HANDLE;
|
||||
@ -655,7 +664,7 @@ NvIndexIsAccessible(
|
||||
{
|
||||
// if shEnable is CLEAR, an ownerCreate NV Index should not be
|
||||
// indicated as present
|
||||
if(!IsNv_TPMA_NV_PLATFORMCREATE(nvIndex->publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, PLATFORMCREATE))
|
||||
{
|
||||
if(gc.shEnable == FALSE)
|
||||
return TPM_RC_HANDLE;
|
||||
@ -665,9 +674,9 @@ NvIndexIsAccessible(
|
||||
else if(gc.phEnableNV == FALSE)
|
||||
return TPM_RC_HANDLE;
|
||||
}
|
||||
#if 0 // Writelock test
|
||||
#if 0 // Writelock test for debug
|
||||
// If the Index is write locked and this is an NV Write operation...
|
||||
if(IsNv_TPMA_NV_WRITELOCKED(nvIndex->publicArea.attributes)
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITELOCKED)
|
||||
&& IsWriteOperation(commandIndex))
|
||||
{
|
||||
// then return a locked indication unless the command is TPM2_NV_WriteLock
|
||||
@ -676,9 +685,9 @@ NvIndexIsAccessible(
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#if 0 // Readlock Test
|
||||
#if 0 // Readlock Test for debug
|
||||
// If the Index is read locked and this is an NV Read operation...
|
||||
if(IsNv_TPMA_NV_READLOCKED(nvIndex->publicArea.attributes)
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, READLOCKED)
|
||||
&& IsReadOperation(commandIndex))
|
||||
{
|
||||
// then return a locked indication unless the command is TPM2_NV_ReadLock
|
||||
@ -721,6 +730,7 @@ NvIndexCacheInit(
|
||||
s_cachedNvRef = NV_REF_INIT;
|
||||
s_cachedNvRamRef = NV_RAM_REF_INIT;
|
||||
s_cachedNvIndex.publicArea.nvIndex = TPM_RH_UNASSIGNED;
|
||||
return;
|
||||
}
|
||||
/* 8.4.5.6 NvGetIndexData() */
|
||||
/* This function is used to access the data in an NV Index. The data is returned as a byte
|
||||
@ -737,10 +747,11 @@ NvGetIndexData(
|
||||
)
|
||||
{
|
||||
TPMA_NV nvAttributes;
|
||||
//
|
||||
pAssert(nvIndex != NULL);
|
||||
nvAttributes = nvIndex->publicArea.attributes;
|
||||
pAssert(nvAttributes.TPMA_NV_WRITTEN == SET);
|
||||
if(nvAttributes.TPMA_NV_ORDERLY == SET)
|
||||
pAssert(IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN));
|
||||
if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, ORDERLY))
|
||||
{
|
||||
// Get data from RAM buffer
|
||||
NV_RAM_REF ramAddr = NvRamGetIndex(nvIndex->publicArea.nvIndex);
|
||||
@ -785,7 +796,8 @@ NvWriteIndexAttributes(
|
||||
)
|
||||
{
|
||||
TPM_RC result;
|
||||
if(IsNv_TPMA_NV_ORDERLY(attributes))
|
||||
//
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY))
|
||||
{
|
||||
NV_RAM_REF ram = NvRamGetIndex(handle);
|
||||
NvWriteRamIndexAttributes(ram, attributes);
|
||||
@ -808,17 +820,23 @@ NvWriteIndexAuth(
|
||||
TPM2B_AUTH *authValue // IN: the authValue to write
|
||||
)
|
||||
{
|
||||
TPM_RC result;
|
||||
if(locator == s_cachedNvRef)
|
||||
{
|
||||
MemoryCopy2B(&s_cachedNvIndex.authValue.b, &authValue->b,
|
||||
sizeof(s_cachedNvIndex.authValue.t.buffer));
|
||||
}
|
||||
result = NvConditionallyWrite(
|
||||
locator + offsetof(NV_INDEX, authValue),
|
||||
sizeof(UINT16) + authValue->t.size,
|
||||
authValue);
|
||||
return result;
|
||||
{
|
||||
TPM_RC result;
|
||||
//
|
||||
// If the locator is pointing to the cached index value...
|
||||
if(locator == s_cachedNvRef)
|
||||
{
|
||||
// copy the authValue to the cached index so it will be there if we
|
||||
// look for it. This is a safety thing.
|
||||
MemoryCopy2B(&s_cachedNvIndex.authValue.b, &authValue->b,
|
||||
sizeof(s_cachedNvIndex.authValue.t.buffer));
|
||||
}
|
||||
result = NvConditionallyWrite(
|
||||
locator + offsetof(NV_INDEX, authValue),
|
||||
sizeof(UINT16) + authValue->t.size,
|
||||
authValue);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
/* 8.4.5.10 NvGetIndexInfo() */
|
||||
/* This function loads the nvIndex Info into the NV cache and returns a pointer to the NV_INDEX. If
|
||||
@ -840,7 +858,7 @@ NvGetIndexInfo(
|
||||
if(s_cachedNvRef == 0)
|
||||
return NULL;
|
||||
NvReadNvIndexInfo(s_cachedNvRef, &s_cachedNvIndex);
|
||||
if(IsNv_TPMA_NV_ORDERLY(s_cachedNvIndex.publicArea.attributes))
|
||||
if(IS_ATTRIBUTE(s_cachedNvIndex.publicArea.attributes, TPMA_NV, ORDERLY))
|
||||
{
|
||||
s_cachedNvRamRef = NvRamGetIndex(nvHandle);
|
||||
s_cachedNvIndex.publicArea.attributes =
|
||||
@ -857,7 +875,7 @@ NvGetIndexInfo(
|
||||
/* This function requires that the NV Index is defined, and the data is within the defined data
|
||||
range for the index. */
|
||||
/* Index data is only written due to a command that modifies the data in a single index. There is no
|
||||
case where changes are made to multiple indices data at the same time. Multiple attributes may be
|
||||
case where changes are made to multiple indexes data at the same time. Multiple attributes may be
|
||||
change but not multiple index data. This is important because we will normally be handling the
|
||||
index for which we have the cached pointer values. */
|
||||
/* Error Returns Meaning */
|
||||
@ -872,6 +890,7 @@ NvWriteIndexData(
|
||||
)
|
||||
{
|
||||
TPM_RC result = TPM_RC_SUCCESS;
|
||||
//
|
||||
pAssert(nvIndex != NULL);
|
||||
// Make sure that this is dealing with the 'default' index.
|
||||
// Note: it is tempting to change the calling sequence so that the 'default' is
|
||||
@ -881,13 +900,13 @@ NvWriteIndexData(
|
||||
pAssert(offset <= nvIndex->publicArea.dataSize
|
||||
&& size <= (nvIndex->publicArea.dataSize - offset));
|
||||
// Update TPMA_NV_WRITTEN bit if necessary
|
||||
if(!IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
|
||||
{
|
||||
// Update the in memory version of the attributes
|
||||
nvIndex->publicArea.attributes.TPMA_NV_WRITTEN = SET;
|
||||
SET_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN);
|
||||
// If this is not orderly, then update the NV version of
|
||||
// the attributes
|
||||
if(!IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
|
||||
{
|
||||
result = NvWriteNvIndexAttributes(s_cachedNvRef,
|
||||
nvIndex->publicArea.attributes);
|
||||
@ -911,7 +930,7 @@ NvWriteIndexData(
|
||||
SET_NV_UPDATE(UT_ORDERLY);
|
||||
// If setting the written attribute on an ordinary index, make sure that
|
||||
// the data is all cleared out in case there is a partial write. This
|
||||
// is only necessary for ordinary indices because all of the other types
|
||||
// is only necessary for ordinary indexes because all of the other types
|
||||
// are always written in total.
|
||||
else if(IsNvOrdinaryIndex(nvIndex->publicArea.attributes))
|
||||
MemorySet(s_cachedNvRamRef + sizeof(NV_RAM_HEADER),
|
||||
@ -919,7 +938,7 @@ NvWriteIndexData(
|
||||
}
|
||||
}
|
||||
// If this is orderly data, write it to RAM
|
||||
if(IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes))
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
|
||||
{
|
||||
// Note: if this is the first write to a counter, the code above will queue
|
||||
// the write to NV of the RAM data in order to update TPMA_NV_WRITTEN. In
|
||||
@ -1005,14 +1024,16 @@ NvDefineIndex(
|
||||
TPM2B_AUTH *authValue // IN: The initial authorization value
|
||||
)
|
||||
{
|
||||
|
||||
// The buffer to be written to NV memory
|
||||
NV_INDEX nvIndex; // the index data
|
||||
UINT16 entrySize; // size of entry
|
||||
TPM_RC result;
|
||||
//
|
||||
entrySize = sizeof(NV_INDEX);
|
||||
// only allocate data space for Indices that are going to be written to NV.
|
||||
// Orderly indices don't need space.
|
||||
if(!IsNv_TPMA_NV_ORDERLY(publicArea->attributes))
|
||||
// only allocate data space for indexes that are going to be written to NV.
|
||||
// Orderly indexes don't need space.
|
||||
if(!IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY))
|
||||
entrySize += publicArea->dataSize;
|
||||
// Check if we have enough space to create the NV Index
|
||||
// In this implementation, the only resource limitation is the available NV
|
||||
@ -1022,7 +1043,7 @@ NvDefineIndex(
|
||||
return TPM_RC_NV_SPACE;
|
||||
// if the index to be defined is RAM backed, check RAM space availability
|
||||
// as well
|
||||
if(IsNv_TPMA_NV_ORDERLY(publicArea->attributes)
|
||||
if(IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY)
|
||||
&& !NvRamTestSpaceIndex(publicArea->dataSize))
|
||||
return TPM_RC_NV_SPACE;
|
||||
// Copy input value to nvBuffer
|
||||
@ -1030,11 +1051,12 @@ NvDefineIndex(
|
||||
// Copy the authValue
|
||||
nvIndex.authValue = *authValue;
|
||||
// Add index to NV memory
|
||||
result = NvAdd(entrySize, sizeof(NV_INDEX), TPM_RH_UNASSIGNED, (BYTE *)&nvIndex);
|
||||
result = NvAdd(entrySize, sizeof(NV_INDEX), TPM_RH_UNASSIGNED,
|
||||
(BYTE *)&nvIndex);
|
||||
if(result == TPM_RC_SUCCESS)
|
||||
{
|
||||
// If the data of NV Index is RAM backed, add the data area in RAM as well
|
||||
if(IsNv_TPMA_NV_ORDERLY(publicArea->attributes))
|
||||
if(IS_ATTRIBUTE(publicArea->attributes, TPMA_NV, ORDERLY))
|
||||
NvAddRAM(publicArea);
|
||||
}
|
||||
return result;
|
||||
@ -1081,18 +1103,19 @@ NvDeleteIndex(
|
||||
)
|
||||
{
|
||||
TPM_RC result;
|
||||
//
|
||||
if(nvIndex != NULL)
|
||||
{
|
||||
// Whenever a counter is deleted, make sure that the MaxCounter value is
|
||||
// updated to reflect the value
|
||||
if(IsNvCounterIndex(nvIndex->publicArea.attributes)
|
||||
&& IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes))
|
||||
&& IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
|
||||
NvUpdateMaxCount(NvGetUINT64Data(nvIndex, entityAddr));
|
||||
result = NvDelete(entityAddr);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
// If the NV Index is RAM backed, delete the RAM data as well
|
||||
if(IsNv_TPMA_NV_ORDERLY(nvIndex->publicArea.attributes))
|
||||
if(IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, ORDERLY))
|
||||
NvDeleteRAM(nvIndex->publicArea.nvIndex);
|
||||
NvIndexCacheInit();
|
||||
}
|
||||
@ -1127,11 +1150,13 @@ NvFlushHierarchy(
|
||||
NV_REF currentAddr;
|
||||
TPM_HANDLE entityHandle;
|
||||
TPM_RC result = TPM_RC_SUCCESS;
|
||||
//
|
||||
while((currentAddr = NvNext(&iter, &entityHandle)) != 0)
|
||||
{
|
||||
if(HandleGetType(entityHandle) == TPM_HT_NV_INDEX)
|
||||
{
|
||||
NV_INDEX nvIndex;
|
||||
//
|
||||
// If flush endorsement or platform hierarchy, no NV Index would be
|
||||
// flushed
|
||||
if(hierarchy == TPM_RH_ENDORSEMENT || hierarchy == TPM_RH_PLATFORM)
|
||||
@ -1139,7 +1164,8 @@ NvFlushHierarchy(
|
||||
// Get the index information
|
||||
NvReadNvIndexInfo(currentAddr, &nvIndex);
|
||||
// For storage hierarchy, flush OwnerCreated index
|
||||
if(!IsNv_TPMA_NV_PLATFORMCREATE(nvIndex.publicArea.attributes))
|
||||
if(!IS_ATTRIBUTE(nvIndex.publicArea.attributes, TPMA_NV,
|
||||
PLATFORMCREATE))
|
||||
{
|
||||
// Delete the index (including RAM for orderly)
|
||||
result = NvDeleteIndex(&nvIndex, currentAddr);
|
||||
@ -1152,18 +1178,19 @@ NvFlushHierarchy(
|
||||
else if(HandleGetType(entityHandle) == TPM_HT_PERSISTENT)
|
||||
{
|
||||
OBJECT_ATTRIBUTES attributes;
|
||||
//
|
||||
NvRead(&attributes,
|
||||
(UINT32)(currentAddr
|
||||
+ sizeof(TPM_HANDLE)
|
||||
+ offsetof(OBJECT, attributes)),
|
||||
sizeof(OBJECT_ATTRIBUTES));
|
||||
// If the evict object belongs to the hierarchy to be flushed
|
||||
if((hierarchy == TPM_RH_PLATFORM && attributes.ppsHierarchy == SET)
|
||||
|| (hierarchy == TPM_RH_OWNER && attributes.spsHierarchy == SET)
|
||||
// If the evict object belongs to the hierarchy to be flushed...
|
||||
if((hierarchy == TPM_RH_PLATFORM && attributes.ppsHierarchy == SET)
|
||||
|| (hierarchy == TPM_RH_OWNER && attributes.spsHierarchy == SET)
|
||||
|| (hierarchy == TPM_RH_ENDORSEMENT
|
||||
&& attributes.epsHierarchy == SET))
|
||||
{
|
||||
// Delete the evict object
|
||||
// ...then delete the evict object
|
||||
result = NvDelete(currentAddr);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
break;
|
||||
@ -1179,7 +1206,7 @@ NvFlushHierarchy(
|
||||
return result;
|
||||
}
|
||||
/* 8.4.5.20 NvSetGlobalLock() */
|
||||
/* This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indices that have
|
||||
/* This function is used to SET the TPMA_NV_WRITELOCKED attribute for all NV Indexes that have
|
||||
TPMA_NV_GLOBALLOCK SET. This function is use by TPM2_NV_GlobalWriteLock(). */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_NV_RATE NV is unavailable because of rate limit */
|
||||
@ -1194,28 +1221,30 @@ NvSetGlobalLock(
|
||||
NV_REF currentAddr;
|
||||
NV_RAM_REF currentRamAddr;
|
||||
TPM_RC result = TPM_RC_SUCCESS;
|
||||
// Check all normal Indices
|
||||
while((currentAddr = NvNextIndex(NULL, &iter)) != 0)
|
||||
{
|
||||
TPMA_NV attributes = NvReadNvIndexAttributes(currentAddr);
|
||||
// See if it should be locked
|
||||
if(!IsNv_TPMA_NV_ORDERLY(attributes)
|
||||
&& IsNv_TPMA_NV_GLOBALLOCK(attributes))
|
||||
{
|
||||
attributes.TPMA_NV_WRITELOCKED = SET;
|
||||
result = NvWriteNvIndexAttributes(currentAddr, attributes);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Check all normal indexes
|
||||
while((currentAddr = NvNextIndex(NULL, &iter)) != 0)
|
||||
{
|
||||
TPMA_NV attributes = NvReadNvIndexAttributes(currentAddr);
|
||||
//
|
||||
// See if it should be locked
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY)
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_NV, GLOBALLOCK))
|
||||
{
|
||||
SET_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED);
|
||||
result = NvWriteNvIndexAttributes(currentAddr, attributes);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// Now search all the orderly attributes
|
||||
while((currentRamAddr = NvRamNext(&ramIter, NULL)) != 0)
|
||||
{
|
||||
// See if it should be locked
|
||||
TPMA_NV attributes = NvReadRamIndexAttributes(currentRamAddr);
|
||||
if(IsNv_TPMA_NV_GLOBALLOCK(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, GLOBALLOCK))
|
||||
{
|
||||
attributes.TPMA_NV_WRITELOCKED = SET;
|
||||
SET_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED);
|
||||
NvWriteRamIndexAttributes(currentRamAddr, attributes);
|
||||
}
|
||||
}
|
||||
@ -1299,16 +1328,16 @@ NvCapGetPersistent(
|
||||
// A handle with a value larger than start handle is a candidate
|
||||
// for return. Insert sort it to the return list. Insert sort algorithm
|
||||
// is chosen here for simplicity based on the assumption that the total
|
||||
// number of NV Indices is small. For an implementation that may allow
|
||||
// large number of NV Indices, a more efficient sorting algorithm may be
|
||||
// number of NV Indexes is small. For an implementation that may allow
|
||||
// large number of NV Indexes, a more efficient sorting algorithm may be
|
||||
// used here.
|
||||
InsertSort(handleList, count, entityHandle);
|
||||
}
|
||||
return more;
|
||||
}
|
||||
/* 8.4.5.23 NvCapGetIndex() */
|
||||
/* This function returns a list of handles of NV Indices, starting from handle. Handle must be in
|
||||
the range of NV Indices, but does not have to reference an existing NV Index. */
|
||||
/* This function returns a list of handles of NV Indexes, starting from handle. Handle must be in
|
||||
the range of NV Indexes, but does not have to reference an existing NV Index. */
|
||||
/* Return Values Meaning */
|
||||
/* YES if there are more handles to report */
|
||||
/* NO all the available handles has been reported */
|
||||
@ -1340,8 +1369,8 @@ NvCapGetIndex(
|
||||
// A handle with a value larger than start handle is a candidate
|
||||
// for return. Insert sort it to the return list. Insert sort algorithm
|
||||
// is chosen here for simplicity based on the assumption that the total
|
||||
// number of NV Indices is small. For an implementation that may allow
|
||||
// large number of NV Indices, a more efficient sorting algorithm may be
|
||||
// number of NV Indexes is small. For an implementation that may allow
|
||||
// large number of NV Indexes, a more efficient sorting algorithm may be
|
||||
// used here.
|
||||
InsertSort(handleList, count, nvHandle);
|
||||
}
|
||||
@ -1399,7 +1428,7 @@ NvCapGetPersistentAvail(
|
||||
return availNVSpace / NV_EVICT_OBJECT_SIZE;
|
||||
}
|
||||
/* 8.4.5.27 NvCapGetCounterNumber() */
|
||||
/* Get the number of defined NV Indexes that are counter indices. */
|
||||
/* Get the number of defined NV Indexes that are counter indexes. */
|
||||
UINT32
|
||||
NvCapGetCounterNumber(
|
||||
void
|
||||
@ -1425,20 +1454,22 @@ NvSetStartupAttributes(
|
||||
)
|
||||
{
|
||||
// Clear read lock
|
||||
attributes.TPMA_NV_READLOCKED = CLEAR;
|
||||
CLEAR_ATTRIBUTE(attributes, TPMA_NV, READLOCKED);
|
||||
// Will change a non counter index to the unwritten state if:
|
||||
// a) TPMA_NV_CLEAR_STCLEAR is SET
|
||||
// b) orderly and TPM Reset
|
||||
if(!IsNvCounterIndex(attributes))
|
||||
{
|
||||
if(IsNv_TPMA_NV_CLEAR_STCLEAR(attributes)
|
||||
|| (IsNv_TPMA_NV_ORDERLY(attributes) && (type == SU_RESET)))
|
||||
attributes.TPMA_NV_WRITTEN = CLEAR;
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR)
|
||||
|| (IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY)
|
||||
&& (type == SU_RESET)))
|
||||
CLEAR_ATTRIBUTE(attributes, TPMA_NV, WRITTEN);
|
||||
}
|
||||
// Unlock any index that is not written or that does not have
|
||||
// TPMA_NV_WRITEDEFINE SET.
|
||||
if(!IsNv_TPMA_NV_WRITTEN(attributes) || !IsNv_TPMA_NV_WRITEDEFINE(attributes))
|
||||
attributes.TPMA_NV_WRITELOCKED = CLEAR;
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, WRITTEN)
|
||||
|| !IS_ATTRIBUTE(attributes, TPMA_NV, WRITEDEFINE))
|
||||
CLEAR_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED);
|
||||
return attributes;
|
||||
}
|
||||
/* 8.4.5.29 NvEntityStartup() */
|
||||
@ -1471,13 +1502,13 @@ NvEntityStartup(
|
||||
{
|
||||
attributes = NvReadNvIndexAttributes(currentAddr);
|
||||
// If this is an orderly index, defer processing until loop below
|
||||
if(IsNv_TPMA_NV_ORDERLY(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, ORDERLY))
|
||||
continue;
|
||||
// Set the attributes appropriate for this startup type
|
||||
attributes = NvSetStartupAttributes(attributes, type);
|
||||
NvWriteNvIndexAttributes(currentAddr, attributes);
|
||||
}
|
||||
// Iterate all the orderly indices to clear the locks and initialize counters
|
||||
// Iterate all the orderly indexes to clear the locks and initialize counters
|
||||
while((currentRamAddr = NvRamNext(&ramIter, NULL)) != 0)
|
||||
{
|
||||
attributes = NvReadRamIndexAttributes(currentRamAddr);
|
||||
@ -1502,7 +1533,7 @@ NvEntityStartup(
|
||||
return;
|
||||
}
|
||||
/* 8.4.5.30 NvCapGetCounterAvail() */
|
||||
/* This function returns an estimate of the number of additional counter type NV Indices that can be
|
||||
/* This function returns an estimate of the number of additional counter type NV Indexes that can be
|
||||
defined. */
|
||||
UINT32
|
||||
NvCapGetCounterAvail(
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Dynamic space for user defined NV */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: NVDynamic_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: NVDynamic_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: NV_spt.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: NV_spt.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -80,7 +80,7 @@ NvReadAccessChecks(
|
||||
)
|
||||
{
|
||||
// If data is read locked, returns an error
|
||||
if(IsNv_TPMA_NV_READLOCKED(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, READLOCKED))
|
||||
return TPM_RC_NV_LOCKED;
|
||||
// If the authorization was provided by the owner or platform, then check
|
||||
// that the attributes allow the read. If the authorization handle
|
||||
@ -89,13 +89,13 @@ NvReadAccessChecks(
|
||||
if(authHandle == TPM_RH_OWNER)
|
||||
{
|
||||
// If Owner provided authorization then ONWERWRITE must be SET
|
||||
if(!IsNv_TPMA_NV_OWNERREAD(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERREAD))
|
||||
return TPM_RC_NV_AUTHORIZATION;
|
||||
}
|
||||
else if(authHandle == TPM_RH_PLATFORM)
|
||||
{
|
||||
// If Platform provided authorization then PPWRITE must be SET
|
||||
if(!IsNv_TPMA_NV_PPREAD(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, PPREAD))
|
||||
return TPM_RC_NV_AUTHORIZATION;
|
||||
}
|
||||
// If neither Owner nor Platform provided authorization, make sure that it was
|
||||
@ -105,7 +105,7 @@ NvReadAccessChecks(
|
||||
// If the index has not been written, then the value cannot be read
|
||||
// NOTE: This has to come after other access checks to make sure that
|
||||
// the proper authorization is given to TPM2_NV_ReadLock()
|
||||
if(!IsNv_TPMA_NV_WRITTEN(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, WRITTEN))
|
||||
return TPM_RC_NV_UNINITIALIZED;
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
@ -124,7 +124,7 @@ NvWriteAccessChecks(
|
||||
)
|
||||
{
|
||||
// If data is write locked, returns an error
|
||||
if(IsNv_TPMA_NV_WRITELOCKED(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, WRITELOCKED))
|
||||
return TPM_RC_NV_LOCKED;
|
||||
// If the authorization was provided by the owner or platform, then check
|
||||
// that the attributes allow the write. If the authorization handle
|
||||
@ -133,13 +133,13 @@ NvWriteAccessChecks(
|
||||
if(authHandle == TPM_RH_OWNER)
|
||||
{
|
||||
// If Owner provided authorization then ONWERWRITE must be SET
|
||||
if(!IsNv_TPMA_NV_OWNERWRITE(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, OWNERWRITE))
|
||||
return TPM_RC_NV_AUTHORIZATION;
|
||||
}
|
||||
else if(authHandle == TPM_RH_PLATFORM)
|
||||
{
|
||||
// If Platform provided authorization then PPWRITE must be SET
|
||||
if(!IsNv_TPMA_NV_PPWRITE(attributes))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_NV, PPWRITE))
|
||||
return TPM_RC_NV_AUTHORIZATION;
|
||||
}
|
||||
// If neither Owner nor Platform provided authorization, make sure that it was
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Manage the object store of the TPM. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Object.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Object.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -76,7 +76,6 @@ ObjectFlush(
|
||||
)
|
||||
{
|
||||
object->attributes.occupied = CLEAR;
|
||||
// MemorySet(&object->attributes, 0, sizeof(OBJECT_ATTRIBUTES));
|
||||
}
|
||||
/* 8.6.3.2 ObjectSetInUse() */
|
||||
/* This access function sets the occupied attribute of an object slot. */
|
||||
@ -317,9 +316,12 @@ ObjectSetLoadedAttributes(
|
||||
)
|
||||
{
|
||||
OBJECT *parent = HandleToObject(parentHandle);
|
||||
TPMA_OBJECT objectAttributes = object->publicArea.objectAttributes;
|
||||
//
|
||||
// Copy the stClear attribute from the public area. This could be overwritten
|
||||
// if the parent has stClear SET
|
||||
object->attributes.stClear = object->publicArea.objectAttributes.stClear;
|
||||
object->attributes.stClear =
|
||||
IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear);
|
||||
// If parent handle is a permanent handle, it is a primary (unless it is NULL
|
||||
if(parent == NULL)
|
||||
{
|
||||
@ -346,7 +348,7 @@ ObjectSetLoadedAttributes(
|
||||
{
|
||||
// is this a stClear object
|
||||
object->attributes.stClear =
|
||||
(object->publicArea.objectAttributes.stClear == SET
|
||||
(IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, stClear)
|
||||
|| (parent->attributes.stClear == SET));
|
||||
object->attributes.epsHierarchy = parent->attributes.epsHierarchy;
|
||||
object->attributes.spsHierarchy = parent->attributes.spsHierarchy;
|
||||
@ -363,9 +365,9 @@ ObjectSetLoadedAttributes(
|
||||
else
|
||||
{
|
||||
// check attributes for different types of parents
|
||||
if(object->publicArea.objectAttributes.restricted
|
||||
if(IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, restricted)
|
||||
&& !object->attributes.publicOnly
|
||||
&& object->publicArea.objectAttributes.decrypt
|
||||
&& IS_ATTRIBUTE(objectAttributes, TPMA_OBJECT, decrypt)
|
||||
&& object->publicArea.nameAlg != TPM_ALG_NULL)
|
||||
{
|
||||
// This is a parent. If it is not a KEYEDHASH, it is an ordinary parent.
|
||||
@ -404,6 +406,7 @@ ObjectLoad(
|
||||
{
|
||||
TPM_RC result = TPM_RC_SUCCESS;
|
||||
BOOL doCheck;
|
||||
//
|
||||
// Do validations of public area object descriptions
|
||||
// Is this public only or a no-name object?
|
||||
if(sensitive == NULL || publicArea->nameAlg == TPM_ALG_NULL)
|
||||
@ -414,6 +417,13 @@ ObjectLoad(
|
||||
}
|
||||
else
|
||||
{
|
||||
// For any sensitive area, make sure that the seedSize is no larger than the
|
||||
// digest size of nameAlg
|
||||
#if 1 //??
|
||||
if(sensitive->seedValue.t.size
|
||||
> CryptHashGetDigestSize(publicArea->nameAlg))
|
||||
return TPM_RC_SENSITIVE; // not a 'safe' return code so no add
|
||||
#endif
|
||||
// Check attributes and schemes for consistency
|
||||
result = PublicAttributesValidation(parent, publicArea);
|
||||
}
|
||||
@ -426,7 +436,8 @@ ObjectLoad(
|
||||
// If the parent is not NULL, then this is an ordinary load and we only check
|
||||
// if the parent is not fixedTPM
|
||||
else if(parent != NULL)
|
||||
doCheck = parent->publicArea.objectAttributes.fixedTPM == CLEAR;
|
||||
doCheck = !IS_ATTRIBUTE(parent->publicArea.objectAttributes,
|
||||
TPMA_OBJECT, fixedTPM);
|
||||
else
|
||||
// This is a loadExternal. Check everything.
|
||||
// Note: the check functions will filter things based on the name algorithm
|
||||
@ -495,7 +506,7 @@ AllocateSequenceSlot(
|
||||
// be marked as temporary so that it can't be persisted
|
||||
object->attributes.temporary = SET;
|
||||
// A sequence object is DA exempt.
|
||||
object->objectAttributes.noDA = SET;
|
||||
SET_ATTRIBUTE(object->objectAttributes, TPMA_OBJECT, noDA);
|
||||
// Copy the authorization value
|
||||
if(auth != NULL)
|
||||
object->auth = *auth;
|
||||
@ -508,6 +519,7 @@ AllocateSequenceSlot(
|
||||
/* This function creates an internal HMAC sequence object. */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_OBJECT_MEMORY if there is no free slot for an object */
|
||||
#if defined TPM_CC_HMAC_Start || defined TPM_CC_MAC_Start
|
||||
TPM_RC
|
||||
ObjectCreateHMACSequence(
|
||||
TPMI_ALG_HASH hashAlg, // IN: hash algorithm
|
||||
@ -517,17 +529,27 @@ ObjectCreateHMACSequence(
|
||||
)
|
||||
{
|
||||
HASH_OBJECT *hmacObject;
|
||||
//
|
||||
// Try to allocate a slot for new object
|
||||
hmacObject = AllocateSequenceSlot(newHandle, auth);
|
||||
if(hmacObject == NULL)
|
||||
return TPM_RC_OBJECT_MEMORY;
|
||||
// Set HMAC sequence bit
|
||||
hmacObject->attributes.hmacSeq = SET;
|
||||
CryptHmacStart(&hmacObject->state.hmacState, hashAlg,
|
||||
keyObject->sensitive.sensitive.bits.b.size,
|
||||
keyObject->sensitive.sensitive.bits.b.buffer);
|
||||
#ifndef SMAC_IMPLEMENTED
|
||||
if(CryptHmacStart(&hmacObject->state.hmacState, hashAlg,
|
||||
keyObject->sensitive.sensitive.bits.b.size,
|
||||
keyObject->sensitive.sensitive.bits.b.buffer) == 0)
|
||||
#else
|
||||
if(CryptMacStart(&hmacObject->state.hmacState,
|
||||
&keyObject->publicArea.parameters,
|
||||
hashAlg, &keyObject->sensitive.sensitive.any.b) == 0)
|
||||
#endif // SMAC_IMPLEMENTED
|
||||
return TPM_RC_FAILURE;
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 8.6.3.18 ObjectCreateHashSequence() */
|
||||
/* This function creates a hash sequence object. */
|
||||
/* Error Returns Meaning */
|
||||
@ -587,7 +609,7 @@ ObjectTerminateEvent(
|
||||
if(hashObject->attributes.eventSeq)
|
||||
{
|
||||
// If it is, close any open hash contexts. This is done in case
|
||||
// the crypto implementation has some context values that need to be
|
||||
// the cryptographic implementation has some context values that need to be
|
||||
// cleaned up (hygiene).
|
||||
//
|
||||
for(count = 0; CryptHashGetAlgByIndex(count) != TPM_ALG_NULL; count++)
|
||||
@ -738,18 +760,15 @@ ObjectLoadEvict(
|
||||
TPM2B_NAME *
|
||||
ObjectComputeName(
|
||||
UINT32 size, // IN: the size of the area to digest
|
||||
BYTE *publicArea, // IN: the public area to digest area
|
||||
BYTE *publicArea, // IN: the public area to digest
|
||||
TPM_ALG_ID nameAlg, // IN: the hash algorithm to use
|
||||
TPM2B_NAME *name // OUT: Computed name
|
||||
)
|
||||
{
|
||||
HASH_STATE hashState; // hash state
|
||||
// Start hash stack
|
||||
name->t.size = CryptHashStart(&hashState, nameAlg);
|
||||
// Adding public area
|
||||
CryptDigestUpdate(&hashState, size, publicArea);
|
||||
// Complete hash leaving room for the name algorithm
|
||||
CryptHashEnd(&hashState, name->t.size, &name->t.name[2]);
|
||||
// Hash the publicArea into the name buffer leaving room for the nameAlg
|
||||
name->t.size = CryptHashBlock(nameAlg, size, publicArea,
|
||||
sizeof(name->t.name) - 2,
|
||||
&name->t.name[2]);
|
||||
// set the nameAlg
|
||||
UINT16_TO_BYTE_ARRAY(nameAlg, name->t.name);
|
||||
name->t.size += 2;
|
||||
@ -781,20 +800,11 @@ PublicMarshalAndComputeName(
|
||||
}
|
||||
return name;
|
||||
}
|
||||
/* 8.6.3.27 AlgOfName() */
|
||||
/* This function as a macro returns the nameAlg from a TPM2B_NAME. */
|
||||
TPMI_ALG_HASH
|
||||
AlgOfName(
|
||||
TPM2B_NAME *name
|
||||
)
|
||||
{
|
||||
return BYTE_ARRAY_TO_UINT16(name->t.name);
|
||||
}
|
||||
/* 8.6.3.28 ComputeQualifiedName() */
|
||||
/* This function computes the qualified name of an object. */
|
||||
void
|
||||
ComputeQualifiedName(
|
||||
TPM_HANDLE parentHandle, // IN: parent's name
|
||||
TPM_HANDLE parentHandle, // IN: parent's handle
|
||||
TPM_ALG_ID nameAlg, // IN: name hash
|
||||
TPM2B_NAME *name, // IN: name of the object
|
||||
TPM2B_NAME *qualifiedName // OUT: qualified name of the object
|
||||
@ -804,6 +814,7 @@ ComputeQualifiedName(
|
||||
TPM2B_NAME parentName;
|
||||
if(parentHandle == TPM_RH_UNASSIGNED)
|
||||
{
|
||||
MemoryCopy2B(&qualifiedName->b, &name->b, sizeof(qualifiedName->t.name));
|
||||
*qualifiedName = *name;
|
||||
}
|
||||
else
|
||||
@ -838,10 +849,11 @@ ObjectIsStorage(
|
||||
{
|
||||
OBJECT *object = HandleToObject(handle);
|
||||
TPMT_PUBLIC *publicArea = ((object != NULL) ? &object->publicArea : NULL);
|
||||
//
|
||||
return (publicArea != NULL
|
||||
&& publicArea->objectAttributes.restricted == SET
|
||||
&& publicArea->objectAttributes.decrypt == SET
|
||||
&& publicArea->objectAttributes.sign == CLEAR
|
||||
&& IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted)
|
||||
&& IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, decrypt)
|
||||
&& !IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign)
|
||||
&& (object->publicArea.type == ALG_RSA_VALUE
|
||||
|| object->publicArea.type == ALG_ECC_VALUE));
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Object Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: ObjectCommands.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: ObjectCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -203,9 +203,11 @@ TPM2_LoadExternal(
|
||||
// An external object with a sensitive area must have fixedTPM == CLEAR
|
||||
// fixedParent == CLEAR so that it does not appear to be a key created by
|
||||
// this TPM.
|
||||
if(in->inPublic.publicArea.objectAttributes.fixedTPM != CLEAR
|
||||
|| in->inPublic.publicArea.objectAttributes.fixedParent != CLEAR
|
||||
|| in->inPublic.publicArea.objectAttributes.restricted != CLEAR)
|
||||
if(IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT, fixedTPM)
|
||||
|| IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT,
|
||||
fixedParent)
|
||||
|| IS_ATTRIBUTE(in->inPublic.publicArea.objectAttributes, TPMA_OBJECT,
|
||||
restricted))
|
||||
return TPM_RCS_ATTRIBUTES + RC_LoadExternal_inPublic;
|
||||
// Have sensitive point to something other than NULL so that object
|
||||
// initialization will load the sensitive part too
|
||||
@ -269,8 +271,9 @@ TPM2_ActivateCredential(
|
||||
activateObject = HandleToObject(in->activateHandle);
|
||||
// input decrypt key must be an asymmetric, restricted decryption key
|
||||
if(!CryptIsAsymAlgorithm(object->publicArea.type)
|
||||
|| object->publicArea.objectAttributes.decrypt == CLEAR
|
||||
|| object->publicArea.objectAttributes.restricted == CLEAR)
|
||||
|| !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
|
||||
|| !IS_ATTRIBUTE(object->publicArea.objectAttributes,
|
||||
TPMA_OBJECT, restricted))
|
||||
return TPM_RCS_TYPE + RC_ActivateCredential_keyHandle;
|
||||
// Command output
|
||||
// Decrypt input credential data via asymmetric decryption. A
|
||||
@ -314,8 +317,8 @@ TPM2_MakeCredential(
|
||||
// input key must be an asymmetric, restricted decryption key
|
||||
// NOTE: Needs to be restricted to have a symmetric value.
|
||||
if(!CryptIsAsymAlgorithm(object->publicArea.type)
|
||||
|| object->publicArea.objectAttributes.decrypt == CLEAR
|
||||
|| object->publicArea.objectAttributes.restricted == CLEAR)
|
||||
|| !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
|
||||
|| !IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, restricted))
|
||||
return TPM_RCS_TYPE + RC_MakeCredential_handle;
|
||||
// The credential information may not be larger than the digest size used for
|
||||
// the Name of the key associated with handle.
|
||||
@ -349,9 +352,9 @@ TPM2_Unseal(
|
||||
// Input handle must be a data object
|
||||
if(object->publicArea.type != TPM_ALG_KEYEDHASH)
|
||||
return TPM_RCS_TYPE + RC_Unseal_itemHandle;
|
||||
if(object->publicArea.objectAttributes.decrypt == SET
|
||||
|| object->publicArea.objectAttributes.sign == SET
|
||||
|| object->publicArea.objectAttributes.restricted == SET)
|
||||
if(IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, decrypt)
|
||||
|| IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, sign)
|
||||
|| IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT, restricted))
|
||||
return TPM_RCS_ATTRIBUTES + RC_Unseal_itemHandle;
|
||||
// Command Output
|
||||
// Copy data
|
||||
@ -407,9 +410,7 @@ TPM2_CreateLoaded(
|
||||
CreateLoaded_Out *out // OUT: output parameter list
|
||||
)
|
||||
{
|
||||
// Local variables
|
||||
TPM_RC result = TPM_RC_SUCCESS;
|
||||
// These are the values used in object creation
|
||||
OBJECT *parent = HandleToObject(in->parentHandle);
|
||||
OBJECT *newObject;
|
||||
BOOL derivation;
|
||||
@ -439,7 +440,8 @@ TPM2_CreateLoaded(
|
||||
// unmarshaled like other public areas. Since it is not, this command needs its
|
||||
// on template that is a TPM2B that is unmarshaled as a BYTE array with a
|
||||
// its own unmarshal function.
|
||||
result = UnmarshalToPublic(publicArea, &in->inPublic, derivation);
|
||||
result = UnmarshalToPublic(publicArea, &in->inPublic, derivation,
|
||||
&labelContext);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result + RC_CreateLoaded_inPublic;
|
||||
// Validate that the authorization size is appropriate
|
||||
@ -459,7 +461,8 @@ TPM2_CreateLoaded(
|
||||
return TPM_RCS_TYPE + RC_CreateLoaded_inPublic;
|
||||
// sensitiveDataOrigin has to be CLEAR in a derived object. Since this
|
||||
// is specific to a derived object, it is checked here.
|
||||
if(publicArea->objectAttributes.sensitiveDataOrigin)
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT,
|
||||
sensitiveDataOrigin))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
// Check the reset of the attributes
|
||||
result = PublicAttributesValidation(parent, publicArea);
|
||||
@ -467,8 +470,7 @@ TPM2_CreateLoaded(
|
||||
return RcSafeAddToResult(result, RC_CreateLoaded_inPublic);
|
||||
// Process the template and sensitive areas to get the actual 'label' and
|
||||
// 'context' values to be used for this derivation.
|
||||
result = SetLabelAndContext(&labelContext, publicArea,
|
||||
&in->inSensitive.sensitive.data);
|
||||
result = SetLabelAndContext(&labelContext, &in->inSensitive.sensitive.data);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
// Set up the KDF for object generation
|
||||
@ -477,7 +479,8 @@ TPM2_CreateLoaded(
|
||||
scheme->details.xorr.kdf,
|
||||
&parent->sensitive.sensitive.bits.b,
|
||||
&labelContext.label.b,
|
||||
&labelContext.context.b);
|
||||
&labelContext.context.b,
|
||||
TPM_MAX_DERIVATION_BITS);
|
||||
// Clear the sensitive size so that the creation functions will not try
|
||||
// to use this value.
|
||||
in->inSensitive.sensitive.data.t.size = 0;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Object Command Support */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Object_spt.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Object_spt.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -321,13 +321,13 @@ CreateChecks(
|
||||
//
|
||||
// If the caller indicates that they have provided the data, then make sure that
|
||||
// they have provided some data.
|
||||
if((attributes.sensitiveDataOrigin == CLEAR)
|
||||
if((!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
|
||||
&& (sensitiveDataSize == 0))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
// For an ordinary object, data can only be provided when sensitiveDataOrigin
|
||||
// is CLEAR
|
||||
if((parentObject != NULL)
|
||||
&& (attributes.sensitiveDataOrigin == SET)
|
||||
&& (IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
|
||||
&& (sensitiveDataSize != 0))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
switch(publicArea->type)
|
||||
@ -335,8 +335,9 @@ CreateChecks(
|
||||
case TPM_ALG_KEYEDHASH:
|
||||
// if this is a data object (sign == decrypt == CLEAR) then the
|
||||
// TPM cannot be the data source.
|
||||
if(!attributes.sign && !attributes.decrypt
|
||||
&& attributes.sensitiveDataOrigin)
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt)
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
|
||||
result = TPM_RC_ATTRIBUTES;
|
||||
// comment out the next line in order to prevent a fixedTPM derivation
|
||||
// parent
|
||||
@ -345,13 +346,14 @@ CreateChecks(
|
||||
// A restricted key symmetric key (SYMCIPHER and KEYEDHASH)
|
||||
// must have sensitiveDataOrigin SET unless it has fixedParent and
|
||||
// fixedTPM CLEAR.
|
||||
if(attributes.restricted)
|
||||
if(!attributes.sensitiveDataOrigin)
|
||||
if(attributes.fixedParent || attributes.fixedTPM)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent)
|
||||
|| IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM))
|
||||
result = TPM_RCS_ATTRIBUTES;
|
||||
break;
|
||||
default: // Asymmetric keys cannot have the sensitive portion provided
|
||||
if(!attributes.sensitiveDataOrigin)
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, sensitiveDataOrigin))
|
||||
result = TPM_RCS_ATTRIBUTES;
|
||||
break;
|
||||
}
|
||||
@ -382,24 +384,33 @@ SchemeChecks(
|
||||
TPM_ALG_ID scheme = TPM_ALG_NULL;
|
||||
TPMA_OBJECT attributes = publicArea->objectAttributes;
|
||||
TPMU_PUBLIC_PARMS *parms = &publicArea->parameters;
|
||||
//
|
||||
switch(publicArea->type)
|
||||
{
|
||||
case TPM_ALG_SYMCIPHER:
|
||||
symAlgs = &parms->symDetail.sym;
|
||||
// If this is a decrypt key, then only the block cipher modes (not
|
||||
// SMAC) are valid. TPM_ALG_NULL is OK too. If this is a 'sign' key,
|
||||
// then any mode that got through the unmarshaling is OK.
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt)
|
||||
&& !CryptSymModeIsValid(symAlgs->mode.sym, TRUE))
|
||||
return TPM_RCS_SCHEME;
|
||||
break;
|
||||
case TPM_ALG_KEYEDHASH:
|
||||
scheme = parms->keyedHashDetail.scheme.scheme;
|
||||
// if both sign and decrypt
|
||||
if(attributes.sign == attributes.decrypt)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
|
||||
== IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
// if both sign and decrypt are set or clear, then need
|
||||
// TPM_ALG_NULL as scheme
|
||||
if(scheme != TPM_ALG_NULL)
|
||||
return TPM_RCS_SCHEME;
|
||||
}
|
||||
else if(attributes.sign && scheme != TPM_ALG_HMAC)
|
||||
else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
|
||||
&& scheme != TPM_ALG_HMAC)
|
||||
return TPM_RCS_SCHEME;
|
||||
else if(attributes.decrypt)
|
||||
else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
if(scheme != TPM_ALG_XOR)
|
||||
return TPM_RCS_SCHEME;
|
||||
@ -407,7 +418,7 @@ SchemeChecks(
|
||||
// SP800-108 for this implementation. This is the only derivation
|
||||
// supported by this implementation. Other implementations could
|
||||
// support additional schemes. There is no default.
|
||||
if(attributes.restricted)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
|
||||
{
|
||||
if(parms->keyedHashDetail.scheme.details.xorr.kdf
|
||||
!= TPM_ALG_KDF1_SP800_108)
|
||||
@ -425,13 +436,14 @@ SchemeChecks(
|
||||
// if the key is both sign and decrypt, then the scheme must be
|
||||
// TPM_ALG_NULL because there is no way to specify both a sign and a
|
||||
// decrypt scheme in the key.
|
||||
if(attributes.sign == attributes.decrypt)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
|
||||
== IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
// scheme must be TPM_ALG_NULL
|
||||
if(scheme != TPM_ALG_NULL)
|
||||
return TPM_RCS_SCHEME;
|
||||
}
|
||||
else if(attributes.sign)
|
||||
else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign))
|
||||
{
|
||||
// If this is a signing key, see if it has a signing scheme
|
||||
if(CryptIsAsymSignScheme(publicArea->type, scheme))
|
||||
@ -446,13 +458,14 @@ SchemeChecks(
|
||||
// signing key that does not have a proper signing scheme.
|
||||
// This is OK if the key is not restricted and its scheme
|
||||
// is TPM_ALG_NULL
|
||||
if(attributes.restricted || scheme != TPM_ALG_NULL)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
|
||||
|| scheme != TPM_ALG_NULL)
|
||||
return TPM_RCS_SCHEME;
|
||||
}
|
||||
}
|
||||
else if(attributes.decrypt)
|
||||
else if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
if(attributes.restricted)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
|
||||
{
|
||||
// for a restricted decryption key (a parent), scheme
|
||||
// is required to be TPM_ALG_NULL
|
||||
@ -468,7 +481,8 @@ SchemeChecks(
|
||||
return TPM_RCS_SCHEME;
|
||||
}
|
||||
}
|
||||
if(!attributes.restricted || !attributes.decrypt)
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
|
||||
|| !IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
// For an asymmetric key that is not a parent, the symmetric
|
||||
// algorithms must be TPM_ALG_NULL
|
||||
@ -508,7 +522,9 @@ SchemeChecks(
|
||||
// If this is a restricted decryption key with symmetric algorithms, then it
|
||||
// is an ordinary parent (not a derivation parent). It needs to specific
|
||||
// symmetric algorithms other than TPM_ALG_NULL
|
||||
if(symAlgs != NULL && attributes.restricted && attributes.decrypt)
|
||||
if(symAlgs != NULL
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted)
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
if(symAlgs->algorithm == TPM_ALG_NULL)
|
||||
return TPM_RCS_SYMMETRIC;
|
||||
@ -521,7 +537,8 @@ SchemeChecks(
|
||||
#endif
|
||||
// If this parent is not duplicable, then the symmetric algorithms
|
||||
// (encryption and hash) must match those of its parent
|
||||
if(attributes.fixedParent && (parentObject != NULL))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent)
|
||||
&& (parentObject != NULL))
|
||||
{
|
||||
if(publicArea->nameAlg != parentObject->publicArea.nameAlg)
|
||||
return TPM_RCS_HASH;
|
||||
@ -553,6 +570,7 @@ PublicAttributesValidation(
|
||||
{
|
||||
TPMA_OBJECT attributes = publicArea->objectAttributes;
|
||||
TPMA_OBJECT parentAttributes = {0};
|
||||
//
|
||||
if(parentObject != NULL)
|
||||
parentAttributes = parentObject->publicArea.objectAttributes;
|
||||
if(publicArea->nameAlg == TPM_ALG_NULL)
|
||||
@ -565,48 +583,56 @@ PublicAttributesValidation(
|
||||
return TPM_RCS_SIZE;
|
||||
// If the parent is fixedTPM (including a Primary Object) the object must have
|
||||
// the same value for fixedTPM and fixedParent
|
||||
if(parentObject == NULL || parentAttributes.fixedTPM == SET)
|
||||
if(parentObject == NULL
|
||||
|| IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, fixedTPM))
|
||||
{
|
||||
if(attributes.fixedParent != attributes.fixedTPM)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent)
|
||||
!= IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The parent is not fixedTPM so the object can't be fixedTPM
|
||||
if(attributes.fixedTPM == SET)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
}
|
||||
// See if sign and decrypt are the same
|
||||
if(attributes.sign == attributes.decrypt)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign)
|
||||
== IS_ATTRIBUTE(attributes, TPMA_OBJECT, decrypt))
|
||||
{
|
||||
// a restricted key cannot have both SET or both CLEAR
|
||||
if(attributes.restricted)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, restricted))
|
||||
return TPM_RC_ATTRIBUTES;
|
||||
// only a data object may have both sign and decrypt CLEAR
|
||||
// BTW, since we know that decrypt==sign, no need to check both
|
||||
if(publicArea->type != TPM_ALG_KEYEDHASH && !attributes.sign)
|
||||
if(publicArea->type != TPM_ALG_KEYEDHASH
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_OBJECT, sign))
|
||||
return TPM_RC_ATTRIBUTES;
|
||||
}
|
||||
// If the object can't be duplicated (directly or indirectly) then there
|
||||
// is no justification for having encryptedDuplication SET
|
||||
if(attributes.fixedTPM == SET && attributes.encryptedDuplication == SET)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM)
|
||||
&& IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
// If a parent object has fixedTPM CLEAR, the child must have the
|
||||
// same encryptedDuplication value as its parent.
|
||||
// Primary objects are considered to have a fixedTPM parent (the seeds).
|
||||
if(parentObject != NULL && parentAttributes.fixedTPM == CLEAR)
|
||||
if(parentObject != NULL
|
||||
&& !IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, fixedTPM))
|
||||
{
|
||||
if(attributes.encryptedDuplication != parentAttributes.encryptedDuplication)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, encryptedDuplication)
|
||||
!= IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, encryptedDuplication))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
}
|
||||
// Special checks for derived objects
|
||||
if((parentObject != NULL) && (parentObject->attributes.derivation == SET))
|
||||
{
|
||||
// A derived object has the same settings for fixedTPM as its parent
|
||||
if(attributes.fixedTPM != parentAttributes.fixedTPM)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedTPM)
|
||||
!= IS_ATTRIBUTE(parentAttributes, TPMA_OBJECT, fixedTPM))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
// A derived object is required to be fixedParent
|
||||
if(!attributes.fixedParent)
|
||||
if(!IS_ATTRIBUTE(attributes, TPMA_OBJECT, fixedParent))
|
||||
return TPM_RCS_ATTRIBUTES;
|
||||
}
|
||||
return SchemeChecks(parentObject, publicArea);
|
||||
@ -836,7 +862,7 @@ UnwrapOuter(
|
||||
}
|
||||
}
|
||||
// If no errors, decrypt private in place. Since this function uses CFB,
|
||||
// CryptSymmetricDecrypt() will not return any errors It may fail but it will
|
||||
// CryptSymmetricDecrypt() will not return any errors. It may fail but it will
|
||||
// not return an error.
|
||||
if(result == TPM_RC_SUCCESS)
|
||||
CryptSymmetricDecrypt(sensitiveData, symAlg, keyBits,
|
||||
@ -854,7 +880,7 @@ MarshalSensitive(
|
||||
TPMI_ALG_HASH nameAlg // IN:
|
||||
)
|
||||
{
|
||||
BYTE *sizeField = buffer;; // saved so that size can be
|
||||
BYTE *sizeField = buffer; // saved so that size can be
|
||||
// marshaled after it is known
|
||||
UINT16 retVal;
|
||||
// Pad the authValue if needed
|
||||
@ -1300,38 +1326,34 @@ MemoryRemoveTrailingZeros(
|
||||
can end up being an Empty Buffer. */
|
||||
TPM_RC
|
||||
SetLabelAndContext(
|
||||
TPMS_DERIVE *labelContext, // OUT: the recovered label and context
|
||||
TPMT_PUBLIC *publicArea, // IN/OUT: the public area containing the
|
||||
// unmarshaled template
|
||||
TPMS_DERIVE *labelContext, // IN/OUT: the recovered label and context
|
||||
TPM2B_SENSITIVE_DATA *sensitive // IN: the sensitive data
|
||||
)
|
||||
{
|
||||
TPMS_DERIVE sensitiveValue;
|
||||
TPM_RC result;
|
||||
INT32 size;
|
||||
BYTE *buff;
|
||||
//
|
||||
// In case neither the sensitive nor publicArea have a label or a context
|
||||
labelContext->label.b.size = 0;
|
||||
labelContext->context.b.size = 0;
|
||||
// Unmarshal a TPMS_DERIVE from the TPM2B_SENSITIVE_DATA buffer
|
||||
// If there is something to unmarshal...
|
||||
if(sensitive->t.size != 0)
|
||||
{
|
||||
size = sensitive->t.size;
|
||||
buff = sensitive->t.buffer;
|
||||
result = TPMS_DERIVE_Unmarshal(labelContext, &buff, &size);
|
||||
result = TPMS_DERIVE_Unmarshal(&sensitiveValue, &buff, &size);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
// If there was a label in the public area leave it there, otherwise, copy
|
||||
// the new value
|
||||
if(labelContext->label.t.size == 0)
|
||||
MemoryCopy2B(&labelContext->label.b, &sensitiveValue.label.b,
|
||||
sizeof(labelContext->label.t.buffer));
|
||||
// if there was a context string in publicArea, it overrides
|
||||
if(labelContext->context.t.size == 0)
|
||||
MemoryCopy2B(&labelContext->context.b, &sensitiveValue.context.b,
|
||||
sizeof(labelContext->label.t.buffer));
|
||||
}
|
||||
// If there is a label string in publicArea, it overrides
|
||||
if(publicArea->unique.derive.label.t.size != 0)
|
||||
MemoryCopy2B(&labelContext->label.b, &publicArea->unique.derive.label.b,
|
||||
sizeof(labelContext->label.t.buffer));
|
||||
// if there is a context string in publicArea, it overrides
|
||||
if(publicArea->unique.derive.context.t.size != 0)
|
||||
MemoryCopy2B(&labelContext->context.b,
|
||||
&publicArea->unique.derive.context.b,
|
||||
sizeof(labelContext->label.t.buffer));
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
/* 7.6.3.19 UnmarshalToPublic() */
|
||||
@ -1341,9 +1363,10 @@ SetLabelAndContext(
|
||||
contain a label and context that are unmarshaled into derive. */
|
||||
TPM_RC
|
||||
UnmarshalToPublic(
|
||||
TPMT_PUBLIC *tOut, // OUT: output
|
||||
TPM2B_TEMPLATE *tIn, // IN:
|
||||
BOOL derivation // IN: indicates if this is for a derivation
|
||||
TPMT_PUBLIC *tOut, // OUT: output
|
||||
TPM2B_TEMPLATE *tIn, // IN:
|
||||
BOOL derivation, // IN: indicates if this is for a derivation
|
||||
TPMS_DERIVE *labelContext // OUT: label and context if derivation
|
||||
)
|
||||
{
|
||||
BYTE *buffer = tIn->t.buffer;
|
||||
@ -1353,57 +1376,33 @@ UnmarshalToPublic(
|
||||
// make sure that tOut is zeroed so that there are no remnants from previous
|
||||
// uses
|
||||
MemorySet(tOut, 0, sizeof(TPMT_PUBLIC));
|
||||
// Unmarshal a TPMT_PUBLIC but don't allow a nameAlg of TPM_ALG_NULL
|
||||
result = TPMT_PUBLIC_Unmarshal(tOut, &buffer, &size, FALSE);
|
||||
if((result == TPM_RC_SUCCESS) && (derivation == TRUE))
|
||||
{
|
||||
// Make sure that the unmarshaled value is a valid label (not too big)
|
||||
if(tOut->unique.derive.label.t.size
|
||||
> sizeof(tOut->unique.derive.label.t.buffer))
|
||||
{
|
||||
result = TPM_RC_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if ALG_ECC
|
||||
// If we just unmarshaled an ECC public key, then the label value is in the
|
||||
// correct spot but the context value is in the wrong place if the
|
||||
// maximum ECC parameter size is larger than the largest digest.
|
||||
// So, move it.
|
||||
if(tOut->type == ALG_ECC_VALUE)
|
||||
#if LABEL_MAX_BUFFER != MAX_ECC_KEY_BYTES
|
||||
{
|
||||
TPM2B_LABEL context;
|
||||
// Make sure that the context is not too big
|
||||
if(tOut->unique.ecc.y.t.size > sizeof(context.t.buffer))
|
||||
{
|
||||
result = TPM_RC_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This could probably be a direct copy because we are moving
|
||||
// data to lower addresses but, just to be safe...
|
||||
MemoryCopy2B(&context.b, &tOut->unique.ecc.y.b,
|
||||
sizeof(context.t.buffer));
|
||||
MemoryCopy2B(&tOut->unique.derive.context.b, &context.b,
|
||||
sizeof(tOut->unique.derive.context.t.buffer));
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
// if the label buffer and ECC key sizes match, everything is where it
|
||||
// should be so nothing else to do
|
||||
}
|
||||
#endif // LABEL_MAX_BUFFER != MAX_ECC_KEY_BYTES
|
||||
else
|
||||
#endif // ALG_ECC
|
||||
// For object types other than ECC, should have completed
|
||||
// unmarshaling with data left in the buffer so try to unmarshal
|
||||
// the remainder as a TPM2B_LABEL into the context
|
||||
result = TPM2B_LABEL_Unmarshal(&tOut->unique.derive.context,
|
||||
&buffer, &size);
|
||||
}
|
||||
}
|
||||
// Unmarshal the components of the TPMT_PUBLIC up to the unique field
|
||||
result = TPMI_ALG_PUBLIC_Unmarshal(&tOut->type, &buffer, &size);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
result = TPMI_ALG_HASH_Unmarshal(&tOut->nameAlg, &buffer, &size, FALSE);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
result = TPMA_OBJECT_Unmarshal(&tOut->objectAttributes, &buffer, &size);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
result = TPM2B_DIGEST_Unmarshal(&tOut->authPolicy, &buffer, &size);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
result = TPMU_PUBLIC_PARMS_Unmarshal(&tOut->parameters, &buffer, &size,
|
||||
tOut->type);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result;
|
||||
// No unmarshal a TPMS_DERIVE if this is for derivation
|
||||
if(derivation)
|
||||
result = TPMS_DERIVE_Unmarshal(labelContext, &buffer, &size);
|
||||
else
|
||||
// otherwise, unmarshal a TPMU_PUBLIC_ID
|
||||
result = TPMU_PUBLIC_ID_Unmarshal(&tOut->unique, &buffer, &size,
|
||||
tOut->type);
|
||||
// Make sure the template was used up
|
||||
if((result == TPM_RC_SUCCESS) && (size != 0))
|
||||
result = TPM_RC_SIZE;
|
||||
return result;
|
||||
}
|
||||
/* 7.6.3.20 ObjectSetExternal() */
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Object Command Support */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Object_spt_fp.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Object_spt_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -224,15 +224,14 @@ MemoryRemoveTrailingZeros(
|
||||
TPM_RC
|
||||
SetLabelAndContext(
|
||||
TPMS_DERIVE *labelContext, // OUT: the recovered label and context
|
||||
TPMT_PUBLIC *publicArea, // IN/OUT: the public area containing
|
||||
// the unmarshaled template
|
||||
TPM2B_SENSITIVE_DATA *sensitive // IN: the sensitive data
|
||||
);
|
||||
TPM_RC
|
||||
UnmarshalToPublic(
|
||||
TPMT_PUBLIC *tOut, // OUT: output
|
||||
TPM2B_TEMPLATE *tIn, // IN:
|
||||
BOOL derivation // IN: indicates if this is for a derivation
|
||||
BOOL derivation, // IN: indicates if this is for a derivation
|
||||
TPMS_DERIVE *labelContext // OUT: label and context if derivation
|
||||
);
|
||||
void
|
||||
ObjectSetHierarchy(
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: PCR.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: PCR.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -792,7 +792,7 @@ PCRRead(
|
||||
pcr++;
|
||||
}
|
||||
// Exit inner loop
|
||||
break;;
|
||||
break;
|
||||
}
|
||||
// Need the size of each digest
|
||||
digest->digests[digest->count].t.size =
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Instance data for the Platform module. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: PlatformData.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: PlatformData.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017. */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -72,10 +72,6 @@
|
||||
canceled */
|
||||
extern int s_isCanceled;
|
||||
#include <time.h>
|
||||
typedef struct {
|
||||
time_t tv_sec; // Seconds - >= 0
|
||||
long tv_nsec; // Nanoseconds - [0, 999999999]
|
||||
} timespec_t;
|
||||
#ifndef HARDWARE_CLOCK
|
||||
/* This is the value returned the last time that the system clock was read. This is only relevant
|
||||
for a simulator or virtual TPM. */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Platform_fp.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Platform_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -89,7 +89,8 @@ _plat__ClearCancel(
|
||||
/* C.8.2. From Clock.c */
|
||||
/* C.8.2.1. _plat__TimerReset() */
|
||||
/* This function sets current system clock time as t0 for counting TPM time. This function is called
|
||||
at a power on event to reset the clock. */
|
||||
at a power on event to reset the clock. When the clock is reset, the indication that the clock
|
||||
was stopped is also set. */
|
||||
LIB_EXPORT void
|
||||
_plat__TimerReset(
|
||||
void
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: PropertyCap.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: PropertyCap.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -202,13 +202,13 @@ TPMPropertyIsDefined(
|
||||
{
|
||||
TPMA_MEMORY att;
|
||||
UINT32 u32;
|
||||
} attributes = {{0}};
|
||||
attributes.att.sharedNV = SET;
|
||||
attributes.att.objectCopiedToRam = SET;
|
||||
// Copy the bytes of the TPMA_MEMORY to the 32 bit integer assuming
|
||||
// that the structure is going to be packed and, because the union
|
||||
// contains a UINT32, it will be properly aligned. Note: this will
|
||||
// get and could get byte swapped if the CPU is little-endian.
|
||||
} attributes = {0};
|
||||
SET_ATTRIBUTE(attributes.att, TPMA_MEMORY, sharedNV);
|
||||
SET_ATTRIBUTE(attributes.att, TPMA_MEMORY, objectCopiedToRam);
|
||||
// Note: For a LSb0 machine, the bits in a bit field are in the correct
|
||||
// order even if the machine is MSB0. For a MSb0 machine, a TPMA will
|
||||
// be an integer manipulated by masking (NO_BIT_FIELD_STRUCTURES will
|
||||
// be defined) so the bits are manipulated correctly.
|
||||
*value = attributes.u32;
|
||||
break;
|
||||
}
|
||||
@ -393,41 +393,52 @@ TPMPropertyIsDefined(
|
||||
case TPM_PT_PERMANENT:
|
||||
// TPMA_PERMANENT
|
||||
{
|
||||
TPMA_PERMANENT flags = {0};
|
||||
union {
|
||||
TPMA_PERMANENT attr;
|
||||
UINT32 u32;
|
||||
} flags = {0};
|
||||
if(gp.ownerAuth.t.size != 0)
|
||||
flags.ownerAuthSet = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, ownerAuthSet);
|
||||
if(gp.endorsementAuth.t.size != 0)
|
||||
flags.endorsementAuthSet = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, endorsementAuthSet);
|
||||
if(gp.lockoutAuth.t.size != 0)
|
||||
flags.lockoutAuthSet = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, lockoutAuthSet);
|
||||
if(gp.disableClear)
|
||||
flags.disableClear = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, disableClear);
|
||||
if(gp.failedTries >= gp.maxTries)
|
||||
flags.inLockout = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, inLockout);
|
||||
// In this implementation, EPS is always generated by TPM
|
||||
flags.tpmGeneratedEPS = SET;
|
||||
// Note: Different compilers may require a different method to cast
|
||||
// a bit field structure to a UINT32.
|
||||
*value = *(UINT32 *)&flags;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_PERMANENT, tpmGeneratedEPS);
|
||||
// Note: For a LSb0 machine, the bits in a bit field are in the correct
|
||||
// order even if the machine is MSB0. For a MSb0 machine, a TPMA will
|
||||
// be an integer manipulated by masking (NO_BIT_FIELD_STRUCTURES will
|
||||
// be defined) so the bits are manipulate correctly.
|
||||
*value = flags.u32;
|
||||
break;
|
||||
}
|
||||
case TPM_PT_STARTUP_CLEAR:
|
||||
// TPMA_STARTUP_CLEAR
|
||||
{
|
||||
TPMA_STARTUP_CLEAR flags = {0};
|
||||
union {
|
||||
TPMA_STARTUP_CLEAR attr;
|
||||
UINT32 u32;
|
||||
} flags = {0};
|
||||
//
|
||||
if(g_phEnable)
|
||||
flags.phEnable = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, phEnable);
|
||||
if(gc.shEnable)
|
||||
flags.shEnable = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, shEnable);
|
||||
if(gc.ehEnable)
|
||||
flags.ehEnable = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, ehEnable);
|
||||
if(gc.phEnableNV)
|
||||
flags.phEnableNV = SET;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, phEnableNV);
|
||||
if(g_prevOrderlyState != SU_NONE_VALUE)
|
||||
flags.orderly = SET;
|
||||
// Note: Different compilers may require a different method to cast
|
||||
// a bit field structure to a UINT32.
|
||||
*value = *(UINT32 *)&flags;
|
||||
SET_ATTRIBUTE(flags.attr, TPMA_STARTUP_CLEAR, orderly);
|
||||
// Note: For a LSb0 machine, the bits in a bit field are in the correct
|
||||
// order even if the machine is MSB0. For a MSb0 machine, a TPMA will
|
||||
// be an integer manipulated by masking (NO_BIT_FIELD_STRUCTURES will
|
||||
// be defined) so the bits are manipulate correctly.
|
||||
*value = flags.u32;
|
||||
break;
|
||||
}
|
||||
case TPM_PT_HR_NV_INDEX:
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Manage the session context counter */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Session.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Session.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -199,9 +199,9 @@ SessionIsSaved(
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
/* 8.9.5.3 SequenceNumbereForSavedContextIsValid() */
|
||||
/* 8.9.5.3 SequenceNumberForSavedContextIsValid() */
|
||||
BOOL
|
||||
SequenceNumbereForSavedContextIsValid(
|
||||
SequenceNumberForSavedContextIsValid(
|
||||
TPMS_CONTEXT *context // IN: pointer to a context
|
||||
// structure to be validated
|
||||
)
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Session Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: SessionCommands.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: SessionCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -97,7 +97,7 @@ TPM2_StartAuthSession(
|
||||
return TPM_RCS_HANDLE + RC_StartAuthSession_tpmKey;
|
||||
// HMAC session input handle check.
|
||||
// tpmKey should be a decryption key
|
||||
if(tpmKey->publicArea.objectAttributes.decrypt != SET)
|
||||
if(!IS_ATTRIBUTE(tpmKey->publicArea.objectAttributes, TPMA_OBJECT, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + RC_StartAuthSession_tpmKey;
|
||||
// Secret Decryption. A TPM_RC_VALUE, TPM_RC_KEY or Unmarshal errors
|
||||
// may be returned at this point
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Process the Authorization Sessions */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: SessionProcess.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: SessionProcess.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -79,6 +79,7 @@ IsDAExempted(
|
||||
)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
//
|
||||
switch(HandleGetType(handle))
|
||||
{
|
||||
case TPM_HT_PERMANENT:
|
||||
@ -90,13 +91,14 @@ IsDAExempted(
|
||||
// into an object slot and assigned a transient handle.
|
||||
case TPM_HT_TRANSIENT:
|
||||
{
|
||||
result = (ObjectGetPublicAttributes(handle).noDA == SET);
|
||||
TPMA_OBJECT attributes = ObjectGetPublicAttributes(handle);
|
||||
result = IS_ATTRIBUTE(attributes, TPMA_OBJECT, noDA);
|
||||
break;
|
||||
}
|
||||
case TPM_HT_NV_INDEX:
|
||||
{
|
||||
NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
|
||||
result = (nvIndex->publicArea.attributes.TPMA_NV_NO_DA == SET);
|
||||
result = IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, NO_DA);
|
||||
break;
|
||||
}
|
||||
case TPM_HT_PCR:
|
||||
@ -120,6 +122,7 @@ IncrementLockout(
|
||||
TPM_HANDLE handle = s_associatedHandles[sessionIndex];
|
||||
TPM_HANDLE sessionHandle = s_sessionHandles[sessionIndex];
|
||||
SESSION *session = NULL;
|
||||
//
|
||||
// Don't increment lockout unless the handle associated with the session
|
||||
// is DA protected or the session is bound to a DA protected entity.
|
||||
if(sessionHandle == TPM_RS_PW)
|
||||
@ -232,7 +235,8 @@ IsPolicySessionRequired(
|
||||
if(type == TPM_HT_TRANSIENT)
|
||||
{
|
||||
OBJECT *object = HandleToObject(s_associatedHandles[sessionIndex]);
|
||||
if(object->publicArea.objectAttributes.adminWithPolicy == CLEAR)
|
||||
if(!IS_ATTRIBUTE(object->publicArea.objectAttributes, TPMA_OBJECT,
|
||||
adminWithPolicy))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@ -268,6 +272,7 @@ IsAuthValueAvailable(
|
||||
)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
//
|
||||
switch(HandleGetType(handle))
|
||||
{
|
||||
case TPM_HT_PERMANENT:
|
||||
@ -302,7 +307,10 @@ IsAuthValueAvailable(
|
||||
// handle changed.
|
||||
{
|
||||
OBJECT *object;
|
||||
TPMA_OBJECT attributes;
|
||||
//
|
||||
object = HandleToObject(handle);
|
||||
attributes = object->publicArea.objectAttributes;
|
||||
// authValue is always available for a sequence object.
|
||||
// An alternative for this is to SET
|
||||
// object->publicArea.objectAttributes.userWithAuth when the
|
||||
@ -317,10 +325,9 @@ IsAuthValueAvailable(
|
||||
// 1. userWithAuth bit is SET, or
|
||||
// 2. ADMIN role is required
|
||||
if(object->attributes.publicOnly == CLEAR
|
||||
&& (object->publicArea.objectAttributes.userWithAuth == SET
|
||||
&& (IS_ATTRIBUTE(attributes, TPMA_OBJECT, userWithAuth)
|
||||
|| (CommandAuthRole(commandIndex, sessionIndex) == AUTH_ADMIN
|
||||
&& object->publicArea.objectAttributes.adminWithPolicy
|
||||
== CLEAR)))
|
||||
&& !IS_ATTRIBUTE(attributes, TPMA_OBJECT, adminWithPolicy))))
|
||||
result = TRUE;
|
||||
}
|
||||
break;
|
||||
@ -330,12 +337,13 @@ IsAuthValueAvailable(
|
||||
NV_REF locator;
|
||||
NV_INDEX *nvIndex = NvGetIndexInfo(handle, &locator);
|
||||
TPMA_NV nvAttributes;
|
||||
//
|
||||
pAssert(nvIndex != 0);
|
||||
nvAttributes = nvIndex->publicArea.attributes;
|
||||
if(IsWriteOperation(commandIndex))
|
||||
{
|
||||
// AuthWrite can't be set for a PIN index
|
||||
if(nvAttributes.TPMA_NV_AUTHWRITE == SET)
|
||||
if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, AUTHWRITE))
|
||||
result = TRUE;
|
||||
}
|
||||
else
|
||||
@ -347,15 +355,15 @@ IsAuthValueAvailable(
|
||||
|| IsNvPinPassIndex(nvAttributes))
|
||||
{
|
||||
NV_PIN pin;
|
||||
if(nvAttributes.TPMA_NV_WRITTEN != SET)
|
||||
if(!IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN))
|
||||
break; // return false
|
||||
// get the index values
|
||||
pin.intVal = NvGetUINT64Data(nvIndex, locator);
|
||||
if(pin.pin.pinCount < pin.pin.pinLimit)
|
||||
result = TRUE;
|
||||
}
|
||||
// For non-PIN Indices, need to allow use of the authValue
|
||||
else if(nvAttributes.TPMA_NV_AUTHREAD == SET)
|
||||
// For non-PIN Indexes, need to allow use of the authValue
|
||||
else if(IS_ATTRIBUTE(nvAttributes, TPMA_NV, AUTHREAD))
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
@ -371,6 +379,8 @@ IsAuthValueAvailable(
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 6.4.3.6 IsAuthPolicyAvailable() */
|
||||
/* This function indicates if an authPolicy is available and allowed. */
|
||||
/* This function does not check that the handle reference is valid or if the entity is in an enabled
|
||||
hierarchy. Those checks are assumed to have been performed during the handle unmarshaling. */
|
||||
@ -385,6 +395,7 @@ IsAuthPolicyAvailable(
|
||||
)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
//
|
||||
switch(HandleGetType(handle))
|
||||
{
|
||||
case TPM_HT_PERMANENT:
|
||||
@ -433,6 +444,7 @@ IsAuthPolicyAvailable(
|
||||
{
|
||||
NV_INDEX *nvIndex = NvGetIndexInfo(handle, NULL);
|
||||
TPMA_NV attributes = nvIndex->publicArea.attributes;
|
||||
//
|
||||
// If the policy size is not zero, check if policy can be used.
|
||||
if(nvIndex->publicArea.authPolicy.t.size != 0)
|
||||
{
|
||||
@ -444,12 +456,12 @@ IsAuthPolicyAvailable(
|
||||
// attributes.
|
||||
else if(IsWriteOperation(commandIndex))
|
||||
{
|
||||
if(IsNv_TPMA_NV_POLICYWRITE(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, POLICYWRITE))
|
||||
result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IsNv_TPMA_NV_POLICYREAD(attributes))
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, POLICYREAD))
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
@ -609,13 +621,14 @@ GetCpHash(
|
||||
)
|
||||
{
|
||||
TPM2B_DIGEST *cpHash = GetCpHashPointer(command, hashAlg);
|
||||
//
|
||||
pAssert(cpHash->t.size != 0);
|
||||
return cpHash;
|
||||
}
|
||||
/* 6.4.4.6 CompareTemplateHash() */
|
||||
/* This function computes the template hash and compares it to the session templateHash. It is the
|
||||
hash of the second parameter assuming that the command is TPM2_Create(), TPM2_CreatePrimary(), or
|
||||
TPM2_Derive() */
|
||||
TPM2_CreateLoaded() */
|
||||
static BOOL
|
||||
CompareTemplateHash(
|
||||
COMMAND *command, // IN: parsing structure
|
||||
@ -824,7 +837,7 @@ CheckSessionHMAC(
|
||||
{
|
||||
TPM2B_DIGEST hmac; // authHMAC for comparing
|
||||
// Compute authHMAC
|
||||
ComputeCommandHMAC(command, sessionIndex, &hmac);
|
||||
ComputeCommandHMAC(command, sessionIndex, &hmac);
|
||||
// Compare the input HMAC with the authHMAC computed above.
|
||||
if(!MemoryEqual2B(&s_inputAuthValues[sessionIndex].b, &hmac.b))
|
||||
{
|
||||
@ -918,7 +931,7 @@ CheckPolicyAuthSession(
|
||||
BYTE sessionLocality[sizeof(TPMA_LOCALITY)];
|
||||
BYTE *buffer = sessionLocality;
|
||||
// Get existing locality setting in canonical form
|
||||
sessionLocality[0] = 0; // Code analysis says that this is not initialized
|
||||
sessionLocality[0] = 0;
|
||||
TPMA_LOCALITY_Marshal(&session->commandLocality, &buffer, NULL);
|
||||
// See if the locality has been set
|
||||
if(sessionLocality[0] != 0)
|
||||
@ -975,7 +988,7 @@ CheckPolicyAuthSession(
|
||||
// Get the index data
|
||||
nvIndex = NvGetIndexInfo(s_associatedHandles[sessionIndex], &locator);
|
||||
// Make sure that the TPMA_WRITTEN_ATTRIBUTE has the desired state
|
||||
if((IsNv_TPMA_NV_WRITTEN(nvIndex->publicArea.attributes))
|
||||
if((IS_ATTRIBUTE(nvIndex->publicArea.attributes, TPMA_NV, WRITTEN))
|
||||
!= (session->attributes.nvWrittenState == SET))
|
||||
return TPM_RC_POLICY_FAIL;
|
||||
}
|
||||
@ -997,6 +1010,7 @@ RetrieveSessionData(
|
||||
int i;
|
||||
TPM_RC result;
|
||||
SESSION *session;
|
||||
TPMA_SESSION sessionAttributes;
|
||||
TPM_HT sessionType;
|
||||
INT32 sessionIndex;
|
||||
TPM_RC errorIndex;
|
||||
@ -1039,15 +1053,16 @@ RetrieveSessionData(
|
||||
&command->authSize);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return result + errorIndex;
|
||||
sessionAttributes = s_attributes[sessionIndex];
|
||||
if(s_sessionHandles[sessionIndex] == TPM_RS_PW)
|
||||
{
|
||||
// A PWAP session needs additional processing.
|
||||
// Can't have any attributes set other than continueSession bit
|
||||
if(s_attributes[sessionIndex].encrypt
|
||||
|| s_attributes[sessionIndex].decrypt
|
||||
|| s_attributes[sessionIndex].audit
|
||||
|| s_attributes[sessionIndex].auditExclusive
|
||||
|| s_attributes[sessionIndex].auditReset)
|
||||
if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, encrypt)
|
||||
|| IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, decrypt)
|
||||
|| IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, audit)
|
||||
|| IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditExclusive)
|
||||
|| IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditReset))
|
||||
return TPM_RCS_ATTRIBUTES + errorIndex;
|
||||
// The nonce size must be zero.
|
||||
if(s_nonceCaller[sessionIndex].t.size != 0)
|
||||
@ -1073,9 +1088,9 @@ RetrieveSessionData(
|
||||
return TPM_RCS_HANDLE + errorIndex;
|
||||
}
|
||||
// If the session is used for parameter encryption or audit as well, set
|
||||
// the corresponding indices.
|
||||
// the corresponding Indexes.
|
||||
// First process decrypt.
|
||||
if(s_attributes[sessionIndex].decrypt)
|
||||
if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, decrypt))
|
||||
{
|
||||
// Check if the commandCode allows command parameter encryption.
|
||||
if(DecryptSize(command->index) == 0)
|
||||
@ -1091,7 +1106,7 @@ RetrieveSessionData(
|
||||
s_decryptSessionIndex = sessionIndex;
|
||||
}
|
||||
// Now process encrypt.
|
||||
if(s_attributes[sessionIndex].encrypt)
|
||||
if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, encrypt))
|
||||
{
|
||||
// Check if the commandCode allows response parameter encryption.
|
||||
if(EncryptSize(command->index) == 0)
|
||||
@ -1107,7 +1122,7 @@ RetrieveSessionData(
|
||||
s_encryptSessionIndex = sessionIndex;
|
||||
}
|
||||
// At last process audit.
|
||||
if(s_attributes[sessionIndex].audit)
|
||||
if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, audit))
|
||||
{
|
||||
// Audit attribute can only appear in one session.
|
||||
if(s_auditSessionIndex != UNDEFINED_INDEX)
|
||||
@ -1119,12 +1134,12 @@ RetrieveSessionData(
|
||||
// If this is a reset of the audit session, or the first use
|
||||
// of the session as an audit session, it doesn't matter what
|
||||
// the exclusive state is. The session will become exclusive.
|
||||
if(s_attributes[sessionIndex].auditReset == CLEAR
|
||||
if(!IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditReset)
|
||||
&& session->attributes.isAudit == SET)
|
||||
{
|
||||
// Not first use or reset. If auditExlusive is SET, then this
|
||||
// session must be the current exclusive session.
|
||||
if(s_attributes[sessionIndex].auditExclusive == SET
|
||||
if(IS_ATTRIBUTE(sessionAttributes, TPMA_SESSION, auditExclusive)
|
||||
&& g_exclusiveAuditSession != s_sessionHandles[sessionIndex])
|
||||
return TPM_RC_EXCLUSIVE;
|
||||
}
|
||||
@ -1294,7 +1309,7 @@ CheckAuthSession(
|
||||
result = CheckPWAuthSession(sessionIndex);
|
||||
else
|
||||
result = CheckSessionHMAC(command, sessionIndex);
|
||||
// Do processing for PIN indices are only three possibilities for 'result' at
|
||||
// Do processing for PIN Indexes are only three possibilities for 'result' at
|
||||
// this point.
|
||||
// TPM_RC_SUCCESS
|
||||
// TPM_RC_AUTH_FAIL
|
||||
@ -1312,7 +1327,8 @@ CheckAuthSession(
|
||||
nvAttributes = nvIndex->publicArea.attributes;
|
||||
// If this is a PIN FAIL index and the value has been written
|
||||
// then we can update the counter (increment or clear)
|
||||
if(IsNvPinFailIndex(nvAttributes) && nvAttributes.TPMA_NV_WRITTEN == SET)
|
||||
if(IsNvPinFailIndex(nvAttributes)
|
||||
&& IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN))
|
||||
{
|
||||
pinData.intVal = NvGetUINT64Data(nvIndex, locator);
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
@ -1327,8 +1343,8 @@ CheckAuthSession(
|
||||
// would not get here because the authorization value would not
|
||||
// be available and the TPM would have returned before it gets here
|
||||
else if(IsNvPinPassIndex(nvAttributes)
|
||||
&& nvAttributes.TPMA_NV_WRITTEN == SET
|
||||
&& result == TPM_RC_SUCCESS)
|
||||
&& IS_ATTRIBUTE(nvAttributes, TPMA_NV, WRITTEN)
|
||||
&& result == TPM_RC_SUCCESS)
|
||||
{
|
||||
// If the access is valid, then increment the use counter
|
||||
pinData.intVal = NvGetUINT64Data(nvIndex, locator);
|
||||
@ -1422,9 +1438,9 @@ ParseSessionBuffer(
|
||||
if(s_associatedHandles[sessionIndex] == TPM_RH_UNASSIGNED)
|
||||
return TPM_RCS_HANDLE + errorIndex;
|
||||
// a password session can't be audit, encrypt or decrypt
|
||||
if(s_attributes[sessionIndex].audit == SET
|
||||
|| s_attributes[sessionIndex].encrypt == SET
|
||||
|| s_attributes[sessionIndex].decrypt == SET)
|
||||
if(IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit)
|
||||
|| IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, encrypt)
|
||||
|| IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + errorIndex;
|
||||
session = NULL;
|
||||
}
|
||||
@ -1446,7 +1462,7 @@ ParseSessionBuffer(
|
||||
return result;
|
||||
}
|
||||
// If this session is for auditing, make sure the cpHash is computed.
|
||||
if(s_attributes[sessionIndex].audit)
|
||||
if(IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit))
|
||||
ComputeCpHash(command, session->authHashAlg);
|
||||
}
|
||||
// if the session has an associated handle, check the authorization
|
||||
@ -1460,9 +1476,9 @@ ParseSessionBuffer(
|
||||
{
|
||||
// a session that is not for authorization must either be encrypt,
|
||||
// decrypt, or audit
|
||||
if(s_attributes[sessionIndex].audit == CLEAR
|
||||
&& s_attributes[sessionIndex].encrypt == CLEAR
|
||||
&& s_attributes[sessionIndex].decrypt == CLEAR)
|
||||
if(!IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, audit)
|
||||
&& !IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, encrypt)
|
||||
&& !IS_ATTRIBUTE(s_attributes[sessionIndex], TPMA_SESSION, decrypt))
|
||||
return TPM_RCS_ATTRIBUTES + errorIndex;
|
||||
// no authValue included in any of the HMAC computations
|
||||
pAssert(session != NULL);
|
||||
@ -1691,7 +1707,7 @@ UpdateAuditSessionStatus(
|
||||
continue;
|
||||
session = SessionGet(s_sessionHandles[i]);
|
||||
// If a session is used for audit
|
||||
if(s_attributes[i].audit == SET)
|
||||
if(IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, audit))
|
||||
{
|
||||
// An audit session has been found
|
||||
auditSession = s_sessionHandles[i];
|
||||
@ -1699,7 +1715,7 @@ UpdateAuditSessionStatus(
|
||||
// the auditSetting bits indicate a reset, initialize it and set
|
||||
// it to be the exclusive session
|
||||
if(session->attributes.isAudit == CLEAR
|
||||
|| s_attributes[i].auditReset == SET)
|
||||
|| IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditReset))
|
||||
{
|
||||
InitAuditSession(session);
|
||||
g_exclusiveAuditSession = auditSession;
|
||||
@ -1714,11 +1730,11 @@ UpdateAuditSessionStatus(
|
||||
// Report audit session exclusivity.
|
||||
if(g_exclusiveAuditSession == auditSession)
|
||||
{
|
||||
s_attributes[i].auditExclusive = SET;
|
||||
SET_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditExclusive);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_attributes[i].auditExclusive = CLEAR;
|
||||
CLEAR_ATTRIBUTE(s_attributes[i], TPMA_SESSION, auditExclusive);
|
||||
}
|
||||
// Extend audit log.
|
||||
Audit(command, session);
|
||||
@ -1761,8 +1777,8 @@ ComputeResponseHMAC(
|
||||
// s_associatedHandles[] value for the session is now set to TPM_RH_NULL so
|
||||
// this will return the authValue associated with TPM_RH_NULL and that is
|
||||
// and empty buffer.
|
||||
// Get the authValue with trailing zeros removed
|
||||
TPM2B_AUTH authValue;
|
||||
// Get the authValue with trailing zeros removed
|
||||
EntityGetAuthValue(s_associatedHandles[sessionIndex], &authValue);
|
||||
// Add it to the key
|
||||
MemoryConcat2B(&key.b, &authValue.b, sizeof(key.t.buffer));
|
||||
@ -1802,7 +1818,7 @@ UpdateInternalSession(
|
||||
// If nonce is rolling in a policy session, the policy related data
|
||||
// will be re-initialized.
|
||||
if(HandleGetType(s_sessionHandles[i]) == TPM_HT_POLICY_SESSION
|
||||
&& s_attributes[i].continueSession != CLEAR)
|
||||
&& IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession))
|
||||
{
|
||||
// When the nonce rolls it starts a new timing interval for the
|
||||
// policy session.
|
||||
@ -1928,7 +1944,7 @@ BuildResponseSession(
|
||||
// to keep track of the closed sessions.
|
||||
if(s_sessionHandles[i] == TPM_RS_PW)
|
||||
{
|
||||
s_attributes[i].continueSession = SET;
|
||||
SET_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession);
|
||||
responseAuth.t.size = 0;
|
||||
nonceTPM = (TPM2B_NONCE *)&responseAuth;
|
||||
}
|
||||
@ -1947,7 +1963,7 @@ BuildResponseSession(
|
||||
command->authSize += TPM2B_DIGEST_Marshal(&responseAuth,
|
||||
&command->responseBuffer,
|
||||
NULL);
|
||||
if(s_attributes[i].continueSession == CLEAR)
|
||||
if(!IS_ATTRIBUTE(s_attributes[i], TPMA_SESSION, continueSession))
|
||||
SessionFlush(s_sessionHandles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Session_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Session_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -75,7 +75,7 @@ SessionIsSaved(
|
||||
TPM_HANDLE handle // IN: session handle
|
||||
);
|
||||
BOOL
|
||||
SequenceNumbereForSavedContextIsValid(
|
||||
SequenceNumberForSavedContextIsValid(
|
||||
TPMS_CONTEXT *context // IN: pointer to a context structure to be
|
||||
// validated
|
||||
);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: SigningCommands.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: SigningCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -73,7 +73,7 @@ TPM2_VerifySignature(
|
||||
TPMI_RH_HIERARCHY hierarchy;
|
||||
// Input Validation
|
||||
// The object to validate the signature must be a signing key.
|
||||
if(signObject->publicArea.objectAttributes.sign != SET)
|
||||
if(!IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, sign))
|
||||
return TPM_RCS_ATTRIBUTES + RC_VerifySignature_keyHandle;
|
||||
// Validate Signature. TPM_RC_SCHEME, TPM_RC_HANDLE or TPM_RC_SIGNATURE
|
||||
// error may be returned by CryptCVerifySignatrue()
|
||||
@ -123,7 +123,7 @@ TPM2_Sign(
|
||||
return TPM_RCS_SCHEME + RC_Sign_inScheme;
|
||||
// If validation is provided, or the key is restricted, check the ticket
|
||||
if(in->validation.digest.t.size != 0
|
||||
|| signObject->publicArea.objectAttributes.restricted == SET)
|
||||
|| IS_ATTRIBUTE(signObject->publicArea.objectAttributes, TPMA_OBJECT, restricted))
|
||||
{
|
||||
// Compute and compare ticket
|
||||
TicketComputeHashCheck(in->validation.hierarchy,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: SupportLibraryFunctionPrototypes_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: SupportLibraryFunctionPrototypes_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -55,13 +55,12 @@
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
#ifndef SUPPORTLIBRARYFUNCTIONPROTOTYPES_FP_H
|
||||
#define SUPPORTLIBRARYFUNCTIONPROTOTYPES_FP_H
|
||||
|
||||
#ifndef SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H
|
||||
#define SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H
|
||||
|
||||
/* This file contains the function prototypes for the functions that need to be present in the
|
||||
selected match library. For each function listed, there should be a small stub function. That
|
||||
@ -69,8 +68,6 @@
|
||||
function will only need to do a format conversion between the TPM big number and the support
|
||||
library big number. The TPM big number format was chosen to make this relatively simple and
|
||||
fast. */
|
||||
#ifndef SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H
|
||||
#define SUPPORT_LIBRARY_FUNCTION_PROTOTYPES_H
|
||||
LIB_EXPORT int SupportLibInit(void);
|
||||
/* MathLibraryCompatibililtyCheck() This function is only used during development to make sure that
|
||||
the library that is being referenced is using the same size of data structures as the TPM. */
|
||||
@ -79,53 +76,49 @@ MathLibraryCompatibilityCheck(
|
||||
void
|
||||
);
|
||||
/* 5.19.2 BnModMult() */
|
||||
/* Does multiply and divide returning the remainder of the divide. */
|
||||
/* Does multiply op1 * op2 and divide by modulus returning the remainder of the divide. */
|
||||
LIB_EXPORT BOOL
|
||||
BnModMult(bigNum result, bigConst op1, bigConst op2, bigConst modulus);
|
||||
/* 5.19.3 BnMult() */
|
||||
/* Multiplies two numbers */
|
||||
/* Multiplies two numbers and returns the result */
|
||||
LIB_EXPORT BOOL BnMult(bigNum result, bigConst multiplicand, bigConst multiplier);
|
||||
/* 5.19.4 BnDiv() */
|
||||
/* This function divides two bigNum values. The function always returns TRUE. */
|
||||
/* This function divides two bigNum values. The function returns FALSE if there is an error in the
|
||||
operation. */
|
||||
LIB_EXPORT BOOL BnDiv(bigNum quotient, bigNum remainder,
|
||||
bigConst dividend, bigConst divisor);
|
||||
/* 5.19.5 BnMod() */
|
||||
#define BnMod(a, b) BnDiv(NULL, (a), (a), (b))
|
||||
#ifdef TPM_ALG_RSA
|
||||
/* 5.19.6 BnGcd() */
|
||||
/* Get the greatest common divisor of two numbers */
|
||||
/* Get the greatest common divisor of two numbers. This function is only needed when the TPM
|
||||
implements RSA. */
|
||||
LIB_EXPORT BOOL BnGcd(bigNum gcd, bigConst number1, bigConst number2);
|
||||
/* 5.19.7 BnModExp() */
|
||||
/* Do modular exponentiation using bigNum values. */
|
||||
/* Do modular exponentiation using bigNum values. This function is only needed when the TPM
|
||||
implements RSA. */
|
||||
LIB_EXPORT BOOL BnModExp(bigNum result, bigConst number,
|
||||
bigConst exponent, bigConst modulus);
|
||||
/* 5.19.8 BnModInverse() */
|
||||
/* Modular multiplicative inverse */
|
||||
/* Modular multiplicative inverse. This function is only needed when the TPM implements RSA. */
|
||||
LIB_EXPORT BOOL BnModInverse(bigNum result, bigConst number,
|
||||
bigConst modulus);
|
||||
#endif // TPM_ALG_RSA
|
||||
#ifdef TPM_ALG_ECC
|
||||
/* 5.19.9 BnEccModMult() */
|
||||
/* This function does a point multiply of the form R = [d]S */
|
||||
/* Return Value Meaning */
|
||||
/* FALSE failure in operation; treat as result being point at infinity */
|
||||
/* This function does a point multiply of the form R = [d]S. A return of FALSE indicates that the
|
||||
result was the point at infinity. This function is only needed if the TPM supports ECC. */
|
||||
LIB_EXPORT BOOL BnEccModMult(bigPoint R, pointConst S, bigConst d, bigCurve E);
|
||||
/* 5.19.10 BnEccModMult2() */
|
||||
/* This function does a point multiply of the form R = [d]S + [u]Q */
|
||||
/* Return Value Meaning */
|
||||
/* FALSE failure in operation; treat as result being point at infinity */
|
||||
/* This function does a point multiply of the form R = [d]S + [u]Q. A return of FALSE indicates that
|
||||
the result was the point at infinity. This function is only needed if the TPM supports ECC */
|
||||
LIB_EXPORT BOOL BnEccModMult2(bigPoint R, pointConst S, bigConst d,
|
||||
pointConst Q, bigConst u, bigCurve E);
|
||||
/* 5.19.11 BnEccAdd() */
|
||||
/* This function does a point add R = S + Q */
|
||||
/* Return Values Meaning */
|
||||
/* FALSE failure in operation; treat as result being point at infinity */
|
||||
/* This function does a point add R = S + Q. A return of FALSE indicates that the result was the
|
||||
point at infinity. This function is only needed if the TPM supports ECC. */
|
||||
LIB_EXPORT BOOL BnEccAdd(bigPoint R, pointConst S, pointConst Q, bigCurve E);
|
||||
/* 5.19.12 BnCurveInitialize() */
|
||||
/* This function is used to initialize the pointers of a bnCurve_t structure. The structure is a set
|
||||
of pointers to bigNum values. The curve-dependent values are set by a different function. */
|
||||
of pointers to bigNum values. The curve-dependent values are set by a different function. This
|
||||
function is only needed if the TPM supports ECC.*/
|
||||
LIB_EXPORT bigCurve BnCurveInitialize(bigCurve E, TPM_ECC_CURVE curveId);
|
||||
#endif // TPM_ALG_ECC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Symmetric Commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: SymmetricCommands.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: SymmetricCommands.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -259,10 +259,12 @@ TPM2_HMAC(
|
||||
if(publicArea->type != TPM_ALG_KEYEDHASH)
|
||||
return TPM_RCS_TYPE + RC_HMAC_handle;
|
||||
// and that it is unrestricted
|
||||
if(publicArea->objectAttributes.restricted == SET)
|
||||
if (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
|
||||
// if(publicArea->objectAttributes.restricted == SET) kgold
|
||||
return TPM_RCS_ATTRIBUTES + RC_HMAC_handle;
|
||||
// and that it is a signing key
|
||||
if(publicArea->objectAttributes.sign != SET)
|
||||
if (!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
// if(publicArea->objectAttributes.sign != SET) kgold
|
||||
return TPM_RCS_KEY + RC_HMAC_handle;
|
||||
// See if the key has a default
|
||||
if(publicArea->parameters.keyedHashDetail.scheme.scheme == TPM_ALG_NULL)
|
||||
@ -291,3 +293,56 @@ TPM2_HMAC(
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif // CC_HMAC
|
||||
|
||||
#include "Tpm.h"
|
||||
#include "MAC_fp.h"
|
||||
#if defined TPM_CC_MAC // Conditional expansion of this file
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_ATTRIBUTES key referenced by handle is a restricted key */
|
||||
/* TPM_RC_KEY handle does not reference a signing key */
|
||||
/* TPM_RC_TYPE key referenced by handle is not an HMAC key */
|
||||
/* TPM_RC_VALUE hashAlg is not compatible with the hash algorithm of the scheme of the object
|
||||
referenced by handle */
|
||||
TPM_RC
|
||||
TPM2_MAC(
|
||||
MAC_In *in, // IN: input parameter list
|
||||
MAC_Out *out // OUT: output parameter list
|
||||
)
|
||||
{
|
||||
OBJECT *keyObject;
|
||||
HMAC_STATE state;
|
||||
TPMT_PUBLIC *publicArea;
|
||||
TPM_RC result;
|
||||
// Input Validation
|
||||
// Get MAC key object and public area pointers
|
||||
keyObject = HandleToObject(in->handle);
|
||||
publicArea = &keyObject->publicArea;
|
||||
// If the key is not able to do a MAC, indicate that the handle selects an
|
||||
// object that can't do a MAC
|
||||
result = CryptSelectMac(publicArea, &in->inScheme);
|
||||
if(result == TPM_RCS_TYPE)
|
||||
return TPM_RCS_TYPE + RC_MAC_handle;
|
||||
// If there is another error type, indicate that the scheme and key are not
|
||||
// compatible
|
||||
if(result != TPM_RC_SUCCESS)
|
||||
return RcSafeAddToResult(result, RC_MAC_inScheme);
|
||||
// Make sure that the key is not restricted
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, restricted))
|
||||
return TPM_RCS_ATTRIBUTES + RC_MAC_handle;
|
||||
// and that it is a signing key
|
||||
if(!IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
return TPM_RCS_KEY + RC_MAC_handle;
|
||||
// Command Output
|
||||
out->outMAC.t.size = CryptMacStart(&state, &publicArea->parameters,
|
||||
in->inScheme,
|
||||
&keyObject->sensitive.sensitive.any.b);
|
||||
// If the mac can't start, treat it as a fatal error
|
||||
if(out->outMAC.t.size == 0)
|
||||
return TPM_RC_FAILURE;
|
||||
CryptDigestUpdate2B(&state.hashState, &in->buffer.b);
|
||||
// If the MAC result is not what was expected, it is a fatal error
|
||||
if(CryptHmacEnd2B(&state, &out->outMAC.b) != out->outMAC.t.size)
|
||||
return TPM_RC_FAILURE;
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif // CC_MAC
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Structures and data definitions for the symmetric tests */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: SymmetricTest.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: SymmetricTest.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -72,7 +72,7 @@
|
||||
#define _SYMMETRIC_TEST_H
|
||||
#include "SymmetricTestData.h"
|
||||
|
||||
/* 10.1.11.2 Structures */
|
||||
/* 10.1.11.2 Symmetric Test Structures */
|
||||
|
||||
const SYMMETRIC_TEST_VECTOR c_symTestValues[NUM_SYMS] = {
|
||||
#undef COMMA
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Process the commands */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TPMCmdp.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: TPMCmdp.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -216,7 +216,8 @@ _rpc__Signal_HashEnd(
|
||||
_TPM_Hash_End();
|
||||
return;
|
||||
}
|
||||
/* Command interface Entry of a RPC call */
|
||||
/* D.5.3.10. rpc_Send_Command() */
|
||||
/* This is the interface to the TPM code. */
|
||||
void
|
||||
_rpc__Send_Command(
|
||||
unsigned char locality,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TcpServer.c 812 2016-11-16 21:28:29Z kgoldman $ */
|
||||
/* $Id: TcpServer.c 1048 2017-07-20 20:28:26Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -66,9 +66,12 @@
|
||||
#include "TpmBuildSwitches.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef TPM_WINDOWS
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
|
||||
#else
|
||||
typedef int SOCKET
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Functions used for ticket computations. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Ticket.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: Ticket.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -102,7 +102,7 @@ TicketComputeVerified(
|
||||
TPMT_TK_VERIFIED *ticket // OUT: verified ticket
|
||||
)
|
||||
{
|
||||
TPM2B_AUTH *proof;
|
||||
TPM2B_PROOF *proof;
|
||||
HMAC_STATE hmacState;
|
||||
//
|
||||
// Fill in ticket fields
|
||||
@ -137,7 +137,7 @@ TicketComputeAuth(
|
||||
TPMT_TK_AUTH *ticket // OUT: Created ticket
|
||||
)
|
||||
{
|
||||
TPM2B_AUTH *proof;
|
||||
TPM2B_PROOF *proof;
|
||||
HMAC_STATE hmacState;
|
||||
//
|
||||
// Get proper proof
|
||||
@ -182,7 +182,7 @@ TicketComputeHashCheck(
|
||||
TPMT_TK_HASHCHECK *ticket // OUT: Created ticket
|
||||
)
|
||||
{
|
||||
TPM2B_AUTH *proof;
|
||||
TPM2B_PROOF *proof;
|
||||
HMAC_STATE hmacState;
|
||||
//
|
||||
// Get proper proof
|
||||
@ -213,7 +213,7 @@ TicketComputeCreation(
|
||||
TPMT_TK_CREATION *ticket // OUT: created ticket
|
||||
)
|
||||
{
|
||||
TPM2B_AUTH *proof;
|
||||
TPM2B_PROOF *proof;
|
||||
HMAC_STATE hmacState;
|
||||
// Get proper proof
|
||||
proof = HierarchyGetProof(hierarchy);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Functions relating to the TPM's time functions */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Time.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Time.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -124,7 +124,7 @@ TimeStartup(
|
||||
an NV write occurs, then go.safe is SET. */
|
||||
void
|
||||
TimeClockUpdate(
|
||||
UINT64 newTime
|
||||
UINT64 newTime // IN: New time value in mS.
|
||||
)
|
||||
{
|
||||
#define CLOCK_UPDATE_MASK ((1ULL << NV_CLOCK_UPDATE_INTERVAL)- 1)
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Root header file for building any TPM.lib code */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Tpm.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Tpm.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -59,14 +59,14 @@
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* 5.20 Tpm.h */
|
||||
/* 5.19 Tpm.h */
|
||||
/* Root header file for building any TPM.lib code */
|
||||
#ifndef _TPM_H_
|
||||
#define _TPM_H_
|
||||
#include "Implementation.h"
|
||||
#include "LibSupport.h" // Types from the library. These need to come before
|
||||
/* Global.h because some of the structures in that file depend on the structures used by the
|
||||
cryptographic libraries. */
|
||||
#include "LibSupport.h" /* Types from the library. These need to come before Global.h
|
||||
because some of the structures in that file depend on the
|
||||
structures used by the cryptographic libraries. */
|
||||
#include "GpMacros.h" // Define additional macros
|
||||
#include "Global.h" // Define other TPM types
|
||||
#include "InternalRoutines.h" // Function prototypes
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Build Switches */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmBuildSwitches.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: TpmBuildSwitches.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -151,13 +151,13 @@
|
||||
#endif // SIMULATION
|
||||
#ifndef NDEBUG
|
||||
/* In some cases, the relationship between two values may be dependent on things that change based
|
||||
on various selections like the chosen crypto libraries. It is possible that these selections will
|
||||
result in incompatible settings. These are often detectable by the compiler but it isn't always
|
||||
possible to do the check in the preprocessor code. For example, when the check requires use of
|
||||
'sizeof()' then the preprocessor can't do the comparison. For these cases, we include a special
|
||||
macro that, depending on the compiler will generate a warning to indicate if the check always
|
||||
passes or always fails because it involves fixed constants. To run these checks, define
|
||||
COMPILER_CHECKS. */
|
||||
on various selections like the chosen cryptographic libraries. It is possible that these
|
||||
selections will result in incompatible settings. These are often detectable by the compiler but
|
||||
it isn't always possible to do the check in the preprocessor code. For example, when the check
|
||||
requires use of 'sizeof()' then the preprocessor can't do the comparison. For these cases, we
|
||||
include a special macro that, depending on the compiler will generate a warning to indicate if
|
||||
the check always passes or always fails because it involves fixed constants. To run these checks,
|
||||
define COMPILER_CHECKS. */
|
||||
#ifndef COMPILER_CHECKS
|
||||
//# define COMPILER_CHECKS
|
||||
#endif
|
||||
@ -168,17 +168,17 @@
|
||||
#ifndef RUNTIME_SIZE_CHECKS
|
||||
#define RUNTIME_SIZE_CHECKS
|
||||
#endif
|
||||
|
||||
/* If doing debug, can set the DRBG to print out the intermediate test values. Before enabling this,
|
||||
make sure that the dbgDumpMemBlock() function has been added someplace (preferably, somewhere in
|
||||
CryptRand.c) */
|
||||
#ifndef DRBG_DEBUG_PRINT
|
||||
//# define DRBG_DEBUG_PRINT
|
||||
#endif
|
||||
|
||||
/* If an assertion event it not going to produce any trace information (function and line number)
|
||||
then define NO_FAIL_TRACE */
|
||||
#ifndef NO_FAIL_TRACE
|
||||
# define NO_FAIL_TRACE
|
||||
//# define NO_FAIL_TRACE
|
||||
#endif
|
||||
#endif // NDEBUG
|
||||
/* If the implementation is going to give lockout time credit for time up to the last orderly
|
||||
@ -186,5 +186,30 @@
|
||||
#ifndef ACCUMULATE_SELF_HEAL_TIMER
|
||||
#define ACCUMULATE_SELF_HEAL_TIMER
|
||||
#endif // ACCUMULATE_SELF_HEAL_TIMER
|
||||
/* If the implementation is to compute the sizes of the proof and primary seed size values based on
|
||||
the implemented algorithms, then use this define. */
|
||||
#ifndef USE_SPEC_COMPLIANT_PROOFS
|
||||
#define USE_SPEC_COMPLIANT_PROOFS
|
||||
#endif
|
||||
/* Comment this out to allow compile to continue even though the chosen proof values do not match
|
||||
the compliant values. This is written so that someone would have to proactively ignore errors. */
|
||||
#ifndef SKIP_PROOF_ERRORS
|
||||
//#define SKIP_PROOF_ERRORS
|
||||
#endif
|
||||
/* This define is used to eliminate the use of bit-fields. It can be enable for big- or
|
||||
little-endian machines but is required of big-endian system that number bits in registers from
|
||||
left to right. Little-endian machines number from right to left with the least significant bit
|
||||
having assigned a bit number of 0. These are LSb0() machines (they are also little-endian so they
|
||||
are also least-significant byte 0 (LSB0) machines. Big-endian (MSB0) machines may number in
|
||||
either direction (MSb0() or LSb0()). For an MSB0+MSb0() machine this value should be defined */
|
||||
#ifndef NO_BIT_FIELD_STRUCTURES
|
||||
//# define NO_BIT_FIELD_STRUCTURES
|
||||
#endif
|
||||
/* Change these definitions to turn all algorithms or commands ON or OFF. That is, to turn all
|
||||
algorithms on, set ALG_NO to YES. This is mostly useful as a debug feature. */
|
||||
#define ALG_YES YES
|
||||
#define ALG_NO NO
|
||||
#define CC_YES YES
|
||||
#define CC_NO NO
|
||||
#endif // _TPM_BUILD_SWITCHES_H_
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmFail.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: TpmFail.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -194,10 +194,10 @@ TpmFail(
|
||||
// On a 64-bit machine, this may truncate the address of the string
|
||||
// of the function name where the error occurred.
|
||||
#ifndef NO_FAIL_TRACE
|
||||
s_failFunction = *(UINT32*)&function;
|
||||
s_failFunction = *(UINT32 *)&function;
|
||||
s_failLine = line;
|
||||
#else
|
||||
s_failFunction = 0; /* kgold was NULL */
|
||||
s_failFunction = (UINT32)NULL;
|
||||
s_failLine = 0;
|
||||
#endif
|
||||
s_failCode = code;
|
||||
|
||||
1187
src/tpm2/TpmTypes.h
1187
src/tpm2/TpmTypes.h
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
||||
/* Parameter Unmarshaling */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Unmarshal.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Unmarshal.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corporation 2015, 2016 */
|
||||
/* */
|
||||
@ -470,10 +470,10 @@ TPMA_ALGORITHM_Unmarshal(TPMA_ALGORITHM *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT32_Unmarshal((UINT32 *)target, buffer, size);
|
||||
rc = UINT32_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
if (*(UINT32 *)target & TPMA_ALGORITHM_RESERVED) {
|
||||
if (*target & TPMA_ALGORITHM_reserved) {
|
||||
rc = TPM_RC_RESERVED_BITS;
|
||||
}
|
||||
}
|
||||
@ -488,10 +488,10 @@ TPMA_OBJECT_Unmarshal(TPMA_OBJECT *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT32_Unmarshal((UINT32 *)target, buffer, size);
|
||||
rc = UINT32_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
if (*(UINT32 *)target & TPMA_OBJECT_RESERVED) {
|
||||
if (*target & TPMA_OBJECT_reserved) {
|
||||
rc = TPM_RC_RESERVED_BITS;
|
||||
}
|
||||
}
|
||||
@ -506,10 +506,10 @@ TPMA_SESSION_Unmarshal(TPMA_SESSION *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT8_Unmarshal(&target->val, buffer, size);
|
||||
rc = UINT8_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
if (target->val & TPMA_SESSION_RESERVED) {
|
||||
if (*target & TPMA_SESSION_reserved) {
|
||||
rc = TPM_RC_RESERVED_BITS;
|
||||
}
|
||||
}
|
||||
@ -524,7 +524,7 @@ TPMA_LOCALITY_Unmarshal(TPMA_LOCALITY *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT8_Unmarshal(&target->val, buffer, size);
|
||||
rc = UINT8_Unmarshal(target, buffer, size);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -537,10 +537,10 @@ TPMA_CC_Unmarshal(TPMA_CC *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT32_Unmarshal((UINT32 *)target, buffer, size);
|
||||
rc = UINT32_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
if (*(UINT32 *)target & TPMA_CC_RESERVED) {
|
||||
if (*target & TPMA_CC_reserved) {
|
||||
rc = TPM_RC_RESERVED_BITS;
|
||||
}
|
||||
}
|
||||
@ -1162,6 +1162,9 @@ TPMI_ALG_SYM_MODE_Unmarshal(TPMI_ALG_SYM_MODE *target, BYTE **buffer, INT32 *siz
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECB
|
||||
case TPM_ALG_ECB:
|
||||
#endif
|
||||
#ifdef TPM_ALG_CMAC
|
||||
case TPM_ALG_CMAC:
|
||||
#endif
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
@ -1311,7 +1314,88 @@ TPMI_ST_COMMAND_TAG_Unmarshal(TPMI_ST_COMMAND_TAG *target, BYTE **buffer, INT32
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Table 70 TPMI_ALG_MAC_SCHEME */
|
||||
|
||||
TPM_RC
|
||||
TPMI_ALG_MAC_SCHEME_Unmarshal(TPMI_ALG_MAC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull)
|
||||
{
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
switch (*target) {
|
||||
#ifdef TPM_ALG_SHA1
|
||||
case TPM_ALG_SHA1:
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA256
|
||||
case TPM_ALG_SHA256:
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA384
|
||||
case TPM_ALG_SHA384:
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA512
|
||||
case TPM_ALG_SHA512:
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM3_256
|
||||
case TPM_ALG_SM3_256:
|
||||
#endif
|
||||
#ifdef TPM_ALG_CMAC
|
||||
case TPM_ALG_CMAC:
|
||||
#endif
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
if (allowNull) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = TPM_RC_SYMMETRIC;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Table 70 TPMI_ALG_CIPHER_MODE */
|
||||
|
||||
TPM_RC
|
||||
TPMI_ALG_CIPHER_MODE_Unmarshal(TPMI_ALG_CIPHER_MODE*target, BYTE **buffer, INT32 *size, BOOL allowNull)
|
||||
{
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = TPM_ALG_ID_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
switch (*target) {
|
||||
#ifdef TPM_ALG_CTR
|
||||
case TPM_ALG_CTR:
|
||||
#endif
|
||||
#ifdef TPM_ALG_OFB
|
||||
case TPM_ALG_OFB:
|
||||
#endif
|
||||
#ifdef TPM_ALG_CBC
|
||||
case TPM_ALG_CBC:
|
||||
#endif
|
||||
#ifdef TPM_ALG_CFB
|
||||
case TPM_ALG_CFB:
|
||||
#endif
|
||||
#ifdef TPM_ALG_ECB
|
||||
case TPM_ALG_ECB:
|
||||
#endif
|
||||
break;
|
||||
case TPM_ALG_NULL:
|
||||
if (allowNull) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = TPM_RC_MODE;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Table 68 - Definition of TPMS_EMPTY Structure <IN/OUT> */
|
||||
|
||||
TPM_RC
|
||||
@ -1493,7 +1577,7 @@ TPM2B_TIMEOUT_Unmarshal(TPM2B_TIMEOUT *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = TPM2B_DIGEST_Unmarshal(target, buffer, size);
|
||||
rc = TPM2B_Unmarshal(&target->b, sizeof(target->t.buffer), buffer, size);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -4128,10 +4212,10 @@ TPMA_NV_Unmarshal(TPMA_NV *target, BYTE **buffer, INT32 *size)
|
||||
TPM_RC rc = TPM_RC_SUCCESS;
|
||||
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = UINT32_Unmarshal(&target->val, buffer, size);
|
||||
rc = UINT32_Unmarshal(target, buffer, size);
|
||||
}
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
if (target->val & TPMA_NV_RESERVED) {
|
||||
if (*target & TPMA_NV_RESERVED) {
|
||||
rc = TPM_RC_RESERVED_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: Unmarshal_fp.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: Unmarshal_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -187,6 +187,10 @@ extern "C" {
|
||||
LIB_EXPORT TPM_RC
|
||||
TPMI_ST_COMMAND_TAG_Unmarshal(TPMI_ST_COMMAND_TAG *target, BYTE **buffer, INT32 *size);
|
||||
LIB_EXPORT TPM_RC
|
||||
TPMI_ALG_MAC_SCHEME_Unmarshal(TPMI_ALG_MAC_SCHEME *target, BYTE **buffer, INT32 *size, BOOL allowNull);
|
||||
LIB_EXPORT TPM_RC
|
||||
TPMI_ALG_CIPHER_MODE_Unmarshal(TPMI_ALG_CIPHER_MODE*target, BYTE **buffer, INT32 *size, BOOL allowNull);
|
||||
LIB_EXPORT TPM_RC
|
||||
TPMS_EMPTY_Unmarshal(TPMS_EMPTY *target, BYTE **buffer, INT32 *size);
|
||||
LIB_EXPORT TPM_RC
|
||||
TPMU_HA_Unmarshal(TPMU_HA *target, BYTE **buffer, INT32 *size, UINT32 selector);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptEcc.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptEcc.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Hash structure definitions */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptHash.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptHash.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -62,8 +62,10 @@
|
||||
#ifndef CRYPTHASH_H
|
||||
#define CRYPTHASH_H
|
||||
|
||||
/* 10.1.3 CryptHash.h */
|
||||
/* 10.1.3.1 Hash Related Structures */
|
||||
/* This header contains the hash structure definitions used in the TPM code to define the amount of
|
||||
space to be reserved for the hash state. This allows the TPM code to not have to import all of
|
||||
the symbols used by the hash computations. This lets the build environment of the TPM code not to
|
||||
have include the header files associated with the CryptoEngine() code. */
|
||||
typedef struct
|
||||
{
|
||||
const TPM_ALG_ID alg;
|
||||
@ -72,6 +74,43 @@ typedef struct
|
||||
const UINT16 derSize;
|
||||
const BYTE der[20];
|
||||
} HASH_INFO;
|
||||
union SMAC_STATES;
|
||||
/* These definitions add the high-level methods for processing state that may be an SMAC */
|
||||
typedef void(* SMAC_DATA_METHOD)(
|
||||
union SMAC_STATES *state,
|
||||
UINT32 size,
|
||||
const BYTE *buffer
|
||||
);
|
||||
typedef UINT16(* SMAC_END_METHOD)(
|
||||
union SMAC_STATES *state,
|
||||
UINT32 size,
|
||||
BYTE *buffer
|
||||
);
|
||||
typedef struct sequenceMethods {
|
||||
SMAC_DATA_METHOD data;
|
||||
SMAC_END_METHOD end;
|
||||
} SMAC_METHODS;
|
||||
#if defined TPM_CC_MAC || defined TPM_CC_MAC_Start
|
||||
# define SMAC_IMPLEMENTED
|
||||
#endif
|
||||
/* These definitions are here because the SMAC state is in the union of hash states. */
|
||||
typedef struct tpmCmacState {
|
||||
TPM_ALG_ID symAlg;
|
||||
UINT16 keySizeBits;
|
||||
INT16 bcount; // current count of bytes accumulated in IV
|
||||
TPM2B_IV iv; // IV buffer
|
||||
TPM2B_SYM_KEY symKey;
|
||||
} tpmCmacState_t;
|
||||
typedef union SMAC_STATES {
|
||||
#ifdef TPM_ALG_CMAC
|
||||
tpmCmacState_t cmac;
|
||||
#endif
|
||||
UINT64 pad;
|
||||
} SMAC_STATES;
|
||||
typedef struct SMAC_STATE {
|
||||
SMAC_METHODS smacMethods;
|
||||
SMAC_STATES state;
|
||||
} SMAC_STATE;
|
||||
typedef union
|
||||
{
|
||||
#ifdef TPM_ALG_SHA1
|
||||
@ -85,6 +124,10 @@ typedef union
|
||||
#endif
|
||||
#ifdef TPM_ALG_SHA512
|
||||
tpmHashStateSHA512_t Sha512;
|
||||
#endif
|
||||
// Additions for symmetric block cipher MAC
|
||||
#ifdef SMAC_IMPLEMENTED
|
||||
SMAC_STATE smac;
|
||||
#endif
|
||||
// to force structure alignment to be no worse than HASH_ALIGNMENT
|
||||
#if HASH_ALIGNMENT == 4
|
||||
@ -124,10 +167,10 @@ typedef ANY_HASH_STATE ALIGNED_HASH_STATE;
|
||||
# define HASH_STATE_EXPORT_METHOD_DEF void (HASH_STATE_EXPORT_METHOD)(void)
|
||||
#endif
|
||||
#ifndef HASH_STATE_IMPORT_METHOD_DEF
|
||||
# define HASH_STATE_IMPORT_METHOD_DEF void ( HASH_STATE_IMPORT_METHOD)(void)
|
||||
# define HASH_STATE_IMPORT_METHOD_DEF void (HASH_STATE_IMPORT_METHOD)(void)
|
||||
#endif
|
||||
/* Define the prototypical function call for each of the methods. This defines the order in
|
||||
which the parameters are passed to the underlying function. */
|
||||
/* Define the prototypical function call for each of the methods. This defines the order in which
|
||||
the parameters are passed to the underlying function. */
|
||||
typedef HASH_START_METHOD_DEF;
|
||||
typedef HASH_DATA_METHOD_DEF;
|
||||
typedef HASH_END_METHOD_DEF;
|
||||
@ -139,10 +182,10 @@ typedef struct _HASH_METHODS
|
||||
HASH_START_METHOD *start;
|
||||
HASH_DATA_METHOD *data;
|
||||
HASH_END_METHOD *end;
|
||||
HASH_STATE_COPY_METHOD *copy; // Copy a hash block
|
||||
HASH_STATE_EXPORT_METHOD *copyOut; // Copy a hash block from a hash
|
||||
HASH_STATE_COPY_METHOD *copy; // Copy a hash block
|
||||
HASH_STATE_EXPORT_METHOD *copyOut; // Copy a hash block from a hash
|
||||
// context
|
||||
HASH_STATE_IMPORT_METHOD *copyIn; // Copy a hash block to a proper hash
|
||||
HASH_STATE_IMPORT_METHOD *copyIn; // Copy a hash block to a proper hash
|
||||
// context
|
||||
} HASH_METHODS, *PHASH_METHODS;
|
||||
#if ALG_SHA1
|
||||
@ -184,13 +227,16 @@ typedef const struct
|
||||
HASH##_DIGEST_SIZE, /*data size */ \
|
||||
sizeof(tpmHashState##HASH##_t), \
|
||||
TPM_ALG_##HASH}
|
||||
/* These definitions are for the types that can be in a hash state structure. These types are
|
||||
used in the crypto utilities. This is a define rather than an enum so that the size of this
|
||||
field can be explicit. */
|
||||
/* These definitions are for the types that can be in a hash state structure. These types are used
|
||||
in the cryptographic utilities. This is a define rather than an enum so that the size of this
|
||||
field can be explicit. */
|
||||
typedef BYTE HASH_STATE_TYPE;
|
||||
#define HASH_STATE_EMPTY ((HASH_STATE_TYPE) 0)
|
||||
#define HASH_STATE_HASH ((HASH_STATE_TYPE) 1)
|
||||
#define HASH_STATE_HMAC ((HASH_STATE_TYPE) 2)
|
||||
#if defined TPM_CC_MAC || defined TPM_CC_MAC_Start
|
||||
#define HASH_STATE_SMAC ((HASH_STATE_TYPE) 3)
|
||||
#endif
|
||||
/* This is the structure that is used for passing a context into the hashing functions. It should be
|
||||
the same size as the function context used within the hashing functions. This is checked when the
|
||||
hash function is initialized. This version uses a new layout for the contexts and a different
|
||||
@ -198,14 +244,18 @@ typedef BYTE HASH_STATE_TYPE;
|
||||
the structure on a HASH_UNIT boundary. If the structure is not properly aligned, the code that
|
||||
manipulates the structure will copy to a properly aligned structure before it is used and copy
|
||||
the result back. This just makes things slower. */
|
||||
/* NOTE: This version of the state had the pointer to the update method in the state. This is to
|
||||
allow the SMAC functions to use the same structure without having to replicate the entire
|
||||
HASH_DEF structure. */
|
||||
typedef struct _HASH_STATE
|
||||
{
|
||||
PHASH_DEF def;
|
||||
TPM_ALG_ID hashAlg;
|
||||
HASH_STATE_TYPE type; // type of the context
|
||||
TPM_ALG_ID hashAlg;
|
||||
PHASH_DEF def;
|
||||
ANY_HASH_STATE state;
|
||||
} HASH_STATE, *PHASH_STATE;
|
||||
typedef const HASH_STATE *PCHASH_STATE;
|
||||
|
||||
/* 10.1.3.2 HMAC State Structures */
|
||||
/* This header contains the hash structure definitions used in the TPM code to define the amount of
|
||||
space to be reserved for the hash state. This allows the TPM code to not have to import all of
|
||||
@ -215,7 +265,7 @@ typedef const HASH_STATE *PCHASH_STATE;
|
||||
/* An HMAC_STATE structure contains an opaque HMAC stack state. A caller would use this structure
|
||||
when performing incremental HMAC operations. This structure contains a hash state and an HMAC key
|
||||
and allows slightly better stack optimization than adding an HMAC key to each hash state. */
|
||||
typedef struct
|
||||
typedef struct hmacState
|
||||
{
|
||||
HASH_STATE hashState; // the hash state
|
||||
TPM2B_HASH_BLOCK hmacKey; // the HMAC key
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Implementation of cryptographic functions for hashing. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptHash_fp.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptHash_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -75,10 +75,10 @@ CryptGetHashDef(
|
||||
TPM_ALG_ID hashAlg
|
||||
);
|
||||
BOOL
|
||||
CryptHashIsImplemented(
|
||||
TPM_ALG_ID hashAlg,
|
||||
BOOL flag
|
||||
);
|
||||
CryptHashIsValidAlg(
|
||||
TPM_ALG_ID hashAlg,
|
||||
BOOL flag
|
||||
);
|
||||
LIB_EXPORT TPM_ALG_ID
|
||||
CryptHashGetAlgByIndex(
|
||||
UINT32 index // IN: the index
|
||||
@ -202,11 +202,7 @@ CryptKDFa(
|
||||
UINT32 sizeInBits, // IN: size of generated key in bits
|
||||
BYTE *keyStream, // OUT: key buffer
|
||||
UINT32 *counterInOut, // IN/OUT: caller may provide the iteration
|
||||
// counter for incremental operations to
|
||||
// avoid large intermediate buffers.
|
||||
BOOL once // IN: TRUE - only 1 iteration is performed
|
||||
// FALSE if iteration count determined by
|
||||
// "sizeInBits"
|
||||
UINT16 blocks // IN: If non-zero, this is the maximum number
|
||||
);
|
||||
LIB_EXPORT UINT16
|
||||
CryptKDFe(
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* DRBG with a behavior according to SP800-90A */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptRand.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptRand.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -149,11 +149,14 @@ typedef struct
|
||||
{
|
||||
UINT64 counter;
|
||||
UINT32 magic;
|
||||
UINT32 limit;
|
||||
TPM2B *seed;
|
||||
const TPM2B *label;
|
||||
TPM2B *context;
|
||||
TPM_ALG_ID hash;
|
||||
TPM_ALG_ID kdf;
|
||||
UINT16 digestSize;
|
||||
TPM2B_DIGEST residual;
|
||||
} KDF_STATE, *pKDR_STATE;
|
||||
#define KDF_MAGIC ((UINT32) 0x4048444a) // "KDF " backwards
|
||||
/* Make sure that any other structures added to this union start with a 64-bit counter and a 32-bit
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* DRBG with a behavior according to SP800-90A */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptRand_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptRand_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -113,7 +113,8 @@ DRBG_InstantiateSeededKdf(
|
||||
TPM_ALG_ID kdf, // IN: the KDF to use
|
||||
TPM2B *seed, // IN: the seed to use
|
||||
const TPM2B *label, // IN: a label for the generation process.
|
||||
TPM2B *context // IN: the context value
|
||||
TPM2B *context, // IN: the context value
|
||||
UINT32 limit // IN: Maximum number of bits from the KDF
|
||||
);
|
||||
LIB_EXPORT void
|
||||
DRBG_AdditionalData(
|
||||
|
||||
153
src/tpm2/crypto/CryptSym.h
Normal file
153
src/tpm2/crypto/CryptSym.h
Normal file
@ -0,0 +1,153 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* Implementation of the symmetric block cipher modes */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptSym.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
/* 1. Copyright Licenses: */
|
||||
/* */
|
||||
/* - Trusted Computing Group (TCG) grants to the user of the source code in */
|
||||
/* this specification (the "Source Code") a worldwide, irrevocable, */
|
||||
/* nonexclusive, royalty free, copyright license to reproduce, create */
|
||||
/* derivative works, distribute, display and perform the Source Code and */
|
||||
/* derivative works thereof, and to grant others the rights granted herein. */
|
||||
/* */
|
||||
/* - The TCG grants to the user of the other parts of the specification */
|
||||
/* (other than the Source Code) the rights to reproduce, distribute, */
|
||||
/* display, and perform the specification solely for the purpose of */
|
||||
/* developing products based on such documents. */
|
||||
/* */
|
||||
/* 2. Source Code Distribution Conditions: */
|
||||
/* */
|
||||
/* - 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 */
|
||||
/* licenses, this list of conditions and the following disclaimers in the */
|
||||
/* documentation and/or other materials provided with the distribution. */
|
||||
/* */
|
||||
/* 3. Disclaimers: */
|
||||
/* */
|
||||
/* - THE COPYRIGHT LICENSES SET FORTH ABOVE DO NOT REPRESENT ANY FORM OF */
|
||||
/* LICENSE OR WAIVER, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, WITH */
|
||||
/* RESPECT TO PATENT RIGHTS HELD BY TCG MEMBERS (OR OTHER THIRD PARTIES) */
|
||||
/* THAT MAY BE NECESSARY TO IMPLEMENT THIS SPECIFICATION OR OTHERWISE. */
|
||||
/* Contact TCG Administration (admin@trustedcomputinggroup.org) for */
|
||||
/* information on specification licensing rights available through TCG */
|
||||
/* membership agreements. */
|
||||
/* */
|
||||
/* - THIS SPECIFICATION IS PROVIDED "AS IS" WITH NO EXPRESS OR IMPLIED */
|
||||
/* WARRANTIES WHATSOEVER, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR */
|
||||
/* FITNESS FOR A PARTICULAR PURPOSE, ACCURACY, COMPLETENESS, OR */
|
||||
/* NONINFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS, OR ANY WARRANTY */
|
||||
/* OTHERWISE ARISING OUT OF ANY PROPOSAL, SPECIFICATION OR SAMPLE. */
|
||||
/* */
|
||||
/* - Without limitation, TCG and its members and licensors disclaim all */
|
||||
/* liability, including liability for infringement of any proprietary */
|
||||
/* rights, relating to use of information in this specification and to the */
|
||||
/* implementation of this specification, and TCG disclaims all liability for */
|
||||
/* cost of procurement of substitute goods or services, lost profits, loss */
|
||||
/* of use, loss of data or any incidental, consequential, direct, indirect, */
|
||||
/* or special damages, whether under contract, tort, warranty or otherwise, */
|
||||
/* arising in any way out of use or reliance upon this specification or any */
|
||||
/* information herein. */
|
||||
/* */
|
||||
/* (c) Copyright IBM Corp. and others, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* kgold - Missing in 146 code merge. Taken from 142. */
|
||||
|
||||
#ifndef CRYPTSYM_H
|
||||
#define CRYPTSYM_H
|
||||
|
||||
union tpmCryptKeySchedule_t {
|
||||
#ifdef TPM_ALG_AES
|
||||
tpmKeyScheduleAES AES;
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM4
|
||||
tpmKeyScheduleSM4 SM4;
|
||||
#endif
|
||||
#ifdef TPM_ALG_CAMELLIA
|
||||
tpmKeyScheduleCAMELLIA CAMELLIA;
|
||||
#endif
|
||||
#ifdef TPM_ALG_TDES
|
||||
tpmKeyScheduleTDES TDES[3];
|
||||
#endif
|
||||
#if SYMMETRIC_ALIGNMENT == 8
|
||||
uint64_t alignment;
|
||||
#else
|
||||
uint32_t alignment;
|
||||
#endif
|
||||
};
|
||||
/* Each block cipher within a library is expected to conform to the same calling conventions with
|
||||
three parameters (keySchedule, in, and out) in the same order. That means that all algorithms
|
||||
would use the same order of the same parameters. The code is written assuming the (keySchedule,
|
||||
in, and out) order. However, if the library uses a different order, the order can be changed with
|
||||
a SWIZZLE macro that puts the parameters in the correct order. Note that all algorithms have to
|
||||
use the same order and number of parameters because the code to build the calling list is common
|
||||
for each call to encrypt or decrypt with the algorithm chosen by setting a function pointer to
|
||||
select the algorithm that is used. */
|
||||
# define ENCRYPT(keySchedule, in, out) \
|
||||
encrypt(SWIZZLE(keySchedule, in, out))
|
||||
# define DECRYPT(keySchedule, in, out) \
|
||||
decrypt(SWIZZLE(keySchedule, in, out))
|
||||
/* Note that the macros rely on encrypt as local values in the functions that use these
|
||||
macros. Those parameters are set by the macro that set the key schedule to be used for the
|
||||
call. */
|
||||
#define ENCRYPT_CASE(ALG) \
|
||||
case TPM_ALG_##ALG: \
|
||||
TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \
|
||||
encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG; \
|
||||
break;
|
||||
#define DECRYPT_CASE(ALG) \
|
||||
case TPM_ALG_##ALG: \
|
||||
TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \
|
||||
decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG; \
|
||||
break;
|
||||
#ifdef TPM_ALG_AES
|
||||
#define ENCRYPT_CASE_AES ENCRYPT_CASE(AES)
|
||||
#define DECRYPT_CASE_AES DECRYPT_CASE(AES)
|
||||
#else
|
||||
#define ENCRYPT_CASE_AES
|
||||
#define DECRYPT_CASE_AES
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM4
|
||||
#define ENCRYPT_CASE_SM4 ENCRYPT_CASE(SM4)
|
||||
#define DECRYPT_CASE_SM4 DECRYPT_CASE(SM4)
|
||||
#else
|
||||
#define ENCRYPT_CASE_SM4
|
||||
#define DECRYPT_CASE_SM4
|
||||
#endif
|
||||
#ifdef TPM_ALG_CAMELLIA
|
||||
#define ENCRYPT_CASE_CAMELLIA ENCRYPT_CASE(CAMELLIA)
|
||||
#define DECRYPT_CASE_CAMELLIA DECRYPT_CASE(CAMELLIA)
|
||||
#else
|
||||
#define ENCRYPT_CASE_CAMELLIA
|
||||
#define DECRYPT_CASE_CAMELLIA
|
||||
#endif
|
||||
#ifdef TPM_ALG_TDES
|
||||
#define ENCRYPT_CASE_TDES ENCRYPT_CASE(TDES)
|
||||
#define DECRYPT_CASE_TDES DECRYPT_CASE(TDES)
|
||||
#else
|
||||
#define ENCRYPT_CASE_TDES
|
||||
#define DECRYPT_CASE_TDES
|
||||
#endif
|
||||
/* For each algorithm the case will either be defined or null. */
|
||||
#define SELECT(direction) \
|
||||
switch(algorithm) \
|
||||
{ \
|
||||
direction##_CASE_AES \
|
||||
direction##_CASE_SM4 \
|
||||
direction##_CASE_CAMELLIA \
|
||||
direction##_CASE_TDES \
|
||||
default: \
|
||||
return TPM_RC_FAILURE; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptSym_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptSym_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* constant definitions used for self-test. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptTest.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptTest.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -65,12 +65,14 @@
|
||||
/* 10.1.7 CryptTest.h */
|
||||
/* This file contains constant definitions used for self test */
|
||||
/* This is the definition of a bit array with one bit per algorithm */
|
||||
/* NOTE: Since bit numbering starts at zero, when ALG_LAST_VALUE is a multiple of 8,
|
||||
ALGORITHM_VECTOR will need to have byte for the single bit in the last byte. So, for example,
|
||||
when ALG_LAST_VECTOR is 8, ALGORITHM_VECTOR will need 2 bytes. */
|
||||
#define ALGORITHM_VECTOR_BYTES ((ALG_LAST_VALUE + 8) / 8)
|
||||
typedef BYTE ALGORITHM_VECTOR[ALGORITHM_VECTOR_BYTES];
|
||||
#ifdef TEST_SELF_TEST
|
||||
LIB_EXPORT extern ALGORITHM_VECTOR LibToTest;
|
||||
#endif
|
||||
/* 10.1.7.2 Self-test */
|
||||
/* This structure is used to contain self-test tracking information for the cryptographic
|
||||
modules. Each of the major modules is given a 32-bit value in which it may maintain its own self
|
||||
test information. The convention for this state is that when all of the bits in this structure
|
||||
@ -87,7 +89,6 @@ typedef struct
|
||||
UINT32 ecc;
|
||||
#endif
|
||||
} CRYPTO_SELF_TEST_STATE;
|
||||
/* 10.1.7.2.1 g_cryptoSelfTestState */
|
||||
/* This structure contains the cryptographic self-test state values. */
|
||||
extern CRYPTO_SELF_TEST_STATE g_cryptoSelfTestState;
|
||||
#endif // _CRYPT_TEST_H
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptUtil_fp.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptUtil_fp.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -220,6 +220,26 @@ void
|
||||
CryptAlgsSetImplemented(
|
||||
void
|
||||
);
|
||||
|
||||
TPM_RC
|
||||
CryptSelectMac(
|
||||
TPMT_PUBLIC *publicArea,
|
||||
TPMI_ALG_MAC_SCHEME *inMac
|
||||
);
|
||||
BOOL
|
||||
CryptMacIsValidForKey(
|
||||
TPM_ALG_ID keyType,
|
||||
TPM_ALG_ID macAlg,
|
||||
BOOL flag
|
||||
);
|
||||
BOOL
|
||||
CryptSmacIsValidAlg(
|
||||
TPM_ALG_ID alg,
|
||||
BOOL FLAG // IN: Indicates if TPM_ALG_NULL is valid
|
||||
);
|
||||
BOOL
|
||||
CryptSymModeIsValid(
|
||||
TPM_ALG_ID mode,
|
||||
BOOL flag
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptDataEcc.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptDataEcc.c 1012 2017-05-23 21:45:57Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -300,7 +300,7 @@ const TPM2B_32_BYTE_VALUE BN_P256_p = {32,
|
||||
const TPM2B_1_BYTE_VALUE BN_P256_a = {1,{0}};
|
||||
const TPM2B_1_BYTE_VALUE BN_P256_b = {1,{3}};
|
||||
const TPM2B_1_BYTE_VALUE BN_P256_gX = {1,{1}};
|
||||
const TPM2B_1_BYTE_VALUE BN_P256_gY = {1,{2}};;
|
||||
const TPM2B_1_BYTE_VALUE BN_P256_gY = {1,{2}};
|
||||
const TPM2B_32_BYTE_VALUE BN_P256_n = {32,
|
||||
{0xFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFC, 0XF0, 0XCD,
|
||||
0X46, 0XE5, 0XF2, 0X5E, 0XEE, 0X71, 0XA4, 0X9E,
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptDes.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptDes.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -167,7 +167,8 @@ CryptGenerateKeyDes(
|
||||
BYTE *pK = sensitive->sensitive.sym.t.buffer;
|
||||
int i = (sensitive->sensitive.sym.t.size + 7) / 8;
|
||||
// Use the random number generator to generate the required number of bits
|
||||
DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size);
|
||||
if(DRBG_Generate(rand, pK, sensitive->sensitive.sym.t.size) == 0)
|
||||
return TPM_RC_NO_RESULT;
|
||||
for(; i > 0; pK += 8, i--)
|
||||
{
|
||||
UINT64 k = BYTE_ARRAY_TO_UINT64(pK);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Functions that are used for the two-phase, ECC, key-exchange protocols */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptEccKeyExchange.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptEccKeyExchange.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptEccMain.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptEccMain.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -333,8 +333,6 @@ CryptGenerateR(
|
||||
// requirements of the random value.
|
||||
// want to generate a new r.
|
||||
r->t.size = n.t.size;
|
||||
// Arbitrary upper limit on the number of times that we can look for
|
||||
// a suitable random value. The normally number of tries will be 1.
|
||||
for(iterations = 1; iterations < 1000000;)
|
||||
{
|
||||
int i;
|
||||
@ -489,7 +487,7 @@ CryptEccIsValidPrivateKey(
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_NO_RESULTS result of multiplication is a point at infinity */
|
||||
/* TPM_RC_ECC_POINT S or Q is not on the curve */
|
||||
/* TPM_RC_VALUE d or u is not 0 < d < n */
|
||||
/* TPM_RC_VALUE d or u is not < n */
|
||||
TPM_RC
|
||||
BnPointMult(
|
||||
bigPoint R, // OUT: computed point
|
||||
@ -543,6 +541,9 @@ BnPointMult(
|
||||
search will take more than one iteration is very small. As a consequence, the weighted-average
|
||||
run time for this function is significantly less than the method of key pair generation with
|
||||
extra random bits. */
|
||||
/* Return Value Meaning */
|
||||
/* TRUE value generated */
|
||||
/* FALSE failure generating private key */
|
||||
BOOL
|
||||
BnEccGetPrivate(
|
||||
bigNum dOut, // OUT: the qualified random value
|
||||
@ -551,16 +552,31 @@ BnEccGetPrivate(
|
||||
RAND_STATE *rand // IN: state for DRBG
|
||||
)
|
||||
{
|
||||
//
|
||||
bigConst order = CurveGetOrder(C);
|
||||
BOOL OK;
|
||||
UINT32 orderBits = BnSizeInBits(order);
|
||||
#if 1 // This is the "extra bits" method of key generation
|
||||
UINT32 orderBytes = BITS_TO_BYTES(orderBits);
|
||||
BN_VAR(bnExtraBits, MAX_ECC_KEY_BITS + 64);
|
||||
BN_VAR(nMinus1, MAX_ECC_KEY_BITS);
|
||||
//
|
||||
OK = BnGetRandomBits(bnExtraBits, (orderBytes * 8) + 64, rand);
|
||||
OK = OK && BnSubWord(nMinus1, order, 1);
|
||||
OK = OK && BnMod(bnExtraBits, nMinus1);
|
||||
OK = OK && BnAddWord(dOut, bnExtraBits, 1);
|
||||
#else
|
||||
// This is the "testing candidates" version of key generation
|
||||
do
|
||||
{
|
||||
BnGetRandomBits(dOut, BnSizeInBits(order), rand);
|
||||
BnAddWord(dOut, dOut, 1);
|
||||
} while(BnUnsignedCmp(dOut, order) >= 0);
|
||||
return TRUE;
|
||||
OK = BnGetRandomBits(dOut, BnSizeInBits(order), rand);
|
||||
OK = OK && BnAddWord(dOut, dOut, 1);
|
||||
} while(OK && BnUnsignedCmp(dOut, order) >= 0);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
/* 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. */
|
||||
BOOL
|
||||
BnEccGenerateKeyPair(
|
||||
bigNum bnD, // OUT: private scalar
|
||||
@ -570,14 +586,10 @@ BnEccGenerateKeyPair(
|
||||
)
|
||||
{
|
||||
BOOL OK = FALSE;
|
||||
int limit;
|
||||
for(limit = 100; (limit > 0) && !OK; limit--)
|
||||
{
|
||||
// Get a private scalar
|
||||
BnEccGetPrivate(bnD, E->C, rand);
|
||||
// Do a point multiply
|
||||
OK = BnEccModMult(ecQ, NULL, bnD, E);
|
||||
}
|
||||
// Get a private scalar
|
||||
OK = BnEccGetPrivate(bnD, E->C, rand);
|
||||
// Do a point multiply
|
||||
OK = OK && BnEccModMult(ecQ, NULL, bnD, E);
|
||||
if(!OK)
|
||||
BnSetWord(ecQ->z, 0);
|
||||
else
|
||||
@ -688,7 +700,7 @@ CryptEccIsPointOnCurve(
|
||||
key */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_CURVE curve is not supported */
|
||||
/* TPM_RC_FAIL ??? */
|
||||
/* TPM_RC_NO_RESULT could not verify key with signature (FIPS only) */
|
||||
LIB_EXPORT TPM_RC
|
||||
CryptEccGenerateKey(
|
||||
TPMT_PUBLIC *publicArea, // IN/OUT: The public area template for
|
||||
@ -706,9 +718,8 @@ CryptEccGenerateKey(
|
||||
CURVE_INITIALIZED(E, publicArea->parameters.eccDetail.curveID);
|
||||
ECC_NUM(bnD);
|
||||
POINT(ecQ);
|
||||
const UINT32 MaxCount = 100;
|
||||
UINT32 count = 0;
|
||||
TPM_RC retVal = TPM_RC_NO_RESULT;
|
||||
BOOL OK;
|
||||
TPM_RC retVal;
|
||||
TEST(TPM_ALG_ECDSA); // ECDSA is used to verify each key
|
||||
// Validate parameters
|
||||
if(E == NULL)
|
||||
@ -716,37 +727,32 @@ CryptEccGenerateKey(
|
||||
publicArea->unique.ecc.x.t.size = 0;
|
||||
publicArea->unique.ecc.y.t.size = 0;
|
||||
sensitive->sensitive.ecc.t.size = 0;
|
||||
// Start search for key (should be quick)
|
||||
for(count = 1; (count < MaxCount) && (retVal != TPM_RC_SUCCESS); count++)
|
||||
OK = BnEccGenerateKeyPair(bnD, ecQ, E, rand);
|
||||
if(OK)
|
||||
{
|
||||
if(!BnEccGenerateKeyPair(bnD, ecQ, E, rand))
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
retVal = TPM_RC_SUCCESS;
|
||||
#ifdef FIPS_COMPLIANT
|
||||
// See if PWCT is required
|
||||
if(publicArea->objectAttributes.sign)
|
||||
{
|
||||
ECC_NUM(bnT);
|
||||
ECC_NUM(bnS);
|
||||
TPM2B_DIGEST digest;
|
||||
TEST(TPM_ALG_ECDSA);
|
||||
digest.t.size =
|
||||
(UINT16)BITS_TO_BYTES(BnSizeInBits(CurveGetPrime(
|
||||
AccessCurveData(E))));
|
||||
// Get a random value to sign using the current DRBG state
|
||||
DRBG_Generate(NULL, digest.t.buffer, digest.t.size);
|
||||
BnSignEcdsa(bnT, bnS, E, bnD, &digest, NULL);
|
||||
// and make sure that we can validate the signature
|
||||
retVal = BnValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest);
|
||||
}
|
||||
#endif
|
||||
BnPointTo2B(&publicArea->unique.ecc, ecQ, E);
|
||||
BnTo2B(bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size);
|
||||
}
|
||||
// if counter maxed out, put the TPM to failure mode
|
||||
if(count == MaxCount)
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
// Convert results
|
||||
BnPointTo2B(&publicArea->unique.ecc, ecQ, E);
|
||||
BnTo2B(bnD, &sensitive->sensitive.ecc.b, publicArea->unique.ecc.x.t.size);
|
||||
#if defined FIPS_COMPLIANT || 1
|
||||
// See if PWCT is required
|
||||
if(OK && (IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))) // kgold
|
||||
// if(OK && publicArea->objectAttributes.sign)
|
||||
{
|
||||
ECC_NUM(bnT);
|
||||
ECC_NUM(bnS);
|
||||
TPM2B_DIGEST digest;
|
||||
TEST(TPM_ALG_ECDSA);
|
||||
digest.t.size =
|
||||
(UINT16)BITS_TO_BYTES(BnSizeInBits(CurveGetPrime(
|
||||
AccessCurveData(E))));
|
||||
// Get a random value to sign using the built in DRBG state
|
||||
DRBG_Generate(NULL, digest.t.buffer, digest.t.size);
|
||||
BnSignEcdsa(bnT, bnS, E, bnD, &digest, NULL);
|
||||
// and make sure that we can validate the signature
|
||||
OK = BnValidateSignatureEcdsa(bnT, bnS, E, ecQ, &digest) == TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
retVal = (OK) ? TPM_RC_SUCCESS : TPM_RC_NO_RESULT;
|
||||
Exit:
|
||||
CURVE_FREE(E);
|
||||
return retVal;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptEccSignature.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: CryptEccSignature.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -216,6 +216,7 @@ BnSignEcdsa(
|
||||
this function u */
|
||||
/* Error Returns Meaning */
|
||||
/* TPM_RC_SCHEME unsupported hash algorithm */
|
||||
/* TPM_RC_NO_RESULT cannot get values from random number generator */
|
||||
static TPM_RC
|
||||
BnSignEcdaa(
|
||||
TPM2B_ECC_PARAMETER *nonceK, // OUT: nonce component of the signature
|
||||
@ -242,14 +243,18 @@ BnSignEcdaa(
|
||||
retVal = TPM_RC_VALUE;
|
||||
else
|
||||
{
|
||||
// This allocation is here because k is not defined until CrypGenerateR()
|
||||
// is done.
|
||||
// This allocation is here because 'r' doesn't have a value until
|
||||
// CrypGenerateR() is done.
|
||||
ECC_INITIALIZED(bnR, &r);
|
||||
do
|
||||
{
|
||||
// generate nonceK such that 0 < nonceK < n
|
||||
// use bnT as a temp.
|
||||
BnEccGetPrivate(bnT, AccessCurveData(E), rand);
|
||||
if(!BnEccGetPrivate(bnT, AccessCurveData(E), rand))
|
||||
{
|
||||
retVal = TPM_RC_NO_RESULT;
|
||||
break;
|
||||
}
|
||||
BnTo2B(bnT, &nonceK->b, 0);
|
||||
T.t.size = CryptHashStart(&state, scheme->details.ecdaa.hashAlg);
|
||||
if(T.t.size == 0)
|
||||
@ -397,7 +402,7 @@ BnSignEcSm2(
|
||||
// debug)
|
||||
)
|
||||
{
|
||||
BN_MAX_INITIALIZZED(bnE, digest); // Don't know how big digest might be
|
||||
BN_MAX_INITIALIZED(bnE, digest); // Don't know how big digest might be
|
||||
ECC_NUM(bnN);
|
||||
ECC_NUM(bnK);
|
||||
ECC_NUM(bnX1);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Implementation of cryptographic functions for hashing. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptHash.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptHash.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -81,6 +81,8 @@ HASH_DEF_TEMPLATE(SHA512);
|
||||
#endif
|
||||
HASH_DEF nullDef = {{0}};
|
||||
/* 10.2.14.3 Obligatory Initialization Functions */
|
||||
/* This function is called by _TPM_Init() do perform the initialization operations for the
|
||||
library. */
|
||||
BOOL
|
||||
CryptHashInit(
|
||||
void
|
||||
@ -89,6 +91,9 @@ CryptHashInit(
|
||||
LibHashInit();
|
||||
return TRUE;
|
||||
}
|
||||
/* 10.2.13.3.2 CryptHashStartup() */
|
||||
/* This function is called by TPM2_Startup() in case there is work to do at startup. Currently, this
|
||||
is a placeholder. */
|
||||
BOOL
|
||||
CryptHashStartup(
|
||||
void
|
||||
@ -136,17 +141,17 @@ CryptGetHashDef(
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
/* 10.2.14.4.3 CryptHashIsImplemented() */
|
||||
/* 10.2.13.4.3 CryptHashIsValidAlg() */
|
||||
/* This function tests to see if an algorithm ID is a valid hash algorithm. If flag is true, then
|
||||
TPM_ALG_NULL is a valid hash. */
|
||||
/* Return Values Meaning */
|
||||
/* TRUE hashAlg is a valid, implemented hash on this TPM. */
|
||||
/* FALSE not valid */
|
||||
/* Return Value Meaning */
|
||||
/* TRUE hashAlg is a valid, implemented hash on this TPM. */
|
||||
/* FALSE not valid */
|
||||
BOOL
|
||||
CryptHashIsImplemented(
|
||||
TPM_ALG_ID hashAlg,
|
||||
BOOL flag
|
||||
)
|
||||
CryptHashIsValidAlg(
|
||||
TPM_ALG_ID hashAlg,
|
||||
BOOL flag
|
||||
)
|
||||
{
|
||||
switch(hashAlg)
|
||||
{
|
||||
@ -263,7 +268,6 @@ CryptHashGetContextAlg(
|
||||
return state->hashAlg;
|
||||
}
|
||||
/* 10.2.14.5 State Import and Export */
|
||||
#if 1
|
||||
/* 10.2.14.5.1 CryptHashCopyState */
|
||||
/* This function is used to clone a HASH_STATE. */
|
||||
LIB_EXPORT void
|
||||
@ -290,7 +294,6 @@ CryptHashCopyState(
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif //0
|
||||
/* 10.2.14.5.2 CryptHashExportState() */
|
||||
/* This function is used to export a hash or HMAC hash state. This function would be called when
|
||||
preparing to context save a sequence object. */
|
||||
@ -304,11 +307,21 @@ CryptHashExportState(
|
||||
BYTE *outBuf = (BYTE *)externalFmt;
|
||||
//
|
||||
cAssert(sizeof(HASH_STATE) <= sizeof(EXPORT_HASH_STATE));
|
||||
// the following #define is used to move data from an aligned internal data
|
||||
// structure to a byte buffer (external format data.
|
||||
#define CopyToOffset(value) \
|
||||
memcpy(&outBuf[offsetof(HASH_STATE,value)], &internalFmt->value, \
|
||||
sizeof(internalFmt->value))
|
||||
// Copy the hashAlg
|
||||
CopyToOffset(hashAlg);
|
||||
CopyToOffset(type);
|
||||
#ifdef HASH_STATE_SMAC
|
||||
if(internalFmt->type == HASH_STATE_SMAC)
|
||||
{
|
||||
memcpy(outBuf, internalFmt, sizeof(HASH_STATE));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(internalFmt->type == HASH_STATE_HMAC)
|
||||
{
|
||||
HMAC_STATE *from = (HMAC_STATE *)internalFmt;
|
||||
@ -339,6 +352,13 @@ CryptHashImportState(
|
||||
CopyFromOffset(type);
|
||||
if(internalFmt->hashAlg != TPM_ALG_NULL)
|
||||
{
|
||||
#ifdef HASH_STATE_SMAC
|
||||
if(internalFmt->type == HASH_STATE_SMAC)
|
||||
{
|
||||
memcpy(internalFmt, inBuf, sizeof(HASH_STATE));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
internalFmt->def = CryptGetHashDef(internalFmt->hashAlg);
|
||||
HASH_STATE_IMPORT(internalFmt, inBuf);
|
||||
if(internalFmt->type == HASH_STATE_HMAC)
|
||||
@ -362,7 +382,8 @@ HashEnd(
|
||||
)
|
||||
{
|
||||
BYTE temp[MAX_DIGEST_SIZE];
|
||||
if(hashState->hashAlg == TPM_ALG_NULL)
|
||||
if((hashState->hashAlg == TPM_ALG_NULL)
|
||||
|| (hashState->type != HASH_STATE_HASH))
|
||||
dOutSize = 0;
|
||||
if(dOutSize > 0)
|
||||
{
|
||||
@ -377,7 +398,6 @@ HashEnd(
|
||||
memcpy(dOut, &temp, dOutSize);
|
||||
}
|
||||
hashState->type = HASH_STATE_EMPTY;
|
||||
// hashState->hashAlg = TPM_ALG_ERROR;
|
||||
return (UINT16)dOutSize;
|
||||
}
|
||||
/* 10.2.14.6.2 CryptHashStart() */
|
||||
@ -415,9 +435,9 @@ CryptHashStart(
|
||||
hashState->type = HASH_STATE_HASH;
|
||||
return retVal;
|
||||
}
|
||||
/* 10.2.14.6.3 CryptDigestUpdate() */
|
||||
/* Add data to a hash or HMAC stack. */
|
||||
LIB_EXPORT void
|
||||
/* 10.2.13.6.3 CryptDigestUpdate() */
|
||||
/* Add data to a hash or HMAC, SMAC stack. */
|
||||
void
|
||||
CryptDigestUpdate(
|
||||
PHASH_STATE hashState, // IN: the hash context information
|
||||
UINT32 dataSize, // IN: the size of data to be added
|
||||
@ -426,10 +446,21 @@ CryptDigestUpdate(
|
||||
{
|
||||
if(hashState->hashAlg != TPM_ALG_NULL)
|
||||
{
|
||||
#ifndef SMAC_IMPLEMENTED
|
||||
pAssert((hashState->type == HASH_STATE_HASH)
|
||||
|| (hashState->type == HASH_STATE_HMAC));
|
||||
hashState->def = CryptGetHashDef(hashState->hashAlg);
|
||||
//?? hashState->def = CryptGetHashDef(hashState->hashAlg);
|
||||
HASH_DATA(hashState, dataSize, (BYTE *)data);
|
||||
#else
|
||||
if((hashState->type == HASH_STATE_HASH)
|
||||
|| (hashState->type == HASH_STATE_HMAC))
|
||||
HASH_DATA(hashState, dataSize, (BYTE *)data);
|
||||
else if(hashState->type == HASH_STATE_SMAC)
|
||||
(hashState->state.smac.smacMethods.data)(&hashState->state.smac.state,
|
||||
dataSize, data);
|
||||
else
|
||||
FAIL(FATAL_ERROR_INTERNAL);
|
||||
#endif // SMAC_IMPLEMENTED
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -489,7 +520,7 @@ CryptDigestUpdate2B(
|
||||
return;
|
||||
}
|
||||
/* 10.2.14.6.7 CryptHashEnd2B() */
|
||||
/* This function is the same as CypteCompleteHash() but the digest is placed in a TPM2B. This is the
|
||||
/* This function is the same as CryptCompleteHash() but the digest is placed in a TPM2B. This is the
|
||||
most common use and this is provided for specification clarity. 'digest.size' should be set to
|
||||
indicate the number of bytes to place in the buffer */
|
||||
/* Return Values Meaning */
|
||||
@ -513,7 +544,7 @@ CryptDigestUpdateInt(
|
||||
UINT64 intValue // IN: integer value to be hashed
|
||||
)
|
||||
{
|
||||
#if LITTLE_ENDIAN_TPM == YES
|
||||
#if LITTLE_ENDIAN_TPM
|
||||
intValue = REVERSE_ENDIAN_64(intValue);
|
||||
#endif
|
||||
CryptDigestUpdate(state, intSize, &((BYTE *)&intValue)[8 - intSize]);
|
||||
@ -593,6 +624,13 @@ CryptHmacEnd(
|
||||
{
|
||||
BYTE temp[MAX_DIGEST_SIZE];
|
||||
PHASH_STATE hState = (PHASH_STATE)&state->hashState;
|
||||
#ifdef SMAC_IMPLEMENTED
|
||||
if(hState->type == HASH_STATE_SMAC)
|
||||
return (state->hashState.state.smac.smacMethods.end)
|
||||
(&state->hashState.state.smac.state,
|
||||
dOutSize,
|
||||
dOut);
|
||||
#endif
|
||||
pAssert(hState->type == HASH_STATE_HMAC);
|
||||
hState->def = CryptGetHashDef(hState->hashAlg);
|
||||
// Change the state type for completion processing
|
||||
@ -713,18 +751,18 @@ CryptKDFa(
|
||||
UINT32 *counterInOut, // IN/OUT: caller may provide the iteration
|
||||
// counter for incremental operations to
|
||||
// avoid large intermediate buffers.
|
||||
BOOL once // IN: TRUE - only 1 iteration is performed
|
||||
// FALSE if iteration count determined by
|
||||
// "sizeInBits"
|
||||
UINT16 blocks // IN: If non-zero, this is the maximum number
|
||||
// of blocks to be returned, regardless
|
||||
// of sizeInBit
|
||||
)
|
||||
{
|
||||
UINT32 counter = 0; // counter value
|
||||
INT16 bytes; // number of bytes to produce
|
||||
UINT32 counter = 0; // counter value
|
||||
INT16 bytes; // number of bytes to produce
|
||||
UINT16 generated; // number of bytes generated
|
||||
BYTE *stream = keyStream;
|
||||
HMAC_STATE hState;
|
||||
UINT16 digestSize = CryptHashGetDigestSize(hashAlg);
|
||||
pAssert(key != NULL && keyStream != NULL);
|
||||
pAssert(once == FALSE || (sizeInBits & 7) == 0);
|
||||
if(digestSize == 0)
|
||||
return 0;
|
||||
if(counterInOut != NULL)
|
||||
@ -732,13 +770,16 @@ CryptKDFa(
|
||||
// If the size of the request is larger than the numbers will handle,
|
||||
// it is a fatal error.
|
||||
pAssert(((sizeInBits + 7) / 8) <= INT16_MAX);
|
||||
bytes = once ? digestSize : (INT16)((sizeInBits + 7) / 8);
|
||||
// The number of bytes to be generated is the smaller of the sizeInBits bytes or
|
||||
// the number of requested blocks. The number of blocks is the smaller of the
|
||||
// number requested or the number allowed by sizeInBits. A partial block is
|
||||
// a full block.
|
||||
bytes = (blocks > 0) ? blocks * digestSize : (UINT16)BITS_TO_BYTES(sizeInBits);
|
||||
generated = bytes;
|
||||
// Generate required bytes
|
||||
for(; bytes > 0; bytes -= digestSize)
|
||||
{
|
||||
counter++;
|
||||
if(bytes < digestSize)
|
||||
digestSize = bytes;
|
||||
// Start HMAC
|
||||
if(CryptHmacStart(&hState, hashAlg, key->size, key->buffer) == 0)
|
||||
return 0;
|
||||
@ -764,15 +805,22 @@ CryptKDFa(
|
||||
HASH_DATA(&hState.hashState, contextV->size, contextV->buffer);
|
||||
// Adding size in bits
|
||||
CryptDigestUpdateInt(&hState.hashState, 4, sizeInBits);
|
||||
CryptHmacEnd(&hState, digestSize, stream);
|
||||
// Complete and put the data in the buffer
|
||||
CryptHmacEnd(&hState, bytes, stream);
|
||||
stream = &stream[digestSize];
|
||||
}
|
||||
// Mask off bits if the required bits is not a multiple of byte size
|
||||
if((sizeInBits % 8) != 0)
|
||||
// Mask off bits if the required bits is not a multiple of byte size. Only do
|
||||
// this if this is a call that is returning all the blocks indicated in
|
||||
// sizeInBits
|
||||
#if 0 //?? Masking in the KDF is disabled. If the calling function wants something
|
||||
//?? less than even number of bytes, then the caller should do the masking
|
||||
//?? because there is no universal way to do it here
|
||||
if((blocks == 0) && (sizeInBits % 8) != 0)
|
||||
keyStream[0] &= ((1 << (sizeInBits % 8)) - 1);
|
||||
#endif
|
||||
if(counterInOut != NULL)
|
||||
*counterInOut = counter;
|
||||
return (UINT16)((sizeInBits + 7) / 8);
|
||||
return generated;
|
||||
}
|
||||
/* 10.2.14.8.3 CryptKDFe() */
|
||||
/* KDFe() as defined in TPM specification part 1. */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* DRBG with a behavior according to SP800-90A */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptRand.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptRand.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -119,13 +119,13 @@ DfStart(
|
||||
BYTE init[8];
|
||||
int i;
|
||||
UINT32 drbgSeedSize = sizeof(DRBG_SEED);
|
||||
const BYTE dfKey[] = {
|
||||
const BYTE dfKey[DRBG_KEY_SIZE_BYTES] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
/* #if DRBG_KEY_SIZE_WORDS > 4 kgold */
|
||||
#if DRBG_KEY_SIZE_BYTES > 16
|
||||
,0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
/* #endif */
|
||||
#endif
|
||||
};
|
||||
memset(dfState, 0, sizeof(DF_STATE));
|
||||
DRBG_ENCRYPT_SETUP(&dfKey[0], DRBG_KEY_SIZE_BITS, &dfState->keySchedule);
|
||||
@ -543,16 +543,20 @@ DRBG_InstantiateSeededKdf(
|
||||
TPM_ALG_ID kdf, // IN: the KDF to use
|
||||
TPM2B *seed, // IN: the seed to use
|
||||
const TPM2B *label, // IN: a label for the generation process.
|
||||
TPM2B *context // IN: the context value
|
||||
TPM2B *context, // IN: the context value
|
||||
UINT32 limit // IN: Maximum number of bits from the KDF
|
||||
)
|
||||
{
|
||||
state->magic = KDF_MAGIC;
|
||||
state->limit = limit;
|
||||
state->seed = seed;
|
||||
state->hash = hashAlg;
|
||||
state->kdf = kdf;
|
||||
state->label = label;
|
||||
state->context = context;
|
||||
state->counter = 1;
|
||||
state->digestSize = CryptHashGetDigestSize(hashAlg);
|
||||
state->counter = 0;
|
||||
state->residual.t.size = 0;
|
||||
return TRUE;
|
||||
}
|
||||
/* 10.2.18.4.5 DRBG_AdditionalData() */
|
||||
@ -654,18 +658,73 @@ DRBG_Generate(
|
||||
UINT16 randomSize // IN: the number of bytes to generate
|
||||
)
|
||||
{
|
||||
//
|
||||
if(state == NULL)
|
||||
state = (RAND_STATE *)&drbgDefault;
|
||||
// If the caller used a KDF state, generate a sequence from the KDF
|
||||
// If the caller used a KDF state, generate a sequence from the KDF not to
|
||||
// exceed the limit.
|
||||
if(state->kdf.magic == KDF_MAGIC)
|
||||
{
|
||||
KDF_STATE *kdf = (KDF_STATE *)state;
|
||||
UINT32 count = (UINT32)kdf->counter;
|
||||
if((randomSize != 0) && (random != NULL))
|
||||
CryptKDFa(kdf->hash, kdf->seed, kdf->label, kdf->context, NULL,
|
||||
randomSize * 8, random, &count, 0);
|
||||
kdf->counter = count;
|
||||
UINT32 counter = (UINT32)kdf->counter;
|
||||
INT32 bytesLeft = randomSize;
|
||||
if(random == NULL)
|
||||
return 0;
|
||||
// If the number of bytes to be returned would put the generator
|
||||
// over the limit, then return 0
|
||||
if((((kdf->counter * kdf->digestSize) + randomSize) * 8) > kdf->limit)
|
||||
return 0;
|
||||
// Process partial and full blocks until all requested bytes provided
|
||||
while(bytesLeft > 0)
|
||||
{
|
||||
// If there is any residual data in the buffer, copy it to the output
|
||||
// buffer
|
||||
if(kdf->residual.t.size > 0)
|
||||
{
|
||||
INT32 size;
|
||||
//
|
||||
// Don't use more of the residual than will fit or more than are
|
||||
// available
|
||||
size = MIN(kdf->residual.t.size, bytesLeft);
|
||||
// Copy some or all of the residual to the output. The residual is
|
||||
// at the end of the buffer. The residual might be a full buffer.
|
||||
MemoryCopy(random,
|
||||
&kdf->residual.t.buffer
|
||||
[kdf->digestSize - kdf->residual.t.size], size);
|
||||
// Advance the buffer pointer
|
||||
random += size;
|
||||
// Reduce the number of bytes left to get
|
||||
bytesLeft -= size;
|
||||
// And reduce the residual size appropriately
|
||||
kdf->residual.t.size -= (UINT16)size;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 blocks = (UINT16)(bytesLeft / kdf->digestSize);
|
||||
//
|
||||
// Get the number of required full blocks
|
||||
if(blocks > 0)
|
||||
{
|
||||
UINT16 size = blocks * kdf->digestSize;
|
||||
// Get some number of full blocks and put them in the return buffer
|
||||
CryptKDFa(kdf->hash, kdf->seed, kdf->label, kdf->context, NULL,
|
||||
kdf->limit, random, &counter, blocks);
|
||||
// reduce the size remaining to be moved and advance the pointer
|
||||
bytesLeft -= size;
|
||||
random += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fill the residual buffer with a full block and then loop to
|
||||
// top to get part of it copied to the output.
|
||||
kdf->residual.t.size = CryptKDFa(kdf->hash, kdf->seed,
|
||||
kdf->label, kdf->context, NULL,
|
||||
kdf->limit,
|
||||
kdf->residual.t.buffer,
|
||||
&counter, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
kdf->counter = counter;
|
||||
return randomSize;
|
||||
}
|
||||
else if(state->drbg.magic == DRBG_MAGIC)
|
||||
@ -762,6 +821,7 @@ DRBG_Uninstantiate(
|
||||
/* This function generates a value that as not larger than (2^max) - 1 and no smaller than 2^(min -
|
||||
1). For example, if max == 4 and min == 2, then the number will be between 0x0010 and 0x1111
|
||||
inclusively. If max == 4 and min == 4 then the number will be between 0x1000 and 0x1111. */
|
||||
#if 0
|
||||
LIB_EXPORT NUMBYTES
|
||||
CryptRandMinMax(
|
||||
BYTE *out,
|
||||
@ -780,3 +840,4 @@ CryptRandMinMax(
|
||||
BnToBytes(bn, out, &size);
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* implementation of cryptographic primitives for RSA */
|
||||
/* Implementation of cryptographic primitives for RSA */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptRsa.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptRsa.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -410,12 +410,12 @@ OaepDecode(
|
||||
dataOut->size = 0;
|
||||
return retVal;
|
||||
}
|
||||
/* 10.2.19.4.7 PKSC1v1_5Encode() */
|
||||
/* 10.2.19.4.7 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 */
|
||||
static TPM_RC
|
||||
RSAES_PKSC1v1_5Encode(
|
||||
RSAES_PKCS1v1_5Encode(
|
||||
TPM2B *padded, // OUT: the pad data
|
||||
TPM2B *message, // IN: the message being padded
|
||||
RAND_STATE *rand
|
||||
@ -638,7 +638,7 @@ static TPM_RC
|
||||
RSASSA_Encode(
|
||||
TPM2B *pOut, // IN:OUT on in, the size of the public key
|
||||
// on out, the encoded area
|
||||
TPM_ALG_ID hashAlg, // IN: hash algorithm for PKSC1v1_5
|
||||
TPM_ALG_ID hashAlg, // IN: hash algorithm for PKCS1v1_5
|
||||
TPM2B *hIn // IN: digest value to encode
|
||||
)
|
||||
{
|
||||
@ -863,7 +863,7 @@ CryptRsaEncrypt(
|
||||
}
|
||||
break;
|
||||
case TPM_ALG_RSAES:
|
||||
retVal = RSAES_PKSC1v1_5Encode(&cOut->b, dIn, rand);
|
||||
retVal = RSAES_PKCS1v1_5Encode(&cOut->b, dIn, rand);
|
||||
break;
|
||||
case TPM_ALG_OAEP:
|
||||
retVal = OaepEncode(&cOut->b, scheme->details.oaep.hashAlg, label, dIn,
|
||||
@ -1143,7 +1143,7 @@ CryptRsaGenerateKey(
|
||||
}
|
||||
retVal = TPM_RC_SUCCESS;
|
||||
// Do a trial encryption decryption if this is a signing key
|
||||
if(publicArea->objectAttributes.sign)
|
||||
if(IS_ATTRIBUTE(publicArea->objectAttributes, TPMA_OBJECT, sign))
|
||||
{
|
||||
BN_RSA(temp1);
|
||||
BN_RSA(temp2);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Symmetric block cipher modes */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: CryptSym.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: CryptSym.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -59,98 +59,15 @@
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
/* 10.2.20 CryptSym.c */
|
||||
/* 10.2.20.1 Introduction */
|
||||
/* 10.2.19 CryptSym.c */
|
||||
/* 10.2.19.1 Introduction */
|
||||
/* This file contains the implementation of the symmetric block cipher modes allowed for a
|
||||
TPM. These functions only use the single block encryption functions of the selected symmetric
|
||||
crypto library. */
|
||||
/* 10.2.20.2 Includes, Defines, and Typedefs */
|
||||
/* 10.2.19.2 Includes, Defines, and Typedefs */
|
||||
#include "Tpm.h"
|
||||
union tpmCryptKeySchedule_t {
|
||||
#ifdef TPM_ALG_AES
|
||||
tpmKeyScheduleAES AES;
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM4
|
||||
tpmKeyScheduleSM4 SM4;
|
||||
#endif
|
||||
#ifdef TPM_ALG_CAMELLIA
|
||||
tpmKeyScheduleCAMELLIA CAMELLIA;
|
||||
#endif
|
||||
#ifdef TPM_ALG_TDES
|
||||
tpmKeyScheduleTDES TDES[3];
|
||||
#endif
|
||||
#if SYMMETRIC_ALIGNMENT == 8
|
||||
uint64_t alignment;
|
||||
#else
|
||||
uint32_t alignment;
|
||||
#endif
|
||||
};
|
||||
/* Each block cipher within a library is expected to conform to the same calling conventions with
|
||||
three parameters (keySchedule, in, and out) in the same order. That means that all algorithms
|
||||
would use the same order of the same parameters. The code is written assuming the (keySchedule,
|
||||
in, and out) order. However, if the library uses a different order, the order can be changed with
|
||||
a SWIZZLE macro that puts the parameters in the correct order. Note that all algorithms have to
|
||||
use the same order and number of parameters because the code to build the calling list is common
|
||||
for each call to encrypt or decrypt with the algorithm chosen by setting a function pointer to
|
||||
select the algorithm that is used. */
|
||||
# define ENCRYPT(keySchedule, in, out) \
|
||||
encrypt(SWIZZLE(keySchedule, in, out))
|
||||
# define DECRYPT(keySchedule, in, out) \
|
||||
decrypt(SWIZZLE(keySchedule, in, out))
|
||||
/* Note that the macros rely on encrypt as local values in the functions that use these
|
||||
macros. Those parameters are set by the macro that set the key schedule to be used for the
|
||||
call. */
|
||||
#define ENCRYPT_CASE(ALG) \
|
||||
case TPM_ALG_##ALG: \
|
||||
TpmCryptSetEncryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \
|
||||
encrypt = (TpmCryptSetSymKeyCall_t)TpmCryptEncrypt##ALG; \
|
||||
break;
|
||||
#define DECRYPT_CASE(ALG) \
|
||||
case TPM_ALG_##ALG: \
|
||||
TpmCryptSetDecryptKey##ALG(key, keySizeInBits, &keySchedule.ALG); \
|
||||
decrypt = (TpmCryptSetSymKeyCall_t)TpmCryptDecrypt##ALG; \
|
||||
break;
|
||||
#ifdef TPM_ALG_AES
|
||||
#define ENCRYPT_CASE_AES ENCRYPT_CASE(AES)
|
||||
#define DECRYPT_CASE_AES DECRYPT_CASE(AES)
|
||||
#else
|
||||
#define ENCRYPT_CASE_AES
|
||||
#define DECRYPT_CASE_AES
|
||||
#endif
|
||||
#ifdef TPM_ALG_SM4
|
||||
#define ENCRYPT_CASE_SM4 ENCRYPT_CASE(SM4)
|
||||
#define DECRYPT_CASE_SM4 DECRYPT_CASE(SM4)
|
||||
#else
|
||||
#define ENCRYPT_CASE_SM4
|
||||
#define DECRYPT_CASE_SM4
|
||||
#endif
|
||||
#ifdef TPM_ALG_CAMELLIA
|
||||
#define ENCRYPT_CASE_CAMELLIA ENCRYPT_CASE(CAMELLIA)
|
||||
#define DECRYPT_CASE_CAMELLIA DECRYPT_CASE(CAMELLIA)
|
||||
#else
|
||||
#define ENCRYPT_CASE_CAMELLIA
|
||||
#define DECRYPT_CASE_CAMELLIA
|
||||
#endif
|
||||
#ifdef TPM_ALG_TDES
|
||||
#define ENCRYPT_CASE_TDES ENCRYPT_CASE(TDES)
|
||||
#define DECRYPT_CASE_TDES DECRYPT_CASE(TDES)
|
||||
#else
|
||||
#define ENCRYPT_CASE_TDES
|
||||
#define DECRYPT_CASE_TDES
|
||||
#endif
|
||||
/* For each algorithm the case will either be defined or null. */
|
||||
#define SELECT(direction) \
|
||||
switch(algorithm) \
|
||||
{ \
|
||||
direction##_CASE_AES \
|
||||
direction##_CASE_SM4 \
|
||||
direction##_CASE_CAMELLIA \
|
||||
direction##_CASE_TDES \
|
||||
default: \
|
||||
return TPM_RC_FAILURE; \
|
||||
}
|
||||
/* 10.2.20.3 Obligatory Initialization Functions */
|
||||
/* 10.2.20.3.1 CryptSymInit() */
|
||||
#include "CryptSym.h"
|
||||
/* 10.2.19.3.1 CryptSymInit() */
|
||||
/* This function is called to do _TPM_Init() processing */
|
||||
BOOL
|
||||
CryptSymInit(
|
||||
@ -159,7 +76,7 @@ CryptSymInit(
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* 10.2.20.3.2 CryptSymStartup() */
|
||||
/* 10.2.19.3.2 CryptSymStartup() */
|
||||
/* This function is called to do TPM2_Startup() processing */
|
||||
BOOL
|
||||
CryptSymStartup(
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmToOsslDesSupport.c 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: TpmToOsslDesSupport.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* Used to splice the OpenSSL() hash code into the TPM code */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmToOsslHash.h 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: TpmToOsslHash.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -72,9 +72,10 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
/* Redefine the internal name used for each of the hash state structures to the name used by the
|
||||
library. These defines need to be known in all parts of the TPM so that the structure sizes
|
||||
can be properly computed when needed. */
|
||||
/* B.2.2.1.2. Links to the OpenSSL HASH code */
|
||||
/* Redefine the internal name used for each of the hash state structures to the name used by the
|
||||
library. These defines need to be known in all parts of the TPM so that the structure sizes can
|
||||
be properly computed when needed. */
|
||||
#define tpmHashStateSHA1_t SHA_CTX
|
||||
#define tpmHashStateSHA256_t SHA256_CTX
|
||||
#define tpmHashStateSHA384_t SHA512_CTX
|
||||
@ -82,9 +83,9 @@
|
||||
#ifdef TPM_ALG_SM3
|
||||
# error "The version of OpenSSL used by this code does not support SM3"
|
||||
#endif
|
||||
/* The defines below are only needed when compiling CryptHash.c. This isolation is primarily to
|
||||
avoid name space collision. However, if there is a real collision, it will likely show up
|
||||
when the linker tries to put things together. */
|
||||
/* The defines below are only needed when compiling CryptHash.c or CryptSmac.c. This isolation
|
||||
is primarily to avoid name space collision. However, if there is a real collision, it will
|
||||
likely show up when the linker tries to put things together. */
|
||||
#ifdef _CRYPT_HASH_C_
|
||||
typedef BYTE *PBYTE;
|
||||
typedef const BYTE *PCBYTE;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmToOsslMath.c 953 2017-03-06 20:31:40Z kgoldman $ */
|
||||
/* $Id: TpmToOsslMath.c 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -72,22 +72,6 @@
|
||||
#include "Tpm.h"
|
||||
#if MATH_LIB == OSSL
|
||||
#include "TpmToOsslMath_fp.h"
|
||||
/* B.2.3.2.3. Functions */
|
||||
#if 0
|
||||
INLINE void
|
||||
SetSizeOsslToTpm(
|
||||
bigNum a,
|
||||
BIGNUM *b
|
||||
)
|
||||
{
|
||||
if(a != NULL)
|
||||
{
|
||||
pAssert(((crypt_uword_t *)b->d == &a->d[0])
|
||||
&& ((unsigned)b->top <= a->allocated));
|
||||
a->size = b->top;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* B.2.3.2.3.1. OsslToTpmBn() */
|
||||
/* This function converts an OpenSSL() BIGNUM to a TPM bignum. In this implementation it is assumed
|
||||
that OpenSSL() used the same format for a big number as does the TPM -- an array of native-endian
|
||||
@ -220,8 +204,11 @@ BnModMult(
|
||||
pAssert(BnGetAllocated(result) >= BnGetSize(modulus));
|
||||
OK = BN_mul(bnTemp, bnOp1, bnOp2, CTX);
|
||||
OK = OK && BN_div(NULL, bnResult, bnTemp, bnMod, CTX);
|
||||
result->size = bnResult->top;
|
||||
OsslToTpmBn(result, bnResult);
|
||||
if(OK)
|
||||
{
|
||||
result->size = bnResult->top;
|
||||
OsslToTpmBn(result, bnResult);
|
||||
}
|
||||
OSSL_LEAVE();
|
||||
return OK;
|
||||
}
|
||||
@ -244,13 +231,17 @@ BnMult(
|
||||
(BITS_TO_CRYPT_WORDS(BnSizeInBits(multiplicand)
|
||||
+ BnSizeInBits(multiplier))));
|
||||
OK = BN_mul(bnTemp, bnA, bnB, CTX);
|
||||
OsslToTpmBn(temp, bnTemp);
|
||||
if(OK)
|
||||
{
|
||||
OsslToTpmBn(temp, bnTemp);
|
||||
BnCopy(result, temp);
|
||||
}
|
||||
OSSL_LEAVE();
|
||||
BnCopy(result, temp);
|
||||
return OK;
|
||||
}
|
||||
/* B.2.3.2.3.4. BnDiv() */
|
||||
/* This function divides two bigNum values. The function always returns TRUE. */
|
||||
/* This function divides two bigNum values. The function returns FALSE if there is an error in the
|
||||
operation. */
|
||||
LIB_EXPORT BOOL
|
||||
BnDiv(
|
||||
bigNum quotient,
|
||||
@ -282,8 +273,11 @@ BnDiv(
|
||||
pAssert((remainder == NULL)
|
||||
|| (remainder->allocated >= divisor->size));
|
||||
OK = BN_div(bnQ, bnR, bnDend, bnSor, CTX);
|
||||
OsslToTpmBn(quotient, bnQ);
|
||||
OsslToTpmBn(remainder, bnR);
|
||||
if(OK)
|
||||
{
|
||||
OsslToTpmBn(quotient, bnQ);
|
||||
OsslToTpmBn(remainder, bnR);
|
||||
}
|
||||
}
|
||||
DEBUG_PRINT("In BnDiv:\n");
|
||||
BIGNUM_PRINT(" bnDividend: ", bnDend, TRUE);
|
||||
@ -310,8 +304,11 @@ BnGcd(
|
||||
BOOL OK;
|
||||
pAssert(gcd != NULL);
|
||||
OK = BN_gcd(bnGcd, bn1, bn2, CTX);
|
||||
OsslToTpmBn(gcd, bnGcd);
|
||||
gcd->size = bnGcd->top;
|
||||
if(OK)
|
||||
{
|
||||
OsslToTpmBn(gcd, bnGcd);
|
||||
gcd->size = bnGcd->top;
|
||||
}
|
||||
OSSL_LEAVE();
|
||||
return OK;
|
||||
}
|
||||
@ -334,7 +331,10 @@ BnModExp(
|
||||
BOOL OK;
|
||||
//
|
||||
OK = BN_mod_exp(bnResult, bnN, bnE, bnM, CTX);
|
||||
OsslToTpmBn(result, bnResult);
|
||||
if(OK)
|
||||
{
|
||||
OsslToTpmBn(result, bnResult);
|
||||
}
|
||||
OSSL_LEAVE();
|
||||
return OK;
|
||||
}
|
||||
@ -353,7 +353,10 @@ BnModInverse(
|
||||
BIG_INITIALIZED(bnM, modulus);
|
||||
BOOL OK;
|
||||
OK = (BN_mod_inverse(bnResult, bnN, bnM, CTX) != NULL);
|
||||
OsslToTpmBn(result, bnResult);
|
||||
if(OK)
|
||||
{
|
||||
OsslToTpmBn(result, bnResult);
|
||||
}
|
||||
OSSL_LEAVE();
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmToOsslMath.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: TpmToOsslMath.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -73,7 +73,8 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
/* Make sure that the library is using the correct size for a crypt word */
|
||||
/* B.2.2.2.2. Macros and Defines */
|
||||
/* Make sure that the library is using the correct size for a crypt word */
|
||||
#if defined THIRTY_TWO_BIT && (RADIX_BITS != 32) \
|
||||
|| defined SIXTY_FOUR_BIT && (RADIX_BITS != 64)
|
||||
# error "Ossl library is using different radix"
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
/********************************************************************************/
|
||||
/* */
|
||||
/* */
|
||||
/* Splice the OpenSSL() library into the TPM code. */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: TpmToOsslSym.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: TpmToOsslSym.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* 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, 2017 */
|
||||
/* */
|
||||
/********************************************************************************/
|
||||
|
||||
@ -74,6 +74,7 @@
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
/* B.2.2.3.2. Links to the OpenSSL AES code */
|
||||
#ifdef TPM_ALG_SM4
|
||||
#error "SM4 is not available"
|
||||
#endif
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
/* */
|
||||
/* Written by Ken Goldman */
|
||||
/* IBM Thomas J. Watson Research Center */
|
||||
/* $Id: swap.h 809 2016-11-16 18:31:54Z kgoldman $ */
|
||||
/* $Id: swap.h 1047 2017-07-20 18:27:34Z kgoldman $ */
|
||||
/* */
|
||||
/* Licenses and Notices */
|
||||
/* */
|
||||
@ -62,7 +62,7 @@
|
||||
#ifndef SWAP_H
|
||||
#define SWAP_H
|
||||
|
||||
#if LITTLE_ENDIAN_TPM == YES
|
||||
#if LITTLE_ENDIAN_TPM
|
||||
#define TO_BIG_ENDIAN_UINT16(i) REVERSE_ENDIAN_16(i)
|
||||
#define FROM_BIG_ENDIAN_UINT16(i) REVERSE_ENDIAN_16(i)
|
||||
#define TO_BIG_ENDIAN_UINT32(i) REVERSE_ENDIAN_32(i)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user