TianoCore EDK2 master
Loading...
Searching...
No Matches
Tpm2Sequences.c
Go to the documentation of this file.
1
13#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
15
16#pragma pack(1)
17
18typedef struct {
20 TPM2B_AUTH Auth;
21 TPMI_ALG_HASH HashAlg;
23
24typedef struct {
26 TPMI_DH_OBJECT SequenceHandle;
28
29typedef struct {
31 TPMI_DH_OBJECT SequenceHandle;
32 UINT32 AuthorizationSize;
33 TPMS_AUTH_COMMAND AuthSessionSeq;
34 TPM2B_MAX_BUFFER Buffer;
36
37typedef struct {
39 UINT32 ParameterSize;
40 TPMS_AUTH_RESPONSE AuthSessionSeq;
42
43typedef struct {
45 TPMI_DH_PCR PcrHandle;
46 TPMI_DH_OBJECT SequenceHandle;
47 UINT32 AuthorizationSize;
48 TPMS_AUTH_COMMAND AuthSessionPcr;
49 TPMS_AUTH_COMMAND AuthSessionSeq;
50 TPM2B_MAX_BUFFER Buffer;
52
53typedef struct {
55 UINT32 ParameterSize;
56 TPML_DIGEST_VALUES Results;
57 TPMS_AUTH_RESPONSE AuthSessionPcr;
58 TPMS_AUTH_RESPONSE AuthSessionSeq;
60
61typedef struct {
63 TPMI_DH_OBJECT SequenceHandle;
64 UINT32 AuthorizationSize;
65 TPMS_AUTH_COMMAND AuthSessionSeq;
66 TPM2B_MAX_BUFFER Buffer;
67 TPMI_RH_HIERARCHY Hierarchy;
69
70typedef struct {
72 UINT32 ParameterSize;
73 TPM2B_DIGEST Digest;
74 TPMS_AUTH_RESPONSE AuthSessionSeq;
76
77#pragma pack()
78
92EFIAPI
94 IN TPMI_ALG_HASH HashAlg,
95 OUT TPMI_DH_OBJECT *SequenceHandle
96 )
97{
98 EFI_STATUS Status;
101 UINT32 CmdSize;
102 UINT32 RespSize;
103 UINT8 *Buffer;
104 UINT32 ResultBufSize;
105
106 ZeroMem (&Cmd, sizeof (Cmd));
107
108 //
109 // Construct command
110 //
111 Cmd.Header.tag = SwapBytes16 (TPM_ST_NO_SESSIONS);
112 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_HashSequenceStart);
113
114 Buffer = (UINT8 *)&Cmd.Auth;
115
116 // auth = nullAuth
117 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (0));
118 Buffer += sizeof (UINT16);
119
120 // hashAlg
121 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (HashAlg));
122 Buffer += sizeof (UINT16);
123
124 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
125 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
126
127 //
128 // Call the TPM
129 //
130 ResultBufSize = sizeof (Res);
131 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
132 if (EFI_ERROR (Status)) {
133 return Status;
134 }
135
136 if (ResultBufSize > sizeof (Res)) {
137 DEBUG ((DEBUG_ERROR, "HashSequenceStart: Failed ExecuteCommand: Buffer Too Small\r\n"));
138 return EFI_BUFFER_TOO_SMALL;
139 }
140
141 //
142 // Validate response headers
143 //
144 RespSize = SwapBytes32 (Res.Header.paramSize);
145 if (RespSize > sizeof (Res)) {
146 DEBUG ((DEBUG_ERROR, "HashSequenceStart: Response size too large! %d\r\n", RespSize));
147 return EFI_BUFFER_TOO_SMALL;
148 }
149
150 //
151 // Fail if command failed
152 //
153 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
154 DEBUG ((DEBUG_ERROR, "HashSequenceStart: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
155 return EFI_DEVICE_ERROR;
156 }
157
158 //
159 // Unmarshal the response
160 //
161
162 // sequenceHandle
163 *SequenceHandle = SwapBytes32 (Res.SequenceHandle);
164
165 return EFI_SUCCESS;
166}
167
180EFIAPI
182 IN TPMI_DH_OBJECT SequenceHandle,
183 IN TPM2B_MAX_BUFFER *Buffer
184 )
185{
186 EFI_STATUS Status;
189 UINT32 CmdSize;
190 UINT32 RespSize;
191 UINT8 *BufferPtr;
192 UINT32 SessionInfoSize;
193 UINT32 ResultBufSize;
194
195 ZeroMem (&Cmd, sizeof (Cmd));
196
197 //
198 // Construct command
199 //
200 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
201 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_SequenceUpdate);
202 Cmd.SequenceHandle = SwapBytes32 (SequenceHandle);
203
204 //
205 // Add in Auth session
206 //
207 BufferPtr = (UINT8 *)&Cmd.AuthSessionSeq;
208
209 // sessionInfoSize
210 SessionInfoSize = CopyAuthSessionCommand (NULL, BufferPtr);
211 BufferPtr += SessionInfoSize;
212 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
213
214 // buffer.size
215 WriteUnaligned16 ((UINT16 *)BufferPtr, SwapBytes16 (Buffer->size));
216 BufferPtr += sizeof (UINT16);
217
218 CopyMem (BufferPtr, &Buffer->buffer, Buffer->size);
219 BufferPtr += Buffer->size;
220
221 CmdSize = (UINT32)(BufferPtr - (UINT8 *)&Cmd);
222 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
223
224 //
225 // Call the TPM
226 //
227 ResultBufSize = sizeof (Res);
228 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
229 if (EFI_ERROR (Status)) {
230 return Status;
231 }
232
233 if (ResultBufSize > sizeof (Res)) {
234 DEBUG ((DEBUG_ERROR, "SequenceUpdate: Failed ExecuteCommand: Buffer Too Small\r\n"));
235 return EFI_BUFFER_TOO_SMALL;
236 }
237
238 //
239 // Validate response headers
240 //
241 RespSize = SwapBytes32 (Res.Header.paramSize);
242 if (RespSize > sizeof (Res)) {
243 DEBUG ((DEBUG_ERROR, "SequenceUpdate: Response size too large! %d\r\n", RespSize));
244 return EFI_BUFFER_TOO_SMALL;
245 }
246
247 //
248 // Fail if command failed
249 //
250 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
251 DEBUG ((DEBUG_ERROR, "SequenceUpdate: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
252 return EFI_DEVICE_ERROR;
253 }
254
255 //
256 // Unmarshal the response
257 //
258
259 // None
260
261 return EFI_SUCCESS;
262}
263
279EFIAPI
281 IN TPMI_DH_PCR PcrHandle,
282 IN TPMI_DH_OBJECT SequenceHandle,
283 IN TPM2B_MAX_BUFFER *Buffer,
284 OUT TPML_DIGEST_VALUES *Results
285 )
286{
287 EFI_STATUS Status;
290 UINT32 CmdSize;
291 UINT32 RespSize;
292 UINT8 *BufferPtr;
293 UINT32 SessionInfoSize;
294 UINT32 SessionInfoSize2;
295 UINT32 Index;
296 UINT32 ResultBufSize;
297 UINT16 DigestSize;
298
299 ZeroMem (&Cmd, sizeof (Cmd));
300
301 //
302 // Construct command
303 //
304 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
305 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_EventSequenceComplete);
306 Cmd.PcrHandle = SwapBytes32 (PcrHandle);
307 Cmd.SequenceHandle = SwapBytes32 (SequenceHandle);
308
309 //
310 // Add in pcrHandle Auth session
311 //
312 BufferPtr = (UINT8 *)&Cmd.AuthSessionPcr;
313
314 // sessionInfoSize
315 SessionInfoSize = CopyAuthSessionCommand (NULL, BufferPtr);
316 BufferPtr += SessionInfoSize;
317
318 // sessionInfoSize
319 SessionInfoSize2 = CopyAuthSessionCommand (NULL, BufferPtr);
320 BufferPtr += SessionInfoSize2;
321 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize + SessionInfoSize2);
322
323 // buffer.size
324 WriteUnaligned16 ((UINT16 *)BufferPtr, SwapBytes16 (Buffer->size));
325 BufferPtr += sizeof (UINT16);
326
327 CopyMem (BufferPtr, &Buffer->buffer[0], Buffer->size);
328 BufferPtr += Buffer->size;
329
330 CmdSize = (UINT32)(BufferPtr - (UINT8 *)&Cmd);
331 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
332
333 //
334 // Call the TPM
335 //
336 ResultBufSize = sizeof (Res);
337 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
338 if (EFI_ERROR (Status)) {
339 return Status;
340 }
341
342 if (ResultBufSize > sizeof (Res)) {
343 DEBUG ((DEBUG_ERROR, "EventSequenceComplete: Failed ExecuteCommand: Buffer Too Small\r\n"));
344 return EFI_BUFFER_TOO_SMALL;
345 }
346
347 //
348 // Validate response headers
349 //
350 RespSize = SwapBytes32 (Res.Header.paramSize);
351 if (RespSize > sizeof (Res)) {
352 DEBUG ((DEBUG_ERROR, "EventSequenceComplete: Response size too large! %d\r\n", RespSize));
353 return EFI_BUFFER_TOO_SMALL;
354 }
355
356 //
357 // Fail if command failed
358 //
359 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
360 DEBUG ((DEBUG_ERROR, "EventSequenceComplete: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
361 return EFI_DEVICE_ERROR;
362 }
363
364 //
365 // Unmarshal the response
366 //
367
368 BufferPtr = (UINT8 *)&Res.Results;
369
370 // count
371 Results->count = SwapBytes32 (ReadUnaligned32 ((UINT32 *)BufferPtr));
372 if (Results->count > HASH_COUNT) {
373 DEBUG ((DEBUG_ERROR, "Tpm2EventSequenceComplete - Results->count error %x\n", Results->count));
374 return EFI_DEVICE_ERROR;
375 }
376
377 BufferPtr += sizeof (UINT32);
378
379 for (Index = 0; Index < Results->count; Index++) {
380 Results->digests[Index].hashAlg = SwapBytes16 (ReadUnaligned16 ((UINT16 *)BufferPtr));
381 BufferPtr += sizeof (UINT16);
382
383 DigestSize = GetHashSizeFromAlgo (Results->digests[Index].hashAlg);
384 if (DigestSize == 0) {
385 DEBUG ((DEBUG_ERROR, "EventSequenceComplete: Unknown hash algorithm %d\r\n", Results->digests[Index].hashAlg));
386 return EFI_DEVICE_ERROR;
387 }
388
389 CopyMem (
390 &Results->digests[Index].digest,
391 BufferPtr,
392 DigestSize
393 );
394 BufferPtr += DigestSize;
395 }
396
397 return EFI_SUCCESS;
398}
399
411EFIAPI
413 IN TPMI_DH_OBJECT SequenceHandle,
414 IN TPM2B_MAX_BUFFER *Buffer,
415 OUT TPM2B_DIGEST *Result
416 )
417{
418 EFI_STATUS Status;
421 UINT32 CmdSize;
422 UINT32 RespSize;
423 UINT8 *BufferPtr;
424 UINT32 SessionInfoSize;
425 UINT32 ResultBufSize;
426
427 ZeroMem (&Cmd, sizeof (Cmd));
428
429 //
430 // Construct command
431 //
432 Cmd.Header.tag = SwapBytes16 (TPM_ST_SESSIONS);
433 Cmd.Header.commandCode = SwapBytes32 (TPM_CC_SequenceComplete);
434 Cmd.SequenceHandle = SwapBytes32 (SequenceHandle);
435
436 //
437 // Add in Auth session
438 //
439 BufferPtr = (UINT8 *)&Cmd.AuthSessionSeq;
440
441 // sessionInfoSize
442 SessionInfoSize = CopyAuthSessionCommand (NULL, BufferPtr);
443 BufferPtr += SessionInfoSize;
444 Cmd.AuthorizationSize = SwapBytes32 (SessionInfoSize);
445
446 // buffer.size
447 WriteUnaligned16 ((UINT16 *)BufferPtr, SwapBytes16 (Buffer->size));
448 BufferPtr += sizeof (UINT16);
449
450 CopyMem (BufferPtr, &Buffer->buffer[0], Buffer->size);
451 BufferPtr += Buffer->size;
452
453 // Hierarchy
454 WriteUnaligned32 ((UINT32 *)BufferPtr, SwapBytes32 (TPM_RH_NULL));
455 BufferPtr += sizeof (UINT32);
456
457 CmdSize = (UINT32)(BufferPtr - (UINT8 *)&Cmd);
458 Cmd.Header.paramSize = SwapBytes32 (CmdSize);
459
460 //
461 // Call the TPM
462 //
463 ResultBufSize = sizeof (Res);
464 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
465 if (EFI_ERROR (Status)) {
466 return Status;
467 }
468
469 if (ResultBufSize > sizeof (Res)) {
470 DEBUG ((DEBUG_ERROR, "SequenceComplete: Failed ExecuteCommand: Buffer Too Small\r\n"));
471 return EFI_BUFFER_TOO_SMALL;
472 }
473
474 //
475 // Validate response headers
476 //
477 RespSize = SwapBytes32 (Res.Header.paramSize);
478 if (RespSize > sizeof (Res)) {
479 DEBUG ((DEBUG_ERROR, "SequenceComplete: Response size too large! %d\r\n", RespSize));
480 return EFI_BUFFER_TOO_SMALL;
481 }
482
483 //
484 // Fail if command failed
485 //
486 if (SwapBytes32 (Res.Header.responseCode) != TPM_RC_SUCCESS) {
487 DEBUG ((DEBUG_ERROR, "SequenceComplete: Response Code error! 0x%08x\r\n", SwapBytes32 (Res.Header.responseCode)));
488 return EFI_DEVICE_ERROR;
489 }
490
491 //
492 // Unmarshal the response
493 //
494
495 BufferPtr = (UINT8 *)&Res.Digest;
496
497 // digestSize
498 Result->size = SwapBytes16 (ReadUnaligned16 ((UINT16 *)BufferPtr));
499 if (Result->size > sizeof (TPMU_HA)) {
500 DEBUG ((DEBUG_ERROR, "Tpm2SequenceComplete - Result->size error %x\n", Result->size));
501 return EFI_DEVICE_ERROR;
502 }
503
504 BufferPtr += sizeof (UINT16);
505
506 CopyMem (
507 Result->buffer,
508 BufferPtr,
509 Result->size
510 );
511
512 return EFI_SUCCESS;
513}
UINT16 EFIAPI SwapBytes16(IN UINT16 Value)
Definition: SwapBytes16.c:25
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
Definition: Unaligned.c:29
UINT32 EFIAPI SwapBytes32(IN UINT32 Value)
Definition: SwapBytes32.c:25
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
Definition: Unaligned.c:177
UINT16 EFIAPI WriteUnaligned16(OUT UINT16 *Buffer, IN UINT16 Value)
Definition: Unaligned.c:61
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT16 GetHashSizeFromAlgo(IN TPMI_ALG_HASH HashAlgo)
Definition: TdTcg2Dxe.c:152
UINT32 EFIAPI CopyAuthSessionCommand(IN TPMS_AUTH_COMMAND *AuthSessionIn OPTIONAL, OUT UINT8 *AuthSessionOut)
Definition: Tpm2Help.c:88
EFI_STATUS EFIAPI Tpm2SubmitCommand(IN UINT32 InputParameterBlockSize, IN UINT8 *InputParameterBlock, IN OUT UINT32 *OutputParameterBlockSize, IN UINT8 *OutputParameterBlock)
EFI_STATUS EFIAPI Tpm2HashSequenceStart(IN TPMI_ALG_HASH HashAlg, OUT TPMI_DH_OBJECT *SequenceHandle)
Definition: Tpm2Sequences.c:93
EFI_STATUS EFIAPI Tpm2SequenceComplete(IN TPMI_DH_OBJECT SequenceHandle, IN TPM2B_MAX_BUFFER *Buffer, OUT TPM2B_DIGEST *Result)
EFI_STATUS EFIAPI Tpm2EventSequenceComplete(IN TPMI_DH_PCR PcrHandle, IN TPMI_DH_OBJECT SequenceHandle, IN TPM2B_MAX_BUFFER *Buffer, OUT TPML_DIGEST_VALUES *Results)
EFI_STATUS EFIAPI Tpm2SequenceUpdate(IN TPMI_DH_OBJECT SequenceHandle, IN TPM2B_MAX_BUFFER *Buffer)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
Definition: Tpm20.h:905