1 /** @file
2   Ihis library is TPM2 device router. Platform can register multi TPM2 instance to it
3   via PcdTpmInstanceGuid. Platform need make choice that which one will be final one.
4   At most one TPM2 instance can be finally registered, and other will return unsupported.
5 
6 Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved. <BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution.  The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11 
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/HobLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/PcdLib.h>
22 #include <Library/Tpm2DeviceLib.h>
23 
24 EFI_GUID mInternalTpm2DeviceInterfaceGuid = {
25   0x349cf818, 0xc0ba, 0x4c43, { 0x92, 0x9a, 0xc8, 0xa1, 0xb1, 0xb3, 0xd2, 0x55 }
26 };
27 
28 /**
29   This function get TPM2.0 interface.
30 
31   @retval TPM2.0 interface.
32 **/
33 TPM2_DEVICE_INTERFACE *
InternalGetTpm2DeviceInterface(VOID)34 InternalGetTpm2DeviceInterface (
35   VOID
36   )
37 {
38   EFI_HOB_GUID_TYPE *Hob;
39 
40   Hob = GetFirstGuidHob (&mInternalTpm2DeviceInterfaceGuid);
41   if (Hob == NULL) {
42     return NULL;
43   }
44   return (TPM2_DEVICE_INTERFACE *)(Hob + 1);
45 }
46 
47 /**
48   This service enables the sending of commands to the TPM2.
49 
50   @param[in]      InputParameterBlockSize  Size of the TPM2 input parameter block.
51   @param[in]      InputParameterBlock      Pointer to the TPM2 input parameter block.
52   @param[in,out]  OutputParameterBlockSize Size of the TPM2 output parameter block.
53   @param[in]      OutputParameterBlock     Pointer to the TPM2 output parameter block.
54 
55   @retval EFI_SUCCESS            The command byte stream was successfully sent to the device and a response was successfully received.
56   @retval EFI_DEVICE_ERROR       The command was not successfully sent to the device or a response was not successfully received from the device.
57   @retval EFI_BUFFER_TOO_SMALL   The output parameter block is too small.
58 **/
59 EFI_STATUS
60 EFIAPI
Tpm2SubmitCommand(IN UINT32 InputParameterBlockSize,IN UINT8 * InputParameterBlock,IN OUT UINT32 * OutputParameterBlockSize,IN UINT8 * OutputParameterBlock)61 Tpm2SubmitCommand (
62   IN UINT32            InputParameterBlockSize,
63   IN UINT8             *InputParameterBlock,
64   IN OUT UINT32        *OutputParameterBlockSize,
65   IN UINT8             *OutputParameterBlock
66   )
67 {
68   TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;
69 
70   Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
71   if (Tpm2DeviceInterface == NULL) {
72     return EFI_UNSUPPORTED;
73   }
74 
75   return Tpm2DeviceInterface->Tpm2SubmitCommand (
76                                 InputParameterBlockSize,
77                                 InputParameterBlock,
78                                 OutputParameterBlockSize,
79                                 OutputParameterBlock
80                                 );
81 }
82 
83 /**
84   This service requests use TPM2.
85 
86   @retval EFI_SUCCESS      Get the control of TPM2 chip.
87   @retval EFI_NOT_FOUND    TPM2 not found.
88   @retval EFI_DEVICE_ERROR Unexpected device behavior.
89 **/
90 EFI_STATUS
91 EFIAPI
Tpm2RequestUseTpm(VOID)92 Tpm2RequestUseTpm (
93   VOID
94   )
95 {
96   TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;
97 
98   Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
99   if (Tpm2DeviceInterface == NULL) {
100     return EFI_UNSUPPORTED;
101   }
102   return Tpm2DeviceInterface->Tpm2RequestUseTpm ();
103 }
104 
105 /**
106   This service register TPM2 device.
107 
108   @param Tpm2Device  TPM2 device
109 
110   @retval EFI_SUCCESS          This TPM2 device is registered successfully.
111   @retval EFI_UNSUPPORTED      System does not support register this TPM2 device.
112   @retval EFI_ALREADY_STARTED  System already register this TPM2 device.
113 **/
114 EFI_STATUS
115 EFIAPI
Tpm2RegisterTpm2DeviceLib(IN TPM2_DEVICE_INTERFACE * Tpm2Device)116 Tpm2RegisterTpm2DeviceLib (
117   IN TPM2_DEVICE_INTERFACE   *Tpm2Device
118   )
119 {
120   TPM2_DEVICE_INTERFACE *Tpm2DeviceInterface;
121 
122   if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &Tpm2Device->ProviderGuid)){
123     DEBUG ((EFI_D_ERROR, "WARNING: Tpm2RegisterTpm2DeviceLib - does not support %g registration\n", &Tpm2Device->ProviderGuid));
124     return EFI_UNSUPPORTED;
125   }
126 
127   Tpm2DeviceInterface = InternalGetTpm2DeviceInterface ();
128   if (Tpm2DeviceInterface != NULL) {
129     //
130     // In PEI phase, there will be shadow driver dispatched again.
131     //
132     DEBUG ((EFI_D_INFO, "Tpm2RegisterTpm2DeviceLib - Override\n"));
133     CopyMem (Tpm2DeviceInterface, Tpm2Device, sizeof(*Tpm2Device));
134     return EFI_SUCCESS;
135   } else {
136     Tpm2Device = BuildGuidDataHob (&mInternalTpm2DeviceInterfaceGuid, Tpm2Device, sizeof(*Tpm2Device));
137     if (Tpm2Device != NULL) {
138       return EFI_SUCCESS;
139     } else {
140       return EFI_OUT_OF_RESOURCES;
141     }
142   }
143 }
144