From 7d31d5ae8ba4c1e7ff4ef527fa2955d0ccfe8ca1 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Wed, 27 Dec 2023 16:57:10 -0500 Subject: [PATCH] rev180: Add TPM2_SetCapability and dependencies This command does not do much at the moment and should therefore also not be enabled. Signed-off-by: Stefan Berger --- src/Makefile.am | 1 + src/tpm2/CapabilityCommands.c | 22 ++++++ src/tpm2/CommandAttributeData.h | 7 ++ src/tpm2/CommandDispatchData.h | 41 ++++++++++- src/tpm2/Marshal_fp.h | 11 ++- src/tpm2/RuntimeCommands.c | 3 +- src/tpm2/SetCapability_fp.h | 82 +++++++++++++++++++++ src/tpm2/TpmAlgorithmDefines.h | 1 + src/tpm2/TpmTypes.h | 17 ++++- src/tpm2/Unmarshal.c | 123 ++++++++++++++++++++++++++++++++ src/tpm2/Unmarshal_fp.h | 6 ++ tests/nvram_offsets.c | 2 +- 12 files changed, 311 insertions(+), 5 deletions(-) create mode 100644 src/tpm2/SetCapability_fp.h diff --git a/src/Makefile.am b/src/Makefile.am index fe2f5a2c..9a8d7e0d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -510,6 +510,7 @@ noinst_HEADERS += \ tpm2/Session_fp.h \ tpm2/SessionProcess_fp.h \ tpm2/SetAlgorithmSet_fp.h \ + tpm2/SetCapability_fp.h \ tpm2/SetCommandCodeAuditStatus_fp.h \ tpm2/SetPrimaryPolicy_fp.h \ tpm2/Shutdown_fp.h \ diff --git a/src/tpm2/CapabilityCommands.c b/src/tpm2/CapabilityCommands.c index cf7555ce..0ea86ea2 100644 --- a/src/tpm2/CapabilityCommands.c +++ b/src/tpm2/CapabilityCommands.c @@ -213,3 +213,25 @@ TPM2_TestParms( return TPM_RC_SUCCESS; } #endif // CC_TestParms + +#include "Tpm.h" +#include "SetCapability_fp.h" + +#if CC_SetCapability // Conditional expansion of this file + +/*(See part 3 specification) +// This command allows configuration of the TPM's capabilities. +*/ +// Return Type: TPM_RC +// TPM_RC_HANDLE value of 'property' is in an unsupported handle range +// for the TPM_CAP_HANDLES 'capability' value +// TPM_RC_VALUE invalid 'capability' +TPM_RC +TPM2_SetCapability(SetCapability_In* in // IN: input parameter list + ) +{ + // This reference implementation does not implement any settable capabilities. + return TPM_RCS_VALUE + SetCapability_setCapabilityData; +} + +#endif // CC_SetCapability diff --git a/src/tpm2/CommandAttributeData.h b/src/tpm2/CommandAttributeData.h index f2dbe8f3..eab4fad9 100644 --- a/src/tpm2/CommandAttributeData.h +++ b/src/tpm2/CommandAttributeData.h @@ -457,6 +457,9 @@ const TPMA_CC s_ccAttr [] = { #if (PAD_LIST || CC_NV_ReadPublic2) TPMA_CC_INITIALIZER(0x019E, 0, 0, 0, 0, 1, 0, 0, 0), #endif +#if (PAD_LIST || CC_SetCapability) + TPMA_CC_INITIALIZER(0x019F, 0, 1, 0, 0, 1, 0, 0, 0), +#endif #if (PAD_LIST || CC_Vendor_TCG_Test) TPMA_CC_INITIALIZER(0x0000, 0, 0, 0, 0, 0, 0, 1, 0), #endif @@ -974,6 +977,10 @@ const COMMAND_ATTRIBUTES s_commandAttributes [] = { (COMMAND_ATTRIBUTES)(CC_NV_ReadPublic2 * // 0x019E (IS_IMPLEMENTED+ENCRYPT_2)), #endif +#if (PAD_LIST || CC_SetCapability) + (COMMAND_ATTRIBUTES)(CC_SetCapability * // 0x019F + (IS_IMPLEMENTED+DECRYPT_2+HANDLE_1_USER)), +#endif #if (PAD_LIST || CC_Vendor_TCG_Test) (COMMAND_ATTRIBUTES)(CC_Vendor_TCG_Test * // 0x0000 (IS_IMPLEMENTED+DECRYPT_2+ENCRYPT_2)), diff --git a/src/tpm2/CommandDispatchData.h b/src/tpm2/CommandDispatchData.h index 2a224e74..539088b5 100644 --- a/src/tpm2/CommandDispatchData.h +++ b/src/tpm2/CommandDispatchData.h @@ -167,8 +167,10 @@ const _UNMARSHAL_T_ unmarshalArray[] = { #define TPM2B_SENSITIVE_DATA_P_UNMARSHAL \ (TPM2B_SENSITIVE_CREATE_P_UNMARSHAL + 1) UNMARSHAL_DISPATCH(TPM2B_SENSITIVE_DATA), +#define TPM2B_SET_CAPABILITY_DATA_P_UNMARSHAL (TPM2B_SENSITIVE_DATA_P_UNMARSHAL + 1) + UNMARSHAL_DISPATCH(TPM2B_SET_CAPABILITY_DATA), #define TPM2B_TEMPLATE_P_UNMARSHAL \ - (TPM2B_SENSITIVE_DATA_P_UNMARSHAL + 1) + (TPM2B_SET_CAPABILITY_DATA_P_UNMARSHAL + 1) UNMARSHAL_DISPATCH(TPM2B_TEMPLATE), #define TPM2B_TIMEOUT_P_UNMARSHAL (TPM2B_TEMPLATE_P_UNMARSHAL + 1) UNMARSHAL_DISPATCH(TPM2B_TIMEOUT), @@ -4216,6 +4218,40 @@ NV_ReadPublic2_COMMAND_DESCRIPTOR_t _NV_ReadPublic2Data = { #define _NV_ReadPublic2DataAddress 0 #endif // CC_NV_ReadPublic2 +#if CC_SetCapability +#include "SetCapability_fp.h" + +typedef TPM_RC (SetCapability_Entry)( + SetCapability_In* in + ); + +typedef const struct +{ + SetCapability_Entry *entry; + UINT16 inSize; + UINT16 outSize; + UINT16 offsetOfTypes; + UINT16 paramOffsets[1]; + BYTE types[4]; +} SetCapability_COMMAND_DESCRIPTOR_t; + +SetCapability_COMMAND_DESCRIPTOR_t _SetCapabilityData = { + /* entry */ &TPM2_SetCapability, + /* inSize */ (UINT16)(sizeof(SetCapability_In)), + /* outSize */ 0, + /* offsetOfTypes */ offsetof(SetCapability_COMMAND_DESCRIPTOR_t, types), + /* offsets */ {(UINT16)(offsetof(SetCapability_In, setCapabilityData))}, + /* types */ {TPMI_RH_HIERARCHY_H_UNMARSHAL, + TPM2B_SET_CAPABILITY_DATA_P_UNMARSHAL, + END_OF_LIST, + END_OF_LIST} +}; + +#define _SetCapabilityDataAddress (&_SetCapabilityData) +#else +#define _SetCapabilityDataAddress 0 +#endif // CC_SetCapability + #if CC_AC_GetCapability #include "AC_GetCapability_fp.h" typedef TPM_RC (AC_GetCapability_Entry)( @@ -4780,6 +4816,9 @@ COMMAND_DESCRIPTOR_t *s_CommandDataArray[] = { #if (PAD_LIST || CC_NV_ReadPublic2) (COMMAND_DESCRIPTOR_t*)_NV_ReadPublic2DataAddress, #endif // CC_NV_ReadPublic2 +#if (PAD_LIST || CC_SetCapability) + (COMMAND_DESCRIPTOR_t*)_SetCapabilityDataAddress, +#endif // CC_SetCapability #if (PAD_LIST || CC_Vendor_TCG_Test) (COMMAND_DESCRIPTOR_t *)_Vendor_TCG_TestDataAddress, #endif diff --git a/src/tpm2/Marshal_fp.h b/src/tpm2/Marshal_fp.h index 05c660bf..f29d05d3 100644 --- a/src/tpm2/Marshal_fp.h +++ b/src/tpm2/Marshal_fp.h @@ -407,7 +407,16 @@ extern "C" { TPMS_AC_OUTPUT_Marshal(TPMS_AC_OUTPUT *source, BYTE **buffer, INT32 *size); UINT16 TPML_AC_CAPABILITIES_Marshal(TPML_AC_CAPABILITIES *source, BYTE **buffer, INT32 *size); - + UINT16 + TPMU_CAPABILITIES_Marshal(TPMU_CAPABILITIES* source, BYTE** buffer, INT32* size, UINT32 selector); + UINT16 + TPMS_CAPABILITY_DATA_Marshal(TPMS_CAPABILITY_DATA* source, BYTE** buffer, INT32* size); + TPM_RC + TPMU_SET_CAPABILITIES_Unmarshal(TPMU_SET_CAPABILITIES* target, BYTE** buffer, INT32* size, UINT32 selector); + TPM_RC + TPMS_SET_CAPABILITY_DATA_Unmarshal(TPMS_SET_CAPABILITY_DATA* target, BYTE** buffer, INT32* size); + TPM_RC + TPM2B_SET_CAPABILITY_DATA_Unmarshal(TPM2B_SET_CAPABILITY_DATA* target, BYTE** buffer, INT32* size); #ifdef __cplusplus } #endif diff --git a/src/tpm2/RuntimeCommands.c b/src/tpm2/RuntimeCommands.c index 5d95483e..9f3f682c 100644 --- a/src/tpm2/RuntimeCommands.c +++ b/src/tpm2/RuntimeCommands.c @@ -190,10 +190,11 @@ static const struct { COMMAND(PolicyParameters, true, 0), // not supported COMMAND(NV_DefineSpace2, true, 0), // not supported COMMAND(NV_ReadPublic2, true, 0), // not supported + COMMAND(SetCapability, true, 0), // not supported /* all new commands added here MUST have CAN_BE_DISABLE = true */ #undef COMMAND }; -MUST_BE(TPM_CC_LAST == TPM_CC_NV_ReadPublic2); /* force update of above list when new commands added */ +MUST_BE(TPM_CC_LAST == TPM_CC_SetCapability); /* force update of above list when new commands added */ static void RuntimeCommandsEnableAllCommands(struct RuntimeCommands *RuntimeCommands, diff --git a/src/tpm2/SetCapability_fp.h b/src/tpm2/SetCapability_fp.h new file mode 100644 index 00000000..2ede14da --- /dev/null +++ b/src/tpm2/SetCapability_fp.h @@ -0,0 +1,82 @@ +/********************************************************************************/ +/* */ +/* */ +/* Written by Ken Goldman */ +/* IBM Thomas J. Watson Research Center */ +/* */ +/* 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, 2023 */ +/* */ +/********************************************************************************/ + +#if CC_SetCapability // Command must be enabled + +# ifndef SETCAPABILITY_FP_H +# define SETCAPABILITY_FP_H + +// Input structure definition +typedef struct +{ + TPMI_RH_HIERARCHY authHandle; + TPM2B_SET_CAPABILITY_DATA setCapabilityData; +} SetCapability_In; + +// Response code modifiers +# define SetCapability_authHandle (TPM_RC_H + TPM_RC_1) +# define SetCapability_setCapabilityData (TPM_RC_P + TPM_RC_1) + +// Function prototype +TPM_RC TPM2_SetCapability(SetCapability_In* in); + +# endif // SETCAPABILITY_FP_H +#endif // CC_SetCapability + diff --git a/src/tpm2/TpmAlgorithmDefines.h b/src/tpm2/TpmAlgorithmDefines.h index b6bd98d1..a83a9d0f 100644 --- a/src/tpm2/TpmAlgorithmDefines.h +++ b/src/tpm2/TpmAlgorithmDefines.h @@ -348,6 +348,7 @@ + (ADD_FILL || CC_PolicyParameters) /* 0x0000019C */ \ + (ADD_FILL || CC_NV_DefineSpace2) /* 0x0000019D */ \ + (ADD_FILL || CC_NV_ReadPublic2) /* 0x0000019E */ \ + + (ADD_FILL || CC_SetCapability) /* 0x0000019F */ \ ) #define VENDOR_COMMAND_ARRAY_SIZE (0 + CC_Vendor_TCG_Test) diff --git a/src/tpm2/TpmTypes.h b/src/tpm2/TpmTypes.h index 936dadba..eb545729 100644 --- a/src/tpm2/TpmTypes.h +++ b/src/tpm2/TpmTypes.h @@ -306,7 +306,8 @@ typedef UINT32 TPM_CC; #define TPM_CC_PolicyParameters (TPM_CC)(0x0000019C) #define TPM_CC_NV_DefineSpace2 (TPM_CC)(0x0000019D) #define TPM_CC_NV_ReadPublic2 (TPM_CC)(0x0000019E) -#define TPM_CC_LAST (TPM_CC)(0x0000019E) +#define TPM_CC_SetCapability (TPM_CC)(0x0000019F) +#define TPM_CC_LAST (TPM_CC)(0x0000019F) #define CC_VEND 0x20000000 #define TPM_CC_Vendor_TCG_Test (TPM_CC)(0x20000000) @@ -1609,11 +1610,25 @@ typedef union { TPML_TAGGED_POLICY authPolicies; TPML_ACT_DATA actData; } TPMU_CAPABILITIES; +/* NOTE The TPMU_SET_CAPABILITIES structure may be defined by a TCG Registry. */ +typedef struct { + UINT32 platformSpecific; +} TPMU_SET_CAPABILITIES; /* Table 2:111 - Definition of TPMS_CAPABILITY_DATA Structure */ typedef struct { TPM_CAP capability; TPMU_CAPABILITIES data; } TPMS_CAPABILITY_DATA; +/* Table 129 - Definition of TPMS_SET_CAPABILITY_DATA Structure */ +typedef struct { + TPM_CAP setCapability; + TPMU_SET_CAPABILITIES data; +} TPMS_SET_CAPABILITY_DATA; +/* Table 130 - Definition of TPM2B_SET_CAPABILITY_DATA Structure */ +typedef struct { + UINT16 size; + TPMS_SET_CAPABILITY_DATA setCapabilityData; +} TPM2B_SET_CAPABILITY_DATA; /* Table 2:112 - Definition of TPMS_CLOCK_INFO Structure */ typedef struct { UINT64 clock; diff --git a/src/tpm2/Unmarshal.c b/src/tpm2/Unmarshal.c index be1ca45e..3d578613 100644 --- a/src/tpm2/Unmarshal.c +++ b/src/tpm2/Unmarshal.c @@ -2437,6 +2437,9 @@ TPML_TAGGED_POLICY_Unmarshal(TPML_TAGGED_POLICY *target, BYTE **buffer, INT32 *s return rc; } +#endif // libtpms added + + /* Table 2:110 - Definition of TPMU_CAPABILITIES Union (StructuresTable()) */ #if 0 @@ -2501,6 +2504,69 @@ TPMS_CAPABILITY_DATA_Unmarshal(TPMS_CAPABILITY_DATA *target, BYTE **buffer, INT3 } #endif +/* NOTE The TPMU_SET_CAPABILITIES structure may be defined by a TCG Registry. */ +TPM_RC +TPMU_SET_CAPABILITIES_Unmarshal(TPMU_SET_CAPABILITIES *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { + default: + rc = TPM_RC_SELECTOR; + } + return rc; +} + +/* Table 129 - Definition of TPMS_SET_CAPABILITY_DATA Structure */ +TPM_RC +TPMS_SET_CAPABILITY_DATA_Unmarshal(TPMS_SET_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_CAP_Unmarshal(&target->setCapability, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMU_SET_CAPABILITIES_Unmarshal(&target->data, buffer, size, target->setCapability); + } + return rc; +} + +/* Table 130 - Definition of TPM2B_SET_CAPABILITY_DATA Structure */ +TPM_RC +TPM2B_SET_CAPABILITY_DATA_Unmarshal(TPM2B_SET_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + INT32 startSize; + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(&target->size, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->size == 0) { + rc = TPM_RC_SIZE; + } + } + if (rc == TPM_RC_SUCCESS) { + startSize = *size; + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMS_SET_CAPABILITY_DATA_Unmarshal(&target->setCapabilityData, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; + } + } + return rc; +} + +#if 0 // libtpms added +typedef struct { + UINT16 size; + TPMS_SET_CAPABILITY_DATA setCapabilityData; +} TPM2B_SET_CAPABILITY_DATA; + /* Table 109 - Definition of TPMS_CLOCK_INFO Structure */ TPM_RC @@ -4906,3 +4972,60 @@ TPM_AT_Unmarshal(TPM_AT *target, BYTE **buffer, INT32 *size) } return rc; } + +#if 0 // libtpms added +TPM_RC +TPMU_SET_CAPABILITIES_Unmarshal(TPMU_SET_CAPABILITIES *target, BYTE **buffer, INT32 *size, UINT32 selector) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + switch (selector) { + default: + rc = TPM_RC_SELECTOR; + } + return rc; +} + +TPM_RC +TPMS_SET_CAPABILITY_DATA_Unmarshal(TPMS_SET_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + if (rc == TPM_RC_SUCCESS) { + rc = TPM_CAP_Unmarshal(&target->setCapability, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMU_SET_CAPABILITIES_Unmarshal(&target->data, buffer, size, target->setCapability); + } + return rc; +} + +TPM_RC +TPM2B_SET_CAPABILITY_DATA_Unmarshal(TPM2B_SET_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size) +{ + TPM_RC rc = TPM_RC_SUCCESS; + + INT32 startSize; + if (rc == TPM_RC_SUCCESS) { + rc = UINT16_Unmarshal(&target->size, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->size == 0) { + rc = TPM_RC_SIZE; + } + } + if (rc == TPM_RC_SUCCESS) { + startSize = *size; + } + if (rc == TPM_RC_SUCCESS) { + rc = TPMS_SET_CAPABILITY_DATA_Unmarshal(&target->setCapabilityData, buffer, size); + } + if (rc == TPM_RC_SUCCESS) { + if (target->size != startSize - *size) { + rc = TPM_RC_SIZE; + } + } + return rc; +} +#endif // libtpms added + diff --git a/src/tpm2/Unmarshal_fp.h b/src/tpm2/Unmarshal_fp.h index d1ebb92c..1fc44e60 100644 --- a/src/tpm2/Unmarshal_fp.h +++ b/src/tpm2/Unmarshal_fp.h @@ -300,6 +300,12 @@ extern "C" { LIB_EXPORT TPM_RC TPMS_CAPABILITY_DATA_Unmarshal(TPMS_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size); #endif /* libtpms added */ + LIB_EXPORT TPM_RC + TPMU_SET_CAPABILITIES_Unmarshal(TPMU_SET_CAPABILITIES *target, BYTE **buffer, INT32 *size, UINT32 selector); + LIB_EXPORT TPM_RC + TPMS_SET_CAPABILITY_DATA_Unmarshal(TPMS_SET_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size); + LIB_EXPORT TPM_RC + TPM2B_SET_CAPABILITY_DATA_Unmarshal(TPM2B_SET_CAPABILITY_DATA *target, BYTE **buffer, INT32 *size); LIB_EXPORT TPM_RC TPMI_AES_KEY_BITS_Unmarshal(TPMI_AES_KEY_BITS *target, BYTE **buffer, INT32 *size); #if ALG_SM4 /* libtpms added begin */ diff --git a/tests/nvram_offsets.c b/tests/nvram_offsets.c index b66e8661..91648951 100644 --- a/tests/nvram_offsets.c +++ b/tests/nvram_offsets.c @@ -12,7 +12,7 @@ int main(void) /* Check size of ppList that expands with new commands */ /* was 14 when COMPRESSED_LISTS was enabled */ -#define PD_PP_LIST_EXP_SIZE 16 +#define PD_PP_LIST_EXP_SIZE 17 if (sizeof(pd.ppList) != PD_PP_LIST_EXP_SIZE) { fprintf(stderr, "sizeof(PERSISTENT_DATA.ppList) does not have expected size "