Home | History | Annotate | Download | only in Tpm2CommandLib
      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
    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
    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
    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
    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
    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
    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
    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