1 // This file was extracted from the TCG Published 2 // Trusted Platform Module Library 3 // Part 4: Supporting Routines 4 // Family "2.0" 5 // Level 00 Revision 01.16 6 // October 30, 2014 7 8 #include "InternalRoutines.h" 9 #include "PP_fp.h" 10 11 // 12 // 13 // Functions 14 // 15 // PhysicalPresencePreInstall_Init() 16 // 17 // This function is used to initialize the array of commands that require confirmation with physical presence. 18 // The array is an array of bits that has a correspondence with the command code. 19 // This command should only ever be executable in a manufacturing setting or in a simulation. 20 // 21 void 22 PhysicalPresencePreInstall_Init( 23 void 24 ) 25 { 26 // Clear all the PP commands 27 MemorySet(&gp.ppList, 0, 28 // 29 ((TPM_CC_PP_LAST - TPM_CC_PP_FIRST + 1) + 7) / 8); 30 // TPM_CC_PP_Commands always requires PP 31 if(CommandIsImplemented(TPM_CC_PP_Commands)) 32 PhysicalPresenceCommandSet(TPM_CC_PP_Commands); 33 // Write PP list to NV 34 NvWriteReserved(NV_PP_LIST, &gp.ppList); 35 return; 36 } 37 // 38 // 39 // PhysicalPresenceCommandSet() 40 // 41 // This function is used to indicate a command that requires PP confirmation. 42 // 43 void 44 PhysicalPresenceCommandSet( 45 TPM_CC commandCode // IN: command code 46 ) 47 { 48 UINT32 bitPos; 49 // Assume command is implemented. It should be checked before this 50 // function is called 51 pAssert(CommandIsImplemented(commandCode)); 52 // If the command is not a PP command, ignore it 53 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST) 54 return; 55 bitPos = commandCode - TPM_CC_PP_FIRST; 56 // Set bit 57 gp.ppList[bitPos/8] |= 1 << (bitPos % 8); 58 return; 59 } 60 // 61 // 62 // PhysicalPresenceCommandClear() 63 // 64 // This function is used to indicate a command that no longer requires PP confirmation. 65 // 66 void 67 PhysicalPresenceCommandClear( 68 TPM_CC commandCode // IN: command code 69 ) 70 { 71 UINT32 bitPos; 72 // Assume command is implemented. It should be checked before this 73 // function is called 74 pAssert(CommandIsImplemented(commandCode)); 75 // If the command is not a PP command, ignore it 76 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST) 77 return; 78 // if the input code is TPM_CC_PP_Commands, it can not be cleared 79 if(commandCode == TPM_CC_PP_Commands) 80 return; 81 bitPos = commandCode - TPM_CC_PP_FIRST; 82 // Set bit 83 gp.ppList[bitPos/8] |= (1 << (bitPos % 8)); 84 // Flip it to off 85 gp.ppList[bitPos/8] ^= (1 << (bitPos % 8)); 86 return; 87 } 88 // 89 // 90 // PhysicalPresenceIsRequired() 91 // 92 // This function indicates if PP confirmation is required for a command. 93 // 94 // Return Value Meaning 95 // 96 // TRUE if physical presence is required 97 // FALSE if physical presence is not required 98 // 99 BOOL 100 PhysicalPresenceIsRequired( 101 TPM_CC commandCode // IN: command code 102 ) 103 { 104 UINT32 bitPos; 105 // if the input commandCode is not a PP command, return FALSE 106 if(commandCode < TPM_CC_PP_FIRST || commandCode > TPM_CC_PP_LAST) 107 return FALSE; 108 bitPos = commandCode - TPM_CC_PP_FIRST; 109 // Check the bit map. If the bit is SET, PP authorization is required 110 return ((gp.ppList[bitPos/8] & (1 << (bitPos % 8))) != 0); 111 } 112 // 113 // 114 // PhysicalPresenceCapGetCCList() 115 // 116 // This function returns a list of commands that require PP confirmation. The list starts from the first 117 // implemented command that has a command code that the same or greater than commandCode. 118 // 119 // Return Value Meaning 120 // 121 // YES if there are more command codes available 122 // NO all the available command codes have been returned 123 // 124 TPMI_YES_NO 125 PhysicalPresenceCapGetCCList( 126 TPM_CC commandCode, // IN: start command code 127 UINT32 count, // IN: count of returned TPM_CC 128 TPML_CC *commandList // OUT: list of TPM_CC 129 ) 130 { 131 TPMI_YES_NO more = NO; 132 UINT32 i; 133 // Initialize output handle list 134 commandList->count = 0; 135 // The maximum count of command we may return is MAX_CAP_CC 136 if(count > MAX_CAP_CC) count = MAX_CAP_CC; 137 // Collect PP commands 138 for(i = commandCode; i <= TPM_CC_PP_LAST; i++) 139 { 140 if(PhysicalPresenceIsRequired(i)) 141 { 142 if(commandList->count < count) 143 { 144 // If we have not filled up the return list, add this command 145 // code to it 146 commandList->commandCodes[commandList->count] = i; 147 commandList->count++; 148 } 149 else 150 { 151 // If the return list is full but we still have PP command 152 // available, report this and stop iterating 153 more = YES; 154 break; 155 } 156 } 157 } 158 return more; 159 } 160