From patchwork Wed Apr 5 09:23:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 96799 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp173428qgd; Wed, 5 Apr 2017 02:23:54 -0700 (PDT) X-Received: by 10.98.34.20 with SMTP id i20mr7623431pfi.102.1491384234748; Wed, 05 Apr 2017 02:23:54 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h1si20066378pfg.225.2017.04.05.02.23.54; Wed, 05 Apr 2017 02:23:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933081AbdDEJXv (ORCPT + 2 others); Wed, 5 Apr 2017 05:23:51 -0400 Received: from mail-wm0-f48.google.com ([74.125.82.48]:38415 "EHLO mail-wm0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933040AbdDEJXt (ORCPT ); Wed, 5 Apr 2017 05:23:49 -0400 Received: by mail-wm0-f48.google.com with SMTP id t189so8335605wmt.1 for ; Wed, 05 Apr 2017 02:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7yt6bt9/BLTB8jweuGJYuVeKq77EzRfl3nAPNwKW7KA=; b=RIKLyQ7pcFgRKkAJoicjmF2qas0/iSaTjYlJUzn28Ns6bWB2lTzuypTzwri5b3C25j +aMBJfXDYZ21KU1EiNfWAk6gngi46Ub6xjd7MdNLCQCkhQhfI2/RG3zeeVgSQmfMRva3 HTjieKs5sBn4ew1AgcgIzWf3BJptQ7j5Xf0OY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7yt6bt9/BLTB8jweuGJYuVeKq77EzRfl3nAPNwKW7KA=; b=FUx89UYNAjDfc6Wgwa6XujkGx7MpbsaTWZ6A5rhrWMCG4J9OAQGa22sic/kRsO09r8 OPoPvMYuZki3za4PIjoqHYe1P7mk6XJNmBJ6nQVPFN2zAidAJ/V29mxYnJ5y7erdUSey bG1FFQMv75kuczxUVzQnhd+MMCrPmDssuwVGfKKMDBSOaNZi1FWCkbNCro4Ak/J2GUTV HIMjdNUqlk2/XXc/1hIdkuFusgrJiq9ZMCBbbQ2zZKXoIinlbzEWxv7OhaWmL70Xy01L shrkkBQYmzXq6LIPhuLVdWFgcgJjD7hN4f3J4AblNNsHkmW9lU5fx2vdoz9bvbq1sm1l OGmw== X-Gm-Message-State: AFeK/H1r5Cz8oYCFyHD9zTh7OuC/E56hosdFXtV9mseRdpB0a737SX2EAPUHyYvVob76noZq X-Received: by 10.28.103.84 with SMTP id b81mr18164751wmc.124.1491384227442; Wed, 05 Apr 2017 02:23:47 -0700 (PDT) Received: from localhost.localdomain ([160.163.145.113]) by smtp.gmail.com with ESMTPSA id b66sm23935271wrd.29.2017.04.05.02.23.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 05 Apr 2017 02:23:46 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: matt@codeblueprint.co.uk, andy.shevchenko@gmail.com, pure.logic@nexus-software.ie, hock.leong.kweh@intel.com, bp@alien8.de, sascha.weisenberger@siemens.com, jan.kiszka@siemens.com, Ard Biesheuvel Subject: [PATCH 8/8] efi/capsule: Add support for Quark security header Date: Wed, 5 Apr 2017 10:23:17 +0100 Message-Id: <20170405092317.27921-9-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170405092317.27921-1-ard.biesheuvel@linaro.org> References: <20170405092317.27921-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org From: Jan Kiszka The firmware for Quark X102x prepends a security header to the capsule which is needed to support the mandatory secure boot on this processor. The header can be detected by checking for the "_CSH" signature and - to avoid any GUID conflict - validating its size field to contain the expected value. Then we need to look for the EFI header right after the security header and pass the real header to __efi_capsule_setup_info. To be minimally invasive and maximally safe, the quirk version of efi_capsule_identify_image is only effective on Quark processors. Signed-off-by: Jan Kiszka Cc: Matt Fleming [ardb: refactor using an override of efi_capsule_setup_info()] Signed-off-by: Ard Biesheuvel --- arch/x86/platform/efi/quirks.c | 112 ++++++++++++++++++++ drivers/firmware/efi/Kconfig | 9 ++ 2 files changed, 121 insertions(+) -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 30031d5293c4..ee922e1b7008 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -13,12 +13,66 @@ #include #include #include +#include #define EFI_MIN_RESERVE 5120 #define EFI_DUMMY_GUID \ EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) +#define QUARK_CSH_SIGNATURE 0x5f435348 /* _CSH */ +#define QUARK_SECURITY_HEADER_SIZE 0x400 + +/* + * Header prepended to the standard EFI capsule on Quark systems the are based + * on Intel firmware BSP. + * @csh_signature: Unique identifier to sanity check signed module + * presence ("_CSH"). + * @version: Current version of CSH used. Should be one for Quark A0. + * @modulesize: Size of the entire module including the module header + * and payload. + * @security_version_number_index: Index of SVN to use for validation of signed + * module. + * @security_version_number: Used to prevent against roll back of modules. + * @rsvd_module_id: Currently unused for Clanton (Quark). + * @rsvd_module_vendor: Vendor Identifier. For Intel products value is + * 0x00008086. + * @rsvd_date: BCD representation of build date as yyyymmdd, where + * yyyy=4 digit year, mm=1-12, dd=1-31. + * @headersize: Total length of the header including including any + * padding optionally added by the signing tool. + * @hash_algo: What Hash is used in the module signing. + * @cryp_algo: What Crypto is used in the module signing. + * @keysize: Total length of the key data including including any + * padding optionally added by the signing tool. + * @signaturesize: Total length of the signature including including any + * padding optionally added by the signing tool. + * @rsvd_next_header: 32-bit pointer to the next Secure Boot Module in the + * chain, if there is a next header. + * @rsvd: Reserved, padding structure to required size. + * + * See also QuartSecurityHeader_t in + * Quark_EDKII_v1.2.1.1/QuarkPlatformPkg/Include/QuarkBootRom.h + * from https://downloadcenter.intel.com/download/23197/Intel-Quark-SoC-X1000-Board-Support-Package-BSP + */ +struct quark_security_header { + u32 csh_signature; + u32 version; + u32 modulesize; + u32 security_version_number_index; + u32 security_version_number; + u32 rsvd_module_id; + u32 rsvd_module_vendor; + u32 rsvd_date; + u32 headersize; + u32 hash_algo; + u32 cryp_algo; + u32 keysize; + u32 signaturesize; + u32 rsvd_next_header; + u32 rsvd[2]; +}; + static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; static bool efi_no_storage_paranoia; @@ -495,3 +549,61 @@ bool efi_poweroff_required(void) { return acpi_gbl_reduced_hardware || acpi_no_s5; } + +#ifdef CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH + +static const struct x86_cpu_id quark_ids[] = { + { X86_VENDOR_INTEL, 5, 9 }, /* Intel Quark X1000 */ + { } +}; + +int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, + size_t hdr_bytes) +{ + struct quark_security_header *csh = kbuff; + + cap_info->total_size = 0; + + if (!x86_match_cpu(quark_ids)) + goto fallback; + + /* Only process data block that is larger than the security header */ + if (hdr_bytes < sizeof(struct quark_security_header)) + return 0; + + if (csh->csh_signature != QUARK_CSH_SIGNATURE || + csh->headersize != QUARK_SECURITY_HEADER_SIZE) + goto fallback; + + /* Only process data block if EFI header is included */ + if (hdr_bytes < QUARK_SECURITY_HEADER_SIZE + + sizeof(efi_capsule_header_t)) + return 0; + + pr_debug("Quark security header detected\n"); + + if (csh->rsvd_next_header != 0) { + pr_err("multiple Quark security headers not supported\n"); + return -EINVAL; + } + + kbuff += csh->headersize; + cap_info->total_size = csh->headersize; + + /* + * Update the first page pointer to skip over the CSH header. + */ + cap_info->pages[0] += csh->headersize; + +fallback: + if (hdr_bytes < sizeof(efi_capsule_header_t)) + return 0; + + memcpy(&cap_info->header, kbuff, sizeof(cap_info->header)); + + cap_info->total_size += cap_info->header.imagesize; + + return __efi_capsule_setup_info(cap_info); +} + +#endif diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 2e78b0b96d74..394db40ed374 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -112,6 +112,15 @@ config EFI_CAPSULE_LOADER Most users should say N. +config EFI_CAPSULE_QUIRK_QUARK_CSH + boolean "Add support for Quark capsules with non-standard headers" + depends on X86 && !64BIT + select EFI_CAPSULE_LOADER + default y + help + Add support for processing Quark X1000 EFI capsules, whose header + layout deviates from the layout mandated by the UEFI specification. + config EFI_TEST tristate "EFI Runtime Service Tests Support" depends on EFI