lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Wed, 22 Feb 2017 09:48:52 -0600 From: Tom Lendacky <thomas.lendacky@....com> To: Borislav Petkov <bp@...en8.de> CC: <linux-arch@...r.kernel.org>, <linux-efi@...r.kernel.org>, <kvm@...r.kernel.org>, <linux-doc@...r.kernel.org>, <x86@...nel.org>, <linux-kernel@...r.kernel.org>, <kasan-dev@...glegroups.com>, <linux-mm@...ck.org>, <iommu@...ts.linux-foundation.org>, Rik van Riel <riel@...hat.com>, Radim Krčmář <rkrcmar@...hat.com>, Toshimitsu Kani <toshi.kani@....com>, Arnd Bergmann <arnd@...db.de>, Jonathan Corbet <corbet@....net>, Matt Fleming <matt@...eblueprint.co.uk>, "Michael S. Tsirkin" <mst@...hat.com>, Joerg Roedel <joro@...tes.org>, Konrad Rzeszutek Wilk <konrad.wilk@...cle.com>, Paolo Bonzini <pbonzini@...hat.com>, Brijesh Singh <brijesh.singh@....com>, Ingo Molnar <mingo@...hat.com>, Alexander Potapenko <glider@...gle.com>, Andy Lutomirski <luto@...nel.org>, "H. Peter Anvin" <hpa@...or.com>, Andrey Ryabinin <aryabinin@...tuozzo.com>, Thomas Gleixner <tglx@...utronix.de>, Larry Woodman <lwoodman@...hat.com>, Dmitry Vyukov <dvyukov@...gle.com> Subject: Re: [RFC PATCH v4 09/28] x86: Add support for early encryption/decryption of memory On 2/20/2017 12:22 PM, Borislav Petkov wrote: > On Thu, Feb 16, 2017 at 09:43:58AM -0600, Tom Lendacky wrote: >> Add support to be able to either encrypt or decrypt data in place during >> the early stages of booting the kernel. This does not change the memory >> encryption attribute - it is used for ensuring that data present in either >> an encrypted or decrypted memory area is in the proper state (for example >> the initrd will have been loaded by the boot loader and will not be >> encrypted, but the memory that it resides in is marked as encrypted). >> >> The early_memmap support is enhanced to specify encrypted and decrypted >> mappings with and without write-protection. The use of write-protection is >> necessary when encrypting data "in place". The write-protect attribute is >> considered cacheable for loads, but not stores. This implies that the >> hardware will never give the core a dirty line with this memtype. >> >> Signed-off-by: Tom Lendacky <thomas.lendacky@....com> >> --- >> arch/x86/include/asm/mem_encrypt.h | 15 +++++++ >> arch/x86/mm/mem_encrypt.c | 79 ++++++++++++++++++++++++++++++++++++ >> 2 files changed, 94 insertions(+) > > ... > >> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c >> index d71df97..ac3565c 100644 >> --- a/arch/x86/mm/mem_encrypt.c >> +++ b/arch/x86/mm/mem_encrypt.c >> @@ -14,6 +14,9 @@ >> #include <linux/init.h> >> #include <linux/mm.h> >> >> +#include <asm/tlbflush.h> >> +#include <asm/fixmap.h> >> + >> extern pmdval_t early_pmd_flags; >> >> /* >> @@ -24,6 +27,82 @@ >> unsigned long sme_me_mask __section(.data) = 0; >> EXPORT_SYMBOL_GPL(sme_me_mask); >> >> +/* Buffer used for early in-place encryption by BSP, no locking needed */ >> +static char sme_early_buffer[PAGE_SIZE] __aligned(PAGE_SIZE); >> + >> +/* >> + * This routine does not change the underlying encryption setting of the >> + * page(s) that map this memory. It assumes that eventually the memory is >> + * meant to be accessed as either encrypted or decrypted but the contents >> + * are currently not in the desired stated. > > state. Will fix. > >> + * >> + * This routine follows the steps outlined in the AMD64 Architecture >> + * Programmer's Manual Volume 2, Section 7.10.8 Encrypt-in-Place. >> + */ >> +static void __init __sme_early_enc_dec(resource_size_t paddr, >> + unsigned long size, bool enc) >> +{ >> + void *src, *dst; >> + size_t len; >> + >> + if (!sme_me_mask) >> + return; >> + >> + local_flush_tlb(); >> + wbinvd(); >> + >> + /* >> + * There are limited number of early mapping slots, so map (at most) >> + * one page at time. >> + */ >> + while (size) { >> + len = min_t(size_t, sizeof(sme_early_buffer), size); >> + >> + /* >> + * Create write protected mappings for the current format > > write-protected Ok. > >> + * of the memory. >> + */ >> + src = enc ? early_memremap_decrypted_wp(paddr, len) : >> + early_memremap_encrypted_wp(paddr, len); >> + >> + /* >> + * Create mappings for the desired format of the memory. >> + */ > > That comment can go - you already say that in the previous one. Ok. > >> + dst = enc ? early_memremap_encrypted(paddr, len) : >> + early_memremap_decrypted(paddr, len); > > Btw, looking at this again, it seems to me that if you write it this > way: > > if (enc) { > src = early_memremap_decrypted_wp(paddr, len); > dst = early_memremap_encrypted(paddr, len); > } else { > src = early_memremap_encrypted_wp(paddr, len); > dst = early_memremap_decrypted(paddr, len); > } > > it might become even more readable. Anyway, just an idea - your decision > which is better. I go back and forth on that one, too. Not sure what I'll do, I guess it will depend on my mood :). > >> + >> + /* >> + * If a mapping can't be obtained to perform the operation, >> + * then eventual access of that area will in the desired > > s/will // Yup. Thanks, Tom > >> + * mode will cause a crash. >> + */ >> + BUG_ON(!src || !dst); >> + >> + /* >> + * Use a temporary buffer, of cache-line multiple size, to >> + * avoid data corruption as documented in the APM. >> + */ >> + memcpy(sme_early_buffer, src, len); >> + memcpy(dst, sme_early_buffer, len); >> + >> + early_memunmap(dst, len); >> + early_memunmap(src, len); >> + >> + paddr += len; >> + size -= len; >> + } >> +} >> + >> +void __init sme_early_encrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, true); >> +} >> + >> +void __init sme_early_decrypt(resource_size_t paddr, unsigned long size) >> +{ >> + __sme_early_enc_dec(paddr, size, false); >> +} >> + >> void __init sme_early_init(void) >> { >> unsigned int i; >> >> >
Powered by blists - more mailing lists