1 /** @file
2 Implement TPM2 Hierarchy related command.
3
4 Copyright (c) 2013 - 2014, 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 <IndustryStandard/UefiTcgPlatform.h>
16 #include <Library/Tpm2CommandLib.h>
17 #include <Library/Tpm2DeviceLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21
22 #pragma pack(1)
23
24 typedef struct {
25 TPM2_COMMAND_HEADER Header;
26 TPMI_RH_HIERARCHY_AUTH AuthHandle;
27 UINT32 AuthSessionSize;
28 TPMS_AUTH_COMMAND AuthSession;
29 TPM2B_DIGEST AuthPolicy;
30 TPMI_ALG_HASH HashAlg;
31 } TPM2_SET_PRIMARY_POLICY_COMMAND;
32
33 typedef struct {
34 TPM2_RESPONSE_HEADER Header;
35 UINT32 AuthSessionSize;
36 TPMS_AUTH_RESPONSE AuthSession;
37 } TPM2_SET_PRIMARY_POLICY_RESPONSE;
38
39 typedef struct {
40 TPM2_COMMAND_HEADER Header;
41 TPMI_RH_CLEAR AuthHandle;
42 UINT32 AuthorizationSize;
43 TPMS_AUTH_COMMAND AuthSession;
44 } TPM2_CLEAR_COMMAND;
45
46 typedef struct {
47 TPM2_RESPONSE_HEADER Header;
48 UINT32 ParameterSize;
49 TPMS_AUTH_RESPONSE AuthSession;
50 } TPM2_CLEAR_RESPONSE;
51
52 typedef struct {
53 TPM2_COMMAND_HEADER Header;
54 TPMI_RH_CLEAR AuthHandle;
55 UINT32 AuthorizationSize;
56 TPMS_AUTH_COMMAND AuthSession;
57 TPMI_YES_NO Disable;
58 } TPM2_CLEAR_CONTROL_COMMAND;
59
60 typedef struct {
61 TPM2_RESPONSE_HEADER Header;
62 UINT32 ParameterSize;
63 TPMS_AUTH_RESPONSE AuthSession;
64 } TPM2_CLEAR_CONTROL_RESPONSE;
65
66 typedef struct {
67 TPM2_COMMAND_HEADER Header;
68 TPMI_RH_HIERARCHY_AUTH AuthHandle;
69 UINT32 AuthorizationSize;
70 TPMS_AUTH_COMMAND AuthSession;
71 TPM2B_AUTH NewAuth;
72 } TPM2_HIERARCHY_CHANGE_AUTH_COMMAND;
73
74 typedef struct {
75 TPM2_RESPONSE_HEADER Header;
76 UINT32 ParameterSize;
77 TPMS_AUTH_RESPONSE AuthSession;
78 } TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE;
79
80 typedef struct {
81 TPM2_COMMAND_HEADER Header;
82 TPMI_RH_PLATFORM AuthHandle;
83 UINT32 AuthorizationSize;
84 TPMS_AUTH_COMMAND AuthSession;
85 } TPM2_CHANGE_EPS_COMMAND;
86
87 typedef struct {
88 TPM2_RESPONSE_HEADER Header;
89 UINT32 ParameterSize;
90 TPMS_AUTH_RESPONSE AuthSession;
91 } TPM2_CHANGE_EPS_RESPONSE;
92
93 typedef struct {
94 TPM2_COMMAND_HEADER Header;
95 TPMI_RH_PLATFORM AuthHandle;
96 UINT32 AuthorizationSize;
97 TPMS_AUTH_COMMAND AuthSession;
98 } TPM2_CHANGE_PPS_COMMAND;
99
100 typedef struct {
101 TPM2_RESPONSE_HEADER Header;
102 UINT32 ParameterSize;
103 TPMS_AUTH_RESPONSE AuthSession;
104 } TPM2_CHANGE_PPS_RESPONSE;
105
106 typedef struct {
107 TPM2_COMMAND_HEADER Header;
108 TPMI_RH_HIERARCHY AuthHandle;
109 UINT32 AuthorizationSize;
110 TPMS_AUTH_COMMAND AuthSession;
111 TPMI_RH_HIERARCHY Hierarchy;
112 TPMI_YES_NO State;
113 } TPM2_HIERARCHY_CONTROL_COMMAND;
114
115 typedef struct {
116 TPM2_RESPONSE_HEADER Header;
117 UINT32 ParameterSize;
118 TPMS_AUTH_RESPONSE AuthSession;
119 } TPM2_HIERARCHY_CONTROL_RESPONSE;
120
121 #pragma pack()
122
123 /**
124 This command allows setting of the authorization policy for the platform hierarchy (platformPolicy), the
125 storage hierarchy (ownerPolicy), and and the endorsement hierarchy (endorsementPolicy).
126
127 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} parameters to be validated
128 @param[in] AuthSession Auth Session context
129 @param[in] AuthPolicy An authorization policy hash
130 @param[in] HashAlg The hash algorithm to use for the policy
131
132 @retval EFI_SUCCESS Operation completed successfully.
133 @retval EFI_DEVICE_ERROR Unexpected device behavior.
134 **/
135 EFI_STATUS
136 EFIAPI
Tpm2SetPrimaryPolicy(IN TPMI_RH_HIERARCHY_AUTH AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN TPM2B_DIGEST * AuthPolicy,IN TPMI_ALG_HASH HashAlg)137 Tpm2SetPrimaryPolicy (
138 IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
139 IN TPMS_AUTH_COMMAND *AuthSession,
140 IN TPM2B_DIGEST *AuthPolicy,
141 IN TPMI_ALG_HASH HashAlg
142 )
143 {
144 EFI_STATUS Status;
145 TPM2_SET_PRIMARY_POLICY_COMMAND SendBuffer;
146 TPM2_SET_PRIMARY_POLICY_RESPONSE RecvBuffer;
147 UINT32 SendBufferSize;
148 UINT32 RecvBufferSize;
149 UINT8 *Buffer;
150 UINT32 SessionInfoSize;
151
152 //
153 // Construct command
154 //
155 SendBuffer.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
156 SendBuffer.Header.commandCode = SwapBytes32(TPM_CC_SetPrimaryPolicy);
157
158 SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
159
160 //
161 // Add in Auth session
162 //
163 Buffer = (UINT8 *)&SendBuffer.AuthSession;
164
165 // sessionInfoSize
166 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
167 Buffer += SessionInfoSize;
168 SendBuffer.AuthSessionSize = SwapBytes32(SessionInfoSize);
169
170 //
171 // Real data
172 //
173 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(AuthPolicy->size));
174 Buffer += sizeof(UINT16);
175 CopyMem (Buffer, AuthPolicy->buffer, AuthPolicy->size);
176 Buffer += AuthPolicy->size;
177 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(HashAlg));
178 Buffer += sizeof(UINT16);
179
180 SendBufferSize = (UINT32)((UINTN)Buffer - (UINTN)&SendBuffer);
181 SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
182
183 //
184 // send Tpm command
185 //
186 RecvBufferSize = sizeof (RecvBuffer);
187 Status = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
188 if (EFI_ERROR (Status)) {
189 return Status;
190 }
191
192 if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
193 DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize));
194 return EFI_DEVICE_ERROR;
195 }
196 if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
197 DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
198 return EFI_DEVICE_ERROR;
199 }
200
201 return EFI_SUCCESS;
202 }
203
204 /**
205 This command removes all TPM context associated with a specific Owner.
206
207 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
208 @param[in] AuthSession Auth Session context
209
210 @retval EFI_SUCCESS Operation completed successfully.
211 @retval EFI_DEVICE_ERROR Unexpected device behavior.
212 **/
213 EFI_STATUS
214 EFIAPI
Tpm2Clear(IN TPMI_RH_CLEAR AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)215 Tpm2Clear (
216 IN TPMI_RH_CLEAR AuthHandle,
217 IN TPMS_AUTH_COMMAND *AuthSession OPTIONAL
218 )
219 {
220 EFI_STATUS Status;
221 TPM2_CLEAR_COMMAND Cmd;
222 TPM2_CLEAR_RESPONSE Res;
223 UINT32 ResultBufSize;
224 UINT32 CmdSize;
225 UINT32 RespSize;
226 UINT8 *Buffer;
227 UINT32 SessionInfoSize;
228
229 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
230 Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear);
231 Cmd.AuthHandle = SwapBytes32(AuthHandle);
232
233 //
234 // Add in Auth session
235 //
236 Buffer = (UINT8 *)&Cmd.AuthSession;
237
238 // sessionInfoSize
239 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
240 Buffer += SessionInfoSize;
241 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
242
243 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
244 Cmd.Header.paramSize = SwapBytes32(CmdSize);
245
246 ResultBufSize = sizeof(Res);
247 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
248 if (EFI_ERROR(Status)) {
249 return Status;
250 }
251
252 if (ResultBufSize > sizeof(Res)) {
253 DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));
254 return EFI_BUFFER_TOO_SMALL;
255 }
256
257 //
258 // Validate response headers
259 //
260 RespSize = SwapBytes32(Res.Header.paramSize);
261 if (RespSize > sizeof(Res)) {
262 DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize));
263 return EFI_BUFFER_TOO_SMALL;
264 }
265
266 //
267 // Fail if command failed
268 //
269 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
270 DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
271 return EFI_DEVICE_ERROR;
272 }
273
274 //
275 // Unmarshal the response
276 //
277
278 // None
279
280 return EFI_SUCCESS;
281 }
282
283 /**
284 Disables and enables the execution of TPM2_Clear().
285
286 @param[in] AuthHandle TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
287 @param[in] AuthSession Auth Session context
288 @param[in] Disable YES if the disableOwnerClear flag is to be SET,
289 NO if the flag is to be CLEAR.
290
291 @retval EFI_SUCCESS Operation completed successfully.
292 @retval EFI_DEVICE_ERROR Unexpected device behavior.
293 **/
294 EFI_STATUS
295 EFIAPI
Tpm2ClearControl(IN TPMI_RH_CLEAR AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,OPTIONAL IN TPMI_YES_NO Disable)296 Tpm2ClearControl (
297 IN TPMI_RH_CLEAR AuthHandle,
298 IN TPMS_AUTH_COMMAND *AuthSession, OPTIONAL
299 IN TPMI_YES_NO Disable
300 )
301 {
302 EFI_STATUS Status;
303 TPM2_CLEAR_CONTROL_COMMAND Cmd;
304 TPM2_CLEAR_CONTROL_RESPONSE Res;
305 UINT32 ResultBufSize;
306 UINT32 CmdSize;
307 UINT32 RespSize;
308 UINT8 *Buffer;
309 UINT32 SessionInfoSize;
310
311 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
312 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl);
313 Cmd.AuthHandle = SwapBytes32(AuthHandle);
314
315 //
316 // Add in Auth session
317 //
318 Buffer = (UINT8 *)&Cmd.AuthSession;
319
320 // sessionInfoSize
321 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
322 Buffer += SessionInfoSize;
323 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
324
325 // disable
326 *(UINT8 *)Buffer = Disable;
327 Buffer++;
328
329 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
330 Cmd.Header.paramSize = SwapBytes32(CmdSize);
331
332 ResultBufSize = sizeof(Res);
333 Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
334 if (EFI_ERROR(Status)) {
335 return Status;
336 }
337
338 if (ResultBufSize > sizeof(Res)) {
339 DEBUG ((EFI_D_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
340 return EFI_BUFFER_TOO_SMALL;
341 }
342
343 //
344 // Validate response headers
345 //
346 RespSize = SwapBytes32(Res.Header.paramSize);
347 if (RespSize > sizeof(Res)) {
348 DEBUG ((EFI_D_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize));
349 return EFI_BUFFER_TOO_SMALL;
350 }
351
352 //
353 // Fail if command failed
354 //
355 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
356 DEBUG ((EFI_D_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
357 return EFI_DEVICE_ERROR;
358 }
359
360 //
361 // Unmarshal the response
362 //
363
364 // None
365
366 return EFI_SUCCESS;
367 }
368
369 /**
370 This command allows the authorization secret for a hierarchy or lockout to be changed using the current
371 authorization value as the command authorization.
372
373 @param[in] AuthHandle TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
374 @param[in] AuthSession Auth Session context
375 @param[in] NewAuth New authorization secret
376
377 @retval EFI_SUCCESS Operation completed successfully.
378 @retval EFI_DEVICE_ERROR Unexpected device behavior.
379 **/
380 EFI_STATUS
381 EFIAPI
Tpm2HierarchyChangeAuth(IN TPMI_RH_HIERARCHY_AUTH AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN TPM2B_AUTH * NewAuth)382 Tpm2HierarchyChangeAuth (
383 IN TPMI_RH_HIERARCHY_AUTH AuthHandle,
384 IN TPMS_AUTH_COMMAND *AuthSession,
385 IN TPM2B_AUTH *NewAuth
386 )
387 {
388 EFI_STATUS Status;
389 TPM2_HIERARCHY_CHANGE_AUTH_COMMAND Cmd;
390 TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE Res;
391 UINT32 CmdSize;
392 UINT32 RespSize;
393 UINT8 *Buffer;
394 UINT32 SessionInfoSize;
395 UINT8 *ResultBuf;
396 UINT32 ResultBufSize;
397
398 //
399 // Construct command
400 //
401 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
402 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
403 Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyChangeAuth);
404 Cmd.AuthHandle = SwapBytes32(AuthHandle);
405
406 //
407 // Add in Auth session
408 //
409 Buffer = (UINT8 *)&Cmd.AuthSession;
410
411 // sessionInfoSize
412 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
413 Buffer += SessionInfoSize;
414 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
415
416 // New Authorization size
417 WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NewAuth->size));
418 Buffer += sizeof(UINT16);
419
420 // New Authorizeation
421 CopyMem(Buffer, NewAuth->buffer, NewAuth->size);
422 Buffer += NewAuth->size;
423
424 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
425 Cmd.Header.paramSize = SwapBytes32(CmdSize);
426
427 ResultBuf = (UINT8 *) &Res;
428 ResultBufSize = sizeof(Res);
429
430 //
431 // Call the TPM
432 //
433 Status = Tpm2SubmitCommand (
434 CmdSize,
435 (UINT8 *)&Cmd,
436 &ResultBufSize,
437 ResultBuf
438 );
439
440 if (ResultBufSize > sizeof(Res)) {
441 DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));
442 return EFI_BUFFER_TOO_SMALL;
443 }
444
445 //
446 // Validate response headers
447 //
448 RespSize = SwapBytes32(Res.Header.paramSize);
449 if (RespSize > sizeof(Res)) {
450 DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize));
451 return EFI_BUFFER_TOO_SMALL;
452 }
453
454 //
455 // Fail if command failed
456 //
457 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
458 DEBUG((EFI_D_ERROR,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
459 return EFI_DEVICE_ERROR;
460 }
461
462 return EFI_SUCCESS;
463 }
464
465 /**
466 This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to
467 their default initialization values.
468
469 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
470 @param[in] AuthSession Auth Session context
471
472 @retval EFI_SUCCESS Operation completed successfully.
473 @retval EFI_DEVICE_ERROR Unexpected device behavior.
474 **/
475 EFI_STATUS
476 EFIAPI
Tpm2ChangeEPS(IN TPMI_RH_PLATFORM AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession)477 Tpm2ChangeEPS (
478 IN TPMI_RH_PLATFORM AuthHandle,
479 IN TPMS_AUTH_COMMAND *AuthSession
480 )
481 {
482 EFI_STATUS Status;
483 TPM2_CHANGE_EPS_COMMAND Cmd;
484 TPM2_CHANGE_EPS_RESPONSE Res;
485 UINT32 CmdSize;
486 UINT32 RespSize;
487 UINT8 *Buffer;
488 UINT32 SessionInfoSize;
489 UINT8 *ResultBuf;
490 UINT32 ResultBufSize;
491
492 //
493 // Construct command
494 //
495 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
496 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
497 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangeEPS);
498 Cmd.AuthHandle = SwapBytes32(AuthHandle);
499
500 //
501 // Add in Auth session
502 //
503 Buffer = (UINT8 *)&Cmd.AuthSession;
504
505 // sessionInfoSize
506 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
507 Buffer += SessionInfoSize;
508 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
509
510 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
511 Cmd.Header.paramSize = SwapBytes32(CmdSize);
512
513 ResultBuf = (UINT8 *) &Res;
514 ResultBufSize = sizeof(Res);
515
516 //
517 // Call the TPM
518 //
519 Status = Tpm2SubmitCommand (
520 CmdSize,
521 (UINT8 *)&Cmd,
522 &ResultBufSize,
523 ResultBuf
524 );
525
526 if (ResultBufSize > sizeof(Res)) {
527 DEBUG ((EFI_D_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
528 return EFI_BUFFER_TOO_SMALL;
529 }
530
531 //
532 // Validate response headers
533 //
534 RespSize = SwapBytes32(Res.Header.paramSize);
535 if (RespSize > sizeof(Res)) {
536 DEBUG ((EFI_D_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize));
537 return EFI_BUFFER_TOO_SMALL;
538 }
539
540 //
541 // Fail if command failed
542 //
543 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
544 DEBUG((EFI_D_ERROR,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
545 return EFI_DEVICE_ERROR;
546 }
547
548 return EFI_SUCCESS;
549 }
550
551 /**
552 This replaces the current PPS with a value from the RNG and sets platformPolicy to the default
553 initialization value (the Empty Buffer).
554
555 @param[in] AuthHandle TPM_RH_PLATFORM+{PP}
556 @param[in] AuthSession Auth Session context
557
558 @retval EFI_SUCCESS Operation completed successfully.
559 @retval EFI_DEVICE_ERROR Unexpected device behavior.
560 **/
561 EFI_STATUS
562 EFIAPI
Tpm2ChangePPS(IN TPMI_RH_PLATFORM AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession)563 Tpm2ChangePPS (
564 IN TPMI_RH_PLATFORM AuthHandle,
565 IN TPMS_AUTH_COMMAND *AuthSession
566 )
567 {
568 EFI_STATUS Status;
569 TPM2_CHANGE_PPS_COMMAND Cmd;
570 TPM2_CHANGE_PPS_RESPONSE Res;
571 UINT32 CmdSize;
572 UINT32 RespSize;
573 UINT8 *Buffer;
574 UINT32 SessionInfoSize;
575 UINT8 *ResultBuf;
576 UINT32 ResultBufSize;
577
578 //
579 // Construct command
580 //
581 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
582 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
583 Cmd.Header.commandCode = SwapBytes32(TPM_CC_ChangePPS);
584 Cmd.AuthHandle = SwapBytes32(AuthHandle);
585
586 //
587 // Add in Auth session
588 //
589 Buffer = (UINT8 *)&Cmd.AuthSession;
590
591 // sessionInfoSize
592 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
593 Buffer += SessionInfoSize;
594 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
595
596 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
597 Cmd.Header.paramSize = SwapBytes32(CmdSize);
598
599 ResultBuf = (UINT8 *) &Res;
600 ResultBufSize = sizeof(Res);
601
602 //
603 // Call the TPM
604 //
605 Status = Tpm2SubmitCommand (
606 CmdSize,
607 (UINT8 *)&Cmd,
608 &ResultBufSize,
609 ResultBuf
610 );
611
612 if (ResultBufSize > sizeof(Res)) {
613 DEBUG ((EFI_D_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
614 return EFI_BUFFER_TOO_SMALL;
615 }
616
617 //
618 // Validate response headers
619 //
620 RespSize = SwapBytes32(Res.Header.paramSize);
621 if (RespSize > sizeof(Res)) {
622 DEBUG ((EFI_D_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize));
623 return EFI_BUFFER_TOO_SMALL;
624 }
625
626 //
627 // Fail if command failed
628 //
629 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
630 DEBUG((EFI_D_ERROR,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
631 return EFI_DEVICE_ERROR;
632 }
633
634 return EFI_SUCCESS;
635 }
636
637 /**
638 This command enables and disables use of a hierarchy.
639
640 @param[in] AuthHandle TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
641 @param[in] AuthSession Auth Session context
642 @param[in] Hierarchy Hierarchy of the enable being modified
643 @param[in] State YES if the enable should be SET,
644 NO if the enable should be CLEAR
645
646 @retval EFI_SUCCESS Operation completed successfully.
647 @retval EFI_DEVICE_ERROR Unexpected device behavior.
648 **/
649 EFI_STATUS
650 EFIAPI
Tpm2HierarchyControl(IN TPMI_RH_HIERARCHY AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN TPMI_RH_HIERARCHY Hierarchy,IN TPMI_YES_NO State)651 Tpm2HierarchyControl (
652 IN TPMI_RH_HIERARCHY AuthHandle,
653 IN TPMS_AUTH_COMMAND *AuthSession,
654 IN TPMI_RH_HIERARCHY Hierarchy,
655 IN TPMI_YES_NO State
656 )
657 {
658 EFI_STATUS Status;
659 TPM2_HIERARCHY_CONTROL_COMMAND Cmd;
660 TPM2_HIERARCHY_CONTROL_RESPONSE Res;
661 UINT32 CmdSize;
662 UINT32 RespSize;
663 UINT8 *Buffer;
664 UINT32 SessionInfoSize;
665 UINT8 *ResultBuf;
666 UINT32 ResultBufSize;
667
668 //
669 // Construct command
670 //
671 Cmd.Header.tag = SwapBytes16(TPM_ST_SESSIONS);
672 Cmd.Header.paramSize = SwapBytes32(sizeof(Cmd));
673 Cmd.Header.commandCode = SwapBytes32(TPM_CC_HierarchyControl);
674 Cmd.AuthHandle = SwapBytes32(AuthHandle);
675
676 //
677 // Add in Auth session
678 //
679 Buffer = (UINT8 *)&Cmd.AuthSession;
680
681 // sessionInfoSize
682 SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
683 Buffer += SessionInfoSize;
684 Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
685
686 WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Hierarchy));
687 Buffer += sizeof(UINT32);
688
689 *(UINT8 *)Buffer = State;
690 Buffer++;
691
692 CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
693 Cmd.Header.paramSize = SwapBytes32(CmdSize);
694
695 ResultBuf = (UINT8 *) &Res;
696 ResultBufSize = sizeof(Res);
697
698 //
699 // Call the TPM
700 //
701 Status = Tpm2SubmitCommand (
702 CmdSize,
703 (UINT8 *)&Cmd,
704 &ResultBufSize,
705 ResultBuf
706 );
707
708 if (ResultBufSize > sizeof(Res)) {
709 DEBUG ((EFI_D_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
710 return EFI_BUFFER_TOO_SMALL;
711 }
712
713 //
714 // Validate response headers
715 //
716 RespSize = SwapBytes32(Res.Header.paramSize);
717 if (RespSize > sizeof(Res)) {
718 DEBUG ((EFI_D_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize));
719 return EFI_BUFFER_TOO_SMALL;
720 }
721
722 //
723 // Fail if command failed
724 //
725 if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
726 DEBUG((EFI_D_ERROR,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
727 return EFI_DEVICE_ERROR;
728 }
729
730 return EFI_SUCCESS;
731 }
732