2 TIS (TPM Interface Specification) functions used by TPM Dxe driver.
4 Copyright (c) 2005 - 2016, 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
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.
15 #include <IndustryStandard/Tpm12.h>
16 #include <Library/TimerLib.h>
17 #include <Library/Tpm12DeviceLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/BaseMemoryLib.h>
23 // Max TPM command/reponse length
25 #define TPMCMDBUFLENGTH SIZE_1KB
27 STATIC UINT8 TpmCommandBuf
[TPMCMDBUFLENGTH
];
28 STATIC UINT8 TpmResponseBuf
[TPMCMDBUFLENGTH
];
31 Format TPM command data according to the format control character.
33 @param[in] FmtChar Format control character.
34 @param[in, out] ap List of arguments.
35 @param[in] TpmBuffer Buffer for TPM command data.
36 @param[out] DataLength TPM command data length.
38 @retval EFI_SUCCESS Operation completed successfully.
39 @retval EFI_INVALID_PARAMETER Invalid format control character.
40 @retval EFI_BUFFER_TOO_SMALL Buffer too small for command data.
54 TPM_RQU_COMMAND_HDR TpmCmdHdr
;
55 TPM_RQU_COMMAND_HDR
*TpmCmdPtr
;
62 DataByte
= VA_ARG (*ap
, UINT8
);
64 Size
= sizeof (DataByte
);
68 DataWord
= VA_ARG (*ap
, UINT16
);
69 DataWord
= SwapBytes16 (DataWord
);
70 Raw
= (UINT8
*)&DataWord
;
71 Size
= sizeof (DataWord
);
75 DataDword
= VA_ARG (*ap
, UINT32
);
76 DataDword
= SwapBytes32 (DataDword
);
77 Raw
= (UINT8
*)&DataDword
;
78 Size
= sizeof (DataDword
);
82 TpmCmdPtr
= VA_ARG (*ap
, TPM_RQU_COMMAND_HDR
*);
83 TpmCmdHdr
.tag
= SwapBytes16 (TpmCmdPtr
->tag
);
84 TpmCmdHdr
.paramSize
= SwapBytes32 (TpmCmdPtr
->paramSize
);
85 TpmCmdHdr
.ordinal
= SwapBytes32 (TpmCmdPtr
->ordinal
);
86 Raw
= (UINT8
*) &TpmCmdHdr
;
87 Size
= sizeof (TpmCmdHdr
);
91 Raw
= VA_ARG (*ap
, UINT8
*);
92 Size
= VA_ARG (*ap
, UINTN
);
96 return EFI_INVALID_PARAMETER
;
99 return EFI_INVALID_PARAMETER
;
103 // Check input to avoid overflow.
105 if ((UINT32
) (~0)- *DataLength
< (UINT32
)Size
) {
106 return EFI_INVALID_PARAMETER
;
109 if(*DataLength
+ (UINT32
) Size
> TPMCMDBUFLENGTH
) {
110 return EFI_BUFFER_TOO_SMALL
;
112 CopyMem (TpmBuffer
+ *DataLength
, Raw
, Size
);
113 *DataLength
+= (UINT32
) Size
;
118 Format reponse data according to the format control character.
120 @param[in] FmtChar Format control character.
121 @param[in, out] ap List of arguments.
122 @param[out] TpmBuffer Buffer for reponse data.
123 @param[in, out] DataIndex Data offset in reponse data buffer.
124 @param[in] RespSize Response data length.
125 @param[out] DataFinished Reach the end of Response data.
127 @retval EFI_SUCCESS Operation completed successfully.
128 @retval EFI_INVALID_PARAMETER Invalid format control character.
129 @retval EFI_BUFFER_TOO_SMALL Buffer too small for command data.
136 OUT UINT8
*TpmBuffer
,
137 IN OUT UINT32
*DataIndex
,
139 OUT BOOLEAN
*DataFinished
143 TPM_RSP_COMMAND_HDR
*TpmRspPtr
;
146 Raw
= VA_ARG (*ap
, UINT8
*);
150 Size
= sizeof (UINT8
);
154 Size
= sizeof (UINT16
);
158 Size
= sizeof (UINT32
);
162 Size
= sizeof (*TpmRspPtr
);
166 Size
= VA_ARG (*ap
, UINTN
);
168 // If overflowed, which means Size is big enough for Response data.
169 // skip this check. Copy the whole data
171 if ((UINT32
) (~0)- *DataIndex
>= (UINT32
)Size
) {
172 if(*DataIndex
+ (UINT32
) Size
<= RespSize
) {
177 *DataFinished
= TRUE
;
178 if (*DataIndex
>= RespSize
) {
181 CopyMem (Raw
, TpmBuffer
+ *DataIndex
, RespSize
- *DataIndex
);
182 *DataIndex
+= RespSize
- *DataIndex
;
186 return EFI_INVALID_PARAMETER
;
189 return EFI_WARN_UNKNOWN_GLYPH
;
192 if(*DataIndex
+ (UINT32
) Size
> RespSize
) {
193 *DataFinished
= TRUE
;
197 if( *DataIndex
+ (UINT32
) Size
> TPMCMDBUFLENGTH
)
198 return EFI_BUFFER_TOO_SMALL
;
200 CopyMem (Raw
, TpmBuffer
+ *DataIndex
, Size
);
201 *DataIndex
+= (UINT32
) Size
;
206 *(UINT16
*)Raw
= SwapBytes16 (*(UINT16
*) Raw
);
210 *(UINT32
*)Raw
= SwapBytes32 (*(UINT32
*) Raw
);
214 TpmRspPtr
= (TPM_RSP_COMMAND_HDR
*) Raw
;
215 TpmRspPtr
->tag
= SwapBytes16 (TpmRspPtr
->tag
);
216 TpmRspPtr
->paramSize
= SwapBytes32 (TpmRspPtr
->paramSize
);
217 TpmRspPtr
->returnCode
= SwapBytes32 (TpmRspPtr
->returnCode
);
224 Send formatted command to TPM for execution and return formatted data from response.
226 @param[in] TisReg TPM Handle.
227 @param[in] Fmt Format control string.
228 @param[in] ... The variable argument list.
230 @retval EFI_SUCCESS Operation completed successfully.
231 @retval EFI_TIMEOUT The register can't run into the expected status in time.
245 BOOLEAN DataFinished
;
250 // Put the formatted command to the TpmCommandBuf
253 while (*Fmt
!= '\0') {
254 if (*Fmt
== '%') Fmt
++;
255 if (*Fmt
== '/') break;
256 Status
= TisPcSendV (*Fmt
, &Ap
, TpmCommandBuf
, &BufSize
);
257 if (EFI_ERROR( Status
)) {
264 // Send the command to TPM
266 ZeroMem (TpmResponseBuf
, sizeof (TpmResponseBuf
));
267 ResponseSize
= sizeof (TpmResponseBuf
);
268 Status
= Tpm12SubmitCommand (BufSize
, TpmCommandBuf
, &ResponseSize
, TpmResponseBuf
);
269 if (EFI_ERROR (Status
)) {
275 // Get the formatted data from the TpmResponseBuf.
278 DataFinished
= FALSE
;
279 while (*Fmt
!= '\0') {
283 Status
= TisPcReceiveV (*Fmt
, &Ap
, TpmResponseBuf
, &BufSize
, ResponseSize
, &DataFinished
);
284 if (EFI_ERROR (Status
)) {