1 /** @file 2 Implement TPM1.2 NV storage related command. 3 4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved. <BR> 5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include <PiPei.h> 17 #include <Library/Tpm12CommandLib.h> 18 #include <Library/BaseLib.h> 19 #include <Library/DebugLib.h> 20 #include <Library/BaseMemoryLib.h> 21 #include <Library/Tpm12DeviceLib.h> 22 23 // 24 // Max TPM NV value length 25 // 26 #define TPMNVVALUELENGTH 1024 27 28 #pragma pack(1) 29 30 typedef struct { 31 TPM_RQU_COMMAND_HDR Hdr; 32 TPM12_NV_DATA_PUBLIC PubInfo; 33 TPM_ENCAUTH EncAuth; 34 } TPM_CMD_NV_DEFINE_SPACE; 35 36 typedef struct { 37 TPM_RQU_COMMAND_HDR Hdr; 38 TPM_NV_INDEX NvIndex; 39 UINT32 Offset; 40 UINT32 DataSize; 41 } TPM_CMD_NV_READ_VALUE; 42 43 typedef struct { 44 TPM_RSP_COMMAND_HDR Hdr; 45 UINT32 DataSize; 46 UINT8 Data[TPMNVVALUELENGTH]; 47 } TPM_RSP_NV_READ_VALUE; 48 49 typedef struct { 50 TPM_RQU_COMMAND_HDR Hdr; 51 TPM_NV_INDEX NvIndex; 52 UINT32 Offset; 53 UINT32 DataSize; 54 UINT8 Data[TPMNVVALUELENGTH]; 55 } TPM_CMD_NV_WRITE_VALUE; 56 57 #pragma pack() 58 59 /** 60 Send NV DefineSpace command to TPM1.2. 61 62 @param PubInfo The public parameters of the NV area. 63 @param EncAuth The encrypted AuthData, only valid if the attributes require subsequent authorization. 64 65 @retval EFI_SUCCESS Operation completed successfully. 66 @retval EFI_DEVICE_ERROR Unexpected device behavior. 67 **/ 68 EFI_STATUS 69 EFIAPI 70 Tpm12NvDefineSpace ( 71 IN TPM12_NV_DATA_PUBLIC *PubInfo, 72 IN TPM_ENCAUTH *EncAuth 73 ) 74 { 75 EFI_STATUS Status; 76 TPM_CMD_NV_DEFINE_SPACE Command; 77 TPM_RSP_COMMAND_HDR Response; 78 UINT32 Length; 79 80 // 81 // send Tpm command TPM_ORD_NV_DefineSpace 82 // 83 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 84 Command.Hdr.paramSize = SwapBytes32 (sizeof (Command)); 85 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_DefineSpace); 86 Command.PubInfo.tag = SwapBytes16 (PubInfo->tag); 87 Command.PubInfo.nvIndex = SwapBytes32 (PubInfo->nvIndex); 88 Command.PubInfo.pcrInfoRead.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoRead.pcrSelection.sizeOfSelect); 89 Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[0]; 90 Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[1]; 91 Command.PubInfo.pcrInfoRead.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoRead.pcrSelection.pcrSelect[2]; 92 Command.PubInfo.pcrInfoRead.localityAtRelease = PubInfo->pcrInfoRead.localityAtRelease; 93 CopyMem (&Command.PubInfo.pcrInfoRead.digestAtRelease, &PubInfo->pcrInfoRead.digestAtRelease, sizeof(PubInfo->pcrInfoRead.digestAtRelease)); 94 Command.PubInfo.pcrInfoWrite.pcrSelection.sizeOfSelect = SwapBytes16 (PubInfo->pcrInfoWrite.pcrSelection.sizeOfSelect); 95 Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[0] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[0]; 96 Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[1] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[1]; 97 Command.PubInfo.pcrInfoWrite.pcrSelection.pcrSelect[2] = PubInfo->pcrInfoWrite.pcrSelection.pcrSelect[2]; 98 Command.PubInfo.pcrInfoWrite.localityAtRelease = PubInfo->pcrInfoWrite.localityAtRelease; 99 CopyMem (&Command.PubInfo.pcrInfoWrite.digestAtRelease, &PubInfo->pcrInfoWrite.digestAtRelease, sizeof(PubInfo->pcrInfoWrite.digestAtRelease)); 100 Command.PubInfo.permission.tag = SwapBytes16 (PubInfo->permission.tag); 101 Command.PubInfo.permission.attributes = SwapBytes32 (PubInfo->permission.attributes); 102 Command.PubInfo.bReadSTClear = PubInfo->bReadSTClear; 103 Command.PubInfo.bWriteSTClear = PubInfo->bWriteSTClear; 104 Command.PubInfo.bWriteDefine = PubInfo->bWriteDefine; 105 Command.PubInfo.dataSize = SwapBytes32 (PubInfo->dataSize); 106 CopyMem (&Command.EncAuth, EncAuth, sizeof(*EncAuth)); 107 Length = sizeof (Response); 108 Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); 109 if (EFI_ERROR (Status)) { 110 return Status; 111 } 112 DEBUG ((DEBUG_INFO, "Tpm12NvDefineSpace - ReturnCode = %x\n", SwapBytes32 (Response.returnCode))); 113 switch (SwapBytes32 (Response.returnCode)) { 114 case TPM_SUCCESS: 115 return EFI_SUCCESS; 116 default: 117 return EFI_DEVICE_ERROR; 118 } 119 } 120 121 /** 122 Send NV ReadValue command to TPM1.2. 123 124 @param NvIndex The index of the area to set. 125 @param Offset The offset into the area. 126 @param DataSize The size of the data area. 127 @param Data The data to set the area to. 128 129 @retval EFI_SUCCESS Operation completed successfully. 130 @retval EFI_DEVICE_ERROR Unexpected device behavior. 131 **/ 132 EFI_STATUS 133 EFIAPI 134 Tpm12NvReadValue ( 135 IN TPM_NV_INDEX NvIndex, 136 IN UINT32 Offset, 137 IN OUT UINT32 *DataSize, 138 OUT UINT8 *Data 139 ) 140 { 141 EFI_STATUS Status; 142 TPM_CMD_NV_READ_VALUE Command; 143 TPM_RSP_NV_READ_VALUE Response; 144 UINT32 Length; 145 146 // 147 // send Tpm command TPM_ORD_NV_ReadValue 148 // 149 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 150 Command.Hdr.paramSize = SwapBytes32 (sizeof (Command)); 151 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_ReadValue); 152 Command.NvIndex = SwapBytes32 (NvIndex); 153 Command.Offset = SwapBytes32 (Offset); 154 Command.DataSize = SwapBytes32 (*DataSize); 155 Length = sizeof (Response); 156 Status = Tpm12SubmitCommand (sizeof (Command), (UINT8 *)&Command, &Length, (UINT8 *)&Response); 157 if (EFI_ERROR (Status)) { 158 return Status; 159 } 160 DEBUG ((DEBUG_INFO, "Tpm12NvReadValue - ReturnCode = %x\n", SwapBytes32 (Response.Hdr.returnCode))); 161 switch (SwapBytes32 (Response.Hdr.returnCode)) { 162 case TPM_SUCCESS: 163 break; 164 default: 165 return EFI_DEVICE_ERROR; 166 } 167 168 // 169 // Return the response 170 // 171 if (SwapBytes32 (Response.DataSize) > *DataSize) { 172 return EFI_BUFFER_TOO_SMALL; 173 } 174 *DataSize = SwapBytes32 (Response.DataSize); 175 ZeroMem (Data, *DataSize); 176 CopyMem (Data, &Response.Data, *DataSize); 177 178 return EFI_SUCCESS; 179 } 180 181 /** 182 Send NV WriteValue command to TPM1.2. 183 184 @param NvIndex The index of the area to set. 185 @param Offset The offset into the NV Area. 186 @param DataSize The size of the data parameter. 187 @param Data The data to set the area to. 188 189 @retval EFI_SUCCESS Operation completed successfully. 190 @retval EFI_DEVICE_ERROR Unexpected device behavior. 191 **/ 192 EFI_STATUS 193 EFIAPI 194 Tpm12NvWriteValue ( 195 IN TPM_NV_INDEX NvIndex, 196 IN UINT32 Offset, 197 IN UINT32 DataSize, 198 IN UINT8 *Data 199 ) 200 { 201 EFI_STATUS Status; 202 TPM_CMD_NV_WRITE_VALUE Command; 203 UINT32 CommandLength; 204 TPM_RSP_COMMAND_HDR Response; 205 UINT32 ResponseLength; 206 207 if (DataSize > sizeof (Command.Data)) { 208 return EFI_UNSUPPORTED; 209 } 210 211 // 212 // send Tpm command TPM_ORD_NV_WriteValue 213 // 214 Command.Hdr.tag = SwapBytes16 (TPM_TAG_RQU_COMMAND); 215 CommandLength = sizeof (Command) - sizeof(Command.Data) + DataSize; 216 Command.Hdr.paramSize = SwapBytes32 (CommandLength); 217 Command.Hdr.ordinal = SwapBytes32 (TPM_ORD_NV_WriteValue); 218 Command.NvIndex = SwapBytes32 (NvIndex); 219 Command.Offset = SwapBytes32 (Offset); 220 Command.DataSize = SwapBytes32 (DataSize); 221 CopyMem (Command.Data, Data, DataSize); 222 ResponseLength = sizeof (Response); 223 Status = Tpm12SubmitCommand (CommandLength, (UINT8 *)&Command, &ResponseLength, (UINT8 *)&Response); 224 if (EFI_ERROR (Status)) { 225 return Status; 226 } 227 DEBUG ((DEBUG_INFO, "Tpm12NvWritedValue - ReturnCode = %x\n", SwapBytes32 (Response.returnCode))); 228 switch (SwapBytes32 (Response.returnCode)) { 229 case TPM_SUCCESS: 230 return EFI_SUCCESS; 231 default: 232 return EFI_DEVICE_ERROR; 233 } 234 } 235