Home | History | Annotate | Download | only in SmmLockBoxLib
      1 /** @file
      2 
      3 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
      4 
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions
      7 of the BSD License which accompanies this distribution.  The
      8 full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include <PiDxe.h>
     17 #include <Library/UefiBootServicesTableLib.h>
     18 #include <Library/UefiRuntimeServicesTableLib.h>
     19 #include <Library/BaseLib.h>
     20 #include <Library/BaseMemoryLib.h>
     21 #include <Library/LockBoxLib.h>
     22 #include <Library/DebugLib.h>
     23 #include <Protocol/SmmCommunication.h>
     24 #include <Guid/SmmLockBox.h>
     25 
     26 #include "SmmLockBoxLibPrivate.h"
     27 
     28 /**
     29   This function will save confidential information to lockbox.
     30 
     31   @param Guid       the guid to identify the confidential information
     32   @param Buffer     the address of the confidential information
     33   @param Length     the length of the confidential information
     34 
     35   @retval RETURN_SUCCESS            the information is saved successfully.
     36   @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or Buffer is NULL, or Length is 0
     37   @retval RETURN_ALREADY_STARTED    the requested GUID already exist.
     38   @retval RETURN_OUT_OF_RESOURCES   no enough resource to save the information.
     39   @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface
     40   @retval RETURN_NOT_STARTED        it is too early to invoke this interface
     41   @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
     42 **/
     43 RETURN_STATUS
     44 EFIAPI
     45 SaveLockBox (
     46   IN  GUID                        *Guid,
     47   IN  VOID                        *Buffer,
     48   IN  UINTN                       Length
     49   )
     50 {
     51   EFI_STATUS                      Status;
     52   EFI_SMM_COMMUNICATION_PROTOCOL  *SmmCommunication;
     53   EFI_SMM_LOCK_BOX_PARAMETER_SAVE *LockBoxParameterSave;
     54   EFI_SMM_COMMUNICATE_HEADER      *CommHeader;
     55   UINT8                           CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SAVE)];
     56   UINTN                           CommSize;
     57 
     58   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SaveLockBox - Enter\n"));
     59 
     60   //
     61   // Basic check
     62   //
     63   if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
     64     return EFI_INVALID_PARAMETER;
     65   }
     66 
     67   //
     68   // Get needed resource
     69   //
     70   Status = gBS->LocateProtocol (
     71                   &gEfiSmmCommunicationProtocolGuid,
     72                   NULL,
     73                   (VOID **)&SmmCommunication
     74                   );
     75   if (EFI_ERROR (Status)) {
     76     return EFI_NOT_STARTED;
     77   }
     78 
     79   //
     80   // Prepare parameter
     81   //
     82   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
     83   CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
     84   CommHeader->MessageLength = sizeof(*LockBoxParameterSave);
     85 
     86   LockBoxParameterSave = (EFI_SMM_LOCK_BOX_PARAMETER_SAVE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
     87   LockBoxParameterSave->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_SAVE;
     88   LockBoxParameterSave->Header.DataLength = sizeof(*LockBoxParameterSave);
     89   LockBoxParameterSave->Header.ReturnStatus = (UINT64)-1;
     90   CopyMem (&LockBoxParameterSave->Guid, Guid, sizeof(*Guid));
     91   LockBoxParameterSave->Buffer     = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
     92   LockBoxParameterSave->Length     = (UINT64)Length;
     93 
     94   //
     95   // Send command
     96   //
     97   CommSize = sizeof(CommBuffer);
     98   Status = SmmCommunication->Communicate (
     99                                SmmCommunication,
    100                                &CommBuffer[0],
    101                                &CommSize
    102                                );
    103   ASSERT_EFI_ERROR (Status);
    104 
    105   Status = (EFI_STATUS)LockBoxParameterSave->Header.ReturnStatus;
    106 
    107   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SaveLockBox - Exit (%r)\n", Status));
    108 
    109   //
    110   // Done
    111   //
    112   return Status;
    113 }
    114 
    115 /**
    116   This function will set lockbox attributes.
    117 
    118   @param Guid       the guid to identify the confidential information
    119   @param Attributes the attributes of the lockbox
    120 
    121   @retval RETURN_SUCCESS            the information is saved successfully.
    122   @retval RETURN_INVALID_PARAMETER  attributes is invalid.
    123   @retval RETURN_NOT_FOUND          the requested GUID not found.
    124   @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface
    125   @retval RETURN_NOT_STARTED        it is too early to invoke this interface
    126   @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
    127 **/
    128 RETURN_STATUS
    129 EFIAPI
    130 SetLockBoxAttributes (
    131   IN  GUID                        *Guid,
    132   IN  UINT64                      Attributes
    133   )
    134 {
    135   EFI_STATUS                                Status;
    136   EFI_SMM_COMMUNICATION_PROTOCOL            *SmmCommunication;
    137   EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *LockBoxParameterSetAttributes;
    138   EFI_SMM_COMMUNICATE_HEADER                *CommHeader;
    139   UINT8                                     CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES)];
    140   UINTN                                     CommSize;
    141 
    142   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Enter\n"));
    143 
    144   //
    145   // Basic check
    146   //
    147   if ((Guid == NULL) ||
    148       ((Attributes & ~LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE) != 0)) {
    149     return EFI_INVALID_PARAMETER;
    150   }
    151 
    152   //
    153   // Get needed resource
    154   //
    155   Status = gBS->LocateProtocol (
    156                   &gEfiSmmCommunicationProtocolGuid,
    157                   NULL,
    158                   (VOID **)&SmmCommunication
    159                   );
    160   if (EFI_ERROR (Status)) {
    161     return EFI_NOT_STARTED;
    162   }
    163 
    164   //
    165   // Prepare parameter
    166   //
    167   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
    168   CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
    169   CommHeader->MessageLength = sizeof(*LockBoxParameterSetAttributes);
    170 
    171   LockBoxParameterSetAttributes = (EFI_SMM_LOCK_BOX_PARAMETER_SET_ATTRIBUTES *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
    172   LockBoxParameterSetAttributes->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_SET_ATTRIBUTES;
    173   LockBoxParameterSetAttributes->Header.DataLength = sizeof(*LockBoxParameterSetAttributes);
    174   LockBoxParameterSetAttributes->Header.ReturnStatus = (UINT64)-1;
    175   CopyMem (&LockBoxParameterSetAttributes->Guid, Guid, sizeof(*Guid));
    176   LockBoxParameterSetAttributes->Attributes = (UINT64)Attributes;
    177 
    178   //
    179   // Send command
    180   //
    181   CommSize = sizeof(CommBuffer);
    182   Status = SmmCommunication->Communicate (
    183                                SmmCommunication,
    184                                &CommBuffer[0],
    185                                &CommSize
    186                                );
    187   ASSERT_EFI_ERROR (Status);
    188 
    189   Status = (EFI_STATUS)LockBoxParameterSetAttributes->Header.ReturnStatus;
    190 
    191   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib SetLockBoxAttributes - Exit (%r)\n", Status));
    192 
    193   //
    194   // Done
    195   //
    196   return Status;
    197 }
    198 
    199 /**
    200   This function will update confidential information to lockbox.
    201 
    202   @param Guid   the guid to identify the original confidential information
    203   @param Offset the offset of the original confidential information
    204   @param Buffer the address of the updated confidential information
    205   @param Length the length of the updated confidential information
    206 
    207   @retval RETURN_SUCCESS            the information is saved successfully.
    208   @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or Buffer is NULL, or Length is 0.
    209   @retval RETURN_NOT_FOUND          the requested GUID not found.
    210   @retval RETURN_BUFFER_TOO_SMALL   the original buffer to too small to hold new information.
    211   @retval RETURN_ACCESS_DENIED      it is too late to invoke this interface
    212   @retval RETURN_NOT_STARTED        it is too early to invoke this interface
    213   @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
    214 **/
    215 RETURN_STATUS
    216 EFIAPI
    217 UpdateLockBox (
    218   IN  GUID                        *Guid,
    219   IN  UINTN                       Offset,
    220   IN  VOID                        *Buffer,
    221   IN  UINTN                       Length
    222   )
    223 {
    224   EFI_STATUS                        Status;
    225   EFI_SMM_COMMUNICATION_PROTOCOL    *SmmCommunication;
    226   EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *LockBoxParameterUpdate;
    227   EFI_SMM_COMMUNICATE_HEADER        *CommHeader;
    228   UINT8                             CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_UPDATE)];
    229   UINTN                             CommSize;
    230 
    231   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib UpdateLockBox - Enter\n"));
    232 
    233   //
    234   // Basic check
    235   //
    236   if ((Guid == NULL) || (Buffer == NULL) || (Length == 0)) {
    237     return EFI_INVALID_PARAMETER;
    238   }
    239 
    240   //
    241   // Get needed resource
    242   //
    243   Status = gBS->LocateProtocol (
    244                   &gEfiSmmCommunicationProtocolGuid,
    245                   NULL,
    246                   (VOID **)&SmmCommunication
    247                   );
    248   if (EFI_ERROR (Status)) {
    249     return EFI_NOT_STARTED;
    250   }
    251 
    252   //
    253   // Prepare parameter
    254   //
    255   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
    256   CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
    257   CommHeader->MessageLength = sizeof(*LockBoxParameterUpdate);
    258 
    259   LockBoxParameterUpdate = (EFI_SMM_LOCK_BOX_PARAMETER_UPDATE *)(UINTN)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
    260   LockBoxParameterUpdate->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_UPDATE;
    261   LockBoxParameterUpdate->Header.DataLength = sizeof(*LockBoxParameterUpdate);
    262   LockBoxParameterUpdate->Header.ReturnStatus = (UINT64)-1;
    263   CopyMem (&LockBoxParameterUpdate->Guid, Guid, sizeof(*Guid));
    264   LockBoxParameterUpdate->Offset = (UINT64)Offset;
    265   LockBoxParameterUpdate->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
    266   LockBoxParameterUpdate->Length = (UINT64)Length;
    267 
    268   //
    269   // Send command
    270   //
    271   CommSize = sizeof(CommBuffer);
    272   Status = SmmCommunication->Communicate (
    273                                SmmCommunication,
    274                                &CommBuffer[0],
    275                                &CommSize
    276                                );
    277   ASSERT_EFI_ERROR (Status);
    278 
    279   Status = (EFI_STATUS)LockBoxParameterUpdate->Header.ReturnStatus;
    280 
    281   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib UpdateLockBox - Exit (%r)\n", Status));
    282 
    283   //
    284   // Done
    285   //
    286   return Status;
    287 }
    288 
    289 /**
    290   This function will restore confidential information from lockbox.
    291 
    292   @param Guid   the guid to identify the confidential information
    293   @param Buffer the address of the restored confidential information
    294                 NULL means restored to original address, Length MUST be NULL at same time.
    295   @param Length the length of the restored confidential information
    296 
    297   @retval RETURN_SUCCESS            the information is restored successfully.
    298   @retval RETURN_INVALID_PARAMETER  the Guid is NULL, or one of Buffer and Length is NULL.
    299   @retval RETURN_WRITE_PROTECTED    Buffer and Length are NULL, but the LockBox has no
    300                                     LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE attribute.
    301   @retval RETURN_BUFFER_TOO_SMALL   the Length is too small to hold the confidential information.
    302   @retval RETURN_NOT_FOUND          the requested GUID not found.
    303   @retval RETURN_NOT_STARTED        it is too early to invoke this interface
    304   @retval RETURN_ACCESS_DENIED      not allow to restore to the address
    305   @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
    306 **/
    307 RETURN_STATUS
    308 EFIAPI
    309 RestoreLockBox (
    310   IN  GUID                        *Guid,
    311   IN  VOID                        *Buffer, OPTIONAL
    312   IN  OUT UINTN                   *Length  OPTIONAL
    313   )
    314 {
    315   EFI_STATUS                         Status;
    316   EFI_SMM_COMMUNICATION_PROTOCOL     *SmmCommunication;
    317   EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *LockBoxParameterRestore;
    318   EFI_SMM_COMMUNICATE_HEADER         *CommHeader;
    319   UINT8                              CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE)];
    320   UINTN                              CommSize;
    321 
    322   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreLockBox - Enter\n"));
    323 
    324   //
    325   // Basic check
    326   //
    327   if ((Guid == NULL) ||
    328       ((Buffer == NULL) && (Length != NULL)) ||
    329       ((Buffer != NULL) && (Length == NULL))) {
    330     return EFI_INVALID_PARAMETER;
    331   }
    332 
    333   //
    334   // Get needed resource
    335   //
    336   Status = gBS->LocateProtocol (
    337                   &gEfiSmmCommunicationProtocolGuid,
    338                   NULL,
    339                   (VOID **)&SmmCommunication
    340                   );
    341   if (EFI_ERROR (Status)) {
    342     return EFI_NOT_STARTED;
    343   }
    344 
    345   //
    346   // Prepare parameter
    347   //
    348   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
    349   CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
    350   CommHeader->MessageLength = sizeof(*LockBoxParameterRestore);
    351 
    352   LockBoxParameterRestore = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
    353   LockBoxParameterRestore->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_RESTORE;
    354   LockBoxParameterRestore->Header.DataLength = sizeof(*LockBoxParameterRestore);
    355   LockBoxParameterRestore->Header.ReturnStatus = (UINT64)-1;
    356   CopyMem (&LockBoxParameterRestore->Guid, Guid, sizeof(*Guid));
    357   LockBoxParameterRestore->Buffer = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
    358   if (Length != NULL) {
    359     LockBoxParameterRestore->Length = (EFI_PHYSICAL_ADDRESS)*Length;
    360   } else {
    361     LockBoxParameterRestore->Length = 0;
    362   }
    363 
    364   //
    365   // Send command
    366   //
    367   CommSize = sizeof(CommBuffer);
    368   Status = SmmCommunication->Communicate (
    369                                SmmCommunication,
    370                                &CommBuffer[0],
    371                                &CommSize
    372                                );
    373   ASSERT_EFI_ERROR (Status);
    374 
    375   if (Length != NULL) {
    376     *Length = (UINTN)LockBoxParameterRestore->Length;
    377   }
    378 
    379   Status = (EFI_STATUS)LockBoxParameterRestore->Header.ReturnStatus;
    380 
    381   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreLockBox - Exit (%r)\n", Status));
    382 
    383   //
    384   // Done
    385   //
    386   return Status;
    387 }
    388 
    389 /**
    390   This function will restore confidential information from all lockbox which have RestoreInPlace attribute.
    391 
    392   @retval RETURN_SUCCESS            the information is restored successfully.
    393   @retval RETURN_NOT_STARTED        it is too early to invoke this interface
    394   @retval RETURN_UNSUPPORTED        the service is not supported by implementaion.
    395 **/
    396 RETURN_STATUS
    397 EFIAPI
    398 RestoreAllLockBoxInPlace (
    399   VOID
    400   )
    401 {
    402   EFI_STATUS                                      Status;
    403   EFI_SMM_COMMUNICATION_PROTOCOL                  *SmmCommunication;
    404   EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *LockBoxParameterRestoreAllInPlace;
    405   EFI_SMM_COMMUNICATE_HEADER                      *CommHeader;
    406   UINT8                                           CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE)];
    407   UINTN                                           CommSize;
    408 
    409   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Enter\n"));
    410 
    411   //
    412   // Get needed resource
    413   //
    414   Status = gBS->LocateProtocol (
    415                   &gEfiSmmCommunicationProtocolGuid,
    416                   NULL,
    417                   (VOID **)&SmmCommunication
    418                   );
    419   if (EFI_ERROR (Status)) {
    420     return EFI_NOT_STARTED;
    421   }
    422 
    423   //
    424   // Prepare parameter
    425   //
    426   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
    427   CopyMem (&CommHeader->HeaderGuid, &gEfiSmmLockBoxCommunicationGuid, sizeof(gEfiSmmLockBoxCommunicationGuid));
    428   CommHeader->MessageLength = sizeof(*LockBoxParameterRestoreAllInPlace);
    429 
    430   LockBoxParameterRestoreAllInPlace = (EFI_SMM_LOCK_BOX_PARAMETER_RESTORE_ALL_IN_PLACE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
    431   LockBoxParameterRestoreAllInPlace->Header.Command    = EFI_SMM_LOCK_BOX_COMMAND_RESTORE_ALL_IN_PLACE;
    432   LockBoxParameterRestoreAllInPlace->Header.DataLength = sizeof(*LockBoxParameterRestoreAllInPlace);
    433   LockBoxParameterRestoreAllInPlace->Header.ReturnStatus = (UINT64)-1;
    434 
    435   //
    436   // Send command
    437   //
    438   CommSize = sizeof(CommBuffer);
    439   Status = SmmCommunication->Communicate (
    440                                SmmCommunication,
    441                                &CommBuffer[0],
    442                                &CommSize
    443                                );
    444   ASSERT_EFI_ERROR (Status);
    445 
    446   Status = (EFI_STATUS)LockBoxParameterRestoreAllInPlace->Header.ReturnStatus;
    447 
    448   DEBUG ((EFI_D_INFO, "SmmLockBoxDxeLib RestoreAllLockBoxInPlace - Exit (%r)\n", Status));
    449 
    450   //
    451   // Done
    452   //
    453   return Status;
    454 }
    455 
    456