From patchwork Thu Nov 18 11:33:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dov Murik X-Patchwork-Id: 12626737 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88180C433F5 for ; Thu, 18 Nov 2021 11:34:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D86761ABD for ; Thu, 18 Nov 2021 11:34:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343640AbhKRLhi (ORCPT ); Thu, 18 Nov 2021 06:37:38 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:31830 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343900AbhKRLh2 (ORCPT ); Thu, 18 Nov 2021 06:37:28 -0500 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1AIA5ZQf002211; Thu, 18 Nov 2021 11:34:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=Br6paflKBQWmT1M4C6tYCxeoN+a95/zcU8FetavsIAo=; b=dIbleNrU74rJm2RDcvZBGezBzN8/MMLLaoE6atmLmuoA2vp87jAvt5tjJmY3ZYagrvpB jadPX4ux8DQJ8NoxdtJq0IXnQNSPtGuQaIx+SI0sltFdy+RQygwz7nlqdgWu8NmOTdNU GF9p2S6rXXap/soysEbR35GfOuHFzB+eMzW3Cm+8OtwAEzQCfXnVwK1eNp5c/RI9ELpv 7p2aZ1EPDakY8wxEFo9SPt0duhwa8ACaPk3PtbrUe3X6FF2jcggyhFimI7GzlVYfUFNY V4UYBNvoHO6rr+YHTASiFmjwbdp1Tk0tDn/8e0xxPiHy4YWavtaepHCM6EKr6eW8e6jx xQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3cdjnu4vqw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:10 +0000 Received: from m0098414.ppops.net (m0098414.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1AIAswFl008612; Thu, 18 Nov 2021 11:34:09 GMT Received: from ppma01wdc.us.ibm.com (fd.55.37a9.ip4.static.sl-reverse.com [169.55.85.253]) by mx0b-001b2d01.pphosted.com with ESMTP id 3cdjnu4vq5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:09 +0000 Received: from pps.filterd (ppma01wdc.us.ibm.com [127.0.0.1]) by ppma01wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1AIBQhI4004991; Thu, 18 Nov 2021 11:34:08 GMT Received: from b01cxnp22033.gho.pok.ibm.com (b01cxnp22033.gho.pok.ibm.com [9.57.198.23]) by ppma01wdc.us.ibm.com with ESMTP id 3cd7c2yq7a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:08 +0000 Received: from b01ledav005.gho.pok.ibm.com (b01ledav005.gho.pok.ibm.com [9.57.199.110]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1AIBY5Mj41877838 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Nov 2021 11:34:05 GMT Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3B11EAE068; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F2633AE066; Thu, 18 Nov 2021 11:34:04 +0000 (GMT) Received: from amdrome3.watson.ibm.com (unknown [9.2.130.16]) by b01ledav005.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 18 Nov 2021 11:34:04 +0000 (GMT) From: Dov Murik To: linux-efi@vger.kernel.org Cc: Dov Murik , Borislav Petkov , Ashish Kalra , Brijesh Singh , Tom Lendacky , Ard Biesheuvel , James Morris , "Serge E. Hallyn" , Andi Kleen , Greg KH , Andrew Scull , Dave Hansen , "Dr. David Alan Gilbert" , James Bottomley , Tobin Feldman-Fitzthum , Jim Cadden , Daniele Buono , linux-coco@lists.linux.dev, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 1/4] efi: Save location of EFI confidential computing area Date: Thu, 18 Nov 2021 11:33:56 +0000 Message-Id: <20211118113359.642571-2-dovmurik@linux.ibm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211118113359.642571-1-dovmurik@linux.ibm.com> References: <20211118113359.642571-1-dovmurik@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: K86UH2ZNXvrTQ7xcKVDBgfoKSq96dYNx X-Proofpoint-ORIG-GUID: LQkLa5OBXiFApWOOsHK9DN2t3902dIkI X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-11-18_05,2021-11-17_01,2020-04-07_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 adultscore=0 impostorscore=0 spamscore=0 phishscore=0 suspectscore=0 lowpriorityscore=0 malwarescore=0 mlxlogscore=999 clxscore=1011 mlxscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2111180067 Precedence: bulk List-ID: Confidential computing (coco) hardware such as AMD SEV (Secure Encrypted Virtualization) allows a guest owner to inject secrets into the VMs memory without the host/hypervisor being able to read them. Firmware support for secret injection is available in OVMF, which reserves a memory area for secret injection and includes a pointer to it the in EFI config table entry LINUX_EFI_COCO_SECRET_TABLE_GUID. If EFI exposes such a table entry, uefi_init() will keep a pointer to the EFI config table entry in efi.coco_secret, so it can be used later by the kernel (specifically drivers/virt/coco/efi_secret). It will also appear in the kernel log as "CocoSecret=ADDRESS"; for example: [ 0.000000] efi: EFI v2.70 by EDK II [ 0.000000] efi: CocoSecret=0x7f22e680 SMBIOS=0x7f541000 ACPI=0x7f77e000 ACPI 2.0=0x7f77e014 MEMATTR=0x7ea0c018 The new functionality can be enabled with CONFIG_EFI_COCO_SECRET=y. Signed-off-by: Dov Murik --- arch/x86/platform/efi/efi.c | 3 +++ drivers/firmware/efi/Kconfig | 16 ++++++++++++++++ drivers/firmware/efi/efi.c | 6 ++++++ include/linux/efi.h | 7 +++++++ 4 files changed, 32 insertions(+) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 147c30a81f15..1591d67e0bcd 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -93,6 +93,9 @@ static const unsigned long * const efi_tables[] = { #ifdef CONFIG_LOAD_UEFI_KEYS &efi.mokvar_table, #endif +#ifdef CONFIG_EFI_COCO_SECRET + &efi.coco_secret, +#endif }; u64 efi_setup; /* efi setup_data physical address */ diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 2c3dac5ecb36..6fa251b3709f 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -284,3 +284,19 @@ config EFI_CUSTOM_SSDT_OVERLAYS See Documentation/admin-guide/acpi/ssdt-overlays.rst for more information. + +config EFI_COCO_SECRET + bool "EFI Confidential Computing Secret Area Support" + depends on EFI + help + Confidential Computing platforms (such as AMD SEV) allow the + Guest Owner to securely inject secrets during guest VM launch. + The secrets are placed in a designated EFI reserved memory area. + + In order to use the secrets in the kernel, the location of the secret + area (as published in the EFI config table) must be kept. + + If you say Y here, the address of the EFI secret area will be kept + for usage inside the kernel. This will allow the + virt/coco/efi_secret module to access the secrets, which in turn + allows userspace programs to access the injected secrets. diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index ae79c3300129..3cc3a7449c64 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -46,6 +46,9 @@ struct efi __read_mostly efi = { #ifdef CONFIG_LOAD_UEFI_KEYS .mokvar_table = EFI_INVALID_TABLE_ADDR, #endif +#ifdef CONFIG_EFI_COCO_SECRET + .coco_secret = EFI_INVALID_TABLE_ADDR, +#endif }; EXPORT_SYMBOL(efi); @@ -528,6 +531,9 @@ static const efi_config_table_type_t common_tables[] __initconst = { #endif #ifdef CONFIG_LOAD_UEFI_KEYS {LINUX_EFI_MOK_VARIABLE_TABLE_GUID, &efi.mokvar_table, "MOKvar" }, +#endif +#ifdef CONFIG_EFI_COCO_SECRET + {LINUX_EFI_COCO_SECRET_AREA_GUID, &efi.coco_secret, "CocoSecret" }, #endif {}, }; diff --git a/include/linux/efi.h b/include/linux/efi.h index dbd39b20e034..f8d2150a2dc4 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -359,6 +359,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2) #define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68) #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) +#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) /* OEM GUIDs */ #define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55) @@ -550,6 +551,7 @@ extern struct efi { unsigned long tpm_log; /* TPM2 Event Log table */ unsigned long tpm_final_log; /* TPM2 Final Events Log table */ unsigned long mokvar_table; /* MOK variable config table */ + unsigned long coco_secret; /* Confidential computing secret table */ efi_get_time_t *get_time; efi_set_time_t *set_time; @@ -1283,4 +1285,9 @@ static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find( } #endif +struct linux_efi_coco_secret_area { + u64 base_pa; + u64 size; +}; + #endif /* _LINUX_EFI_H */ From patchwork Thu Nov 18 11:33:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dov Murik X-Patchwork-Id: 12626745 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DB1CC433EF for ; Thu, 18 Nov 2021 11:36:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D38061AFB for ; Thu, 18 Nov 2021 11:36:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344032AbhKRLji (ORCPT ); Thu, 18 Nov 2021 06:39:38 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:44960 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1344111AbhKRLiW (ORCPT ); Thu, 18 Nov 2021 06:38:22 -0500 Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1AIBJD9L008642; Thu, 18 Nov 2021 11:34:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=SP+6dubD5vvPT0ZMA56BBNLSDVelDCWwbi0gGrBqYK0=; b=SaswI4Qgg5ERJbtBigZkJ3q5F0F/bhgCl6OkWweOHwcxFtXDZDjOf44dZ/8MaCFbiyEh MMjW9GI8gpORD8bsRDzl5gSSizPlHLqK/0Q9aeBg4GRIXlLMYrccU182qHOvi+WF4ban W8eUBZJ7L5DEkN+wK0uBcphZ2jKk1Bd3Vsyj/qffOpZRlO03zwmGo3jr2GPkYD+pMseK j2Uoy0NnnhFtSjH/9QcP/Dc2jj6FCZW3pGUwgxmgBnS8c7/z2iPGnSx5VokDyUIVNFVo Iy60jDEh+0WyDF0t/Yf55AW9qqlxRhu8mmWws9DRbZ2YkRb6aG7mV06X5432rE6RgbW2 QQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3cdnup095s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:11 +0000 Received: from m0098416.ppops.net (m0098416.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1AIBOJ7K029601; Thu, 18 Nov 2021 11:34:10 GMT Received: from ppma02dal.us.ibm.com (a.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.10]) by mx0b-001b2d01.pphosted.com with ESMTP id 3cdnup0958-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:10 +0000 Received: from pps.filterd (ppma02dal.us.ibm.com [127.0.0.1]) by ppma02dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1AIBR1Mx008954; Thu, 18 Nov 2021 11:34:09 GMT Received: from b01cxnp22033.gho.pok.ibm.com (b01cxnp22033.gho.pok.ibm.com [9.57.198.23]) by ppma02dal.us.ibm.com with ESMTP id 3ca50dhgwm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:09 +0000 Received: from b01ledav005.gho.pok.ibm.com (b01ledav005.gho.pok.ibm.com [9.57.199.110]) by b01cxnp22033.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1AIBY5mf41877840 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Nov 2021 11:34:05 GMT Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8F8A0AE068; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4E5B2AE06A; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) Received: from amdrome3.watson.ibm.com (unknown [9.2.130.16]) by b01ledav005.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) From: Dov Murik To: linux-efi@vger.kernel.org Cc: Dov Murik , Borislav Petkov , Ashish Kalra , Brijesh Singh , Tom Lendacky , Ard Biesheuvel , James Morris , "Serge E. Hallyn" , Andi Kleen , Greg KH , Andrew Scull , Dave Hansen , "Dr. David Alan Gilbert" , James Bottomley , Tobin Feldman-Fitzthum , Jim Cadden , Daniele Buono , linux-coco@lists.linux.dev, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 2/4] efi/libstub: Reserve confidential computing secret area Date: Thu, 18 Nov 2021 11:33:57 +0000 Message-Id: <20211118113359.642571-3-dovmurik@linux.ibm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211118113359.642571-1-dovmurik@linux.ibm.com> References: <20211118113359.642571-1-dovmurik@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: pxqOQ61q1EGWNCGJVZE-HYppBKMUbOQB X-Proofpoint-ORIG-GUID: ZYdRp_DSmlyFp3-Yy5cUjH1rUQ69dr8I X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-11-18_05,2021-11-17_01,2020-04-07_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 phishscore=0 adultscore=0 suspectscore=0 bulkscore=0 malwarescore=0 mlxscore=0 mlxlogscore=999 priorityscore=1501 impostorscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2111180067 Precedence: bulk List-ID: Some older firmware declare the confidential computing secret area as EFI_BOOT_SERVICES_DATA region. Fix this up by treating this memory region as EFI_RESERVED_TYPE, as it should be. If that memory region is already EFI_RESERVED_TYPE then this has no effect on the E820 map. Signed-off-by: Dov Murik --- drivers/firmware/efi/libstub/x86-stub.c | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index f14c4ff5839f..dabfa33ae2b3 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -24,6 +24,7 @@ const efi_system_table_t *efi_system_table; extern u32 image_offset; static efi_loaded_image_t *image = NULL; +static u64 efi_coco_secret_phys_addr = U64_MAX; static efi_status_t preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) @@ -443,6 +444,21 @@ static void add_e820ext(struct boot_params *params, params->hdr.setup_data = (unsigned long)e820ext; } +#ifdef CONFIG_EFI_COCO_SECRET +static void efi_set_coco_secret_phys_addr(void) +{ + struct linux_efi_coco_secret_area *secret_area = + get_efi_config_table(LINUX_EFI_COCO_SECRET_AREA_GUID); + + if (!secret_area || secret_area->size == 0 || secret_area->size >= SZ_4G) + return; + + efi_coco_secret_phys_addr = secret_area->base_pa; +} +#else +static void efi_set_coco_secret_phys_addr(void) {} +#endif + static efi_status_t setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_size) { @@ -494,6 +510,16 @@ setup_e820(struct boot_params *params, struct setup_data *e820ext, u32 e820ext_s e820_type = E820_TYPE_SOFT_RESERVED; else e820_type = E820_TYPE_RAM; +#ifdef CONFIG_EFI_COCO_SECRET + if (d->phys_addr == efi_coco_secret_phys_addr) + /* + * Fix a quirk in firmwares which don't mark + * the EFI confidential computing area as + * EFI_RESERVED_TYPE, but instead as + * EFI_BOOT_SERVICES_DATA. + */ + e820_type = E820_TYPE_RESERVED; +#endif break; case EFI_ACPI_MEMORY_NVS: @@ -793,6 +819,8 @@ unsigned long efi_main(efi_handle_t handle, efi_retrieve_tpm2_eventlog(); + efi_set_coco_secret_phys_addr(); + setup_graphics(boot_params); setup_efi_pci(boot_params); From patchwork Thu Nov 18 11:33:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dov Murik X-Patchwork-Id: 12626743 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C5F5C433FE for ; Thu, 18 Nov 2021 11:34:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E9D1F61B73 for ; Thu, 18 Nov 2021 11:34:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343976AbhKRLho (ORCPT ); Thu, 18 Nov 2021 06:37:44 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:4034 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343949AbhKRLhd (ORCPT ); Thu, 18 Nov 2021 06:37:33 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1AIBE3e0017716; Thu, 18 Nov 2021 11:34:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=jwIke+PU0+2RZ1CulmTmFpaDiU3AmNOxzKJXDehjQjw=; b=BVer5xA3tjMaIuEdhjZ4NmUuMbD5HlqMvedO122Fgo9DIGhT2xP1InimjQ9zxLT5m3Rh QbiKbTSrUhJLF8tBqq0U/m3PGbi16fssJFssTY/Vq4HOz4Ovp8o5uzdGlt6srfVAiMhU 4o0jjLUFZG3wMLnO3biyBkNX0M8qybNebfCZ0nDiTkoFwkfjDhhps5qiO0fY8ocXSGnv jaLSjZh16H7UjE1M8UOKrlw1i+eGnA8pi+B1J9VdmDkQ2GF3/etp7UZPx/aSHzbQlm7h dm1g1ZfR63Ee6/RvqhLhrRMtTi5mjw5KAcaI4XFyCoRkq2Vj/P0EviKvb02U8ZcPwuuU gQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3cdns98c3t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:11 +0000 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1AIBFSEr024034; Thu, 18 Nov 2021 11:34:11 GMT Received: from ppma02wdc.us.ibm.com (aa.5b.37a9.ip4.static.sl-reverse.com [169.55.91.170]) by mx0a-001b2d01.pphosted.com with ESMTP id 3cdns98c35-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:10 +0000 Received: from pps.filterd (ppma02wdc.us.ibm.com [127.0.0.1]) by ppma02wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1AIBRlSZ017383; Thu, 18 Nov 2021 11:34:09 GMT Received: from b01cxnp22034.gho.pok.ibm.com (b01cxnp22034.gho.pok.ibm.com [9.57.198.24]) by ppma02wdc.us.ibm.com with ESMTP id 3cd81dpsus-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:09 +0000 Received: from b01ledav005.gho.pok.ibm.com (b01ledav005.gho.pok.ibm.com [9.57.199.110]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1AIBY6pQ48693694 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Nov 2021 11:34:06 GMT Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F0513AE066; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A2EC9AE05C; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) Received: from amdrome3.watson.ibm.com (unknown [9.2.130.16]) by b01ledav005.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 18 Nov 2021 11:34:05 +0000 (GMT) From: Dov Murik To: linux-efi@vger.kernel.org Cc: Dov Murik , Borislav Petkov , Ashish Kalra , Brijesh Singh , Tom Lendacky , Ard Biesheuvel , James Morris , "Serge E. Hallyn" , Andi Kleen , Greg KH , Andrew Scull , Dave Hansen , "Dr. David Alan Gilbert" , James Bottomley , Tobin Feldman-Fitzthum , Jim Cadden , Daniele Buono , linux-coco@lists.linux.dev, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 3/4] virt: Add efi_secret module to expose confidential computing secrets Date: Thu, 18 Nov 2021 11:33:58 +0000 Message-Id: <20211118113359.642571-4-dovmurik@linux.ibm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211118113359.642571-1-dovmurik@linux.ibm.com> References: <20211118113359.642571-1-dovmurik@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: LLRcEYyqyk4Q8pPn_5NXjXPMk1M7FIgU X-Proofpoint-ORIG-GUID: fIl8lWfv37TBPVCcMasQ2x179xR1U3bW X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-11-18_05,2021-11-17_01,2020-04-07_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 malwarescore=0 phishscore=0 impostorscore=0 priorityscore=1501 lowpriorityscore=0 bulkscore=0 suspectscore=0 spamscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2111180067 Precedence: bulk List-ID: The new efi_secret module exposes the confidential computing (coco) EFI secret area via securityfs interface. When the module is loaded (and securityfs is mounted, typically under /sys/kernel/security), a "coco/efi_secret" directory is created in securityfs. In it, a file is created for each secret entry. The name of each such file is the GUID of the secret entry, and its content is the secret data. This allows applications running in a confidential computing setting to read secrets provided by the guest owner via a secure secret injection mechanism (such as AMD SEV's LAUNCH_SECRET command). Removing (unlinking) files in the "coco/efi_secret" directory will zero out the secret in memory, and remove the filesystem entry. If the module is removed and loaded again, that secret will not appear in the filesystem. Signed-off-by: Dov Murik --- .../ABI/testing/securityfs-coco-efi_secret | 50 +++ drivers/virt/Kconfig | 3 + drivers/virt/Makefile | 1 + drivers/virt/coco/efi_secret/Kconfig | 11 + drivers/virt/coco/efi_secret/Makefile | 2 + drivers/virt/coco/efi_secret/efi_secret.c | 341 ++++++++++++++++++ 6 files changed, 408 insertions(+) create mode 100644 Documentation/ABI/testing/securityfs-coco-efi_secret create mode 100644 drivers/virt/coco/efi_secret/Kconfig create mode 100644 drivers/virt/coco/efi_secret/Makefile create mode 100644 drivers/virt/coco/efi_secret/efi_secret.c diff --git a/Documentation/ABI/testing/securityfs-coco-efi_secret b/Documentation/ABI/testing/securityfs-coco-efi_secret new file mode 100644 index 000000000000..ae56976db1bc --- /dev/null +++ b/Documentation/ABI/testing/securityfs-coco-efi_secret @@ -0,0 +1,50 @@ +What: security/coco/efi_secret +Date: October 2021 +Contact: Dov Murik +Description: + Exposes confidential computing (coco) EFI secrets to + userspace via securityfs. + + EFI can declare memory area used by confidential computing + platforms (such as AMD SEV and SEV-ES) for secret injection by + the Guest Owner during VM's launch. The secrets are encrypted + by the Guest Owner and decrypted inside the trusted enclave, + and therefore are not readable by the untrusted host. + + The efi_secret module exposes the secrets to userspace. Each + secret appears as a file under /coco/efi_secret, + where the filename is the GUID of the entry in the secrets + table. + + Two operations are supported for the files: read and unlink. + Reading the file returns the content of secret entry. + Unlinking the file overwrites the secret data with zeroes and + removes the entry from the filesystem. A secret cannot be read + after it has been unlinked. + + For example, listing the available secrets:: + + # modprobe efi_secret + # ls -l /sys/kernel/security/coco/efi_secret + -r--r----- 1 root root 0 Jun 28 11:54 736870e5-84f0-4973-92ec-06879ce3da0b + -r--r----- 1 root root 0 Jun 28 11:54 83c83f7f-1356-4975-8b7e-d3a0b54312c6 + -r--r----- 1 root root 0 Jun 28 11:54 9553f55d-3da2-43ee-ab5d-ff17f78864d2 + -r--r----- 1 root root 0 Jun 28 11:54 e6f5a162-d67f-4750-a67c-5d065f2a9910 + + Reading the secret data by reading a file:: + + # cat /sys/kernel/security/coco/efi_secret/e6f5a162-d67f-4750-a67c-5d065f2a9910 + the-content-of-the-secret-data + + Wiping a secret by unlinking a file:: + + # rm /sys/kernel/security/coco/efi_secret/e6f5a162-d67f-4750-a67c-5d065f2a9910 + # ls -l /sys/kernel/security/coco/efi_secret + -r--r----- 1 root root 0 Jun 28 11:54 736870e5-84f0-4973-92ec-06879ce3da0b + -r--r----- 1 root root 0 Jun 28 11:54 83c83f7f-1356-4975-8b7e-d3a0b54312c6 + -r--r----- 1 root root 0 Jun 28 11:54 9553f55d-3da2-43ee-ab5d-ff17f78864d2 + + Note: The binary format of the secrets table injected by the + Guest Owner is described in + drivers/virt/coco/efi_secret/efi_secret.c under "Structure of + the EFI secret area". diff --git a/drivers/virt/Kconfig b/drivers/virt/Kconfig index 8061e8ef449f..fe7a6579b974 100644 --- a/drivers/virt/Kconfig +++ b/drivers/virt/Kconfig @@ -36,4 +36,7 @@ source "drivers/virt/vboxguest/Kconfig" source "drivers/virt/nitro_enclaves/Kconfig" source "drivers/virt/acrn/Kconfig" + +source "drivers/virt/coco/efi_secret/Kconfig" + endif diff --git a/drivers/virt/Makefile b/drivers/virt/Makefile index 3e272ea60cd9..efdb015783f9 100644 --- a/drivers/virt/Makefile +++ b/drivers/virt/Makefile @@ -8,3 +8,4 @@ obj-y += vboxguest/ obj-$(CONFIG_NITRO_ENCLAVES) += nitro_enclaves/ obj-$(CONFIG_ACRN_HSM) += acrn/ +obj-$(CONFIG_EFI_SECRET) += coco/efi_secret/ diff --git a/drivers/virt/coco/efi_secret/Kconfig b/drivers/virt/coco/efi_secret/Kconfig new file mode 100644 index 000000000000..a39a5a90a1e5 --- /dev/null +++ b/drivers/virt/coco/efi_secret/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-only +config EFI_SECRET + tristate "EFI secret area securityfs support" + depends on EFI + select EFI_COCO_SECRET + select SECURITYFS + help + This is a driver for accessing the EFI secret area via securityfs. + + To compile this driver as a module, choose M here. + The module will be called efi_secret. diff --git a/drivers/virt/coco/efi_secret/Makefile b/drivers/virt/coco/efi_secret/Makefile new file mode 100644 index 000000000000..c7047ce804f7 --- /dev/null +++ b/drivers/virt/coco/efi_secret/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_EFI_SECRET) += efi_secret.o diff --git a/drivers/virt/coco/efi_secret/efi_secret.c b/drivers/virt/coco/efi_secret/efi_secret.c new file mode 100644 index 000000000000..c0eaf63bc85a --- /dev/null +++ b/drivers/virt/coco/efi_secret/efi_secret.c @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * efi_secret module + * + * Copyright (C) 2021 IBM Corporation + * Author: Dov Murik + */ + +/** + * DOC: efi_secret: Allow reading EFI confidential computing (coco) secret area + * via securityfs interface. + * + * When the module is loaded (and securityfs is mounted, typically under + * /sys/kernel/security), a "coco/efi_secret" directory is created in + * securityfs. In it, a file is created for each secret entry. The name of + * each such file is the GUID of the secret entry, and its content is the + * secret data. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EFI_SECRET_NUM_FILES 64 + +#define EFI_SECRET_TABLE_HEADER_GUID \ + EFI_GUID(0x1e74f542, 0x71dd, 0x4d66, 0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b) + +struct efi_secret { + struct dentry *coco_dir; + struct dentry *fs_dir; + struct dentry *fs_files[EFI_SECRET_NUM_FILES]; + void __iomem *secret_data; + u64 secret_data_len; +}; + +/* + * Structure of the EFI secret area + * + * Offset Length + * (bytes) (bytes) Usage + * ------- ------- ----- + * 0 16 Secret table header GUID (must be 1e74f542-71dd-4d66-963e-ef4287ff173b) + * 16 4 Length of bytes of the entire secret area + * + * 20 16 First secret entry's GUID + * 36 4 First secret entry's length in bytes (= 16 + 4 + x) + * 40 x First secret entry's data + * + * 40+x 16 Second secret entry's GUID + * 56+x 4 Second secret entry's length in bytes (= 16 + 4 + y) + * 60+x y Second secret entry's data + * + * (... and so on for additional entries) + * + * The GUID of each secret entry designates the usage of the secret data. + */ + +/** + * struct secret_header - Header of entire secret area; this should be followed + * by instances of struct secret_entry. + * @guid: Must be EFI_SECRET_TABLE_HEADER_GUID + * @len: Length in bytes of entire secret area, including header + */ +struct secret_header { + efi_guid_t guid; + u32 len; +} __attribute((packed)); + +/** + * struct secret_entry - Holds one secret entry + * @guid: Secret-specific GUID (or NULL_GUID if this secret entry was deleted) + * @len: Length of secret entry, including its guid and len fields + * @data: The secret data (full of zeros if this secret entry was deleted) + */ +struct secret_entry { + efi_guid_t guid; + u32 len; + u8 data[]; +} __attribute((packed)); + +static size_t secret_entry_data_len(struct secret_entry *e) +{ + return e->len - sizeof(*e); +} + +static struct efi_secret the_efi_secret; + +static inline struct efi_secret *efi_secret_get(void) +{ + return &the_efi_secret; +} + +static int efi_secret_bin_file_show(struct seq_file *file, void *data) +{ + struct secret_entry *e = file->private; + + if (e) + seq_write(file, e->data, secret_entry_data_len(e)); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(efi_secret_bin_file); + +/* + * Overwrite memory content with zeroes, and ensure that dirty cache lines are + * actually written back to memory, to clear out the secret. + */ +static void wipe_memory(void *addr, size_t size) +{ + memzero_explicit(addr, size); +#ifdef CONFIG_X86 + clflush_cache_range(addr, size); +#endif +} + +static int efi_secret_unlink(struct inode *dir, struct dentry *dentry) +{ + struct efi_secret *s = efi_secret_get(); + struct inode *inode = d_inode(dentry); + struct secret_entry *e = (struct secret_entry *)inode->i_private; + int i; + + if (e) { + /* Zero out the secret data */ + wipe_memory(e->data, secret_entry_data_len(e)); + e->guid = NULL_GUID; + } + + inode->i_private = NULL; + + for (i = 0; i < EFI_SECRET_NUM_FILES; i++) + if (s->fs_files[i] == dentry) + s->fs_files[i] = NULL; + + /* + * securityfs_remove tries to lock the directory's inode, but we reach + * the unlink callback when it's already locked + */ + inode_unlock(dir); + securityfs_remove(dentry); + inode_lock(dir); + + return 0; +} + +static const struct inode_operations efi_secret_dir_inode_operations = { + .lookup = simple_lookup, + .unlink = efi_secret_unlink, +}; + +static int efi_secret_map_area(void) +{ + int ret; + struct efi_secret *s = efi_secret_get(); + struct linux_efi_coco_secret_area *secret_area; + + if (efi.coco_secret == EFI_INVALID_TABLE_ADDR) { + pr_err("Secret area address is not available\n"); + return -EINVAL; + } + + secret_area = memremap(efi.coco_secret, sizeof(*secret_area), MEMREMAP_WB); + if (secret_area == NULL) { + pr_err("Could not map secret area EFI config entry\n"); + return -ENOMEM; + } + if (!secret_area->base_pa || secret_area->size < sizeof(struct secret_header)) { + pr_err("Invalid secret area memory location (base_pa=0x%llx size=0x%llx)\n", + secret_area->base_pa, secret_area->size); + ret = -EINVAL; + goto unmap; + } + + s->secret_data = ioremap_encrypted(secret_area->base_pa, secret_area->size); + if (s->secret_data == NULL) { + pr_err("Could not map secret area\n"); + ret = -ENOMEM; + goto unmap; + } + + s->secret_data_len = secret_area->size; + ret = 0; + +unmap: + memunmap(secret_area); + return ret; +} + +static void efi_secret_securityfs_teardown(void) +{ + struct efi_secret *s = efi_secret_get(); + int i; + + for (i = (EFI_SECRET_NUM_FILES - 1); i >= 0; i--) { + securityfs_remove(s->fs_files[i]); + s->fs_files[i] = NULL; + } + + securityfs_remove(s->fs_dir); + s->fs_dir = NULL; + + securityfs_remove(s->coco_dir); + s->coco_dir = NULL; + + pr_debug("Removed efi_secret securityfs entries\n"); +} + +static int efi_secret_securityfs_setup(void) +{ + efi_guid_t tableheader_guid = EFI_SECRET_TABLE_HEADER_GUID; + struct efi_secret *s = efi_secret_get(); + int ret = 0, i = 0, bytes_left; + unsigned char *ptr; + struct secret_header *h; + struct secret_entry *e; + struct dentry *dent; + char guid_str[EFI_VARIABLE_GUID_LEN + 1]; + + s->coco_dir = NULL; + s->fs_dir = NULL; + memset(s->fs_files, 0, sizeof(s->fs_files)); + + dent = securityfs_create_dir("coco", NULL); + if (IS_ERR(dent)) { + pr_err("Error creating coco securityfs directory entry err=%ld\n", PTR_ERR(dent)); + return PTR_ERR(dent); + } + s->coco_dir = dent; + + dent = securityfs_create_dir("efi_secret", s->coco_dir); + if (IS_ERR(dent)) { + pr_err("Error creating efi_secret securityfs directory entry err=%ld\n", + PTR_ERR(dent)); + return PTR_ERR(dent); + } + d_inode(dent)->i_op = &efi_secret_dir_inode_operations; + s->fs_dir = dent; + + ptr = s->secret_data; + h = (struct secret_header *)ptr; + if (memcmp(&h->guid, &tableheader_guid, sizeof(h->guid))) { + pr_err("EFI secret area does not start with correct GUID\n"); + ret = -EINVAL; + goto err_cleanup; + } + if (h->len < sizeof(*h)) { + pr_err("EFI secret area reported length is too small\n"); + ret = -EINVAL; + goto err_cleanup; + } + if (h->len > s->secret_data_len) { + pr_err("EFI secret area reported length is too big\n"); + ret = -EINVAL; + goto err_cleanup; + } + + bytes_left = h->len - sizeof(*h); + ptr += sizeof(*h); + while (bytes_left >= (int)sizeof(*e) && i < EFI_SECRET_NUM_FILES) { + e = (struct secret_entry *)ptr; + if (e->len < sizeof(*e) || e->len > (unsigned int)bytes_left) { + pr_err("EFI secret area is corrupted\n"); + ret = -EINVAL; + goto err_cleanup; + } + + /* Skip deleted entries (which will have NULL_GUID) */ + if (efi_guidcmp(e->guid, NULL_GUID)) { + efi_guid_to_str(&e->guid, guid_str); + + dent = securityfs_create_file(guid_str, 0440, s->fs_dir, (void *)e, + &efi_secret_bin_file_fops); + if (IS_ERR(dent)) { + pr_err("Error creating efi_secret securityfs entry\n"); + ret = PTR_ERR(dent); + goto err_cleanup; + } + + s->fs_files[i++] = dent; + } + ptr += e->len; + bytes_left -= e->len; + } + + pr_debug("Created %d entries in efi_secret securityfs\n", i); + return 0; + +err_cleanup: + efi_secret_securityfs_teardown(); + return ret; +} + +static void efi_secret_unmap_area(void) +{ + struct efi_secret *s = efi_secret_get(); + + if (s->secret_data) { + iounmap(s->secret_data); + s->secret_data = NULL; + s->secret_data_len = 0; + } +} + +static int __init efi_secret_init(void) +{ + int ret; + + ret = efi_secret_map_area(); + if (ret) + return ret; + + ret = efi_secret_securityfs_setup(); + if (ret) + goto err_unmap; + + return ret; + +err_unmap: + efi_secret_unmap_area(); + return ret; +} + +static void __exit efi_secret_exit(void) +{ + efi_secret_securityfs_teardown(); + efi_secret_unmap_area(); +} + +module_init(efi_secret_init); +module_exit(efi_secret_exit); + +MODULE_DESCRIPTION("Confidential computing EFI secret area access"); +MODULE_AUTHOR("IBM"); +MODULE_LICENSE("GPL"); From patchwork Thu Nov 18 11:33:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dov Murik X-Patchwork-Id: 12626741 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C05AAC4321E for ; Thu, 18 Nov 2021 11:34:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A664661B97 for ; Thu, 18 Nov 2021 11:34:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344009AbhKRLhs (ORCPT ); Thu, 18 Nov 2021 06:37:48 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:59860 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343926AbhKRLhd (ORCPT ); Thu, 18 Nov 2021 06:37:33 -0500 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1AIAGeSG028085; Thu, 18 Nov 2021 11:34:12 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-transfer-encoding : mime-version; s=pp1; bh=bJyIG1THTivVhB2BZ9QU4NOZvj9mhtZ9mG7eBiHj4Tw=; b=F+K/VglwBnj6dIoNKvxJBrQDqH1vKPxw6MwKrUHltUz2ADsQrPbTF85Jnf6X03bz1h12 8A+HLi7yYA2jzdiA5GcDbl7I5fGL+/XXuYfSz+VXR80AIWYyRw/LiKLLN5RnDjxTyK6e +794BsLFyez9t4x5pS9Qn47r72+myqm1Dp04aFWOJvZKMVzXy0/R94a9QZQa4qmojVgV B+dHUUjdnDwvqPE+azhrhjZ93kIN2EUsu6bUkYerIwK3vEerGLTS+qEnOLuEEd0KQ8vN S3SJH09bREx23RtHIJkqWEKQCUd8lnJDzHmB5Fa9q5vZt4Y7hxELx2cIMWxTLCuV1xXg Vw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3cdmxc9n52-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:11 +0000 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1AIArIlt014968; Thu, 18 Nov 2021 11:34:10 GMT Received: from ppma05wdc.us.ibm.com (1b.90.2fa9.ip4.static.sl-reverse.com [169.47.144.27]) by mx0b-001b2d01.pphosted.com with ESMTP id 3cdmxc9n4k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:10 +0000 Received: from pps.filterd (ppma05wdc.us.ibm.com [127.0.0.1]) by ppma05wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1AIBRDrS023773; Thu, 18 Nov 2021 11:34:09 GMT Received: from b01cxnp22034.gho.pok.ibm.com (b01cxnp22034.gho.pok.ibm.com [9.57.198.24]) by ppma05wdc.us.ibm.com with ESMTP id 3ca50cj2hu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Nov 2021 11:34:09 +0000 Received: from b01ledav005.gho.pok.ibm.com (b01ledav005.gho.pok.ibm.com [9.57.199.110]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1AIBY67650004236 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Nov 2021 11:34:06 GMT Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4B967AE077; Thu, 18 Nov 2021 11:34:06 +0000 (GMT) Received: from b01ledav005.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 100E1AE06F; Thu, 18 Nov 2021 11:34:06 +0000 (GMT) Received: from amdrome3.watson.ibm.com (unknown [9.2.130.16]) by b01ledav005.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 18 Nov 2021 11:34:06 +0000 (GMT) From: Dov Murik To: linux-efi@vger.kernel.org Cc: Dov Murik , Borislav Petkov , Ashish Kalra , Brijesh Singh , Tom Lendacky , Ard Biesheuvel , James Morris , "Serge E. Hallyn" , Andi Kleen , Greg KH , Andrew Scull , Dave Hansen , "Dr. David Alan Gilbert" , James Bottomley , Tobin Feldman-Fitzthum , Jim Cadden , Daniele Buono , linux-coco@lists.linux.dev, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 4/4] docs: security: Add coco/efi_secret documentation Date: Thu, 18 Nov 2021 11:33:59 +0000 Message-Id: <20211118113359.642571-5-dovmurik@linux.ibm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211118113359.642571-1-dovmurik@linux.ibm.com> References: <20211118113359.642571-1-dovmurik@linux.ibm.com> X-TM-AS-GCONF: 00 X-Proofpoint-GUID: YjJ-wr7c-NLArkOHZ2vFJaxPh-Y4Anj_ X-Proofpoint-ORIG-GUID: Gyv5FU_GAGXKmmECFz_KincPtLYEmh5Q X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-11-18_05,2021-11-17_01,2020-04-07_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 phishscore=0 mlxlogscore=999 spamscore=0 suspectscore=0 impostorscore=0 adultscore=0 malwarescore=0 priorityscore=1501 mlxscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2111180067 Precedence: bulk List-ID: Add documentation for the efi_secret module which allows access to Confidential Computing injected secrets. Signed-off-by: Dov Murik --- Documentation/security/coco/efi_secret.rst | 103 +++++++++++++++++++++ Documentation/security/coco/index.rst | 9 ++ Documentation/security/index.rst | 1 + 3 files changed, 113 insertions(+) create mode 100644 Documentation/security/coco/efi_secret.rst create mode 100644 Documentation/security/coco/index.rst diff --git a/Documentation/security/coco/efi_secret.rst b/Documentation/security/coco/efi_secret.rst new file mode 100644 index 000000000000..bb7acae22e90 --- /dev/null +++ b/Documentation/security/coco/efi_secret.rst @@ -0,0 +1,103 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========== +efi_secret +========== + +This document describes how Confidential Computing secret injection is handled +from the firmware to the operating system. + + +Introduction +============ + +Confidential Computing (coco) hardware such as AMD SEV (Secure Encrypted +Virtualization) allows guest owners to inject secrets into the VMs +memory without the host/hypervisor being able to read them. In SEV, +secret injection is performed early in the VM launch process, before the +guest starts running. + +The efi_secret kernel module allows userspace applications to access these +secrets via securityfs. + + +Secret data flow +================ + +The guest firmware may reserve a designated memory area for secret injection, +and publish its location (base GPA and length) in the EFI configuration table +under a ``LINUX_EFI_COCO_SECRET_AREA_GUID`` entry +(``adf956ad-e98c-484c-ae11-b51c7d336447``). This memory area should be marked +by the firmware as ``EFI_RESERVED_TYPE``, and therefore the kernel should not +be use it for its own purposes. + +During the VM's launch, the virtual machine manager may inject a secret to that +area. In AMD SEV and SEV-ES this is performed using the +``KVM_SEV_LAUNCH_SECRET`` command (see [amd-mem-enc]_). The strucutre of the +injected Guest Owner secret data should be a GUIDed table of secret values; the +binary format is described in ``drivers/virt/coco/efi_secret/efi_secret.c`` +under "Structure of the EFI secret area". + +On kernel start, the kernel's EFI driver saves the location of the secret +memory (taken from the EFI configuration table) in the ``efi.coco_secret`` +field. + +When a userspace application needs to access the secrets inside the guest VM, +it loads the efi_secret kernel module (``CONFIG_EFI_SECRET=m``) which exposes +the secrets via securityfs. The details of the efi_secret filesystem interface +are in [efi-secret-abi]_. + + + +Application usage example +========================= + +Consider a guest performing computations on encrypted files. The Guest Owner +provides the decryption key (= secret) using the secret injection mechanism. +The guest application reads the secret from the efi_secret filesystem and +proceeds to decrypt the files into memory and then performs the needed +computations on the content. + +In this example, the host can't read the files from the disk image +because they are encrypted. Host can't read the decryption key because +it is passed using the secret injection mechanism (= secure channel). +Host can't read the decrypted content from memory because it's a +confidential (memory-encrypted) guest. + +Here is a simple example for usage of the efi_secret module in a guest +to which an EFI secret area with 4 secrets was injected during launch:: + + # modprobe efi_secret + # ls -la /sys/kernel/security/coco/efi_secret + total 0 + drwxr-xr-x 2 root root 0 Jun 28 11:54 . + drwxr-xr-x 3 root root 0 Jun 28 11:54 .. + -r--r----- 1 root root 0 Jun 28 11:54 736870e5-84f0-4973-92ec-06879ce3da0b + -r--r----- 1 root root 0 Jun 28 11:54 83c83f7f-1356-4975-8b7e-d3a0b54312c6 + -r--r----- 1 root root 0 Jun 28 11:54 9553f55d-3da2-43ee-ab5d-ff17f78864d2 + -r--r----- 1 root root 0 Jun 28 11:54 e6f5a162-d67f-4750-a67c-5d065f2a9910 + + # xxd /sys/kernel/security/coco/efi_secret/e6f5a162-d67f-4750-a67c-5d065f2a9910 + 00000000: 7468 6573 652d 6172 652d 7468 652d 6b61 these-are-the-ka + 00000010: 7461 2d73 6563 7265 7473 0001 0203 0405 ta-secrets...... + 00000020: 0607 .. + + # rm /sys/kernel/security/coco/efi_secret/e6f5a162-d67f-4750-a67c-5d065f2a9910 + + # ls -la /sys/kernel/security/coco/efi_secret + total 0 + drwxr-xr-x 2 root root 0 Jun 28 11:55 . + drwxr-xr-x 3 root root 0 Jun 28 11:54 .. + -r--r----- 1 root root 0 Jun 28 11:54 736870e5-84f0-4973-92ec-06879ce3da0b + -r--r----- 1 root root 0 Jun 28 11:54 83c83f7f-1356-4975-8b7e-d3a0b54312c6 + -r--r----- 1 root root 0 Jun 28 11:54 9553f55d-3da2-43ee-ab5d-ff17f78864d2 + + +References +========== + +See [sev-api-spec]_ for more info regarding SEV ``LAUNCH_SECRET`` operation. + +.. [amd-mem-enc] :ref:`Documentation/virt/kvm/amd-memory-encryption ` +.. [efi-secret-abi] :ref:`Documentation/ABI/testing/securityfs-coco-efi_secret ` +.. [sev-api-spec] https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf diff --git a/Documentation/security/coco/index.rst b/Documentation/security/coco/index.rst new file mode 100644 index 000000000000..56b803d4b33e --- /dev/null +++ b/Documentation/security/coco/index.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0 + +==================================== +Confidential Computing documentation +==================================== + +.. toctree:: + + efi_secret diff --git a/Documentation/security/index.rst b/Documentation/security/index.rst index 16335de04e8c..d4ef543825a7 100644 --- a/Documentation/security/index.rst +++ b/Documentation/security/index.rst @@ -17,3 +17,4 @@ Security Documentation tpm/index digsig landlock + coco