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