//*********************************************************************** //* * //* Copyright (c) 1985-2021, American Megatrends International LLC. * //* * //* All rights reserved. Subject to AMI licensing agreement. * //* * //*********************************************************************** /** @file AMISetupNVLock.c This file contains the algorithm to protect the BIOS Configuration update during runtime. The variables Setup & AMITSESetup write is blocked until the system password provided to Unlock. **/ #include "AMISetupNVLock.h" #include //This function returns the value of Runtime local variable. extern BOOLEAN IsNvramRuntime(); static BOOLEAN gNvWriteProtect = FALSE; static BOOLEAN gEventsRegistered = FALSE; static BOOLEAN gSmiFlashUpdate = FALSE; static UINT16 gPasswordRetryCount = 0; static BOOLEAN gLockedInRuntime = FALSE; static BOOLEAN gSetupNvProtocolValid = FALSE; static UINT8 NvLockSetupControl=0xFF; static BOOLEAN ReadyToBootFlag = FALSE; extern HOOK_LOCK_UNLOCK_NV VALIDATE_AND_LOCK_NV_LIST EndOfLockUnlockHook; SETUPNVLOCK_MAILBOX NvLockMailbox ; //communication between DXE and SMM EFI_GUID NVLockMailboxVariableGuid = SETUPNVLOCK_MAILBOX_ADDRESS_VARIABLE_GUID; EFI_GUID gAmiSetupNvControlProtocolGuid = SETUP_NV_CONTROL_PROTOCOL_GUID; //"ValidateAndLockNvHookList" Has all hook to valiadte HOOK_LOCK_UNLOCK_NV* ValidateAndLockNvHookList[] = {VALIDATE_AND_LOCK_NV_LIST NULL}; AMI_SETUPNV_CONTROL_PROTOCOL SetupNvControl = {ToggleSmiFlashUpdateFlag}; /** This Function Registers the event call back @param *pProtocol The numeric ID of the protocol for which the event is to be registered. @param NotifyFunction The pointer to the event's notification function. @param *pNotifyContext The pointer to the notification function's context. @param *pEvent The pointer to the newly created event. @param **ppRegistration A pointer to a memory location to receive the registration value. @retval EFI_STATUS return the status **/ EFI_STATUS RegisterEventCallback ( EFI_GUID *pProtocol, EFI_EVENT_NOTIFY NotifyFunction, VOID *pNotifyContext, EFI_EVENT *pEvent, VOID **ppRegistration ) { EFI_STATUS Status; Status = pBS->CreateEvent(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, NotifyFunction, pNotifyContext, pEvent ); if (EFI_ERROR(Status)) { return Status; } return pBS->RegisterProtocolNotify(pProtocol, *pEvent, ppRegistration); } /** This Function notifies the call back for EndOfDxe and BeforeBoot event @param Event @param *Context @retval VOID **/ VOID EFIAPI AmiSetupNvEndOfDxeAndBeforeBootNotify ( EFI_EVENT Event, VOID *Context ) { EFI_STATUS Status; gNvWriteProtect = TRUE; DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: EndOfDxe or Entering OS. Lock the Variable Access")); //Set NvLockMailbox variable value with 1 NvLockMailbox.NvLockState = 1; Status = pRS->SetVariable( L"NvLockMailbox", &NVLockMailboxVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS , sizeof(NvLockMailbox), &NvLockMailbox ); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: NvLockMailbox Set Status: %r", Status)); if( EFI_ERROR(Status) ) { return; } DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock:Variable Access Locked")); return; } /** This Function notifies the call back for ReadyToBoot event to lock the protected NVRAM variables @param Event @param *Context @retval VOID **/ VOID EFIAPI AmiSetupNvReadyToBootNotify ( EFI_EVENT Event, VOID *Context ) { EFI_STATUS Status; gNvWriteProtect = TRUE; DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Entering OS. Lock the Variable Access")); //Set NvLockMailbox variable value with 1 NvLockMailbox.NvLockState = 1; Status = pRS->SetVariable( L"NvLockMailbox", &NVLockMailboxVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS , sizeof(NvLockMailbox), &NvLockMailbox ); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: NvLockMailbox Set Status: %r", Status)); if(ReadyToBootFlag == FALSE) ReadyToBootFlag = TRUE; if (EFI_ERROR(Status)){ return ; } return; } /** This Function notifies the call-back for entering into Setup. It will Unlock the protected NVRAM variables only if ReadytoBoot event not triggered before this event. @param Event @param *Context @retval VOID **/ VOID EFIAPI AmiSetupNvEnterSetupNotify ( EFI_EVENT Event, VOID *Context ) { EFI_STATUS RetStatus; gNvWriteProtect = FALSE; gLockedInRuntime = FALSE; DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: ReadyToBootFlag: %d\n",ReadyToBootFlag)); if(ReadyToBootFlag == FALSE) { //Set NvLockMailbox variable value with 0 to unlock the variable Access NvLockMailbox.NvLockState = 0; RetStatus = pRS->SetVariable( L"NvLockMailbox", &NVLockMailboxVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS , sizeof(NvLockMailbox), &NvLockMailbox ); DEBUG_SETUPNVLOCK((DEBUG_ERROR, "\nAmiSetupNvLock: Set Status: %r", RetStatus)); if( EFI_ERROR(RetStatus) ) { return; } DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock:Variable Access Unlocked")); } return; } /** This Function notifies the call back for ReEntering setup from boot option.It will Unlock the protected NVRAM variables only if system password not set. @param Event @param *Context @retval VOID **/ VOID EFIAPI AmiSetupNvReEntryNotify ( EFI_EVENT Event, VOID *Context ) { BOOLEAN PasswordInstalled; gLockedInRuntime = FALSE; PasswordInstalled = CheckPasswordState();//Checks the Password installed or not DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: AmiSetupNvReEntryNotify PasswordInstalled: %d", PasswordInstalled)); if(PasswordInstalled == AMI_PASSWORD_NONE) UnlockNv(); return; } /** This Function Registers the event for different Boot phases to lock/unlock the variable access. @param VOID @retval EFI_STATUS **/ EFI_STATUS RegisterEventsForLockUnlock() { EFI_EVENT Event; EFI_STATUS Status; static EFI_EVENT EnterSetupEvent = NULL; VOID *SetupRegistration = NULL; VOID *SetupEnterNotifyReg = NULL; VOID *BeforeBootRegistration = (VOID*) NULL; //Install Callback for Before Boot Guid (Before Booting to any boot option). Status = RegisterEventCallback( &gAmiTseEventBeforeBootGuid, AmiSetupNvEndOfDxeAndBeforeBootNotify, NULL, &Event, &BeforeBootRegistration ); #if (LOCK_SETVAR_AT_ENDOFDXE == 1) { VOID *Registration = (VOID*) NULL; // Create Callback for End of DXE event. Status = pBS->CreateEventEx(EVT_NOTIFY_SIGNAL, TPL_CALLBACK, AmiSetupNvEndOfDxeAndBeforeBootNotify, NULL, &gEfiDxeSmmReadyToLockProtocolGuid, &Event ); Status = pBS->RegisterProtocolNotify(&gEfiDxeSmmReadyToLockProtocolGuid, Event, &Registration ); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: EndOfDxe CreateEventEx Status: %r", Status)); } #endif //Install Callback for After Boot Guid ( Coming back to BIOS after boot failed). Status = RegisterEventCallback( &gAmiTseEventAfterBootGuid, AmiSetupNvReEntryNotify, NULL, &EnterSetupEvent, &SetupRegistration ); //Install callback on entering into Setup to Unlock the Variable Access Status = RegisterProtocolCallback( &gAmiTseSetupEnterGuid, AmiSetupNvEnterSetupNotify, NULL, &Event, &SetupEnterNotifyReg); return Status; } /** This Function Interface to lock NVRAM Access @param VOID @retval EFI_SUCCESS **/ EFI_STATUS LockNv() { EFI_STATUS RetStatus = EFI_UNSUPPORTED; gNvWriteProtect = TRUE; // Lock the Variable Access. NvLockMailbox.NvLockState = 1; RetStatus = DxeSetVariable( L"NvLockMailbox", &NVLockMailboxVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS , sizeof(NvLockMailbox), &NvLockMailbox ); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Access to Nvram Variables Locked Status: %r", RetStatus)); if( EFI_ERROR(RetStatus) ) { return RetStatus; } return EFI_SUCCESS; } /** This Function Interface to unlock NVRAM Variable Access @param VOID @retval EFI_SUCCESS **/ EFI_STATUS UnlockNv() { EFI_STATUS RetStatus; gNvWriteProtect = FALSE; // UNlock the Variables Access NvLockMailbox.NvLockState = 0; RetStatus = DxeSetVariable( L"NvLockMailbox", &NVLockMailboxVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS , sizeof(NvLockMailbox), &NvLockMailbox ); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Unlock the Variable Access : Status: %r", RetStatus)); if( EFI_ERROR(RetStatus) ) { return RetStatus; } return EFI_SUCCESS; } /** This Function to call all the hook functions in ValidateAndLockNvHookList @param *VariableName NV Variable Name @param *VendorGUID Variable GUID @param Attributes BS / RT / NV @param DataSize Size of the Data @param *Data Variable Data @retval EFI_STATUS **/ EFI_STATUS ValidateAndLockNvHook( IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data ) { UINTN i; EFI_STATUS Result = EFI_UNSUPPORTED; for (i = 0; ValidateAndLockNvHookList[i] && (Result == EFI_UNSUPPORTED); i++) { Result = ValidateAndLockNvHookList[i](VariableName, VendorGuid, Attributes, DataSize, Data); } return Result; } /** This Function to check whether the Variable is $SETUPPASSWD or not. If $SETUPPASSWD, Validates the password in Variable data and Locks/Unlocks NV @param *VariableName NV Variable Name @param *VendorGUID Variable GUID @param Attributes BS / RT / NV @param DataSize Size of the Data @param *Data Variable Data @retval EFI_UNSUPPORTED If Variable is not $SETUPPASSWD @retval EFI_SUCCESS If Variable is $SETUPPASSWD and data matched with admin password @retval EFI_ACCESS_DENIED Password Retry count Expired @retval EFI_NOT_READY No admin Password Set @retval EFI_SECURITY_VIOLATION If Variable is $SETUPPASSWD and data not matched with admin password **/ EFI_STATUS ValidateAndLockNv ( CHAR16 *VariableName, EFI_GUID *VendorGuid, UINT32 Attributes, UINTN DataSize, VOID *Data ) { UINT32 PasswordState = AMI_PASSWORD_NONE; CHAR16 *PassWord = (VOID*)Data; EFI_STATUS Status; if (IsSetupPasswordVariable(VariableName, VendorGuid) != TRUE){ DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Not SetupPasswd Variable.")); return EFI_UNSUPPORTED; } if (gPasswordRetryCount == 3){ DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Password Retry count Expired: Variable Access Denied")); return EFI_ACCESS_DENIED; } //Invoke the to authentication method PasswordAuthenticate PasswordState = AuthenticatePassword(PassWord, DataSize); // If the status is AMI_PASSWORD_NONE, the password is not valid ignore the write // If the status is AMI_INVALID_PASSWORD, Password verified failed. Lock the variable Access // If not, Password verification is success. Allow the Variable Access if (PasswordState == AMI_PASSWORD_NONE){ DEBUG_SETUPNVLOCK((DEBUG_INFO, "\n AmiSetupNvLock: No Password Set. Lock the Variable Access")); LockNv(); // If no Password Set in the System Status = EFI_NOT_READY; } else if (PasswordState == AMI_INVALID_PASSWORD){ DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Password Verification failed.")); if(gNvWriteProtect == TRUE){ // Increment the Password retry Count gPasswordRetryCount++; } else { gPasswordRetryCount = 0; } LockNv(); //When Invalid password is provided for validation Status = EFI_SECURITY_VIOLATION; } else { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Password Verification passed: Unlock the Variable Accesss in Nv")); //If the status is ADMIN, then update the gNvWriteProtect with FALSE UnlockNv(); Status = EFI_SUCCESS; gPasswordRetryCount = 0; } return Status; } /** Hook for the Variable Write Method SetVariableHook(). This method should not allow the Write Calls for Setup / AMITSESetup until the password provided in SETUPPASSWD variable. @param *VariableName NV Variable Name @param *VendorGUID Variable GUID @param Attributes BS / RT / NV @param DataSize Size of the Data @param *Data Variable Data @retval EFI_SECURITY_VIOLATION NV Locked, The variable could not be updated @retval EFI_UNSUPPORTED Variable could be updated **/ EFI_STATUS AmiSetupNvWriteHook( CHAR16 *VariableName, EFI_GUID *VendorGuid, UINT32 Attributes, UINTN DataSize, VOID *Data ) { EFI_STATUS Status = EFI_UNSUPPORTED; EFI_STATUS RetStatus = EFI_UNSUPPORTED; EFI_GUID SetupPwdGuid = SETUPPASSWD_GUID; UINTN VarSize = sizeof(NvLockMailbox); // Get the variable and check the Nvram Variable Access Protocol Support. // NvLockSetupControl =0xFF, it's getting called 1st time to initialize the variable. if(NvLockSetupControl == 0xFF) { SETUP_DATA NvLockSetupVariable = {0}; UINTN SetupVarSize = sizeof(NvLockSetupVariable); Status = DxeGetVariable(L"Setup", &gAmiSetupVariableGuid, NULL, &SetupVarSize, &NvLockSetupVariable ); if(!EFI_ERROR(Status)){ NvLockSetupControl=NvLockSetupVariable.NvLockSetupControl; } } // Setup NvLock is disabled. Allow the Access to all the variables. if(NvLockSetupControl == 0) { return EFI_UNSUPPORTED; } // Protect the NvLockMailBox variable in Runtime as this variable is used by this driver alone // Not allowed to use it from any other driver if (!Wcscmp(VariableName, L"NvLockMailbox") && (guidcmp(VendorGuid, &NVLockMailboxVariableGuid) == FALSE)){ //If Variable has EFI_VARIABLE_RUNTIME_ACCESS,Block the access if ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == EFI_VARIABLE_RUNTIME_ACCESS){ DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: NvLockMailBox Access Blocked")); return EFI_ACCESS_DENIED; } else{ return EFI_UNSUPPORTED ; } } // During Dxe phase, initilize the events if it's not yet registered. This is expected to // get called only one. if(pSmst == NULL && !gEventsRegistered) { DeletePasswordVariable(); RegisterEventsForLockUnlock(); gEventsRegistered = TRUE; } // Install NvControlProtocol once if in SMM // Lock the Variable Access if it's Runtime if(pSmst != NULL){ //When entering Runtime, SetVariable for BOOTSERVICE_ACCESS variable will fail. //So use this to identify Runtime entry and enable Lock for Runtime. if(FALSE == gLockedInRuntime) { if(IsNvramRuntime()== TRUE) { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: RunTime Lock Applied")); LockNv(); gLockedInRuntime = TRUE; } } // Protocol installation called only once. if(FALSE == gSetupNvProtocolValid) { RetStatus = InstallSetupNvControlProtocol(); if(RetStatus == EFI_SUCCESS) gSetupNvProtocolValid = TRUE; } } // Sync the NvWriteProtect Between SMM and Non SMM Nv variable access code. if((gSmiFlashUpdate == FALSE) && (FALSE == gLockedInRuntime)) { // If Variable is present, Control comes in SMM phase first time after ReadyToBoot. RetStatus = DxeGetVariable(L"NvLockMailbox", &NVLockMailboxVariableGuid, NULL, &VarSize, &NvLockMailbox ); if(RetStatus == EFI_SUCCESS ) { //Based on Lock state, Lock/Unlock NV if(NvLockMailbox.NvLockState == 1) { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Write Protect Enabled")); gNvWriteProtect = TRUE; } else { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Write Protect Disabled")); gNvWriteProtect = FALSE; } } else { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: NvLockMailBox Variable Not Found !!: %r", RetStatus)); } } // Validate the Admin and user password Status = ValidateAndLockNvHook(VariableName, VendorGuid, Attributes, DataSize, Data); // The input Variable is not Password variable. Handle the Variable Function. // 1. Password can be modified in runtime // 2. Verify the Protected variable list. Based on the Nv Write Protect Status, return the status to caller if (EFI_UNSUPPORTED == Status){ int Index = 0; SETUP_VARIABLE_DATA ProtectedVarList[] = {PROTECTED_VARIABLE_LIST {"", NULL_GUID}}; int Varcount = sizeof(ProtectedVarList)/sizeof(SETUP_VARIABLE_DATA); CHAR8 VarNameinChar8[256] = {0}; //Set the Setup Password Admin or User Using $SETADMINPASSWD and $SETUSERPASSWD Variables if( ((guidcmp(VendorGuid, &SetupPwdGuid) == FALSE) && (Wcscmp((CHAR16 *)VariableName, (CHAR16 *)SET_ADMINPASS_VAR_NAME) == FALSE) )|| \ ((guidcmp(VendorGuid, &SetupPwdGuid) == FALSE) && (Wcscmp((CHAR16 *)VariableName, (CHAR16 *)SET_USERPASS_VAR_NAME) == FALSE)) ) { Status = ValidateAndSetSetupPwd(VariableName, VendorGuid, Attributes, DataSize, Data); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Set the Admin/User Password Status: %r\n", Status)); return Status; } UnicodeStrToAsciiStrS(VariableName,VarNameinChar8,256); // Check if the variable is present in the protected List. If the variable is present Protected List // Based on the NvWriteProtect, allow the access to the variable. For other variables, access it allowed. for(Index = 0; Index < Varcount; Index++) { if((Strcmp(VarNameinChar8, (ProtectedVarList[Index].VariableName)) == 0) && \ (guidcmp(VendorGuid, &(ProtectedVarList[Index].VariableGuid)) == 0)) { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: AmiSetupNvWriteHook: Security Violation Check for: Var: %a, %x, %x", VarNameinChar8, gNvWriteProtect, gSmiFlashUpdate)); //If the Write is Protected enabled for the NV report EFI_SECURITY_VIOLATION if ((gNvWriteProtect == TRUE) && (gSmiFlashUpdate == FALSE)) { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: AmiSetupNvWriteHook: Security Violation for the Variable")); Status = EFI_SECURITY_VIOLATION; } break; } } } if(Status == EFI_UNSUPPORTED) DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Variable Access allowed. \n")); return Status; } /** Function to update the global flag to check for flash update @param Start TRUE or FALSE @retval EFI_STATUS **/ EFI_STATUS ToggleSmiFlashUpdateFlag ( BOOLEAN Start) { gSmiFlashUpdate = !Start; DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Setting gSmiFlashUpdate to %d", gSmiFlashUpdate)); return EFI_SUCCESS; } /** Function to install the NVControl protocol @param VOID @retval EFI_STATUS **/ EFI_STATUS InstallSetupNvControlProtocol() { EFI_STATUS status = EFI_NOT_READY; if (pSmst != NULL) { status = pSmst->SmmInstallConfigurationTable( pSmst, &gAmiSetupNvControlProtocolGuid, &SetupNvControl, sizeof(SetupNvControl) ); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Install Setup Nv Protocol Status: %r", status)); } return status; } /** Function to set the Setup Password (User or Admin) @param *VariableName NV Variable Name @param *VendorGUID Variable GUID @param Attributes BS / RT / NV @param DataSize Size of the Data @param *Data Variable Data @retval EFI_STATUS **/ EFI_STATUS ValidateAndSetSetupPwd ( CHAR16 *VariableName, EFI_GUID *VendorGuid, UINT32 Attributes, UINTN DataSize, VOID *Data ) { EFI_STATUS Status = EFI_UNSUPPORTED; CHAR16 *PassWord = (VOID*)Data; if (FALSE == gNvWriteProtect){ DEBUG_SETUPNVLOCK((DEBUG_INFO, "\n AmiSetupNvLock: ValidateAndSetSetupPwd Received Password Length: %d", DataSize)); #if (SETUP_STORE_KEYCODE_PASSWORD == 0) //For Unicode Password,exclude the size of NULL for PasswordSize if ( ( DataSize >= 2 ) && ( L'\0' == PassWord[(DataSize/2) -1] ) ) { DataSize = DataSize - 2; DEBUG_SETUPNVLOCK((DEBUG_INFO, "\n AmiSetupNvLock: ValidateAndSetSetupPwd Modified Password Length: %d", DataSize)); } #endif //Password length should be minimum PASSWORD_MIN_SIZE chars and //maximum is TSE_PASSWORD_LENGTH if ((DataSize < (PASSWORD_MIN_SIZE * sizeof(CHAR16)) ) || \ (DataSize > (TSE_PASSWORD_LENGTH * sizeof(CHAR16)) )) { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: ValidateAndSetSetupPwd Invalid Length: %d", DataSize)); Status = EFI_INVALID_PARAMETER; } else { Status = SetPassword(VariableName, Data, DataSize); DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: ValidateAndSetSetupPwd: SetPassword Status: %r",Status)); } } else { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: ValidateAndSetSetupPwd SetPassword: Nv write protected")); Status = EFI_SECURITY_VIOLATION; } return Status; } /** Function to Check the System password installed or not @param void @retval Boolean **/ BOOLEAN CheckPasswordState() { UINTN TsePasswordLength = TSE_PASSWORD_LENGTH; EFI_STATUS Status = EFI_SUCCESS; EFI_GUID TseSetupGuid = AMITSESETUP_GUID; AMITSESETUP *mSysConf = NULL; UINT16 OutBuffer[sizeof(AMITSESETUP)]; UINT16 EmptyPass[TSE_PASSWORD_LENGTH+1]; UINT32 SetupDataAttributes = 0; UINTN SetupDataSize = sizeof(AMITSESETUP); Status = DxeGetVariable(TSE_SETUP_VAR_NAME, &TseSetupGuid, &SetupDataAttributes, &SetupDataSize, &OutBuffer ); if (EFI_SUCCESS != Status) { return FALSE; } mSysConf = (AMITSESETUP *)OutBuffer; MemSet( EmptyPass, (TsePasswordLength + 1)*sizeof(CHAR16), 0 ); if ((!MemCmp(EmptyPass, mSysConf->AdminPassword, TsePasswordLength * sizeof(CHAR16))) && \ (!MemCmp(EmptyPass, mSysConf->UserPassword, TsePasswordLength * sizeof(CHAR16)))) { DEBUG_SETUPNVLOCK((DEBUG_INFO, "\nAmiSetupNvLock: Input Password is Empty")); return FALSE; // Admin and user password not Set. } else return TRUE; }