mirror of
https://github.com/stefanberger/libtpms
synced 2025-08-26 13:14:36 +00:00
Compare commits
1 Commits
0fe563cc64
...
7366dd75c9
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7366dd75c9 |
@ -60,158 +60,45 @@
|
||||
|
||||
#include "Tpm.h"
|
||||
#include "NV_DefineSpace_fp.h"
|
||||
|
||||
#if CC_NV_DefineSpace // Conditional expansion of this file
|
||||
|
||||
/*(See part 3 specification)
|
||||
// Define a NV index space
|
||||
*/
|
||||
// Return Type: TPM_RC
|
||||
// TPM_RC_HIERARCHY for authorizations using TPM_RH_PLATFORM
|
||||
// phEnable_NV is clear preventing access to NV
|
||||
// data in the platform hierarchy.
|
||||
// TPM_RC_ATTRIBUTES attributes of the index are not consistent
|
||||
// TPM_RC_NV_DEFINED index already exists
|
||||
// TPM_RC_NV_SPACE insufficient space for the index
|
||||
// TPM_RC_SIZE 'auth->size' or 'publicInfo->authPolicy.size' is
|
||||
// larger than the digest size of
|
||||
// 'publicInfo->nameAlg'; or 'publicInfo->dataSize'
|
||||
// is not consistent with 'publicInfo->attributes'
|
||||
// (this includes the case when the index is
|
||||
// larger than a MAX_NV_BUFFER_SIZE but the
|
||||
// TPMA_NV_WRITEALL attribute is SET)
|
||||
TPM_RC
|
||||
TPM2_NV_DefineSpace(
|
||||
NV_DefineSpace_In *in // IN: input parameter list
|
||||
)
|
||||
{
|
||||
TPMA_NV attributes = in->publicInfo.nvPublic.attributes;
|
||||
UINT16 nameSize;
|
||||
nameSize = CryptHashGetDigestSize(in->publicInfo.nvPublic.nameAlg);
|
||||
// Input Validation
|
||||
// Checks not specific to type
|
||||
// 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(IS_ATTRIBUTE(attributes, TPMA_NV, POLICY_DELETE))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
#endif
|
||||
// check that the authPolicy consistent with hash algorithm
|
||||
if(in->publicInfo.nvPublic.authPolicy.t.size != 0
|
||||
&& in->publicInfo.nvPublic.authPolicy.t.size != nameSize)
|
||||
return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
|
||||
// make sure that the authValue is not too large
|
||||
if(MemoryRemoveTrailingZeros(&in->auth)
|
||||
> CryptHashGetDigestSize(in->publicInfo.nvPublic.nameAlg))
|
||||
return TPM_RCS_SIZE + RC_NV_DefineSpace_auth;
|
||||
// If an index is being created by the owner and shEnable is
|
||||
// clear, then we would not reach this point because ownerAuth
|
||||
// can't be given when shEnable is CLEAR. However, if phEnable
|
||||
// is SET but phEnableNV is CLEAR, we have to check here
|
||||
if(in->authHandle == TPM_RH_PLATFORM && gc.phEnableNV == CLEAR)
|
||||
return TPM_RCS_HIERARCHY + RC_NV_DefineSpace_authHandle;
|
||||
// Attribute checks
|
||||
// Eliminate the unsupported types
|
||||
switch(GET_TPM_NT(attributes))
|
||||
{
|
||||
#if CC_NV_Increment == YES
|
||||
case TPM_NT_COUNTER:
|
||||
#endif
|
||||
#if CC_NV_SetBits == YES
|
||||
case TPM_NT_BITS:
|
||||
#endif
|
||||
#if CC_NV_Extend == YES
|
||||
case TPM_NT_EXTEND:
|
||||
#endif
|
||||
#if CC_PolicySecret == YES && defined TPM_NT_PIN_PASS
|
||||
case TPM_NT_PIN_PASS:
|
||||
case TPM_NT_PIN_FAIL:
|
||||
#endif
|
||||
case TPM_NT_ORDINARY:
|
||||
break;
|
||||
default:
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
break;
|
||||
}
|
||||
// Check that the sizes are OK based on the type
|
||||
switch(GET_TPM_NT(attributes))
|
||||
{
|
||||
case TPM_NT_ORDINARY:
|
||||
// Can't exceed the allowed size for the implementation
|
||||
if(in->publicInfo.nvPublic.dataSize > MAX_NV_INDEX_SIZE)
|
||||
return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
|
||||
break;
|
||||
case TPM_NT_EXTEND:
|
||||
if(in->publicInfo.nvPublic.dataSize != nameSize)
|
||||
return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
|
||||
break;
|
||||
default:
|
||||
// Everything else needs a size of 8
|
||||
if(in->publicInfo.nvPublic.dataSize != 8)
|
||||
return TPM_RCS_SIZE + RC_NV_DefineSpace_publicInfo;
|
||||
break;
|
||||
}
|
||||
// Handle other specifics
|
||||
switch(GET_TPM_NT(attributes))
|
||||
{
|
||||
case TPM_NT_COUNTER:
|
||||
// Counter can't have TPMA_NV_CLEAR_STCLEAR SET (don't clear counters)
|
||||
if(IS_ATTRIBUTE(attributes, TPMA_NV, CLEAR_STCLEAR))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
break;
|
||||
#ifdef TPM_NT_PIN_FAIL
|
||||
case TPM_NT_PIN_FAIL:
|
||||
// NV_NO_DA must be SET and AUTHWRITE must be CLEAR
|
||||
// NOTE: As with a PIN_PASS index, the authValue of the index is not
|
||||
// available until the index is written. If AUTHWRITE is the only way to
|
||||
// write then index, it could never be written. Rather than go through
|
||||
// all of the other possible ways to write the Index, it is simply
|
||||
// prohibited to write the index with the authValue. Other checks
|
||||
// below will insure that there seems to be a way to write the index
|
||||
// (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(!IS_ATTRIBUTE(attributes, TPMA_NV, NO_DA))
|
||||
return TPM_RCS_ATTRIBUTES + RC_NV_DefineSpace_publicInfo;
|
||||
#endif
|
||||
#ifdef TPM_NT_PIN_PASS
|
||||
/* fallthrough */ // libtpms moved
|
||||
case TPM_NT_PIN_PASS:
|
||||
// AUTHWRITE must be CLEAR (see note above to TPM_NT_PIN_FAIL)
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Locks may not be SET and written cannot be SET
|
||||
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(!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(!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(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((IS_ATTRIBUTE(attributes, TPMA_NV, PLATFORMCREATE)
|
||||
&& in->authHandle == TPM_RH_OWNER)
|
||||
|| (!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(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
|
||||
&& 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))
|
||||
return TPM_RC_NV_DEFINED;
|
||||
// Internal Data Update
|
||||
// define the space. A TPM_RC_NV_SPACE error may be returned at this point
|
||||
return NvDefineIndex(&in->publicInfo.nvPublic, &in->auth);
|
||||
// This command only supports TPM_HT_NV_INDEX-typed NV indices.
|
||||
if(HandleGetType(in->publicInfo.nvPublic.nvIndex) != TPM_HT_NV_INDEX)
|
||||
{
|
||||
return TPM_RCS_HANDLE + RC_NV_DefineSpace_publicInfo;
|
||||
}
|
||||
|
||||
return NvDefineSpace(in->authHandle,
|
||||
&in->auth,
|
||||
&in->publicInfo.nvPublic,
|
||||
RC_NV_DefineSpace_authHandle,
|
||||
RC_NV_DefineSpace_auth,
|
||||
RC_NV_DefineSpace_publicInfo);
|
||||
}
|
||||
|
||||
#endif // CC_NV_DefineSpace
|
||||
#include "Tpm.h"
|
||||
#include "NV_UndefineSpace_fp.h"
|
||||
|
@ -334,6 +334,7 @@ TPM_RC NvPublicFromNvPublic2(
|
||||
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
#endif // libtpms added
|
||||
|
||||
//*** NvDefineSpace()
|
||||
// This function combines the common functionality of TPM2_NV_DefineSpace and
|
||||
@ -507,4 +508,3 @@ TPM_RC NvDefineSpace(TPMI_RH_PROVISION authHandle,
|
||||
// define the space. A TPM_RC_NV_SPACE error may be returned at this point
|
||||
return NvDefineIndex(publicInfo, auth);
|
||||
}
|
||||
#endif // libtpms added
|
||||
|
Loading…
Reference in New Issue
Block a user