diff options
Diffstat (limited to 'UefiLessonsPkg')
| -rw-r--r-- | UefiLessonsPkg/PasswordFormWithHash/Data.h | 20 | ||||
| -rw-r--r-- | UefiLessonsPkg/PasswordFormWithHash/Form.vfr | 31 | ||||
| -rw-r--r-- | UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.c | 317 | ||||
| -rw-r--r-- | UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.inf | 28 | ||||
| -rw-r--r-- | UefiLessonsPkg/PasswordFormWithHash/Strings.uni | 9 | ||||
| -rw-r--r-- | UefiLessonsPkg/UefiLessonsPkg.dsc | 1 | 
6 files changed, 406 insertions, 0 deletions
diff --git a/UefiLessonsPkg/PasswordFormWithHash/Data.h b/UefiLessonsPkg/PasswordFormWithHash/Data.h new file mode 100644 index 0000000..a83476d --- /dev/null +++ b/UefiLessonsPkg/PasswordFormWithHash/Data.h @@ -0,0 +1,20 @@ +#ifndef _DATA_H_ +#define _DATA_H_ + +#define FORMSET_GUID  {0xe54b953d, 0x7ddc, 0x455c, {0x8c, 0x1a, 0x59, 0x92, 0xbb, 0xc7, 0x72, 0xc4}} +#define DATAPATH_GUID {0xb289cf9f, 0xf911, 0x41fd, {0x9b, 0xad, 0x2c, 0x92, 0x57, 0x68, 0x86, 0x64}} +#define STORAGE_GUID  {0xe7f2d73c, 0x699a, 0x4606, {0x92, 0xb6, 0xa3, 0x5e, 0x49, 0x27, 0xc4, 0xd4}} + +#define PASSWORD_MIN_LEN       6 +#define PASSWORD_MAX_LEN       8 +#define HASHED_PASSWORD_SIZE   64 + +#define KEY_PASSWORD 0x1234 + +#pragma pack(1) +typedef struct { +  UINT8 Password[HASHED_PASSWORD_SIZE]; +} VARIABLE_STRUCTURE; +#pragma pack() + +#endif diff --git a/UefiLessonsPkg/PasswordFormWithHash/Form.vfr b/UefiLessonsPkg/PasswordFormWithHash/Form.vfr new file mode 100644 index 0000000..10c1d1f --- /dev/null +++ b/UefiLessonsPkg/PasswordFormWithHash/Form.vfr @@ -0,0 +1,31 @@ +#include <Uefi/UefiMultiPhase.h> +#include "Data.h" + +formset +  guid     = FORMSET_GUID, +  title    = STRING_TOKEN(FORMSET_TITLE), +  help     = STRING_TOKEN(FORMSET_HELP), + +  varstore VARIABLE_STRUCTURE, +    name  = FormData, +    guid  = STORAGE_GUID; + +  defaultstore StandardDefault, +    prompt      = STRING_TOKEN(STANDARD_DEFAULT_PROMPT), +    attribute   = 0x0000; + +  form +    formid = 1, +    title = STRING_TOKEN(FORMID1_TITLE); + +    password +      varid = FormData.Password, +      prompt = STRING_TOKEN(PASSWORD_PROMPT), +      help = STRING_TOKEN(PASSWORD_HELP), +      flags = INTERACTIVE, +      key = KEY_PASSWORD, +      minsize = PASSWORD_MIN_LEN, +      maxsize = PASSWORD_MAX_LEN, +    endpassword; +  endform; +endformset; diff --git a/UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.c b/UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.c new file mode 100644 index 0000000..8b3a4fa --- /dev/null +++ b/UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.c @@ -0,0 +1,317 @@ +#include <Library/BaseMemoryLib.h> +#include <Library/DevicePathLib.h> +#include <Library/HiiLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiHiiServicesLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Protocol/HiiConfigAccess.h> +#include <Protocol/Hash2.h> +#include <Protocol/ServiceBinding.h> +#include "Data.h" + +extern UINT8 FormBin[]; + +#pragma pack(1) +typedef struct { +  VENDOR_DEVICE_PATH             VendorDevicePath; +  EFI_DEVICE_PATH_PROTOCOL       End; +} HII_VENDOR_DEVICE_PATH; +#pragma pack() + +HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = { +  { +    { +      HARDWARE_DEVICE_PATH, +      HW_VENDOR_DP, +      { +        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), +        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) +      } +    }, +    DATAPATH_GUID +  }, +  { +    END_DEVICE_PATH_TYPE, +    END_ENTIRE_DEVICE_PATH_SUBTYPE, +    { +      (UINT8) (END_DEVICE_PATH_LENGTH), +      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) +    } +  } +}; + + +EFI_HII_HANDLE  mHiiHandle = NULL; +EFI_HANDLE      mDriverHandle = NULL; +EFI_HII_CONFIG_ACCESS_PROTOCOL mConfigAccess; +EFI_GUID StorageGuid = STORAGE_GUID; +EFI_STRING StorageName = L"FormData"; + +VARIABLE_STRUCTURE FormStorage; + +EFI_SERVICE_BINDING_PROTOCOL* hash2ServiceBinding; +EFI_HASH2_PROTOCOL* hash2Protocol; +EFI_HANDLE hash2ChildHandle = NULL; + +STATIC +EFI_STATUS +EFIAPI +ExtractConfig ( +  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This, +  IN CONST  EFI_STRING                      Request, +  OUT       EFI_STRING                      *Progress, +  OUT       EFI_STRING                      *Results +) +{ +  BOOLEAN AllocatedRequest = FALSE; + +  if (Progress == NULL || Results == NULL) { +    return EFI_INVALID_PARAMETER; +  } + +  if ((Request != NULL) && !HiiIsConfigHdrMatch(Request, &StorageGuid, StorageName)) { +    return EFI_NOT_FOUND; +  } + +  EFI_STRING ConfigRequest = Request; +  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { +    EFI_STRING ConfigRequestHdr = HiiConstructConfigHdr(&StorageGuid, StorageName, mDriverHandle); +    UINTN Size = (StrLen(ConfigRequestHdr) + StrLen(L"&OFFSET=0&WIDTH=") + sizeof(UINTN)*2 + 1) * sizeof(CHAR16); +    ConfigRequest = AllocateZeroPool(Size); +    AllocatedRequest = TRUE; +    UnicodeSPrint(ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, sizeof(VARIABLE_STRUCTURE)); +    FreePool(ConfigRequestHdr); +  } +  EFI_STATUS Status = gHiiConfigRouting->BlockToConfig(gHiiConfigRouting, +                                                       ConfigRequest, +                                                       (UINT8*)&FormStorage, +                                                       sizeof(VARIABLE_STRUCTURE), +                                                       Results, +                                                       Progress); + +  if (AllocatedRequest) { +    FreePool(ConfigRequest); +    if (Request == NULL) { +      *Progress = NULL; +    } else if (StrStr(Request, L"OFFSET") == NULL) { +      *Progress = Request + StrLen(Request); +    } +  } + +  return Status; +} + +STATIC +EFI_STATUS +EFIAPI +RouteConfig ( +  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This, +  IN CONST  EFI_STRING                      Configuration, +  OUT       EFI_STRING                      *Progress +) +{ +  if (Configuration == NULL || Progress == NULL) { +    return EFI_INVALID_PARAMETER; +  } + +  UINTN BlockSize = sizeof(VARIABLE_STRUCTURE); +  EFI_STATUS Status = gHiiConfigRouting->ConfigToBlock(gHiiConfigRouting, +                                                       Configuration, +                                                       (UINT8*)&FormStorage, +                                                       &BlockSize, +                                                       Progress); + +  return Status; +} + +BOOLEAN OldPasswordVerified = FALSE; + +EFI_STATUS ComputeStringHash(EFI_STRING Password, UINT8* HashedPassword) +{ +  EFI_GUID HashGuid = EFI_HASH_ALGORITHM_SHA512_GUID; +  EFI_HASH2_OUTPUT Hash; +  EFI_STATUS Status = hash2Protocol->Hash(hash2Protocol, +                                          &HashGuid, +                                          (UINT8*)Password, +                                          StrLen(Password)*sizeof(CHAR16), +                                          &Hash); +  if (EFI_ERROR(Status)) { +    return Status; +  } +  CopyMem(HashedPassword, Hash.Sha512Hash, HASHED_PASSWORD_SIZE); +  return EFI_SUCCESS; +} + +EFI_STATUS HandlePasswordInput(EFI_STRING Password) +{ +  EFI_STATUS Status; + +  if (Password[0] == 0) { +    // Form Browser checks if password exists +    if (FormStorage.Password[0] != 0) { +      return EFI_ALREADY_STARTED; +    } else { +      return EFI_SUCCESS; +    } +  } else { +    // Form Browser sends password value +    // It can be old password to check or initial/updated password to set + +    if (FormStorage.Password[0] == 0) { +      // Set initial password +      ComputeStringHash(Password, FormStorage.Password); +      if (EFI_ERROR(Status)) { +        return Status; +      } +      return EFI_SUCCESS; +    } + +    if (!OldPasswordVerified) { +      // Check old password +      UINT8 TempHash[HASHED_PASSWORD_SIZE]; +      ComputeStringHash(Password, TempHash); +      if (CompareMem(TempHash, FormStorage.Password, HASHED_PASSWORD_SIZE)) +        return EFI_NOT_READY; + +      OldPasswordVerified = TRUE; +      return EFI_SUCCESS; +    } + +    // Update password +    Status = ComputeStringHash(Password, FormStorage.Password); +    if (EFI_ERROR(Status)) { +      return Status; +    } +    OldPasswordVerified = FALSE; +    return EFI_SUCCESS; +  } +} + +STATIC +EFI_STATUS +EFIAPI +Callback ( +  IN     CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This, +  IN     EFI_BROWSER_ACTION                     Action, +  IN     EFI_QUESTION_ID                        QuestionId, +  IN     UINT8                                  Type, +  IN OUT EFI_IFR_TYPE_VALUE                     *Value, +  OUT    EFI_BROWSER_ACTION_REQUEST             *ActionRequest +  ) +{ +  EFI_STATUS Status; +  if ((QuestionId == KEY_PASSWORD) && (Action == EFI_BROWSER_ACTION_CHANGING)) { +    if (Value->string == 0) { +      return EFI_UNSUPPORTED; +    } + +    EFI_STRING Password = HiiGetString(mHiiHandle, Value->string, "en-US"); +    Status = HandlePasswordInput(Password); +    FreePool(Password); +    return Status; +  } + +  return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +PasswordFormWithHashUnload ( +  EFI_HANDLE ImageHandle +  ) +{ +  hash2ServiceBinding->DestroyChild(hash2ServiceBinding, hash2ChildHandle); + +  if (mHiiHandle != NULL) +    HiiRemovePackages(mHiiHandle); + +  EFI_STATUS Status = gBS->UninstallMultipleProtocolInterfaces( +                             mDriverHandle, +                             &gEfiDevicePathProtocolGuid, +                             &mHiiVendorDevicePath, +                             &gEfiHiiConfigAccessProtocolGuid, +                             &mConfigAccess, +                             NULL); + +  return Status; +} + +EFI_STATUS +EFIAPI +PasswordFormWithHashEntryPoint ( +  IN EFI_HANDLE        ImageHandle, +  IN EFI_SYSTEM_TABLE  *SystemTable +  ) +{ +  EFI_STATUS Status; +  Status = gBS->LocateProtocol(&gEfiHash2ServiceBindingProtocolGuid, +                               NULL, +                               (VOID **)&hash2ServiceBinding); +  if (EFI_ERROR(Status)) { +    Print(L"Error! Can't locate gEfiHash2ServiceBindingProtocolGuid: %r\n", Status); +    return Status; +  } + +  Status = hash2ServiceBinding->CreateChild(hash2ServiceBinding, +                                            &hash2ChildHandle); +  if (EFI_ERROR(Status)) { +    Print(L"Error! Can't create child on gEfiHash2ServiceBindingProtocolGuid: %r\n", Status); +    return Status; +  } + +  Status = gBS->OpenProtocol(hash2ChildHandle, +                             &gEfiHash2ProtocolGuid, +                             (VOID **)&hash2Protocol, +                             NULL, +                             hash2ChildHandle, +                             EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL); +  if (EFI_ERROR(Status)) { +    Print(L"Error! Can't open gEfiHashProtocolGuid: %r\n", Status); +    return Status; +  } + +  mConfigAccess.ExtractConfig = &ExtractConfig; +  mConfigAccess.RouteConfig   = &RouteConfig; +  mConfigAccess.Callback      = &Callback; + +  Status = gBS->InstallMultipleProtocolInterfaces( +                  &mDriverHandle, +                  &gEfiDevicePathProtocolGuid, +                  &mHiiVendorDevicePath, +                  &gEfiHiiConfigAccessProtocolGuid, +                  &mConfigAccess, +                  NULL +                  ); +  if (EFI_ERROR (Status)) { +    return Status; +  } + +  mHiiHandle = HiiAddPackages( +                 &gEfiCallerIdGuid, +                 mDriverHandle, +                 PasswordFormWithHashStrings, +                 FormBin, +                 NULL +                 ); +  if (mHiiHandle == NULL) { +    gBS->UninstallMultipleProtocolInterfaces( +           mDriverHandle, +           &gEfiDevicePathProtocolGuid, +           &mHiiVendorDevicePath, +           &gEfiHiiConfigAccessProtocolGuid, +           &mConfigAccess, +           NULL); +    return EFI_OUT_OF_RESOURCES; +  } + +  EFI_STRING ConfigStr = HiiConstructConfigHdr(&StorageGuid, StorageName, mDriverHandle); +  UINT16 DefaultId = 0; +  if (!HiiSetToDefaults(ConfigStr, DefaultId)) { +    Print(L"Error! Can't set default configuration #%d\n", DefaultId); +  } + +  return EFI_SUCCESS; +} diff --git a/UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.inf b/UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.inf new file mode 100644 index 0000000..6c25d24 --- /dev/null +++ b/UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.inf @@ -0,0 +1,28 @@ +[Defines] +  INF_VERSION                    = 1.25 +  BASE_NAME                      = PasswordFormWithHash +  FILE_GUID                      = 6dfb156a-ec61-47d2-841b-f739084add1d +  MODULE_TYPE                    = UEFI_DRIVER +  VERSION_STRING                 = 1.0 +  ENTRY_POINT                    = PasswordFormWithHashEntryPoint +  UNLOAD_IMAGE                   = PasswordFormWithHashUnload + +[Sources] +  PasswordFormWithHash.c +  Strings.uni +  Form.vfr + +[Packages] +  MdePkg/MdePkg.dec +  MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] +  UefiDriverEntryPoint +  UefiLib +  UefiHiiServicesLib +  HiiLib + +[Protocols] +  gEfiHiiConfigAccessProtocolGuid +  gEfiHash2ServiceBindingProtocolGuid +  gEfiHash2ProtocolGuid diff --git a/UefiLessonsPkg/PasswordFormWithHash/Strings.uni b/UefiLessonsPkg/PasswordFormWithHash/Strings.uni new file mode 100644 index 0000000..8e27692 --- /dev/null +++ b/UefiLessonsPkg/PasswordFormWithHash/Strings.uni @@ -0,0 +1,9 @@ +#langdef en-US "English" + +#string FORMSET_TITLE            #language en-US  "Simple Formset" +#string FORMSET_HELP             #language en-US  "This is a very simple formset" +#string FORMID1_TITLE            #language en-US  "Simple Form" +#string STANDARD_DEFAULT_PROMPT  #language en-US  "Standard default" +#string MFG_DEFAULT_PROMPT       #language en-US  "Manufacture default" +#string PASSWORD_PROMPT          #language en-US  "Password prompt" +#string PASSWORD_HELP            #language en-US  "Password help" diff --git a/UefiLessonsPkg/UefiLessonsPkg.dsc b/UefiLessonsPkg/UefiLessonsPkg.dsc index 1ca2d09..f592773 100644 --- a/UefiLessonsPkg/UefiLessonsPkg.dsc +++ b/UefiLessonsPkg/UefiLessonsPkg.dsc @@ -96,6 +96,7 @@    UefiLessonsPkg/ProtocolEventDriver/ProtocolEventDriver.inf    UefiLessonsPkg/ShowStrings/ShowStrings.inf    UefiLessonsPkg/PasswordForm/PasswordForm.inf +  UefiLessonsPkg/PasswordFormWithHash/PasswordFormWithHash.inf  #[PcdsFixedAtBuild]  #  gUefiLessonsPkgTokenSpaceGuid.PcdInt8|0x88|UINT8|0x3B81CDF1  | 
