Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp3172775imw; Mon, 11 Jul 2022 03:30:38 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t0Lv7+jQXDJTHxAJcnPtZPVrh5tQJ9cVBcfWp1rjw0/FGqVjOsX3IOv/ULvNn5aU99RrsI X-Received: by 2002:a17:906:ce:b0:715:705e:52fb with SMTP id 14-20020a17090600ce00b00715705e52fbmr17613069eji.303.1657535438487; Mon, 11 Jul 2022 03:30:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657535438; cv=none; d=google.com; s=arc-20160816; b=wNwPy8jhXpWcUEWm4NS4IEiNpBpTFwGVfKojXJHZIUtbwYnvEvcQUS4VNiZW5Wc7RE gRSmswnoZuu0nCB3h1YSYmvsjqdcosc9E1b2TyZOQVduPl3EN+Z5cDeXL6MxceofT8md xqF05MEP8XbjXwkjyk24PQyJbQN3tSDzp94lERfwBqwhrdulHERpjDdfTvdGIHW/JbeS pYLDT6Lbq6ekJxr39Yl0ryERf87uNte8eZbNlxCjwJOETF9mi0J4wmHTSOJBzYZnWdPV 8s+Qwe/PmSnkSAsAw87tzAg8juGv1Gp8SjCY9Uj7Vd8BslhSXgsGjXxHKvW4/kmR2Hmt LlEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=S4PtrRyRTEyIFKiEoWBWTZrQsyD29BiNa7vn2sBQ1GM=; b=bhD0rF4+c8JpoFevWK/ELFwIftlLOmmnX9ni8rYw+6X2OJEsUojHJ5AepPWlwpGknv bmDWT7lK0tIwbJg7tfbeCgMvpDVERpPyxPa38rJVaIQHJKLSWpZ97FuUx2MWG2siJkGO /fghwlUSmQmsIwMQxEbI39xYFwjNRJkkwzd2Y0UY5EkJcvjW+s7F61mexs9HvEGg+p5Q ADeNBABazPbe1fLjEGya6vIILlzy72wrFv6ibFwCs6fIJs13hUo/Ax2/3U8Y53olRNp2 lihu4DHuWi/uqidNqzhAUppUhw1dV8K9ggtKSQjk6n45f8xk/k8eYHlSyeBm+uRSriPt PGzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="d/In4R1W"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=IdozVlif; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l21-20020a170906795500b0072b4afe43desi6563717ejo.105.2022.07.11.03.30.13; Mon, 11 Jul 2022 03:30:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b="d/In4R1W"; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=IdozVlif; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229959AbiGKK2g (ORCPT + 99 others); Mon, 11 Jul 2022 06:28:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229929AbiGKK2M (ORCPT ); Mon, 11 Jul 2022 06:28:12 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1B3B6CFB5B; Mon, 11 Jul 2022 02:39:56 -0700 (PDT) Date: Mon, 11 Jul 2022 09:39:53 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1657532395; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S4PtrRyRTEyIFKiEoWBWTZrQsyD29BiNa7vn2sBQ1GM=; b=d/In4R1Wo5CNCZyHbWz2/cBO+G1b6RWRroi9zyj/rR2gqMhxJButj8lUJgt8qCQE52rhIh mUArZ0Yy/i3DXODW4J/ARxucWdTzOdijBZRRREUsKC4F6GTNN+LIZJFXl/fIVV3zLjpj5q ovhJo6FaFnNkMyxcHoDZhlwp3nvABJkmdWtsY+ywEDh4gZo+J/5yVLH4pPaMY6TxIRNuHl YJxVPQ8uWcnEfA0j1SGXE8qPwdotvdHi6SADQkViYkbW9kzBESCUCUaRhFHiZaYszoC5AP x9/ckRDPUWOLXwDUTrwO86BxWkbfdPQMxFAhMuV2j356dnyd1vzJ+p/W734qwg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1657532395; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S4PtrRyRTEyIFKiEoWBWTZrQsyD29BiNa7vn2sBQ1GM=; b=IdozVlifRWu7Vaxm+GCyJDvjxbTKo0sgSWzjZvrBjAlZltsE9Brg932tTNovsDchs6dShJ ogJy/6ft8xACFUAA== From: "tip-bot2 for Jason A. Donenfeld" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/kdump] x86/setup: Use rng seeds from setup_data Cc: "Jason A. Donenfeld" , Borislav Petkov , "H. Peter Anvin (Intel)" , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20220630113300.1892799-1-Jason@zx2c4.com> References: <20220630113300.1892799-1-Jason@zx2c4.com> MIME-Version: 1.0 Message-ID: <165753239385.15455.13768399417352293953.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the x86/kdump branch of tip: Commit-ID: 68b8e9713c8ec90af93c16e1de51cca18cefdb56 Gitweb: https://git.kernel.org/tip/68b8e9713c8ec90af93c16e1de51cca18cefdb56 Author: Jason A. Donenfeld AuthorDate: Sun, 10 Jul 2022 19:29:21 +02:00 Committer: Borislav Petkov CommitterDate: Mon, 11 Jul 2022 09:59:31 +02:00 x86/setup: Use rng seeds from setup_data Currently, the only way x86 can get an early boot RNG seed is via EFI, which is generally always used now for physical machines, but is very rarely used in VMs, especially VMs that are optimized for starting "instantaneously", such as Firecracker's MicroVM. For tiny fast booting VMs, EFI is not something you generally need or want. Rather, the image loader or firmware should be able to pass a single random seed, exactly as device tree platforms do with the "rng-seed" property. Additionally, this is something that bootloaders can append, with their own seed file management, which is something every other major OS ecosystem has that Linux does not (yet). Add SETUP_RNG_SEED, similar to the other eight setup_data entries that are parsed at boot. It also takes care to zero out the seed immediately after using, in order to retain forward secrecy. This all takes about 7 trivial lines of code. Then, on kexec_file_load(), a new fresh seed is generated and passed to the next kernel, just as is done on device tree architectures when using kexec. And, importantly, I've tested that QEMU is able to properly pass SETUP_RNG_SEED as well, making this work for every step of the way. This code too is pretty straight forward. Together these measures ensure that VMs and nested kexec()'d kernels always receive a proper boot time RNG seed at the earliest possible stage from their parents: - Host [already has strongly initialized RNG] - QEMU [passes fresh seed in SETUP_RNG_SEED field] - Linux [uses parent's seed and gathers entropy of its own] - kexec [passes this in SETUP_RNG_SEED field] - Linux [uses parent's seed and gathers entropy of its own] - kexec [passes this in SETUP_RNG_SEED field] - Linux [uses parent's seed and gathers entropy of its own] - kexec [passes this in SETUP_RNG_SEED field] - ... I've verified in several scenarios that this works quite well from a host kernel to QEMU and down inwards, mixing and matching loaders, with every layer providing a seed to the next. [ bp: Massage commit message. ] Signed-off-by: Jason A. Donenfeld Signed-off-by: Borislav Petkov Acked-by: H. Peter Anvin (Intel) Link: https://lore.kernel.org/r/20220630113300.1892799-1-Jason@zx2c4.com --- arch/x86/include/uapi/asm/bootparam.h | 6 ++-- arch/x86/kernel/kexec-bzimage64.c | 38 +++++++++++++++++++++++--- arch/x86/kernel/setup.c | 10 +++++++- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index be2b9ce..3422906 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -12,11 +12,11 @@ #define SETUP_JAILHOUSE 6 #define SETUP_CC_BLOB 7 #define SETUP_IMA 8 +#define SETUP_RNG_SEED 9 +#define SETUP_ENUM_MAX SETUP_RNG_SEED #define SETUP_INDIRECT (1<<31) - -/* SETUP_INDIRECT | max(SETUP_*) */ -#define SETUP_TYPE_MAX (SETUP_INDIRECT | SETUP_CC_BLOB) +#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT) /* ram_size flags */ #define RAMDISK_IMAGE_START_MASK 0x07FF diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index c63974e..b9bdb40 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -110,6 +111,26 @@ static int setup_e820_entries(struct boot_params *params) return 0; } +enum { RNG_SEED_LENGTH = 32 }; + +static void +setup_rng_seed(struct boot_params *params, unsigned long params_load_addr, + unsigned int rng_seed_setup_data_offset) +{ + struct setup_data *sd = (void *)params + rng_seed_setup_data_offset; + unsigned long setup_data_phys; + + if (!rng_is_initialized()) + return; + + sd->type = SETUP_RNG_SEED; + sd->len = RNG_SEED_LENGTH; + get_random_bytes(sd->data, RNG_SEED_LENGTH); + setup_data_phys = params_load_addr + rng_seed_setup_data_offset; + sd->next = params->hdr.setup_data; + params->hdr.setup_data = setup_data_phys; +} + #ifdef CONFIG_EFI static int setup_efi_info_memmap(struct boot_params *params, unsigned long params_load_addr, @@ -277,9 +298,16 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, sizeof(struct efi_setup_data); #endif - /* Setup IMA log buffer state */ - setup_ima_state(image, params, params_load_addr, - setup_data_offset); + if (IS_ENABLED(CONFIG_IMA_KEXEC)) { + /* Setup IMA log buffer state */ + setup_ima_state(image, params, params_load_addr, + setup_data_offset); + setup_data_offset += sizeof(struct setup_data) + + sizeof(struct ima_setup_data); + } + + /* Setup RNG seed */ + setup_rng_seed(params, params_load_addr, setup_data_offset); /* Setup EDD info */ memcpy(params->eddbuf, boot_params.eddbuf, @@ -435,7 +463,9 @@ static void *bzImage64_load(struct kimage *image, char *kernel, params_cmdline_sz = ALIGN(params_cmdline_sz, 16); kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) + sizeof(struct setup_data) + - sizeof(struct efi_setup_data); + sizeof(struct efi_setup_data) + + sizeof(struct setup_data) + + RNG_SEED_LENGTH; if (IS_ENABLED(CONFIG_IMA_KEXEC)) kbuf.bufsz += sizeof(struct setup_data) + diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 53f863f..216fee7 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -418,6 +419,15 @@ static void __init parse_setup_data(void) case SETUP_IMA: add_early_ima_buffer(pa_data); break; + case SETUP_RNG_SEED: + data = early_memremap(pa_data, data_len); + add_bootloader_randomness(data->data, data->len); + /* Zero seed for forward secrecy. */ + memzero_explicit(data->data, data->len); + /* Zero length in case we find ourselves back here by accident. */ + memzero_explicit(&data->len, sizeof(data->len)); + early_memunmap(data, data_len); + break; default: break; }