]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm
OvmfPkg/ResetVector: Validate the encryption bit position for SEV/SEV-ES
[mirror_edk2.git] / OvmfPkg / ResetVector / Ia32 / Flat32ToFlat64.asm
diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm
new file mode 100644 (file)
index 0000000..c6d0d89
--- /dev/null
@@ -0,0 +1,118 @@
+;------------------------------------------------------------------------------\r
+; @file\r
+; Transition from 32 bit flat protected mode into 64 bit flat protected mode\r
+;\r
+; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+BITS    32\r
+\r
+;\r
+; Modified:  EAX, ECX, EDX\r
+;\r
+Transition32FlatTo64Flat:\r
+\r
+    OneTimeCall SetCr3ForPageTables64\r
+\r
+    mov     eax, cr4\r
+    bts     eax, 5                      ; enable PAE\r
+    mov     cr4, eax\r
+\r
+    mov     ecx, 0xc0000080\r
+    rdmsr\r
+    bts     eax, 8                      ; set LME\r
+    wrmsr\r
+\r
+    ;\r
+    ; SEV-ES mitigation check support\r
+    ;\r
+    xor     ebx, ebx\r
+\r
+    cmp     byte[SEV_ES_WORK_AREA], 0\r
+    jz      EnablePaging\r
+\r
+    ;\r
+    ; SEV-ES is active, perform a quick sanity check against the reported\r
+    ; encryption bit position. This is to help mitigate against attacks where\r
+    ; the hypervisor reports an incorrect encryption bit position.\r
+    ;\r
+    ; This is the first step in a two step process. Before paging is enabled\r
+    ; writes to memory are encrypted. Using the RDRAND instruction (available\r
+    ; on all SEV capable processors), write 64-bits of random data to the\r
+    ; SEV_ES_WORK_AREA and maintain the random data in registers (register\r
+    ; state is protected under SEV-ES). This will be used in the second step.\r
+    ;\r
+RdRand1:\r
+    rdrand  ecx\r
+    jnc     RdRand1\r
+    mov     dword[SEV_ES_WORK_AREA_RDRAND], ecx\r
+RdRand2:\r
+    rdrand  edx\r
+    jnc     RdRand2\r
+    mov     dword[SEV_ES_WORK_AREA_RDRAND + 4], edx\r
+\r
+    ;\r
+    ; Use EBX instead of the SEV_ES_WORK_AREA memory to determine whether to\r
+    ; perform the second step.\r
+    ;\r
+    mov     ebx, 1\r
+\r
+EnablePaging:\r
+    mov     eax, cr0\r
+    bts     eax, 31                     ; set PG\r
+    mov     cr0, eax                    ; enable paging\r
+\r
+    jmp     LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere)\r
+BITS    64\r
+jumpTo64BitAndLandHere:\r
+\r
+    ;\r
+    ; Check if the second step of the SEV-ES mitigation is to be performed.\r
+    ;\r
+    test    ebx, ebx\r
+    jz      InsnCompare\r
+\r
+    ;\r
+    ; SEV-ES is active, perform the second step of the encryption bit postion\r
+    ; mitigation check. The ECX and EDX register contain data from RDRAND that\r
+    ; was stored to memory in encrypted form. If the encryption bit position is\r
+    ; valid, the contents of ECX and EDX will match the memory location.\r
+    ;\r
+    cmp     dword[SEV_ES_WORK_AREA_RDRAND], ecx\r
+    jne     SevEncBitHlt\r
+    cmp     dword[SEV_ES_WORK_AREA_RDRAND + 4], edx\r
+    jne     SevEncBitHlt\r
+\r
+    ;\r
+    ; If SEV or SEV-ES is active, perform a quick sanity check against\r
+    ; the reported encryption bit position. This is to help mitigate\r
+    ; against attacks where the hypervisor reports an incorrect encryption\r
+    ; bit position. If SEV is not active, this check will always succeed.\r
+    ;\r
+    ; The cmp instruction compares the first four bytes of the cmp instruction\r
+    ; itself (which will be read decrypted if SEV or SEV-ES is active and the\r
+    ; encryption bit position is valid) against the immediate within the\r
+    ; instruction (an instruction fetch is always decrypted correctly by\r
+    ; hardware) based on RIP relative addressing.\r
+    ;\r
+InsnCompare:\r
+    cmp     dword[rel InsnCompare], 0xFFF63D81\r
+    je      GoodCompare\r
+\r
+    ;\r
+    ; The hypervisor provided an incorrect encryption bit position, do not\r
+    ; proceed.\r
+    ;\r
+SevEncBitHlt:\r
+    cli\r
+    hlt\r
+    jmp     SevEncBitHlt\r
+\r
+GoodCompare:\r
+    debugShowPostCode POSTCODE_64BIT_MODE\r
+\r
+    OneTimeCallRet Transition32FlatTo64Flat\r
+\r