1 /** @file
2   Implement TPM2 Hierarchy related command.
3 
4 Copyright (c) 2013 - 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
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     goto Done;
190   }
191 
192   if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
193     DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - RecvBufferSize Error - %x\n", RecvBufferSize));
194     Status = EFI_DEVICE_ERROR;
195     goto Done;
196   }
197   if (SwapBytes32(RecvBuffer.Header.responseCode) != TPM_RC_SUCCESS) {
198     DEBUG ((EFI_D_ERROR, "Tpm2SetPrimaryPolicy - responseCode - %x\n", SwapBytes32(RecvBuffer.Header.responseCode)));
199     Status = EFI_DEVICE_ERROR;
200     goto Done;
201   }
202 
203 Done:
204   //
205   // Clear AuthSession Content
206   //
207   ZeroMem (&SendBuffer, sizeof(SendBuffer));
208   ZeroMem (&RecvBuffer, sizeof(RecvBuffer));
209   return Status;
210 }
211 
212 /**
213   This command removes all TPM context associated with a specific Owner.
214 
215   @param[in] AuthHandle        TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
216   @param[in] AuthSession       Auth Session context
217 
218   @retval EFI_SUCCESS      Operation completed successfully.
219   @retval EFI_DEVICE_ERROR Unexpected device behavior.
220 **/
221 EFI_STATUS
222 EFIAPI
Tpm2Clear(IN TPMI_RH_CLEAR AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession OPTIONAL)223 Tpm2Clear (
224   IN TPMI_RH_CLEAR             AuthHandle,
225   IN TPMS_AUTH_COMMAND         *AuthSession OPTIONAL
226   )
227 {
228   EFI_STATUS                        Status;
229   TPM2_CLEAR_COMMAND                Cmd;
230   TPM2_CLEAR_RESPONSE               Res;
231   UINT32                            ResultBufSize;
232   UINT32                            CmdSize;
233   UINT32                            RespSize;
234   UINT8                             *Buffer;
235   UINT32                            SessionInfoSize;
236 
237   Cmd.Header.tag         = SwapBytes16(TPM_ST_SESSIONS);
238   Cmd.Header.commandCode = SwapBytes32(TPM_CC_Clear);
239   Cmd.AuthHandle         = SwapBytes32(AuthHandle);
240 
241   //
242   // Add in Auth session
243   //
244   Buffer = (UINT8 *)&Cmd.AuthSession;
245 
246   // sessionInfoSize
247   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
248   Buffer += SessionInfoSize;
249   Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
250 
251   CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
252   Cmd.Header.paramSize   = SwapBytes32(CmdSize);
253 
254   ResultBufSize = sizeof(Res);
255   Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
256   if (EFI_ERROR(Status)) {
257     goto Done;
258   }
259 
260   if (ResultBufSize > sizeof(Res)) {
261     DEBUG ((EFI_D_ERROR, "Clear: Failed ExecuteCommand: Buffer Too Small\r\n"));
262     Status = EFI_BUFFER_TOO_SMALL;
263     goto Done;
264   }
265 
266   //
267   // Validate response headers
268   //
269   RespSize = SwapBytes32(Res.Header.paramSize);
270   if (RespSize > sizeof(Res)) {
271     DEBUG ((EFI_D_ERROR, "Clear: Response size too large! %d\r\n", RespSize));
272     Status = EFI_BUFFER_TOO_SMALL;
273     goto Done;
274   }
275 
276   //
277   // Fail if command failed
278   //
279   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
280     DEBUG ((EFI_D_ERROR, "Clear: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
281     Status = EFI_DEVICE_ERROR;
282     goto Done;
283   }
284 
285   //
286   // Unmarshal the response
287   //
288 
289   // None
290 Done:
291   //
292   // Clear AuthSession Content
293   //
294   ZeroMem (&Cmd, sizeof(Cmd));
295   ZeroMem (&Res, sizeof(Res));
296   return Status;
297 }
298 
299 /**
300   Disables and enables the execution of TPM2_Clear().
301 
302   @param[in] AuthHandle        TPM_RH_LOCKOUT or TPM_RH_PLATFORM+{PP}
303   @param[in] AuthSession       Auth Session context
304   @param[in] Disable           YES if the disableOwnerClear flag is to be SET,
305                                NO if the flag is to be CLEAR.
306 
307   @retval EFI_SUCCESS      Operation completed successfully.
308   @retval EFI_DEVICE_ERROR Unexpected device behavior.
309 **/
310 EFI_STATUS
311 EFIAPI
Tpm2ClearControl(IN TPMI_RH_CLEAR AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,OPTIONAL IN TPMI_YES_NO Disable)312 Tpm2ClearControl (
313   IN TPMI_RH_CLEAR             AuthHandle,
314   IN TPMS_AUTH_COMMAND         *AuthSession, OPTIONAL
315   IN TPMI_YES_NO               Disable
316   )
317 {
318   EFI_STATUS                        Status;
319   TPM2_CLEAR_CONTROL_COMMAND        Cmd;
320   TPM2_CLEAR_CONTROL_RESPONSE       Res;
321   UINT32                            ResultBufSize;
322   UINT32                            CmdSize;
323   UINT32                            RespSize;
324   UINT8                             *Buffer;
325   UINT32                            SessionInfoSize;
326 
327   Cmd.Header.tag         = SwapBytes16(TPM_ST_SESSIONS);
328   Cmd.Header.commandCode = SwapBytes32(TPM_CC_ClearControl);
329   Cmd.AuthHandle         = SwapBytes32(AuthHandle);
330 
331   //
332   // Add in Auth session
333   //
334   Buffer = (UINT8 *)&Cmd.AuthSession;
335 
336   // sessionInfoSize
337   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
338   Buffer += SessionInfoSize;
339   Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
340 
341   // disable
342   *(UINT8 *)Buffer = Disable;
343   Buffer++;
344 
345   CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
346   Cmd.Header.paramSize   = SwapBytes32(CmdSize);
347 
348   ResultBufSize = sizeof(Res);
349   Status = Tpm2SubmitCommand (CmdSize, (UINT8 *)&Cmd, &ResultBufSize, (UINT8 *)&Res);
350   if (EFI_ERROR(Status)) {
351     goto Done;
352   }
353 
354   if (ResultBufSize > sizeof(Res)) {
355     DEBUG ((EFI_D_ERROR, "ClearControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
356     Status = EFI_BUFFER_TOO_SMALL;
357     goto Done;
358   }
359 
360   //
361   // Validate response headers
362   //
363   RespSize = SwapBytes32(Res.Header.paramSize);
364   if (RespSize > sizeof(Res)) {
365     DEBUG ((EFI_D_ERROR, "ClearControl: Response size too large! %d\r\n", RespSize));
366     Status = EFI_BUFFER_TOO_SMALL;
367     goto Done;
368   }
369 
370   //
371   // Fail if command failed
372   //
373   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
374     DEBUG ((EFI_D_ERROR, "ClearControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
375     Status = EFI_DEVICE_ERROR;
376     goto Done;
377   }
378 
379   //
380   // Unmarshal the response
381   //
382 
383   // None
384 Done:
385   //
386   // Clear AuthSession Content
387   //
388   ZeroMem (&Cmd, sizeof(Cmd));
389   ZeroMem (&Res, sizeof(Res));
390   return Status;
391 }
392 
393 /**
394   This command allows the authorization secret for a hierarchy or lockout to be changed using the current
395   authorization value as the command authorization.
396 
397   @param[in] AuthHandle        TPM_RH_LOCKOUT, TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
398   @param[in] AuthSession       Auth Session context
399   @param[in] NewAuth           New authorization secret
400 
401   @retval EFI_SUCCESS      Operation completed successfully.
402   @retval EFI_DEVICE_ERROR Unexpected device behavior.
403 **/
404 EFI_STATUS
405 EFIAPI
Tpm2HierarchyChangeAuth(IN TPMI_RH_HIERARCHY_AUTH AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN TPM2B_AUTH * NewAuth)406 Tpm2HierarchyChangeAuth (
407   IN TPMI_RH_HIERARCHY_AUTH    AuthHandle,
408   IN TPMS_AUTH_COMMAND         *AuthSession,
409   IN TPM2B_AUTH                *NewAuth
410   )
411 {
412   EFI_STATUS                           Status;
413   TPM2_HIERARCHY_CHANGE_AUTH_COMMAND   Cmd;
414   TPM2_HIERARCHY_CHANGE_AUTH_RESPONSE  Res;
415   UINT32                               CmdSize;
416   UINT32                               RespSize;
417   UINT8                                *Buffer;
418   UINT32                               SessionInfoSize;
419   UINT8                                *ResultBuf;
420   UINT32                               ResultBufSize;
421 
422   //
423   // Construct command
424   //
425   Cmd.Header.tag          = SwapBytes16(TPM_ST_SESSIONS);
426   Cmd.Header.paramSize    = SwapBytes32(sizeof(Cmd));
427   Cmd.Header.commandCode  = SwapBytes32(TPM_CC_HierarchyChangeAuth);
428   Cmd.AuthHandle          = SwapBytes32(AuthHandle);
429 
430   //
431   // Add in Auth session
432   //
433   Buffer = (UINT8 *)&Cmd.AuthSession;
434 
435   // sessionInfoSize
436   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
437   Buffer += SessionInfoSize;
438   Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
439 
440   // New Authorization size
441   WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16(NewAuth->size));
442   Buffer += sizeof(UINT16);
443 
444   // New Authorizeation
445   CopyMem(Buffer, NewAuth->buffer, NewAuth->size);
446   Buffer += NewAuth->size;
447 
448   CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
449   Cmd.Header.paramSize = SwapBytes32(CmdSize);
450 
451   ResultBuf     = (UINT8 *) &Res;
452   ResultBufSize = sizeof(Res);
453 
454   //
455   // Call the TPM
456   //
457   Status = Tpm2SubmitCommand (
458              CmdSize,
459              (UINT8 *)&Cmd,
460              &ResultBufSize,
461              ResultBuf
462              );
463   if (EFI_ERROR(Status)) {
464     goto Done;
465   }
466 
467   if (ResultBufSize > sizeof(Res)) {
468     DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Failed ExecuteCommand: Buffer Too Small\r\n"));
469     Status = EFI_BUFFER_TOO_SMALL;
470     goto Done;
471   }
472 
473   //
474   // Validate response headers
475   //
476   RespSize = SwapBytes32(Res.Header.paramSize);
477   if (RespSize > sizeof(Res)) {
478     DEBUG ((EFI_D_ERROR, "HierarchyChangeAuth: Response size too large! %d\r\n", RespSize));
479     Status = EFI_BUFFER_TOO_SMALL;
480     goto Done;
481   }
482 
483   //
484   // Fail if command failed
485   //
486   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
487     DEBUG((EFI_D_ERROR,"HierarchyChangeAuth: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
488     Status = EFI_DEVICE_ERROR;
489     goto Done;
490   }
491 
492 Done:
493   //
494   // Clear AuthSession Content
495   //
496   ZeroMem (&Cmd, sizeof(Cmd));
497   ZeroMem (&Res, sizeof(Res));
498   return Status;
499 }
500 
501 /**
502   This replaces the current EPS with a value from the RNG and sets the Endorsement hierarchy controls to
503   their default initialization values.
504 
505   @param[in] AuthHandle        TPM_RH_PLATFORM+{PP}
506   @param[in] AuthSession       Auth Session context
507 
508   @retval EFI_SUCCESS      Operation completed successfully.
509   @retval EFI_DEVICE_ERROR Unexpected device behavior.
510 **/
511 EFI_STATUS
512 EFIAPI
Tpm2ChangeEPS(IN TPMI_RH_PLATFORM AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession)513 Tpm2ChangeEPS (
514   IN TPMI_RH_PLATFORM          AuthHandle,
515   IN TPMS_AUTH_COMMAND         *AuthSession
516   )
517 {
518   EFI_STATUS                Status;
519   TPM2_CHANGE_EPS_COMMAND   Cmd;
520   TPM2_CHANGE_EPS_RESPONSE  Res;
521   UINT32                    CmdSize;
522   UINT32                    RespSize;
523   UINT8                     *Buffer;
524   UINT32                    SessionInfoSize;
525   UINT8                     *ResultBuf;
526   UINT32                    ResultBufSize;
527 
528   //
529   // Construct command
530   //
531   Cmd.Header.tag          = SwapBytes16(TPM_ST_SESSIONS);
532   Cmd.Header.paramSize    = SwapBytes32(sizeof(Cmd));
533   Cmd.Header.commandCode  = SwapBytes32(TPM_CC_ChangeEPS);
534   Cmd.AuthHandle          = SwapBytes32(AuthHandle);
535 
536   //
537   // Add in Auth session
538   //
539   Buffer = (UINT8 *)&Cmd.AuthSession;
540 
541   // sessionInfoSize
542   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
543   Buffer += SessionInfoSize;
544   Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
545 
546   CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
547   Cmd.Header.paramSize = SwapBytes32(CmdSize);
548 
549   ResultBuf     = (UINT8 *) &Res;
550   ResultBufSize = sizeof(Res);
551 
552   //
553   // Call the TPM
554   //
555   Status = Tpm2SubmitCommand (
556              CmdSize,
557              (UINT8 *)&Cmd,
558              &ResultBufSize,
559              ResultBuf
560              );
561   if (EFI_ERROR(Status)) {
562     goto Done;
563   }
564 
565   if (ResultBufSize > sizeof(Res)) {
566     DEBUG ((EFI_D_ERROR, "ChangeEPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
567     Status = EFI_BUFFER_TOO_SMALL;
568     goto Done;
569   }
570 
571   //
572   // Validate response headers
573   //
574   RespSize = SwapBytes32(Res.Header.paramSize);
575   if (RespSize > sizeof(Res)) {
576     DEBUG ((EFI_D_ERROR, "ChangeEPS: Response size too large! %d\r\n", RespSize));
577     Status = EFI_BUFFER_TOO_SMALL;
578     goto Done;
579   }
580 
581   //
582   // Fail if command failed
583   //
584   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
585     DEBUG((EFI_D_ERROR,"ChangeEPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
586     Status = EFI_DEVICE_ERROR;
587     goto Done;
588   }
589 
590 Done:
591   //
592   // Clear AuthSession Content
593   //
594   ZeroMem (&Cmd, sizeof(Cmd));
595   ZeroMem (&Res, sizeof(Res));
596   return Status;
597 }
598 
599 /**
600   This replaces the current PPS with a value from the RNG and sets platformPolicy to the default
601   initialization value (the Empty Buffer).
602 
603   @param[in] AuthHandle        TPM_RH_PLATFORM+{PP}
604   @param[in] AuthSession       Auth Session context
605 
606   @retval EFI_SUCCESS      Operation completed successfully.
607   @retval EFI_DEVICE_ERROR Unexpected device behavior.
608 **/
609 EFI_STATUS
610 EFIAPI
Tpm2ChangePPS(IN TPMI_RH_PLATFORM AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession)611 Tpm2ChangePPS (
612   IN TPMI_RH_PLATFORM          AuthHandle,
613   IN TPMS_AUTH_COMMAND         *AuthSession
614   )
615 {
616   EFI_STATUS                Status;
617   TPM2_CHANGE_PPS_COMMAND   Cmd;
618   TPM2_CHANGE_PPS_RESPONSE  Res;
619   UINT32                    CmdSize;
620   UINT32                    RespSize;
621   UINT8                     *Buffer;
622   UINT32                    SessionInfoSize;
623   UINT8                     *ResultBuf;
624   UINT32                    ResultBufSize;
625 
626   //
627   // Construct command
628   //
629   Cmd.Header.tag          = SwapBytes16(TPM_ST_SESSIONS);
630   Cmd.Header.paramSize    = SwapBytes32(sizeof(Cmd));
631   Cmd.Header.commandCode  = SwapBytes32(TPM_CC_ChangePPS);
632   Cmd.AuthHandle          = SwapBytes32(AuthHandle);
633 
634   //
635   // Add in Auth session
636   //
637   Buffer = (UINT8 *)&Cmd.AuthSession;
638 
639   // sessionInfoSize
640   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
641   Buffer += SessionInfoSize;
642   Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
643 
644   CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
645   Cmd.Header.paramSize = SwapBytes32(CmdSize);
646 
647   ResultBuf     = (UINT8 *) &Res;
648   ResultBufSize = sizeof(Res);
649 
650   //
651   // Call the TPM
652   //
653   Status = Tpm2SubmitCommand (
654              CmdSize,
655              (UINT8 *)&Cmd,
656              &ResultBufSize,
657              ResultBuf
658              );
659   if (EFI_ERROR(Status)) {
660     goto Done;
661   }
662 
663   if (ResultBufSize > sizeof(Res)) {
664     DEBUG ((EFI_D_ERROR, "ChangePPS: Failed ExecuteCommand: Buffer Too Small\r\n"));
665     Status = EFI_BUFFER_TOO_SMALL;
666     goto Done;
667   }
668 
669   //
670   // Validate response headers
671   //
672   RespSize = SwapBytes32(Res.Header.paramSize);
673   if (RespSize > sizeof(Res)) {
674     DEBUG ((EFI_D_ERROR, "ChangePPS: Response size too large! %d\r\n", RespSize));
675     Status = EFI_BUFFER_TOO_SMALL;
676     goto Done;
677   }
678 
679   //
680   // Fail if command failed
681   //
682   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
683     DEBUG((EFI_D_ERROR,"ChangePPS: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
684     Status = EFI_DEVICE_ERROR;
685     goto Done;
686   }
687 
688 Done:
689   //
690   // Clear AuthSession Content
691   //
692   ZeroMem (&Cmd, sizeof(Cmd));
693   ZeroMem (&Res, sizeof(Res));
694   return Status;
695 }
696 
697 /**
698   This command enables and disables use of a hierarchy.
699 
700   @param[in] AuthHandle        TPM_RH_ENDORSEMENT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP}
701   @param[in] AuthSession       Auth Session context
702   @param[in] Hierarchy         Hierarchy of the enable being modified
703   @param[in] State             YES if the enable should be SET,
704                                NO if the enable should be CLEAR
705 
706   @retval EFI_SUCCESS      Operation completed successfully.
707   @retval EFI_DEVICE_ERROR Unexpected device behavior.
708 **/
709 EFI_STATUS
710 EFIAPI
Tpm2HierarchyControl(IN TPMI_RH_HIERARCHY AuthHandle,IN TPMS_AUTH_COMMAND * AuthSession,IN TPMI_RH_HIERARCHY Hierarchy,IN TPMI_YES_NO State)711 Tpm2HierarchyControl (
712   IN TPMI_RH_HIERARCHY         AuthHandle,
713   IN TPMS_AUTH_COMMAND         *AuthSession,
714   IN TPMI_RH_HIERARCHY         Hierarchy,
715   IN TPMI_YES_NO               State
716   )
717 {
718   EFI_STATUS                       Status;
719   TPM2_HIERARCHY_CONTROL_COMMAND   Cmd;
720   TPM2_HIERARCHY_CONTROL_RESPONSE  Res;
721   UINT32                           CmdSize;
722   UINT32                           RespSize;
723   UINT8                            *Buffer;
724   UINT32                           SessionInfoSize;
725   UINT8                            *ResultBuf;
726   UINT32                           ResultBufSize;
727 
728   //
729   // Construct command
730   //
731   Cmd.Header.tag          = SwapBytes16(TPM_ST_SESSIONS);
732   Cmd.Header.paramSize    = SwapBytes32(sizeof(Cmd));
733   Cmd.Header.commandCode  = SwapBytes32(TPM_CC_HierarchyControl);
734   Cmd.AuthHandle          = SwapBytes32(AuthHandle);
735 
736   //
737   // Add in Auth session
738   //
739   Buffer = (UINT8 *)&Cmd.AuthSession;
740 
741   // sessionInfoSize
742   SessionInfoSize = CopyAuthSessionCommand (AuthSession, Buffer);
743   Buffer += SessionInfoSize;
744   Cmd.AuthorizationSize = SwapBytes32(SessionInfoSize);
745 
746   WriteUnaligned32 ((UINT32 *)Buffer, SwapBytes32(Hierarchy));
747   Buffer += sizeof(UINT32);
748 
749   *(UINT8 *)Buffer = State;
750   Buffer++;
751 
752   CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
753   Cmd.Header.paramSize = SwapBytes32(CmdSize);
754 
755   ResultBuf     = (UINT8 *) &Res;
756   ResultBufSize = sizeof(Res);
757 
758   //
759   // Call the TPM
760   //
761   Status = Tpm2SubmitCommand (
762              CmdSize,
763              (UINT8 *)&Cmd,
764              &ResultBufSize,
765              ResultBuf
766              );
767   if (EFI_ERROR(Status)) {
768     goto Done;
769   }
770 
771   if (ResultBufSize > sizeof(Res)) {
772     DEBUG ((EFI_D_ERROR, "HierarchyControl: Failed ExecuteCommand: Buffer Too Small\r\n"));
773     Status = EFI_BUFFER_TOO_SMALL;
774     goto Done;
775   }
776 
777   //
778   // Validate response headers
779   //
780   RespSize = SwapBytes32(Res.Header.paramSize);
781   if (RespSize > sizeof(Res)) {
782     DEBUG ((EFI_D_ERROR, "HierarchyControl: Response size too large! %d\r\n", RespSize));
783     Status = EFI_BUFFER_TOO_SMALL;
784     goto Done;
785   }
786 
787   //
788   // Fail if command failed
789   //
790   if (SwapBytes32(Res.Header.responseCode) != TPM_RC_SUCCESS) {
791     DEBUG((EFI_D_ERROR,"HierarchyControl: Response Code error! 0x%08x\r\n", SwapBytes32(Res.Header.responseCode)));
792     Status = EFI_DEVICE_ERROR;
793     goto Done;
794   }
795 
796 Done:
797   //
798   // Clear AuthSession Content
799   //
800   ZeroMem (&Cmd, sizeof(Cmd));
801   ZeroMem (&Res, sizeof(Res));
802   return Status;
803 }
804