From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.62]) by mx.groups.io with SMTP id smtpd.web09.2837.1608065513514007703 for ; Tue, 15 Dec 2020 12:51:53 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=WosAflNP; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.237.62, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=jgUOecZYBOpWXwyJ+LE5iuGThGVdZV0nkLw6SW+T+f5vDB4FYcgh48OXdrW3OXg0mi7cS+Nb7aIo6fXl2kiH524mk1srmr1F6w2ijYy24/VHpj9MLMDLI9n3iKopr1TDVH4cRt2KosMZXlBNhm4WPTzvnrtskqXFS+i3otrWUBnMRuk/FOip4ezetypJHgEaq0oMuc/8qrX17tIyBBzq1Fld5mO33dowNgcIuDCP8v/z57qx/XCm1yIa1n3hFxKYJO3oYnhrJM4IYLm/veYa7LIHahz7E9SlJ84ZevBp7p3HvFagbcCoZy6LZHcOcKFeB7dzL3KtqvYqJNrYzpsBuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=E8a69Lp4y8lgnmbwkniG8e/aE7qeGeCBhOZA2+sobDM=; b=YUFshBxqHt+RAypdAvAMBcctVJ3rzR3gF/aXwHF9F+VcjYWVTXIDSA+BEo3mTJZhXJ0Uu4YDKE1NPmduC/yP8NbSz903rdiIIjKp0ELLWuw3pYOa8CxaAy1NMF5VO0n1FtCHQEiRztNwS7sdG+1bgHxnq30/SW8ubrt+0E3/kcZel67XtnH1w/weHHPGfue/Hrv3R1hSRv7XMInHrxi8XoO38fg1z0+YdVpidr7RNL3/feoJN0W8tLwmEKYVHW4/emj7aoKdZJKqG/r1BwXsj5u3dC15n9Xmje1+d8ahnkls5QpTt4xYuAzAAJKVN2iBKI3NX0hQyu10ZFrUP/wXLQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=E8a69Lp4y8lgnmbwkniG8e/aE7qeGeCBhOZA2+sobDM=; b=WosAflNPf77npsO6cU+jvxEQ481Z2pXcFooFdJ7UhiRTGKJPCLPIWgFucTG7VZy7YjqJLfddm1jJvCWGdUp0CKSQUHpOAVuNpMlUGsMiO06tqeR2+r9zXhtESMJbB+dTnnQYOt1ZX7O0sPtV9BFVggtnvIufDOSNWarxy/QO8qg= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=amd.com; Received: from DM5PR12MB1355.namprd12.prod.outlook.com (10.168.234.7) by DM6PR12MB4155.namprd12.prod.outlook.com (10.141.8.79) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.15; Tue, 15 Dec 2020 20:51:50 +0000 Received: from DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::d95e:b9d:1d6a:e845]) by DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::d95e:b9d:1d6a:e845%12]) with mapi id 15.20.3654.025; Tue, 15 Dec 2020 20:51:50 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [PATCH 03/12] OvmfPkg/ResetVector: Validate the encryption bit position for SEV/SEV-ES Date: Tue, 15 Dec 2020 14:51:02 -0600 Message-ID: <3ffe88b74cf89f79a49441ac844b273e857d013f.1608065471.git.thomas.lendacky@amd.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: CH2PR10CA0020.namprd10.prod.outlook.com (2603:10b6:610:4c::30) To DM5PR12MB1355.namprd12.prod.outlook.com (2603:10b6:3:6e::7) Return-Path: thomas.lendacky@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from tlendack-t1.amd.com (165.204.77.1) by CH2PR10CA0020.namprd10.prod.outlook.com (2603:10b6:610:4c::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12 via Frontend Transport; Tue, 15 Dec 2020 20:51:49 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 4d428b0f-0539-477e-a4e0-08d8a13b3f0c X-MS-TrafficTypeDiagnostic: DM6PR12MB4155: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: RYlajsDgw0WL74lNAHj212CTh0Jpy2r8/yzoQgoX8T9vgtTj3fm3O7+BJjN7EpWjEdigSuCQqDwkH/qDmndXNA1q9RWVAI1QDTkvKZhOwCGU4n2XJ1hu4W064Px9Bqve6UEmItdya+pFl9RZrJk0K4rJhEcNCBaB7TeW0toRdVfz6aO2JKYasio29tgx6BWkKqlgqJoDm40h5EYHe87EQYG6D5K+2iz90vENunCukcFWbXoUTzJt7jqtEc2acDWliGoXncrsAYOh6RaJ7sI7p7eDFPK3TYzW5bhwkB2JVaizDitR1E+B+37MAIVfLNHW0cX+ouTegkkgmgAK29jLUUIo+wwJmYj0D+wj+mRNpXxHT7QNkNOEkkQhmhHr7fzvz3vZJbD4SMNIAD+QnFGq7S5CIKvJrGfaYT/mE+0tN+95m21PwDftYh4zNipbMD6iDi4/1mfaS958c7S5Xtk7Lg== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM5PR12MB1355.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(376002)(366004)(136003)(346002)(66946007)(26005)(4326008)(19627235002)(16526019)(6916009)(8676002)(36756003)(508600001)(52116002)(6666004)(83380400001)(5660300002)(8936002)(966005)(186003)(54906003)(956004)(2616005)(66476007)(2906002)(86362001)(34490700003)(6486002)(66556008)(15650500001)(7696005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?oMyrBRYllTtCEzwtDDrdj0idyxBcdmx5PKBF1Eg9a44gwoleqpqYyi2D/ty9?= =?us-ascii?Q?zUJ0B53f8XoqdP26IB7podIfAmEQZtaCOzLBnsS3b8jXWpuZ3k3c9D2Ui1a2?= =?us-ascii?Q?2qE+OySMM/rQ3PqPR/EoZh2oGukrbG7NVEfE0yX1r3EcWgvvzRlgi2N30kH+?= =?us-ascii?Q?ngxtTuo2SOv6DfTuTMZVDrP/+4AL7usKGkuuO0F2eIGGUGlGOMyzWtZ5dkzJ?= =?us-ascii?Q?izl8w011800iFqF2GD11w1oBZ6Yp6ohyTELXQ7f2syxs2jXFj5EZbydRlWHa?= =?us-ascii?Q?O/vediqWRPVtd5czy7khHryEFYvreqTpA1Y0NqNdZCf0aL6reYCwd0pQlZEd?= =?us-ascii?Q?9WsCGiZFa9yo/eC/889Y9MJGFBWCRpA6MBfL+s3wwGVeGvNylWggh51nnhEG?= =?us-ascii?Q?yB9RirDN8FC6fEGYSWMl8AaDzSiGDx+rrlyZv20jfm53L0QukcvNp3tpZr6J?= =?us-ascii?Q?yER8PCwbs70laF+suVg35VkGnnFIAuMYcJhElrkEHnj8DRyfXEGMC139rzLZ?= =?us-ascii?Q?t/rm8k+S9A/jwbow+6yLl2vmH5piR3Pu8cB19ykEE54NlrazQaQezZA9Xxn2?= =?us-ascii?Q?EleE6uAwaRcm2GJz/WoTRm7OL/p4bU+FHLq1LIBgueUSlCUjOBeJ4gq75uZN?= =?us-ascii?Q?UATd15k5fOJOchaaHAN/6eY8hmVaKUdn9iWlnbSsZuDPZ3X92HkoKC7BOmSz?= =?us-ascii?Q?ezqJy5wXdm86CUv6P3iGBdR75DLxBYaNAp4ZPtKBhPSGpkVSy4AoRLEndzLD?= =?us-ascii?Q?SrOxE8tLe6vg/ttPKootGRqbS1BYKJdLwdu4v8nTMJoKwQE3hvORd0ZZemdG?= =?us-ascii?Q?xFnsBG2gBlVM6jZmdXBXC+pNOcUMeL7rYsy6QS5sh/hITJHVm0J4GuTswUEY?= =?us-ascii?Q?BxRJWJZTdB2VP/EJhhyGqP6y3/xVZvoT2E3Ar7QsZVdKR1r8L51HlD6mu41k?= =?us-ascii?Q?BhlUxFFQ7PWA3gbAaU/78LUtgyCKYWzb0lgTAbDxTzNTDhyzoQOp8d7EaYTa?= =?us-ascii?Q?c67l?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthSource: DM5PR12MB1355.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Dec 2020 20:51:50.4551 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: 4d428b0f-0539-477e-a4e0-08d8a13b3f0c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: r2xMNPuSzb48heEXLLyVySaq1D621+6Kj88lTQqudxDpPlpeUGsoaLxHQodJ/oSXAAz4X3VZWgV+XEwzTqInLA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4155 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable From: Tom Lendacky BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3108 To help mitigate against ROP attacks, add some checks to validate the encryption bit position that is reported by the hypervisor. The first check is to ensure that the hypervisor reports a bit position above bit 31. After extracting the encryption bit position from the CPUID information, the code checks that the value is above 31. If the value is not above 31, then the bit position is not valid, so the code enters a HLT loop. The second check is specific to SEV-ES guests and is a two step process. The first step will obtain random data using RDRAND and store that data to memory before paging is enabled. When paging is not enabled, all writes to memory are encrypted. The random data is maintained in registers, which are protected. After enabling paging, the random data in memory is compared to the register contents. If they don't match, then the reported bit position is not valid, so the code enters a HLT loop. The third check is after switching to 64-bit long mode. Use the fact that instruction fetches are automatically decrypted, while a memory fetch is decrypted only if the encryption bit is set in the page table. By comparing the bytes of an instruction fetch against a memory read of that same instruction, the encryption bit position can be validated. If the compare is not equal, then SEV/SEV-ES is active but the reported bit position is not valid, so the code enters a HLT loop. The encryption mask is saved in the SEV-ES work area so that it can be used later in the boot process. To keep the changes local to the OvmfPkg, an OvmfPkg version of the Flat32ToFlat64.asm file has been created based on the UefiCpuPkg file UefiCpuPkg/ResetVector/Vtf0/Ia32/Flat32ToFlat64.asm. Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Brijesh Singh Signed-off-by: Tom Lendacky --- OvmfPkg/Include/Library/MemEncryptSevLib.h | 4 + OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm | 116 ++++++++++++++++++++ OvmfPkg/ResetVector/Ia32/PageTables64.asm | 12 +- OvmfPkg/ResetVector/ResetVector.nasmb | 4 +- 4 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm diff --git a/OvmfPkg/Include/Library/MemEncryptSevLib.h b/OvmfPkg/Include/L= ibrary/MemEncryptSevLib.h index a6d82dac7fac..dc09c61e58bb 100644 --- a/OvmfPkg/Include/Library/MemEncryptSevLib.h +++ b/OvmfPkg/Include/Library/MemEncryptSevLib.h @@ -21,10 +21,14 @@ // This structure is also used by assembler files: // OvmfPkg/ResetVector/ResetVector.nasmb // OvmfPkg/ResetVector/Ia32/PageTables64.asm +// OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm // any changes must stay in sync with its usage. // typedef struct _SEC_SEV_ES_WORK_AREA { UINT8 SevEsEnabled; + UINT8 Reserved1[7]; + + UINT64 RandomData; } SEC_SEV_ES_WORK_AREA; =20 /** diff --git a/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/ResetVec= tor/Ia32/Flat32ToFlat64.asm new file mode 100644 index 000000000000..8fe0d0eed945 --- /dev/null +++ b/OvmfPkg/ResetVector/Ia32/Flat32ToFlat64.asm @@ -0,0 +1,116 @@ +;-------------------------------------------------------------------------= ----- +; @file +; Transition from 32 bit flat protected mode into 64 bit flat protected mo= de +; +; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+; Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved. +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;-------------------------------------------------------------------------= ----- + +BITS 32 + +; +; Modified: EAX, ECX, EDX +; +Transition32FlatTo64Flat: + + OneTimeCall SetCr3ForPageTables64 + + mov eax, cr4 + bts eax, 5 ; enable PAE + mov cr4, eax + + mov ecx, 0xc0000080 + rdmsr + bts eax, 8 ; set LME + wrmsr + + ; + ; SEV-ES mitigation check support + ; + xor ebx, ebx + + cmp byte[SEV_ES_WORK_AREA], 0 + jz EnablePaging + + ; + ; SEV-ES is active, perform a quick sanity check against the reported + ; encryption bit position. This is to help mitigate against attacks wh= ere + ; the hypervisor reports an incorrect encryption bit position. + ; + ; This is the first step in a two step process. Before paging is enabl= ed + ; writes to memory are encrypted. Using the RDRAND instruction (availa= ble + ; on all SEV capable processors), write 64-bits of random data to the + ; SEV_ES_WORK_AREA and maintain the random data in registers (register + ; state is protected under SEV-ES). This will be used in the second st= ep. + ; +RdRand1: + rdrand ecx + jnc RdRand1 + mov dword[SEV_ES_WORK_AREA_RDRAND], ecx +RdRand2: + rdrand edx + jnc RdRand2 + mov dword[SEV_ES_WORK_AREA_RDRAND + 4], edx + + ; + ; Use EBX instead of the SEV_ES_WORK_AREA memory to determine whether = to + ; perform the second step. + ; + mov ebx, 1 + +EnablePaging: + mov eax, cr0 + bts eax, 31 ; set PG + mov cr0, eax ; enable paging + + jmp LINEAR_CODE64_SEL:ADDR_OF(jumpTo64BitAndLandHere) +BITS 64 +jumpTo64BitAndLandHere: + + ; + ; Check if the second step of the SEV-ES + test ebx, ebx + jz InsnCompare + + ; + ; SEV-ES is active, perform the second step of the encryption bit post= ion + ; mitigation check. The ECX and EDX register contain data from RDRAND = that + ; was stored to memory in encrypted form. If the encryption bit positi= on is + ; valid, the contents of ECX and EDX will match the memory location. + ; + cmp dword[SEV_ES_WORK_AREA_RDRAND], ecx + jne SevEncBitHlt + cmp dword[SEV_ES_WORK_AREA_RDRAND + 4], edx + jne SevEncBitHlt + + ; + ; If SEV or SEV-ES is active, perform a quick sanity check against + ; the reported encryption bit position. This is to help mitigate + ; against attacks where the hypervisor reports an incorrect encryption + ; bit position. If SEV is not active, this check will always succeed. + ; + ; The cmp instruction compares the first four bytes of the cmp instruc= tion + ; itself (which will be read decrypted if SEV or SEV-ES is active and = the + ; encryption bit position is valid) against the immediate within the + ; instruction (an instruction fetch is always decrypted correctly by + ; hardware) based on RIP relative addressing. + ; +InsnCompare: + cmp dword[rel InsnCompare], 0xFFF63D81 + je GoodCompare + + ; + ; The hypervisor provided an incorrect encryption bit position, do not + ; proceed. + ; +SevEncBitHlt: + hlt + jmp SevEncBitHlt + +GoodCompare: + debugShowPostCode POSTCODE_64BIT_MODE + + OneTimeCallRet Transition32FlatTo64Flat + diff --git a/OvmfPkg/ResetVector/Ia32/PageTables64.asm b/OvmfPkg/ResetVecto= r/Ia32/PageTables64.asm index 4032719c3075..3cd909df4f09 100644 --- a/OvmfPkg/ResetVector/Ia32/PageTables64.asm +++ b/OvmfPkg/ResetVector/Ia32/PageTables64.asm @@ -140,9 +140,17 @@ GetSevEncBit: ; Get pte bit position to enable memory encryption ; CPUID Fn8000_001F[EBX] - Bits 5:0 ; + and ebx, 0x3f mov eax, ebx - and eax, 0x3f - jmp SevExit + + ; The encryption bit position is always above 31 + sub ebx, 32 + jns SevExit + + ; Encryption bit was reported as 31 or below, enter a HLT loop +SevEncBitLowHlt: + hlt + jmp SevEncBitLowHlt =20 NoSev: xor eax, eax diff --git a/OvmfPkg/ResetVector/ResetVector.nasmb b/OvmfPkg/ResetVector/Re= setVector.nasmb index c5e0fe93abf4..d3aa87982959 100644 --- a/OvmfPkg/ResetVector/ResetVector.nasmb +++ b/OvmfPkg/ResetVector/ResetVector.nasmb @@ -3,6 +3,7 @@ ; This file includes all other code files to assemble the reset vector cod= e ; ; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
+; Copyright (c) 2020, Advanced Micro Devices, Inc. All rights reserved. ; SPDX-License-Identifier: BSD-2-Clause-Patent ; ;-------------------------------------------------------------------------= ----- @@ -67,13 +68,14 @@ %endif =20 %define PT_ADDR(Offset) (FixedPcdGet32 (PcdOvmfSecPageTablesBase) + (Off= set)) -%include "Ia32/Flat32ToFlat64.asm" =20 %define GHCB_PT_ADDR (FixedPcdGet32 (PcdOvmfSecGhcbPageTableBase)) %define GHCB_BASE (FixedPcdGet32 (PcdOvmfSecGhcbBase)) %define GHCB_SIZE (FixedPcdGet32 (PcdOvmfSecGhcbSize)) %define SEV_ES_WORK_AREA (FixedPcdGet32 (PcdSevEsWorkAreaBase)) + %define SEV_ES_WORK_AREA_RDRAND (FixedPcdGet32 (PcdSevEsWorkAreaBase) + = 8) %define SEV_ES_VC_TOP_OF_STACK (FixedPcdGet32 (PcdOvmfSecPeiTempRamBase)= + FixedPcdGet32 (PcdOvmfSecPeiTempRamSize)) +%include "Ia32/Flat32ToFlat64.asm" %include "Ia32/PageTables64.asm" %endif =20 --=20 2.28.0