diff options
Diffstat (limited to 'Board/EM/MeWrapper/AtAmUi/AtAmUi.c')
-rw-r--r-- | Board/EM/MeWrapper/AtAmUi/AtAmUi.c | 1120 |
1 files changed, 1120 insertions, 0 deletions
diff --git a/Board/EM/MeWrapper/AtAmUi/AtAmUi.c b/Board/EM/MeWrapper/AtAmUi/AtAmUi.c new file mode 100644 index 0000000..8a2cffe --- /dev/null +++ b/Board/EM/MeWrapper/AtAmUi/AtAmUi.c @@ -0,0 +1,1120 @@ +/** @file + This file contines rouines responsible for handling the UI. + +@copyright + Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement + +**/ +#include "AtAmUi.h" +#include EFI_PROTOCOL_CONSUMER (ConsoleControl) +#include EFI_PROTOCOL_CONSUMER (GraphicsOutput) +DXE_AT_POLICY_PROTOCOL *mDxePlatformAtPolicy; +EFI_GUID gAlertAtHandlerGuid = ME_ALERT_AT_HANDLER_GUID; +EFI_GUID gEfiAtAmProtocolGuid = EFI_ATAM_PROTOCOL_GUID; +EFI_EVENT gAlertAtHandlerEvent; +EFI_ATAM_PROTOCOL *mAtAm = NULL; + +// +// Driver entry point +// +EFI_DRIVER_ENTRY_POINT (AtAmUiEntryPoint); + +/** + ATAM UI driver entry point. + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_UNSUPPORTED The function is unsupported by this driver +**/ +EFI_STATUS +AtAmUiEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + EfiInitializeDriverLib (ImageHandle, SystemTable); + Status = gBS->LocateProtocol ( + &gDxePlatformAtPolicyGuid, + NULL, + &mDxePlatformAtPolicy + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: No AT Platform Policy Protocol available")); + return Status; + } + ASSERT_EFI_ERROR (Status); + + if (mDxePlatformAtPolicy->At.AtAmBypass == 1) { + return EFI_SUCCESS; + } + + if (mAtAm == NULL) { + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol failed, Status = %r\n", Status)); + return Status; + } else { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol success, Status = %r\n", Status)); + } + } + + Status = gBS->CreateEventEx ( + EFI_EVENT_NOTIFY_SIGNAL, + EFI_TPL_CALLBACK, + AtAmUiCallback, + NULL, + &gAlertAtHandlerGuid, + &gAlertAtHandlerEvent + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AT - Error Creating Event to Process Suspend Mode\n")); + } + + return Status; +} +EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl; +EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; +EFI_CONSOLE_CONTROL_SCREEN_MODE ScreenMode; +EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *GraphicsModeInfo; +UINTN UgaBltSize = 0; +EFI_UGA_PIXEL *UgaBlt = NULL; +INT32 TextMode; +UINTN StyleGetTextMode(); + +VOID +GraphicsSave +( + VOID +) +{ + UINTN SizeOfGraphicsModeInfo; + + EFI_STATUS + Status = gBS->LocateProtocol( &gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl); + + if(EFI_ERROR(Status)) + { + ConsoleControl = NULL; + return; + } + + Status = ConsoleControl->GetMode(ConsoleControl, &ScreenMode, NULL, NULL); + if(ScreenMode == EfiConsoleControlScreenText) + { + ConsoleControl = NULL; + return; + } + + Status = gBS->LocateProtocol( &gEfiGraphicsOutputProtocolGuid, NULL, &GraphicsOutput); + if(EFI_ERROR(Status)) + { + GraphicsOutput = NULL; + return; + } + + Status = GraphicsOutput->QueryMode( GraphicsOutput, GraphicsOutput->Mode->Mode, + &SizeOfGraphicsModeInfo ,&GraphicsModeInfo); + if(EFI_ERROR(Status)) + { + GraphicsModeInfo = NULL; + return; + } + + UgaBltSize = GraphicsModeInfo->HorizontalResolution * + GraphicsModeInfo->VerticalResolution * + sizeof(EFI_UGA_PIXEL); + + UgaBlt = AllocateZeroPool (UgaBltSize); + if( UgaBlt == NULL ) + return; + + Status = GraphicsOutput->Blt( + GraphicsOutput, + UgaBlt, + EfiBltVideoToBltBuffer, + 0, 0, + 0, 0, + GraphicsModeInfo->HorizontalResolution, + GraphicsModeInfo->VerticalResolution, + 0); + + Status = ConsoleControl->SetMode( ConsoleControl, EfiConsoleControlScreenText ); + TextMode = gST->ConOut->Mode->Mode; + gST->ConOut->SetMode(gST->ConOut, StyleGetTextMode()); +} + +VOID +GraphicsRestore +( + VOID +) +{ + if(!ConsoleControl) + return; + + gST->ConOut->SetMode(gST->ConOut, TextMode); + ConsoleControl->SetMode( ConsoleControl, EfiConsoleControlScreenGraphics ); + + if(!GraphicsOutput) + return; + + if(!UgaBlt || !GraphicsModeInfo) + return; + + GraphicsOutput->Blt( + GraphicsOutput, + UgaBlt, + EfiBltBufferToVideo, + 0, 0, + 0, 0, + GraphicsModeInfo->HorizontalResolution, + GraphicsModeInfo->VerticalResolution, + 0); + + ZeroMem(UgaBlt, UgaBltSize); + FreePool(UgaBlt); +} +/** + ATAM UI callback. + + @param[in] Event The event registered + @param[in] Context Event context. Not used in this event handler. + + @retval None +**/ +VOID +EFIAPI +AtAmUiCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + DXE_AT_POLICY_PROTOCOL *pAtPlatformPolicy; + AT_STATE_INFO AtStateInfo; + EFI_TPL TplBackup; + + pAtPlatformPolicy = NULL; + + DEBUG ((EFI_D_ERROR, "ATAM: AtAmUiCallback \n")); + // + // change TPL to APPLICATION as required by ConIn to function + // + TplBackup = gBS->RaiseTPL (TPL_HIGH_LEVEL); + gBS->RestoreTPL (TplBackup); + if (TplBackup != TPL_APPLICATION) { + gBS->RestoreTPL(TPL_APPLICATION); + } + + Status = gBS->LocateProtocol ( + &gDxePlatformAtPolicyGuid, + NULL, + (VOID **) &pAtPlatformPolicy + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM LocateProtocol failed. \n")); + } + + if (mAtAm == NULL) { + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol failed, Status = %r\n", Status)); + } + } + + mAtAm->AtAmGetAtStateInfo (mAtAm, &AtStateInfo); + + if (AtStateInfo.State == AT_STATE_STOLEN && pAtPlatformPolicy->At.AtPba == 1 && pAtPlatformPolicy->At.AtSupported == 0) { + AtAmUiTheftNotification (); + + } else if (AtStateInfo.State == AT_STATE_STOLEN && AtStateInfo.flags.LockState == 1 && AtStateInfo.flags.AuthenticateModule == AT_AM_SELECTION_ATAM) { + GraphicsSave(); + AtAmUiRecovery (); + GraphicsRestore(); + } else if (AtStateInfo.State == AT_STATE_SUSPEND) { + GraphicsSave(); + AtAmUiExitSuspendState (); + GraphicsRestore(); + } else if (AtStateInfo.State == AT_STATE_ACTIVE) { + if (pAtPlatformPolicy->At.AtEnterSuspendState) { + GraphicsSave(); + AtAmUiEnterSuspendState (); + GraphicsRestore(); + } + } + + // + // Restore TPL + // + if (TplBackup != TPL_APPLICATION) { + gBS->RaiseTPL(TplBackup); + } + + + return; +} + +/** + Function handling entering suspend mode. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +AtAmUiEnterSuspendState ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 *PasswordASCII; + CHAR16 *PasswordUNICODE; + CHAR16 *UniCodeNonceStr; + UINT32 NumOfAttempts; + UINT8 NonceStr[STR_NONCE_LENGTH]; + UINT32 CRow; + UINT32 CCol; + UINT8 *IsvString; + UINT32 IsvId; + AT_BIOS_RECOVERY_CONFIG RecoveryConfig; + + Status = EFI_SUCCESS; + NumOfAttempts = ATAMUI_SUSPEND_ATTEMPTS; + + UniCodeNonceStr = AllocateZeroPool ((STR_NONCE_LENGTH + 1) * sizeof (CHAR16)); + PasswordASCII = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + PasswordUNICODE = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR16)); + IsvString = AllocateZeroPool ((RECOVERY_STRING_LENGTH + 1) * sizeof (UINT8)); + + if (PasswordASCII == NULL || PasswordUNICODE == NULL || UniCodeNonceStr == NULL || IsvString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (mAtAm == NULL) { + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol failed, Status = %r\n", Status)); + } + } + + AtAmUiStrGetCursor (&CRow, &CCol); + + do { + AtAmUiStrClearScreen (); + + RecoveryConfig.IsvPlatformId[0] = L'\0'; + Status = mAtAm->AtAmGetRecoveryConfig (mAtAm, &RecoveryConfig); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetRecoveryConfig command failed, Status = %r\n", Status)); + } + if (RecoveryConfig.IsvPlatformId[0] != L'\0') { + AtAmUiStrSetCursor(4, 13); + AtAmUiStrDisplayFix (STR_ATAMUI_PLATFORM_ID, FALSE); + AtAmUiStrDisplay ((CHAR16 *) RecoveryConfig.IsvPlatformId); + } + + AtAmUiStrSetCursor(4, 14); + Status = mAtAm->AtAmGetIsvId (mAtAm, IsvString, &IsvId); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetIsvId command failed, Status = %r\n", Status)); + } + AtAmUiStrDisplay ((CHAR16 *) IsvString); + + AtAmUiStrEnableCursor (FALSE); + + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ENTER_INFO, TRUE); + + AtAmUiStrSetCursor (4, 2); + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_REFER, FALSE); + Status = mAtAm->AtAmGetNonce (mAtAm, NonceStr); + if (Status == EFI_SUCCESS) { + Uint8ToUnicode (NonceStr, UniCodeNonceStr); + AtAmUiStrDisplay ((UINT16 *) UniCodeNonceStr); + } else { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_NONCE_FAILED, FALSE); + DEBUG ((EFI_D_ERROR, "ATAM: Get Nonce failed, Status = %r\n", Status)); + } + + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ENTER_TOKEN, TRUE); + AtAmUiStrEnableCursor (TRUE); + AtAmUiGetPassword (PasswordASCII, ATAM_SETUP_PASSWORD_LENGTH, PasswordUNICODE, 1); + AtAmUiStrEnableCursor (FALSE); + + Status = mAtAm->AtAmSetSuspendState (mAtAm, ATAM_ENTER_SUSPEND_STATE, PasswordASCII); + if (Status != EFI_SUCCESS) { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ENTER_FAILED, TRUE); + AtAmUiDelay (2 * AT_AM_UI_1_SECOND); + } + + } while (--NumOfAttempts && (Status != EFI_SUCCESS)); + + if (Status == EFI_SUCCESS) { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ENTER_SUCCESS, TRUE); + } else { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ATTEMPT_EXC, TRUE); + } + + ZeroMem (UniCodeNonceStr, (STR_NONCE_LENGTH + 1) * sizeof (UINT16)); + ZeroMem (PasswordASCII, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR8)); + ZeroMem (PasswordUNICODE, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR16)); + + FreePool (UniCodeNonceStr); + FreePool (PasswordASCII); + FreePool (PasswordUNICODE); + + AtAmUiDelay (AT_AM_UI_1_SECOND); + + AtAmUiStrClearScreen (); + AtAmUiStrSetCursor (CCol, CRow); + + return Status; +} + +/** + Function handling exiting suspend mode. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +AtAmUiExitSuspendState ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 *PasswordASCII; + CHAR16 *PasswordUNICODE; + CHAR16 *UniCodeNonceStr; + UINT32 NumOfAttempts; + UINT8 NonceStr[STR_NONCE_LENGTH]; + EFI_INPUT_KEY Key; + UINT32 CRow; + UINT32 CCol; + UINT8 *IsvString; + UINT32 IsvId; + AT_BIOS_RECOVERY_CONFIG RecoveryConfig; + + Status = EFI_SUCCESS; + NumOfAttempts = 3; + + UniCodeNonceStr = AllocateZeroPool ((STR_NONCE_LENGTH + 1) * sizeof (CHAR16)); + PasswordASCII = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + PasswordUNICODE = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR16)); + IsvString = AllocateZeroPool ((RECOVERY_STRING_LENGTH + 1) * sizeof (UINT8)); + + if (PasswordASCII == NULL || PasswordUNICODE == NULL || UniCodeNonceStr == NULL || IsvString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (mAtAm == NULL) { + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol failed, Status = %r\n", Status)); + } + } + + AtAmUiStrGetCursor (&CRow, &CCol); + + do { + AtAmUiStrClearScreen (); + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_EXIT_QUESTION, TRUE); + + AtAmUiStrGetChar (&Key); + if (Key.UnicodeChar == L'y' || Key.UnicodeChar == L'Y' || Key.UnicodeChar == L'n' || Key.UnicodeChar == L'N') { + AtAmUiStrEnableCursor(FALSE); + break; + } + } while (1); + + if (Key.UnicodeChar == L'y' || Key.UnicodeChar == L'Y') { + do { + AtAmUiStrClearScreen (); + + RecoveryConfig.IsvPlatformId[0] = L'\0'; + Status = mAtAm->AtAmGetRecoveryConfig (mAtAm, &RecoveryConfig); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetRecoveryConfig command failed, Status = %r\n", Status)); + } + if (RecoveryConfig.IsvPlatformId[0] != L'\0') { + AtAmUiStrSetCursor(4, 13); + AtAmUiStrDisplayFix (STR_ATAMUI_PLATFORM_ID, FALSE); + AtAmUiStrDisplay ((CHAR16 *) RecoveryConfig.IsvPlatformId); + } + + AtAmUiStrSetCursor(4, 14); + Status = mAtAm->AtAmGetIsvId (mAtAm, IsvString, &IsvId); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetIsvId command failed, Status = %r\n", Status)); + } + AtAmUiStrDisplay ((CHAR16 *) IsvString); + + AtAmUiStrEnableCursor (FALSE); + + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_EXIT_INFO, TRUE); + + AtAmUiStrSetCursor (4, 3); + AtAmUiStrDisplayFix (STR_ATAMUI_RES_REFER, FALSE); + mAtAm->AtAmGetNonce (mAtAm, NonceStr); + Uint8ToUnicode (NonceStr, UniCodeNonceStr); + AtAmUiStrDisplay ((UINT16 *) UniCodeNonceStr); + + AtAmUiStrSetCursor (4, 4); + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ENTER_TOKEN, FALSE); + + AtAmUiStrEnableCursor (TRUE); + AtAmUiGetPassword (PasswordASCII, ATAM_SETUP_PASSWORD_LENGTH, PasswordUNICODE, 1); + AtAmUiStrEnableCursor (FALSE); + + AtAmUiStrDisplayFix (STR_ATAMUI_CHECKING_AUTHENT, TRUE); + + Status = mAtAm->AtAmSetSuspendState (mAtAm, ATAM_EXIT_SUSPEND_STATE, PasswordASCII); + if (Status != EFI_SUCCESS) { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_AUTH_FAILED, FALSE); + AtAmUiDelay (AT_AM_UI_1_SECOND); + } + + AtAmUiDelay (AT_AM_UI_1_SECOND); + } while (--NumOfAttempts && (Status != EFI_SUCCESS)); + + if (Status == EFI_SUCCESS) { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_EXIT_SUCCESS, TRUE); + + } else { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_ATTEMPT_EXC, TRUE); + AtAmUiDelay (AT_AM_UI_1_SECOND); + } + } else if (Key.UnicodeChar == L'n' || Key.UnicodeChar == L'N') { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_STAY, TRUE); + AtAmUiDelay (2 *AT_AM_UI_1_SECOND); + } + + ZeroMem (UniCodeNonceStr, (STR_NONCE_LENGTH + 1) * sizeof (UINT16)); + ZeroMem (PasswordASCII, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR8)); + ZeroMem (PasswordUNICODE, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR16)); + + FreePool (UniCodeNonceStr); + FreePool (PasswordASCII); + FreePool (PasswordUNICODE); + + AtAmUiDelay (AT_AM_UI_1_SECOND); + + AtAmUiStrClearScreen (); + AtAmUiStrSetCursor (CCol, CRow); + + return Status; +} + +VOID +EFIAPI +ShowAtTimerCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINT32 TimerLeft; + UINT32 TimerInterval; + static CHAR16 *TimeLeftStr = NULL; + EFI_STATUS Status; + UINT32 CRow; + UINT32 CCol; + + if(!TimeLeftStr) + TimeLeftStr = AllocateZeroPool ((ATAM_TIMER_STRING_LENGTH + 1) * sizeof (CHAR16)); + + AtAmUiStrGetCursor (&CRow, &CCol); + Status = mAtAm->AtAmGetTimer (mAtAm, &TimerLeft, &TimerInterval); + + if(EFI_ERROR(Status)) + return; + + UnicodeValueToString (TimeLeftStr, 0, TimerLeft, 0); + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT, TRUE); + AtAmUiStrDisplay ((CHAR16 *) TimeLeftStr); + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT_SEC,FALSE); + + AtAmUiStrSetCursor(CCol,CRow); +} +// Set the default TEXT MODE resolution the same with TSE +#define MAX_ROWS (UINT8)(31) +#define MAX_COLS (UINT8)(100) +UINTN StyleGetTextMode() +{ + EFI_STATUS Status; + INT32 i; + UINTN ModeRows, ModeCols; + + + // Default Implementation + for ( i = 0; i < gST->ConOut->Mode->MaxMode; i++ ) + { + Status = gST->ConOut->QueryMode( gST->ConOut, i, &ModeCols, &ModeRows ); + + if ( EFI_ERROR( Status ) ) + continue; + + if ( ( MAX_COLS <= ModeCols ) && ( MAX_ROWS <= ModeRows ) ) + return i; + } + + // return MaxMode if the mode wasn't found + return i; +} +/** + Function handling recovery proccess. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +AtAmUiRecovery ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + UINT32 PassType; + UINT8 IsAuthenticated; + AT_STATE_INFO StateInfo; + UINT32 TimerLeft; + UINT32 TimerInterval; + UINT8 *PasswordASCII; + CHAR16 *PasswordUNICODE; + CHAR16 *TimeLeftStr; + UINT8 *IsvString; + UINT32 CRow; + UINT32 CCol; + UINT32 NumberOfAttempts; + UINT32 IsvId; + CHAR16 *UniCodeNonceStr; + UINT8 NonceStr[STR_NONCE_LENGTH]; + + IsAuthenticated = 0; + + PasswordASCII = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + PasswordUNICODE = AllocateZeroPool ((ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR16)); + TimeLeftStr = AllocateZeroPool ((ATAM_TIMER_STRING_LENGTH + 1) * sizeof (CHAR16)); + IsvString = AllocateZeroPool ((RECOVERY_STRING_LENGTH + 1) * sizeof (UINT8)); + UniCodeNonceStr = AllocateZeroPool ((STR_NONCE_LENGTH + 1) * sizeof (CHAR16)); + + if (PasswordASCII == NULL || PasswordUNICODE == NULL || TimeLeftStr == NULL || IsvString == NULL || UniCodeNonceStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (mAtAm == NULL) { + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol failed, Status = %r\n", Status)); + } + } + + AtAmUiStrGetCursor (&CRow, &CCol); + + NumberOfAttempts = 3; + + do { + AtAmUiStrClearScreen (); + AtAmUiDisplayIsvStrings (); + + do { + AtAmUiStrEnableCursor (FALSE); + + AtAmUiStrSetCursor(4, 20); + Status = mAtAm->AtAmGetIsvId (mAtAm, IsvString, &IsvId); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetIsvId command failed, Status = %r\n", Status)); + } + AtAmUiStrDisplay ((CHAR16 *) IsvString); + + mAtAm->AtAmGetAtStateInfo (mAtAm, &StateInfo); + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_DUE_TO, TRUE); + switch (StateInfo.LastTheftTrigger) { + case 1: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_TIME, FALSE); + break; + + case 2: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_STOLEN, FALSE); + break; + + case 3: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_THRESHOLD, FALSE); + break; + + case 4: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_ATTACK, FALSE); + + default: + break; + } + + mAtAm->AtAmGetTimer (mAtAm, &TimerLeft, &TimerInterval); + UnicodeValueToString (TimeLeftStr, 0, TimerLeft, 0); + + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT, TRUE); + AtAmUiStrDisplay ((CHAR16 *) TimeLeftStr); + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT_SEC,FALSE); + + AtAmUiStrDisplayFix (STR_ATAMUI_SELECT_PASS, TRUE); + + AtAmUiStrDisplayFix (STR_ATAMUI_SELECT_OPTION, TRUE); + + AtAmUiStrGetChar (&Key); + if (Key.UnicodeChar == L'1' || Key.UnicodeChar == L'2') { + break; + } + + AtAmUiStrDisplayFix (STR_ATAMUI_INVALID_SELECT, TRUE); + } while (1); + + AtAmUiStrClearScreen (); + AtAmUiDisplayIsvStrings (); + AtAmUiStrSetCursor(4, 20); + AtAmUiStrDisplay ((CHAR16 *) IsvString); + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_DUE_TO, TRUE); + switch (StateInfo.LastTheftTrigger) { + case 1: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_TIME, FALSE); + break; + + case 2: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_STOLEN, FALSE); + break; + + case 3: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_THRESHOLD, FALSE); + break; + + case 4: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_ATTACK, FALSE); + + default: + break; + } + mAtAm->AtAmGetTimer (mAtAm, &TimerLeft, &TimerInterval); + UnicodeValueToString (TimeLeftStr, 0, TimerLeft, 0); + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT, TRUE); + AtAmUiStrDisplay ((CHAR16 *) TimeLeftStr); + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT_SEC,FALSE); + + switch (Key.UnicodeChar) { + case L'1': + PassType = AT_CREDENTIAL_TYPE_USER_PASSPHRASE; + AtAmUiStrDisplayFix (STR_ATAMUI_USER_PASS, TRUE); + AtAmUiStrDisplayFix (STR_ATAMUI_RECO_ENTER_PASS, TRUE); + AtAmUiStrEnableCursor (TRUE); + AtAmUiGetPassword (PasswordASCII, ATAM_SETUP_PASSWORD_LENGTH, PasswordUNICODE, 0); + AtAmUiStrEnableCursor (FALSE); + AtAmUiStrDisplayFix (STR_ATAMUI_CHECKING_PASS, TRUE); + AtAmUiDelay (AT_AM_UI_1_SECOND); + Status = mAtAm->AtAmVerifyPassword (mAtAm, PasswordASCII, PassType, &IsAuthenticated); + DEBUG ((EFI_D_ERROR, "ATAM: IsAuthenticated %x\n", IsAuthenticated)); + + break; + + case L'2': + AtAmUiStrDisplayFix (STR_ATAMUI_RECO_REFER, TRUE); + Status = mAtAm->AtAmGetNonce (mAtAm, NonceStr); + if (Status == EFI_SUCCESS) { + Uint8ToUnicode (NonceStr, UniCodeNonceStr); + AtAmUiStrDisplay ((UINT16 *) UniCodeNonceStr); + } else { + AtAmUiStrDisplayFix (STR_ATAMUI_SUS_NONCE_FAILED, FALSE); + DEBUG ((EFI_D_ERROR, "ATAM: Get Nonce failed, Status = %r\n", Status)); + } + AtAmUiStrDisplayFix (STR_ATAMUI_SERV_BASED_RECOV, TRUE); + AtAmUiStrSetCursor(4, 6); + AtAmUiStrDisplayFix (STR_ATAMUI_RECO_SEC_TOKEN, FALSE); + + PassType = AT_CREDENTIAL_TYPE_SRTK; + + AtAmUiStrEnableCursor (TRUE); + AtAmUiGetPassword (PasswordASCII, ATAM_SETUP_PASSWORD_LENGTH, PasswordUNICODE, 1); + AtAmUiStrEnableCursor (FALSE); + + AtAmUiStrDisplayFix (STR_ATAMUI_CHECKING_PASS, TRUE); + AtAmUiDelay (AT_AM_UI_1_SECOND); + Status = mAtAm->AtAmVerifyPassword (mAtAm, PasswordASCII, PassType, &IsAuthenticated); + DEBUG ((EFI_D_ERROR, "ATAM: IsAuthenticated %x\n", IsAuthenticated)); + + break; + + default: + DEBUG ((EFI_D_ERROR, "ATAM: Option not supported. \n")); + + break; + } + + ZeroMem (PasswordASCII, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (UINT8)); + ZeroMem (PasswordUNICODE, (ATAM_SETUP_PASSWORD_LENGTH + 1) * sizeof (CHAR16)); + + NumberOfAttempts--; + + if (NumberOfAttempts && IsAuthenticated == 0) { + AtAmUiStrDisplayFix (STR_ATAMUI_RECO_TRY_AGAIN, TRUE); + AtAmUiDelay (AT_AM_UI_1_SECOND); + } + + } while (NumberOfAttempts && (IsAuthenticated == 0)); + + FreePool (TimeLeftStr); + FreePool (PasswordASCII); + FreePool (PasswordUNICODE); + FreePool (IsvString); + FreePool (UniCodeNonceStr); + + if (IsAuthenticated == 1) { + AtAmUiStrDisplayFix (STR_ATAMUI_RECO_SUCCESS, TRUE); + AtAmUiDelay (2 * AT_AM_UI_1_SECOND); + } else { + AtAmUiStrDisplayFix (STR_ATAMUI_RECO_FAILED, TRUE); + AtAmUiDelay (2 * AT_AM_UI_1_SECOND); + gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL); + } + + AtAmUiDelay (AT_AM_UI_1_SECOND); + AtAmUiStrClearScreen (); + AtAmUiStrSetCursor(CCol, CRow); + + return Status; +} + +/** + Function displaing Ivs strings. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +AtAmUiDisplayIsvStrings ( + VOID + ) +{ + EFI_STATUS Status; + CHAR16 *IsvIdString; + AT_BIOS_RECOVERY_CONFIG RecoveryConfig; + UINT8 *IsvString; + UINT32 IsvId; + UINT32 CRow; + UINT32 CCol; + + IsvId = 0; + + DEBUG ((EFI_D_ERROR, "ATAM: AtAmUiDisplayIsvStrings. \n")); + + IsvIdString = AllocateZeroPool (ISV_PLATFORM_ID_LENGTH * sizeof (CHAR16)); + IsvString = AllocateZeroPool ((RECOVERY_STRING_LENGTH + 1) * sizeof (UINT8)); + if (IsvIdString == NULL || IsvString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (mAtAm == NULL) { + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM Protocol failed, Status = %r\n", Status)); + } + } + + AtAmUiStrGetCursor (&CRow, &CCol); + + Status = mAtAm->AtAmGetIsvId (mAtAm, IsvString, &IsvId); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetIsvId command failed, Status = %r\n", Status)); + } + + RecoveryConfig.IsvPlatformId[0] = L'\0'; + Status = mAtAm->AtAmGetRecoveryConfig (mAtAm, &RecoveryConfig); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetRecoveryConfig command failed, Status = %r\n", Status)); + } + + if (RecoveryConfig.IsvPlatformId[0] != L'\0') { + AtAmUiStrDisplayFix (STR_ATAMUI_PLATFORM_ID, TRUE); + AtAmUiStrDisplay ((CHAR16 *) RecoveryConfig.IsvPlatformId); + } + + if (IsvId != 0) { + UnicodeValueToString (IsvIdString, 0, (UINT32) IsvId, 0); + AtAmUiStrDisplayFix (STR_ATAMUI_PROVIDER_ID, TRUE); + AtAmUiStrDisplay (IsvIdString); + } + + FreePool (IsvString); + FreePool (IsvIdString); + + return Status; +} + +/** + This GetRecoveryPassword() process the AT recovery password user input. + + @param[out] PasswordASCII Pointer to an array of ASCII user input + @param[in] MaxPasswordLength Integer value for max password length + @param[out] PasswordUNICODE Pointer to an array of UNICODE user input + @param[in] ShowPassword TRUE - password is shown, FALSE - pasword is hidden by * + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Do not have enough resources to allocate memory or password too long. +**/ +EFI_STATUS +AtAmUiGetPassword ( + OUT UINT8 *PasswordASCII, + IN INTN MaxPasswordLength, + OUT CHAR16 *PasswordUNICODE, + IN UINT8 ShowPassword + ) +{ + INTN StrIndex; + EFI_INPUT_KEY Key = { 0, 0 }; + CHAR16 StarChar[2] = { L' ', L'\0' }; + + DEBUG ((EFI_D_ERROR, "ATAM: AtAmUiGetRecoveryPassword \n")); + + PasswordASCII[0] = L'\0'; + PasswordUNICODE[0] = L'\0'; + + Key.UnicodeChar = 0; + Key.ScanCode = 0; + StrIndex = 0; + + DEBUG ((EFI_D_ERROR, "ATAM: Wait for Key \n")); + + AtAmUiStrEnableCursor (TRUE); + do { + Key.ScanCode = 0; + Key.UnicodeChar = 0; + AtAmUiStrGetChar (&Key); + DEBUG ((EFI_D_ERROR, "ATAM: PasswordUNICODE: %s\n", PasswordUNICODE)); + + switch (Key.UnicodeChar) { + case CHAR_NULL: + /// + /// Non-printable characters handling: do not print caps/numlock, pgup/dn, Fx, cursors etc. + /// When escape pressed, return with empty password and ask for password again + /// + if (Key.ScanCode == SCAN_ESC) { + PasswordASCII[0] = L'\0'; + PasswordUNICODE[0] = L'\0'; + StrIndex = 0; + return EFI_SUCCESS; + } + break; + + case CHAR_CARRIAGE_RETURN: + /// + /// Enter handling: when enter pressed, return with the password + /// + StrIndex = 0; + + DEBUG ((EFI_D_ERROR, "ATAM: Passphrase Entered: %s\n", PasswordUNICODE)); + return EFI_SUCCESS; + + case CHAR_BACKSPACE: + /// + /// Backspace handling + /// + if (StrIndex > 0) { + StrIndex--; + PasswordASCII[StrIndex] = L'\0'; + PasswordUNICODE[StrIndex] = L'\0'; + /// + /// Backspace printing on screen + /// + AtAmUiStrDisplay (L"\b \b"); + } + break; + + default: + /// + /// Normal (printable) characters handling + /// Do not hide password on screen for Server Token Password recovery (usrRsp=2) + /// Hide password with '*' for User Password recovery (usrRsp=1) + /// + StarChar[0] = (ShowPassword == 1) ? Key.UnicodeChar : L'*'; + + if (StrIndex >= 0 && StrIndex < MaxPasswordLength) { + /// + /// Index in range + /// + PasswordASCII[StrIndex] = (UINT8) Key.UnicodeChar; + PasswordUNICODE[StrIndex] = Key.UnicodeChar; + StrIndex++; + /// + /// Print hidden (*) or unhidden password character + /// + AtAmUiStrDisplay (StarChar); + } else if (StrIndex < 0) { + /// + /// Index out of range: StrIndex < 0 - should never go here + /// + AtAmUiStrEnableCursor (FALSE); + StrIndex = 0; + } else { + /// + /// Index out of range: StrIndex >= ATAM_SETUP_PASSWORD_LENGTH - max password length (49 chars) exceeded, + /// only backspace, enter or escape will be accepted + /// + DEBUG ((EFI_D_ERROR, "ATAM: Password Length Exceeded\n")); + } + break; + } + + } while (1); + + AtAmUiStrEnableCursor (FALSE); + + return EFI_TIMEOUT; +} + +/** + Function displaing Ivs strings. + + @param[in] None + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. +**/ +EFI_STATUS +AtAmUiTheftNotification ( + VOID + ) +{ + EFI_STATUS Status; + AT_STATE_INFO StateInfo; + UINT32 TimerLeft; + UINT32 TimerInterval; + UINT8 *IsvString; + UINT32 IsvId; + CHAR16 *TimeLeftStr; + UINT8 PbaFailedExceeded; + UINT16 PbaFailedAttempts; + UINT16 PbaFailedThreshold; + + DEBUG ((EFI_D_ERROR, "ATAM: AtAmUiTheftNotification\n")); + + Status = EFI_SUCCESS; + PbaFailedExceeded = FALSE; + + Status = gBS->LocateProtocol ( + &gEfiAtAmProtocolGuid, + NULL, + (VOID **) &mAtAm + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: ATAM failed = %r\n", Status)); + return Status; + } + + Status = mAtAm->AtAmGetPbaCounter(&PbaFailedExceeded, &PbaFailedAttempts, &PbaFailedThreshold); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetIsvId = %r\n", Status)); + return Status; + } + + if (PbaFailedThreshold >= PbaFailedAttempts) { + return EFI_SUCCESS; + } else { + + IsvString = AllocateZeroPool ((RECOVERY_STRING_LENGTH + 1) * sizeof (UINT8)); + TimeLeftStr = AllocateZeroPool ((ATAM_TIMER_STRING_LENGTH + 1) * sizeof (CHAR16)); + + if (IsvString == NULL || TimeLeftStr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + AtAmUiStrClearScreen (); + + AtAmUiDisplayIsvStrings (); + + AtAmUiStrEnableCursor (FALSE); + + AtAmUiStrSetCursor(4, 20); + Status = mAtAm->AtAmGetIsvId (mAtAm, IsvString, &IsvId); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ATAM: AtAmGetIsvId, Status = %r\n", Status)); + } + + AtAmUiStrDisplay ((CHAR16 *) IsvString); + + mAtAm->AtAmGetAtStateInfo (mAtAm, &StateInfo); + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_DUE_TO, TRUE); + switch (StateInfo.LastTheftTrigger) { + case 1: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_TIME, FALSE); + break; + + case 2: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_STOLEN, FALSE); + break; + + case 3: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_THRESHOLD, FALSE); + break; + + case 4: + AtAmUiStrDisplayFix (STR_ATAMUI_LOCK_ATTACK, FALSE); + + default: + break; + } + + mAtAm->AtAmGetTimer (mAtAm, &TimerLeft, &TimerInterval); + UnicodeValueToString (TimeLeftStr, 0, TimerLeft, 0); + + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT, TRUE); + AtAmUiStrDisplay ((CHAR16 *) TimeLeftStr); + AtAmUiStrDisplayFix (STR_ATAMUI_TIME_LEFT_SEC,FALSE); + + AtAmUiDelay ((PbaFailedAttempts - PbaFailedThreshold) * 10 * AT_AM_UI_1_SECOND); + + AtAmUiStrClearScreen (); + + return Status; + } +} + |