Home | History | Annotate | Download | only in MemoryOverwriteRequestControlLock
      1 /** @file
      2   TCG MOR (Memory Overwrite Request) Lock Control Driver.
      3 
      4   This driver initilize MemoryOverwriteRequestControlLock variable.
      5   This module will add Variable Hook and allow MemoryOverwriteRequestControlLock variable set only once.
      6 
      7 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      8 This program and the accompanying materials
      9 are licensed and made available under the terms and conditions of the BSD License
     10 which accompanies this distribution.  The full text of the license may be found at
     11 http://opensource.org/licenses/bsd-license.php
     12 
     13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 #include <PiDxe.h>
     19 #include <Guid/MemoryOverwriteControl.h>
     20 #include <IndustryStandard/MemoryOverwriteRequestControlLock.h>
     21 #include <Library/DebugLib.h>
     22 #include <Library/BaseLib.h>
     23 #include <Library/BaseMemoryLib.h>
     24 #include "TcgMorLock.h"
     25 
     26 typedef struct {
     27   CHAR16                                 *VariableName;
     28   EFI_GUID                               *VendorGuid;
     29 } VARIABLE_TYPE;
     30 
     31 VARIABLE_TYPE  mMorVariableType[] = {
     32   {MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,      &gEfiMemoryOverwriteControlDataGuid},
     33   {MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,  &gEfiMemoryOverwriteRequestControlLockGuid},
     34 };
     35 
     36 /**
     37   Returns if this is MOR related variable.
     38 
     39   @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String
     40   @param  VendorGuid   Unify identifier for vendor.
     41 
     42   @retval  TRUE            The variable is MOR related.
     43   @retval  FALSE           The variable is NOT MOR related.
     44 **/
     45 BOOLEAN
     46 IsAnyMorVariable (
     47   IN CHAR16                                 *VariableName,
     48   IN EFI_GUID                               *VendorGuid
     49   )
     50 {
     51   UINTN   Index;
     52 
     53   for (Index = 0; Index < sizeof(mMorVariableType)/sizeof(mMorVariableType[0]); Index++) {
     54     if ((StrCmp (VariableName, mMorVariableType[Index].VariableName) == 0) &&
     55         (CompareGuid (VendorGuid, mMorVariableType[Index].VendorGuid))) {
     56       return TRUE;
     57     }
     58   }
     59   return FALSE;
     60 }
     61 
     62 /**
     63   Returns if this is MOR lock variable.
     64 
     65   @param  VariableName the name of the vendor's variable, it's a Null-Terminated Unicode String
     66   @param  VendorGuid   Unify identifier for vendor.
     67 
     68   @retval  TRUE            The variable is MOR lock variable.
     69   @retval  FALSE           The variable is NOT MOR lock variable.
     70 **/
     71 BOOLEAN
     72 IsMorLockVariable (
     73   IN CHAR16                                 *VariableName,
     74   IN EFI_GUID                               *VendorGuid
     75   )
     76 {
     77   if ((StrCmp (VariableName, MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME) == 0) &&
     78       (CompareGuid (VendorGuid, &gEfiMemoryOverwriteRequestControlLockGuid))) {
     79     return TRUE;
     80   }
     81   return FALSE;
     82 }
     83 
     84 /**
     85   This service is a checker handler for the UEFI Runtime Service SetVariable()
     86 
     87   @param  VariableName the name of the vendor's variable, as a
     88                        Null-Terminated Unicode String
     89   @param  VendorGuid   Unify identifier for vendor.
     90   @param  Attributes   Point to memory location to return the attributes of variable. If the point
     91                        is NULL, the parameter would be ignored.
     92   @param  DataSize     The size in bytes of Data-Buffer.
     93   @param  Data         Point to the content of the variable.
     94 
     95   @retval  EFI_SUCCESS            The firmware has successfully stored the variable and its data as
     96                                   defined by the Attributes.
     97   @retval  EFI_INVALID_PARAMETER  An invalid combination of attribute bits was supplied, or the
     98                                   DataSize exceeds the maximum allowed.
     99   @retval  EFI_INVALID_PARAMETER  VariableName is an empty Unicode string.
    100   @retval  EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the variable and its data.
    101   @retval  EFI_DEVICE_ERROR       The variable could not be saved due to a hardware failure.
    102   @retval  EFI_WRITE_PROTECTED    The variable in question is read-only.
    103   @retval  EFI_WRITE_PROTECTED    The variable in question cannot be deleted.
    104   @retval  EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
    105                                   set but the AuthInfo does NOT pass the validation check carried
    106                                   out by the firmware.
    107   @retval  EFI_NOT_FOUND          The variable trying to be updated or deleted was not found.
    108 
    109 **/
    110 EFI_STATUS
    111 EFIAPI
    112 SetVariableCheckHandlerMor (
    113   IN CHAR16     *VariableName,
    114   IN EFI_GUID   *VendorGuid,
    115   IN UINT32     Attributes,
    116   IN UINTN      DataSize,
    117   IN VOID       *Data
    118   )
    119 {
    120   UINTN       MorLockDataSize;
    121   BOOLEAN     MorLock;
    122   EFI_STATUS  Status;
    123 
    124   //
    125   // do not handle non-MOR variable
    126   //
    127   if (!IsAnyMorVariable (VariableName, VendorGuid)) {
    128     return EFI_SUCCESS;
    129   }
    130 
    131   MorLockDataSize = sizeof(MorLock);
    132   Status = InternalGetVariable (
    133              MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,
    134              &gEfiMemoryOverwriteRequestControlLockGuid,
    135              NULL,
    136              &MorLockDataSize,
    137              &MorLock
    138              );
    139   if (!EFI_ERROR (Status) && MorLock) {
    140     //
    141     // If lock, deny access
    142     //
    143     return EFI_INVALID_PARAMETER;
    144   }
    145 
    146   //
    147   // Delete not OK
    148   //
    149   if ((DataSize != sizeof(UINT8)) || (Data == NULL) || (Attributes == 0)) {
    150     return EFI_INVALID_PARAMETER;
    151   }
    152 
    153   //
    154   // check format
    155   //
    156   if (IsMorLockVariable(VariableName, VendorGuid)) {
    157     //
    158     // set to any other value not OK
    159     //
    160     if ((*(UINT8 *)Data != 1) && (*(UINT8 *)Data != 0)) {
    161       return EFI_INVALID_PARAMETER;
    162     }
    163   }
    164   //
    165   // Or grant access
    166   //
    167   return EFI_SUCCESS;
    168 }
    169 
    170 /**
    171   Entry Point for MOR Lock Control driver.
    172 
    173   @param[in] ImageHandle  Image handle of this driver.
    174   @param[in] SystemTable  A Pointer to the EFI System Table.
    175 
    176   @retval EFI_SUCEESS
    177   @return Others          Some error occurs.
    178 **/
    179 EFI_STATUS
    180 EFIAPI
    181 MorLockDriverInit (
    182   VOID
    183   )
    184 {
    185   EFI_STATUS  Status;
    186   UINT8       Data;
    187 
    188   Data = 0;
    189   Status = InternalSetVariable (
    190              MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,
    191              &gEfiMemoryOverwriteRequestControlLockGuid,
    192              EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
    193              1,
    194              &Data
    195              );
    196   return Status;
    197 }
    198