From patchwork Wed Feb 9 10:10:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590299 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=u37I8uHa; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jtwf40D8Tz9sFv for ; Wed, 9 Feb 2022 21:11:55 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7011E83E3A; Wed, 9 Feb 2022 11:11:41 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="u37I8uHa"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E59B583E15; Wed, 9 Feb 2022 11:11:37 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A060583D9D for ; Wed, 9 Feb 2022 11:11:31 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x434.google.com with SMTP id 9so525778pfx.12 for ; Wed, 09 Feb 2022 02:11:31 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=vAUrccOcjJ2G+C/4lh4EvbKPHQfuGlK697Ng84jVThE=; b=u37I8uHaH74B7FkD1Brw270DHH33+avqYql3uuzIr21vSfKKfxuvR8MBBlBCN+/Lw+ Z9AsbGBCEbLJhQgBCxDM0ndfW+t/l/p3VPTl1mVyJZp2hPikvO3OsHnFgx+vYKP6B34y LDQGwDw4gy9Tb0atNpTVe6+3+KJIQlcNjZNTQAR16uMopxZV9yNZAinhAeYI5a0bpgP4 6BUQI1Bl6Ey+Ipcj2+jVi14Kurs5c6nH1cBXlgjKZU+HTOkoMcT88gu9UyAQxxL4A9ix 5DiapmSid2r0wMrv+jV1/bBuuw7h25FtupSMTnB0xCHUP7vAzqVoUwHtNXVVPUvHxAG5 Qk1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=vAUrccOcjJ2G+C/4lh4EvbKPHQfuGlK697Ng84jVThE=; b=ozNRntoLq/TUX0+OClJ71rjfA50SY2oC4H9Cb6Wrgu3oN0ywflb56uHRhurG2NndwR tT7FtWGS8cz1yPvqW9dqiAKkFVkyFUkZSNDXr5OfQsAquqYXu534O0X4do6sQHq7m1DK dKkMWWiscSIFw/8JiAzcxdw4KjwalQoSSjVJw3k9W86lIVrwfISyVRLyzSlfI9xhYsL4 anzYCNCcDyM2usJ2i7sdZwsTyCHIjs/supSkAWd9DpGovC5GBBHEgi3/+G5sP73nxIPj caSNid4L8m9DFdD5vja+500Z9olDzbZlF7wqmZFuOcJkz7oWhR0z7yRmq9faYFQ2rAcc d47g== X-Gm-Message-State: AOAM531dVRNlDhPQjZ58K5PM91GfIJ2SSZtI2yPICdRJ2+9iNUbpWccW +spfxkjNjgNdmPdLWZuC1cAfRw== X-Google-Smtp-Source: ABdhPJyV9gaWF2ujkDfiUpQJJbXi/frlzPPymLiH1h5wUpU48WoEu4dIVLom8BIldS8Tb1JnuhrXAg== X-Received: by 2002:a63:6c46:: with SMTP id h67mr1259328pgc.493.1644401489884; Wed, 09 Feb 2022 02:11:29 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:29 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 1/9] tools: build mkeficapsule with tools-only_defconfig Date: Wed, 9 Feb 2022 19:10:34 +0900 Message-Id: <20220209101042.78036-2-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Add CONFIG_TOOLS_MKEFICAPSULE. Then we want to always build mkeficapsule if tools-only_defconfig is used. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass --- configs/tools-only_defconfig | 1 + tools/Kconfig | 8 ++++++++ tools/Makefile | 3 +-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index 1f8e90a69f53..2246b3c660a6 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -34,3 +34,4 @@ CONFIG_I2C_EDID=y # CONFIG_VIRTIO_SANDBOX is not set # CONFIG_GENERATE_ACPI_TABLE is not set # CONFIG_EFI_LOADER is not set +CONFIG_TOOLS_MKEFICAPSULE=y diff --git a/tools/Kconfig b/tools/Kconfig index 91ce8ae3e516..117c921da3fe 100644 --- a/tools/Kconfig +++ b/tools/Kconfig @@ -90,4 +90,12 @@ config TOOLS_SHA512 help Enable SHA512 support in the tools builds +config TOOLS_MKEFICAPSULE + bool "Build efimkcapsule command" + default y if EFI_CAPSULE_ON_DISK + help + This command allows users to create a UEFI capsule file and, + optionally sign that file. If you want to enable UEFI capsule + update feature on your target, you certainly need this. + endmenu diff --git a/tools/Makefile b/tools/Makefile index 1763f44cac43..766c0674f4a0 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -238,8 +238,7 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include -mkeficapsule-objs := mkeficapsule.o $(LIBFDT_OBJS) -hostprogs-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += mkeficapsule +hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule # We build some files with extra pedantic flags to try to minimize things # that won't build on some weird host compiler -- though there are lots of From patchwork Wed Feb 9 10:10:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590302 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Fasdh4zw; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JtwfZ5gtsz9sFv for ; Wed, 9 Feb 2022 21:12:22 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 112B283E50; Wed, 9 Feb 2022 11:12:01 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Fasdh4zw"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 55C3783DA1; Wed, 9 Feb 2022 11:11:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8DB6A83DF0 for ; Wed, 9 Feb 2022 11:11:34 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x42b.google.com with SMTP id i21so1924841pfd.13 for ; Wed, 09 Feb 2022 02:11:34 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=DZKEY6Eh+BOxkIm5I/qvZfoOPDEkJNQ016tlL/v2wVs=; b=Fasdh4zwjKq+pkAqwHHTc/9xrbPJjYMzk+hEJjWzqEErhoQWk8KQ8iWGBxkvtsxumM h4a417E3XsIo0eETG3pc45vMNXfXXPuxk+TZGEo6idE+PrS1mZh1bSv5bI8nhJfE1OWi ZXKNZJl536yIQXuPj9DUbUMi4b1+8p1toi7AmC361MwlcwqvCooFwz4lXsyO2piUfxax z/4YEjFTp6TnYESR8oQAiT3q3wWoybcq/gOWwioj5qeW4JchAsQuAhbcOgGj9TXVbFAe zDpHXP6f2K9MLO2QWb75y/DKgg2HhMfUF3R8BXL8O6TdUv3s8/sMzIZN3R15AUA+8lk7 uA4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DZKEY6Eh+BOxkIm5I/qvZfoOPDEkJNQ016tlL/v2wVs=; b=N02yPrbwnJnPW+ysSTs4iCF08EZDvJHdX55Rq21kEO+iPS4Vub60vW13mT3gvjy335 19vuSF7vlkO+T1Nyw1BJiGk6CV5raVYcG5hXle+R/d4BBfdvantk+Om51ACMJ839kOb2 ud+yNeDjno8A1tE+GnD0OWr0EwyQq8VwHukcPADuFbboSw5ohPOCRZIf3RLX62yV+d09 SQTNmu2DfAS7BZFrvroBO/HmeP+XV7JKSI5jMu9VPswNOp+E5eiWuaPYsRFQN+/TdlvV l5NiGRrXu5Vuux/VuQBWXW58HamSpUXzIQ0uIzzeXFj4xU8FBc++dK4V5jxe7jEZWhKs 3Lqg== X-Gm-Message-State: AOAM531zTAqeLOvDu+aA+K/MuBg/XtOe/v7Pij1CcQKJAkgaBvmNokKc TS6/+da8/vt0OUv8Uu73gFVTug== X-Google-Smtp-Source: ABdhPJyCS8cSjinhwOY0UNs+G1bjYoubuUuXundOli/Hpt7Kccd7pifUyUyVGby+FvaXw9YUIbdzDw== X-Received: by 2002:aa7:9ad0:: with SMTP id x16mr1451576pfp.55.1644401492682; Wed, 09 Feb 2022 02:11:32 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:32 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 2/9] tools: mkeficapsule: add firmware image signing Date: Wed, 9 Feb 2022 19:10:35 +0900 Message-Id: <20220209101042.78036-3-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean With this enhancement, mkeficapsule will be able to sign a capsule file when it is created. A signature added will be used later in the verification at FMP's SetImage() call. To do that, we need specify additional command parameters: -monotonic-cout : monotonic count -private-key : private key file -certificate : certificate file Only when all of those parameters are given, a signature will be added to a capsule file. Users are expected to maintain and increment the monotonic count at every time of the update for each firmware image. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass Acked-by: Ilias Apalodimas --- .azure-pipelines.yml | 2 +- tools/Makefile | 1 + tools/eficapsule.h | 115 +++++++++++++ tools/mkeficapsule.c | 380 +++++++++++++++++++++++++++++++++++++++---- 4 files changed, 463 insertions(+), 35 deletions(-) create mode 100644 tools/eficapsule.h diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index f2aa332be5cc..aecc9cb88441 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -25,7 +25,7 @@ stages: %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Syyuu" displayName: 'Update MSYS2' - script: | - %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm --needed -Sy make gcc bison flex diffutils openssl-devel" + %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm --needed -Sy make gcc bison flex diffutils openssl-devel libgnutls-devel" displayName: 'Install Toolchain' - script: | echo make tools-only_defconfig tools-only NO_SDL=1 > build-tools.sh diff --git a/tools/Makefile b/tools/Makefile index 766c0674f4a0..8da07d60a755 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -238,6 +238,7 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include +HOSTLDLIBS_mkeficapsule += -lgnutls hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule # We build some files with extra pedantic flags to try to minimize things diff --git a/tools/eficapsule.h b/tools/eficapsule.h new file mode 100644 index 000000000000..8c1560bb0671 --- /dev/null +++ b/tools/eficapsule.h @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2021 Linaro Limited + * Author: AKASHI Takahiro + * + * derived from efi.h and efi_api.h to make the file POSIX-compliant + */ + +#ifndef _EFI_CAPSULE_H +#define _EFI_CAPSULE_H + +#include +#include /* WIN_CERTIFICATE */ + +/* + * Gcc's predefined attributes are not recognized by clang. + */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif + +typedef struct { + uint8_t b[16]; +} efi_guid_t __aligned(8); + +#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ + {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \ + ((a) >> 24) & 0xff, \ + (b) & 0xff, ((b) >> 8) & 0xff, \ + (c) & 0xff, ((c) >> 8) & 0xff, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } } + +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \ + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ + 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) + +#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \ + EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \ + 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47) + +#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID \ + EFI_GUID(0xe2bb9c06, 0x70e9, 0x4b14, 0x97, 0xa3, \ + 0x5a, 0x79, 0x13, 0x17, 0x6e, 0x3f) + +#define EFI_CERT_TYPE_PKCS7_GUID \ + EFI_GUID(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, \ + 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7) + +/* flags */ +#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000 + +struct efi_capsule_header { + efi_guid_t capsule_guid; + uint32_t header_size; + uint32_t flags; + uint32_t capsule_image_size; +} __packed; + +struct efi_firmware_management_capsule_header { + uint32_t version; + uint16_t embedded_driver_count; + uint16_t payload_item_count; + uint32_t item_offset_list[]; +} __packed; + +/* image_capsule_support */ +#define CAPSULE_SUPPORT_AUTHENTICATION 0x0000000000000001 + +struct efi_firmware_management_capsule_image_header { + uint32_t version; + efi_guid_t update_image_type_id; + uint8_t update_image_index; + uint8_t reserved[3]; + uint32_t update_image_size; + uint32_t update_vendor_code_size; + uint64_t update_hardware_instance; + uint64_t image_capsule_support; +} __packed; + +/** + * win_certificate_uefi_guid - A certificate that encapsulates + * a GUID-specific signature + * + * @hdr: Windows certificate header + * @cert_type: Certificate type + * @cert_data: Certificate data + */ +struct win_certificate_uefi_guid { + WIN_CERTIFICATE hdr; + efi_guid_t cert_type; + uint8_t cert_data[]; +} __packed; + +/** + * efi_firmware_image_authentication - Capsule authentication method + * descriptor + * + * This structure describes an authentication information for + * a capsule with IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED set + * and should be included as part of the capsule. + * Only EFI_CERT_TYPE_PKCS7_GUID is accepted. + * + * @monotonic_count: Count to prevent replay + * @auth_info: Authentication info + */ +struct efi_firmware_image_authentication { + uint64_t monotonic_count; + struct win_certificate_uefi_guid auth_info; +} __packed; + +#endif /* _EFI_CAPSULE_H */ diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index 243fd6e48370..b996c66ad26a 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -16,21 +16,13 @@ #include #include -typedef __u8 u8; -typedef __u16 u16; -typedef __u32 u32; -typedef __u64 u64; -typedef __s16 s16; -typedef __s32 s32; +#include -#define aligned_u64 __aligned_u64 +#include +#include +#include -#ifndef __packed -#define __packed __attribute__((packed)) -#endif - -#include -#include +#include "eficapsule.h" static const char *tool_name = "mkeficapsule"; @@ -39,12 +31,19 @@ efi_guid_t efi_guid_image_type_uboot_fit = EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID; efi_guid_t efi_guid_image_type_uboot_raw = EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; +efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; + +static const char *opts_short = "f:r:i:I:v:p:c:m:dh"; static struct option options[] = { {"fit", required_argument, NULL, 'f'}, {"raw", required_argument, NULL, 'r'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, + {"private-key", required_argument, NULL, 'p'}, + {"certificate", required_argument, NULL, 'c'}, + {"monotonic-count", required_argument, NULL, 'm'}, + {"dump-sig", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0}, }; @@ -58,10 +57,40 @@ static void print_usage(void) "\t-r, --raw new raw image file\n" "\t-i, --index update image index\n" "\t-I, --instance update hardware instance\n" + "\t-p, --private-key private key file\n" + "\t-c, --certificate signer's certificate file\n" + "\t-m, --monotonic-count monotonic count\n" + "\t-d, --dump_sig dump signature (*.p7)\n" "\t-h, --help print a help message\n", tool_name); } +/** + * auth_context - authentication context + * @key_file: Path to a private key file + * @cert_file: Path to a certificate file + * @image_data: Pointer to firmware data + * @image_size: Size of firmware data + * @auth: Authentication header + * @sig_data: Signature data + * @sig_size: Size of signature data + * + * Data structure used in create_auth_data(). @key_file through + * @image_size are input parameters. @auth, @sig_data and @sig_size + * are filled in by create_auth_data(). + */ +struct auth_context { + char *key_file; + char *cert_file; + uint8_t *image_data; + size_t image_size; + struct efi_firmware_image_authentication auth; + uint8_t *sig_data; + size_t sig_size; +}; + +static int dump_sig; + /** * read_bin_file - read a firmware binary file * @bin: Path to a firmware binary file @@ -75,7 +104,7 @@ static void print_usage(void) * * 0 - on success * * -1 - on failure */ -static int read_bin_file(char *bin, void **data, off_t *bin_size) +static int read_bin_file(char *bin, uint8_t **data, off_t *bin_size) { FILE *g; struct stat bin_stat; @@ -147,6 +176,205 @@ static int write_capsule_file(FILE *f, void *data, size_t size, const char *msg) return 0; } +/** + * create_auth_data - compose authentication data in capsule + * @auth_context: Pointer to authentication context + * + * Fill up an authentication header (.auth) and signature data (.sig_data) + * in @auth_context, using library functions from openssl. + * All the parameters in @auth_context must be filled in by a caller. + * + * Return: + * * 0 - on success + * * -1 - on failure + */ +static int create_auth_data(struct auth_context *ctx) +{ + gnutls_datum_t cert; + gnutls_datum_t key; + off_t file_size; + gnutls_privkey_t pkey; + gnutls_x509_crt_t x509; + gnutls_pkcs7_t pkcs7; + gnutls_datum_t data; + gnutls_datum_t signature; + int ret; + + ret = read_bin_file(ctx->cert_file, &cert.data, &file_size); + if (ret < 0) + return -1; + if (file_size > UINT_MAX) + return -1; + cert.size = file_size; + + ret = read_bin_file(ctx->key_file, &key.data, &file_size); + if (ret < 0) + return -1; + if (ret < 0) + return -1; + if (file_size > UINT_MAX) + return -1; + key.size = file_size; + + /* + * For debugging, + * gnutls_global_set_time_function(mytime); + * gnutls_global_set_log_function(tls_log_func); + * gnutls_global_set_log_level(6); + */ + + ret = gnutls_privkey_init(&pkey); + if (ret < 0) { + fprintf(stderr, "error in gnutls_privkey_init(): %s\n", + gnutls_strerror(ret)); + return -1; + } + + ret = gnutls_x509_crt_init(&x509); + if (ret < 0) { + fprintf(stderr, "error in gnutls_x509_crt_init(): %s\n", + gnutls_strerror(ret)); + return -1; + } + + /* load a private key */ + ret = gnutls_privkey_import_x509_raw(pkey, &key, GNUTLS_X509_FMT_PEM, + 0, 0); + if (ret < 0) { + fprintf(stderr, + "error in gnutls_privkey_import_x509_raw(): %s\n", + gnutls_strerror(ret)); + return -1; + } + + /* load x509 certificate */ + ret = gnutls_x509_crt_import(x509, &cert, GNUTLS_X509_FMT_PEM); + if (ret < 0) { + fprintf(stderr, "error in gnutls_x509_crt_import(): %s\n", + gnutls_strerror(ret)); + return -1; + } + + /* generate a PKCS #7 structure */ + ret = gnutls_pkcs7_init(&pkcs7); + if (ret < 0) { + fprintf(stderr, "error in gnutls_pkcs7_init(): %s\n", + gnutls_strerror(ret)); + return -1; + } + + /* sign */ + /* + * Data should have + * * firmware image + * * monotonic count + * in this order! + * See EDK2's FmpAuthenticatedHandlerRsa2048Sha256() + */ + data.size = ctx->image_size + sizeof(ctx->auth.monotonic_count); + data.data = malloc(data.size); + if (!data.data) { + fprintf(stderr, "allocating memory (0x%x) failed\n", data.size); + return -1; + } + memcpy(data.data, ctx->image_data, ctx->image_size); + memcpy(data.data + ctx->image_size, &ctx->auth.monotonic_count, + sizeof(ctx->auth.monotonic_count)); + + ret = gnutls_pkcs7_sign(pkcs7, x509, pkey, &data, NULL, NULL, + GNUTLS_DIG_SHA256, + /* GNUTLS_PKCS7_EMBED_DATA? */ + GNUTLS_PKCS7_INCLUDE_CERT | + GNUTLS_PKCS7_INCLUDE_TIME); + if (ret < 0) { + fprintf(stderr, "error in gnutls_pkcs7)sign(): %s\n", + gnutls_strerror(ret)); + return -1; + } + + /* export */ + ret = gnutls_pkcs7_export2(pkcs7, GNUTLS_X509_FMT_DER, &signature); + if (ret < 0) { + fprintf(stderr, "error in gnutls_pkcs7_export2: %s\n", + gnutls_strerror(ret)); + return -1; + } + ctx->sig_data = signature.data; + ctx->sig_size = signature.size; + + /* fill auth_info */ + ctx->auth.auth_info.hdr.dwLength = sizeof(ctx->auth.auth_info) + + ctx->sig_size; + ctx->auth.auth_info.hdr.wRevision = WIN_CERT_REVISION_2_0; + ctx->auth.auth_info.hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID; + memcpy(&ctx->auth.auth_info.cert_type, &efi_guid_cert_type_pkcs7, + sizeof(efi_guid_cert_type_pkcs7)); + + /* + * For better clean-ups, + * gnutls_pkcs7_deinit(pkcs7); + * gnutls_privkey_deinit(pkey); + * gnutls_x509_crt_deinit(x509); + * free(cert.data); + * free(key.data); + * if error + * gnutls_free(signature.data); + */ + + return 0; +} + +/** + * dump_signature - dump out a signature + * @path: Path to a capsule file + * @signature: Signature data + * @sig_size: Size of signature data + * + * Signature data pointed to by @signature will be saved into + * a file whose file name is @path with ".p7" suffix. + * + * Return: + * * 0 - on success + * * -1 - on failure + */ +static int dump_signature(const char *path, uint8_t *signature, size_t sig_size) +{ + char *sig_path; + FILE *f; + size_t size; + int ret = -1; + + sig_path = malloc(strlen(path) + 3 + 1); + if (!sig_path) + return ret; + + sprintf(sig_path, "%s.p7", path); + f = fopen(sig_path, "w"); + if (!f) + goto err; + + size = fwrite(signature, 1, sig_size, f); + if (size == sig_size) + ret = 0; + + fclose(f); +err: + free(sig_path); + return ret; +} + +/** + * free_sig_data - free out signature data + * @ctx: Pointer to authentication context + * + * Free signature data allocated in create_auth_data(). + */ +static void free_sig_data(struct auth_context *ctx) +{ + if (ctx->sig_size) + gnutls_free(ctx->sig_data); +} + /** * create_fwbin - create an uefi capsule file * @path: Path to a created capsule file @@ -168,23 +396,25 @@ static int write_capsule_file(FILE *f, void *data, size_t size, const char *msg) * * -1 - on failure */ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, - unsigned long index, unsigned long instance) + unsigned long index, unsigned long instance, + uint64_t mcount, char *privkey_file, char *cert_file) { struct efi_capsule_header header; struct efi_firmware_management_capsule_header capsule; struct efi_firmware_management_capsule_image_header image; + struct auth_context auth_context; FILE *f; - void *data; + uint8_t *data; off_t bin_size; - u64 offset; + uint64_t offset; int ret; #ifdef DEBUG - printf("For output: %s\n", path); - printf("\tbin: %s\n\ttype: %pUl\n", bin, guid); - printf("\tindex: %ld\n\tinstance: %ld\n", index, instance); + fprintf(stderr, "For output: %s\n", path); + fprintf(stderr, "\tbin: %s\n\ttype: %pUl\n", bin, guid); + fprintf(stderr, "\tindex: %lu\n\tinstance: %lu\n", index, instance); #endif - + auth_context.sig_size = 0; f = NULL; data = NULL; ret = -1; @@ -195,6 +425,27 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, if (read_bin_file(bin, &data, &bin_size)) goto err; + /* first, calculate signature to determine its size */ + if (privkey_file && cert_file) { + auth_context.key_file = privkey_file; + auth_context.cert_file = cert_file; + auth_context.auth.monotonic_count = mcount; + auth_context.image_data = data; + auth_context.image_size = bin_size; + + if (create_auth_data(&auth_context)) { + fprintf(stderr, "Signing firmware image failed\n"); + goto err; + } + + if (dump_sig && + dump_signature(path, auth_context.sig_data, + auth_context.sig_size)) { + fprintf(stderr, "Creating signature file failed\n"); + goto err; + } + } + /* * write a capsule file */ @@ -212,9 +463,12 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, /* TODO: The current implementation ignores flags */ header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; header.capsule_image_size = sizeof(header) - + sizeof(capsule) + sizeof(u64) + + sizeof(capsule) + sizeof(uint64_t) + sizeof(image) + bin_size; + if (auth_context.sig_size) + header.capsule_image_size += sizeof(auth_context.auth) + + auth_context.sig_size; if (write_capsule_file(f, &header, sizeof(header), "Capsule header")) goto err; @@ -230,7 +484,7 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, "Firmware capsule header")) goto err; - offset = sizeof(capsule) + sizeof(u64); + offset = sizeof(capsule) + sizeof(uint64_t); if (write_capsule_file(f, &offset, sizeof(offset), "Offset to capsule image")) goto err; @@ -245,13 +499,32 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, image.reserved[1] = 0; image.reserved[2] = 0; image.update_image_size = bin_size; + if (auth_context.sig_size) + image.update_image_size += sizeof(auth_context.auth) + + auth_context.sig_size; image.update_vendor_code_size = 0; /* none */ image.update_hardware_instance = instance; image.image_capsule_support = 0; + if (auth_context.sig_size) + image.image_capsule_support |= CAPSULE_SUPPORT_AUTHENTICATION; if (write_capsule_file(f, &image, sizeof(image), "Firmware capsule image header")) goto err; + /* + * signature + */ + if (auth_context.sig_size) { + if (write_capsule_file(f, &auth_context.auth, + sizeof(auth_context.auth), + "Authentication header")) + goto err; + + if (write_capsule_file(f, auth_context.sig_data, + auth_context.sig_size, "Signature")) + goto err; + } + /* * firmware binary */ @@ -262,28 +535,43 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, err: if (f) fclose(f); + free_sig_data(&auth_context); free(data); return ret; } -/* - * Usage: - * $ mkeficapsule -f +/** + * main - main entry function of mkeficapsule + * @argc: Number of arguments + * @argv: Array of pointers to arguments + * + * Create an uefi capsule file, optionally signing it. + * Parse all the arguments and pass them on to create_fwbin(). + * + * Return: + * * 0 - on success + * * -1 - on failure */ int main(int argc, char **argv) { char *file; efi_guid_t *guid; unsigned long index, instance; + uint64_t mcount; + char *privkey_file, *cert_file; int c, idx; file = NULL; guid = NULL; index = 0; instance = 0; + mcount = 0; + privkey_file = NULL; + cert_file = NULL; + dump_sig = 0; for (;;) { - c = getopt_long(argc, argv, "f:r:i:I:v:h", options, &idx); + c = getopt_long(argc, argv, opts_short, options, &idx); if (c == -1) break; @@ -291,7 +579,7 @@ int main(int argc, char **argv) case 'f': if (file) { fprintf(stderr, "Image already specified\n"); - return -1; + exit(EXIT_FAILURE); } file = optarg; guid = &efi_guid_image_type_uboot_fit; @@ -299,7 +587,7 @@ int main(int argc, char **argv) case 'r': if (file) { fprintf(stderr, "Image already specified\n"); - return -1; + exit(EXIT_FAILURE); } file = optarg; guid = &efi_guid_image_type_uboot_raw; @@ -310,14 +598,38 @@ int main(int argc, char **argv) case 'I': instance = strtoul(optarg, NULL, 0); break; + case 'p': + if (privkey_file) { + fprintf(stderr, + "Private Key already specified\n"); + exit(EXIT_FAILURE); + } + privkey_file = optarg; + break; + case 'c': + if (cert_file) { + fprintf(stderr, + "Certificate file already specified\n"); + exit(EXIT_FAILURE); + } + cert_file = optarg; + break; + case 'm': + mcount = strtoul(optarg, NULL, 0); + break; + case 'd': + dump_sig = 1; + break; case 'h': print_usage(); - return 0; + exit(EXIT_SUCCESS); } } - /* need an output file */ - if (argc != optind + 1) { + /* check necessary parameters */ + if ((argc != optind + 1) || !file || + ((privkey_file && !cert_file) || + (!privkey_file && cert_file))) { print_usage(); exit(EXIT_FAILURE); } @@ -328,8 +640,8 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); } - if (create_fwbin(argv[optind], file, guid, index, instance) - < 0) { + if (create_fwbin(argv[optind], file, guid, index, instance, + mcount, privkey_file, cert_file) < 0) { fprintf(stderr, "Creating firmware capsule failed\n"); exit(EXIT_FAILURE); } From patchwork Wed Feb 9 10:10:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590300 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=RavSY6Fr; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jtwf550CTz9sFv for ; Wed, 9 Feb 2022 21:11:57 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8634C83E46; Wed, 9 Feb 2022 11:11:48 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="RavSY6Fr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3B4FA83E1D; Wed, 9 Feb 2022 11:11:43 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4CE8483E38 for ; Wed, 9 Feb 2022 11:11:37 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x62f.google.com with SMTP id y7so1802097plp.2 for ; Wed, 09 Feb 2022 02:11:37 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=ol9ddRwnpZf0xiKIvRWpCX3zHIM2hmcgqKnrCjt/dOk=; b=RavSY6FrSPe5ILkYRt0relV+N3UGBwjYAVfauMyCtho6wEGAx+UNZUlPiGQx5wO7/N 8bd8JNsoiSMaVtgD2KhDqya5jgWXgtW1aggy7wJhJCx4h5rhRJDTMsNpUk6nWZIyrQNA gtWnruDDUSreNE6S0h3NhYz6yDryEDVBKqBdEsCHLgamG/ysVWc80nKmW/y9g44QEAIs GL+6w5p9iqsP/SVmFGg9YRHLLqtigCNrfgMDYAnsJEh6nSRtHGyG8twiLbf1ACTLm3Ng 0OivsSgXgGk+64pOafVH7M/d773AJtbePgzV9eERToCwOKXVFPmAxi0obsLFaqgk9C1L U2Nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ol9ddRwnpZf0xiKIvRWpCX3zHIM2hmcgqKnrCjt/dOk=; b=WHo6UOTVBF0RLBvr4F+8oaUrI9p5jL0vNyUBJa6QXAPoB9rS/ee45mjg5flmnK9EU/ 6CkCVs7YdK5buY42UQrN9+mpmT0jxBpg49yd0+jVJTAwxwQxXw6uJGBN0s674uRvBs6n H32cCKcU4MsYcv+N3E7w2O7ZV/REoPRsoOKzLA8RArbew9Aul+R0Byc/DcsYFmLlmR/7 EmF3hvBKbakz+PygpOHPs4JbD52pSU4PnO+Xl7Qo3lZBK+T6k1uCiP8PDnl3OvGbbDAZ iNnw2IJDoTeSRCKruX6Gf5Fr2Lefu/mS1g7fjrB8SQr5JpFIK8uWDtoMv3n2BXgp5E8i w+KQ== X-Gm-Message-State: AOAM531+kD/m+EgrIjrME6/EIdd7J9rPd591pV95Q3VUFVbGeKLDReW1 I2y0vNcJ3CQbmTPNwTZhdRadyg== X-Google-Smtp-Source: ABdhPJyu4Vt1zJ3/8tDHMiLddHNu5gC8IRfmgPP2vsC2QorC8T4eaWFbLHIHO1TbJsoSPua9SlvNug== X-Received: by 2002:a17:90a:2fc5:: with SMTP id n5mr1695239pjm.69.1644401495509; Wed, 09 Feb 2022 02:11:35 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:35 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 3/9] tools: mkeficapsule: add man page Date: Wed, 9 Feb 2022 19:10:36 +0900 Message-Id: <20220209101042.78036-4-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Add a man page for mkeficapsule command. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass Acked-by: Ilias Apalodimas --- MAINTAINERS | 1 + doc/mkeficapsule.1 | 99 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 doc/mkeficapsule.1 diff --git a/MAINTAINERS b/MAINTAINERS index dcdd99e368d1..2a8f70d70833 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -749,6 +749,7 @@ S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-efi.git F: doc/api/efi.rst F: doc/develop/uefi/* +F: doc/mkeficapsule.1 F: doc/usage/bootefi.rst F: drivers/rtc/emul_rtc.c F: include/capitalization.h diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 new file mode 100644 index 000000000000..680362f5c4e9 --- /dev/null +++ b/doc/mkeficapsule.1 @@ -0,0 +1,99 @@ +.\" SPDX-License-Identifier: GPL-2.0+ +.\" Copyright (c) 2021, Linaro Limited +.\" written by AKASHI Takahiro +.TH MAEFICAPSULE 1 "May 2021" + +.SH NAME +mkeficapsule \- Generate EFI capsule file for U-Boot + +.SH SYNOPSIS +.B mkeficapsule +.RI [ options "] " capsule-file + +.SH "DESCRIPTION" +.B mkeficapsule +command is used to create an EFI capsule file for use with the U-Boot +EFI capsule update. +A capsule file may contain various type of firmware blobs which +are to be applied to the system and must be placed in the specific +directory on the UEFI system partition. +An update will be automatically executed at next reboot. + +Optionally, a capsule file can be signed with a given private key. +In this case, the update will be authenticated by verifying the signature +before applying. + +.B mkeficapsule +supports two different format of image files: +.TP +.I raw image +format is a single binary blob of any type of firmware. + +.TP +.I FIT (Flattened Image Tree) image +format is the same as used in the new uImage format and allows for +multiple binary blobs in a single capsule file. +This type of image file can be generated by +.BR mkimage . + +.SH "OPTIONS" +One of +.BR --fit " or " --raw +option must be specified. + +.TP +.BI "-f\fR,\fB --fit " fit-image-file +Specify a FIT image file + +.TP +.BI "-r\fR,\fB --raw " raw-image-file +Specify a raw image file + +.TP +.BI "-i\fR,\fB --index " index +Specify an image index + +.TP +.BI "-I\fR,\fB --instance " instance +Specify a hardware instance + +.TP +.BR -h ", " --help +Print a help message + +.PP +With signing, +.BR --private-key ", " --certificate " and " --monotonic-count +are all mandatory. + +.TP +.BI "-p\fR,\fB --private-key " private-key-file +Specify signer's private key file in PEM + +.TP +.BI "-c\fR,\fB --certificate " certificate-file +Specify signer's certificate file in EFI certificate list format + +.TP +.BI "-m\fR,\fB --monotonic-count " count +Specify a monotonic count which is set to be monotonically incremented +at every firmware update. + +.TP +.B "-d\fR,\fB --dump_sig" +Dump signature data into *.p7 file + +.PP +.SH FILES +.TP +.I /EFI/UpdateCapsule +The directory in which all capsule files be placed + +.SH SEE ALSO +.BR mkimage (1) + +.SH AUTHORS +Written by AKASHI Takahiro + +.SH HOMEPAGE +http://www.denx.de/wiki/U-Boot/WebHome From patchwork Wed Feb 9 10:10:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590301 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=gGLAXV9+; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JtwfM5Hgzz9sFv for ; Wed, 9 Feb 2022 21:12:11 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 246D983E29; Wed, 9 Feb 2022 11:11:57 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="gGLAXV9+"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F3F7083E43; Wed, 9 Feb 2022 11:11:50 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 61AED83DA1 for ; Wed, 9 Feb 2022 11:11:40 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1030.google.com with SMTP id h14-20020a17090a130e00b001b88991a305so4613068pja.3 for ; Wed, 09 Feb 2022 02:11:40 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=Po3UkMMvYld0lfL3rtFZlnEun88jjbYUWYnbEiYi2SQ=; b=gGLAXV9+1sz22hzKHxQUqNMzVRghqnWmhRRtXty7h7P32nMZVqCh67EOfwOtQSMOod e1NKgO7Wnw4DZbCAUnzy6rzgp1lKIOTV7Bwufj13RVXCkHbbGfpThFLmG7LD0fF3POiq uQqlsg9MPfsc1qVefxgL4DmF4l2XbQSHq2YgmccZ2dudLaaU6qeowlMjk8J4vaTh9qKJ zMLFLMKP5exqDfjuhR76V8yROeq2XOBPar//ez4U1SPaVx2rzuIqskU7CqYKg7ni2S+6 ReBmj57NION7IagmtWsk0uWyTcv9Kc5OpEjFLi8CFmHrtbHbsvq1ZdtsY+2h+4zXyoVT mCUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Po3UkMMvYld0lfL3rtFZlnEun88jjbYUWYnbEiYi2SQ=; b=zlf3M2QJrztghxkc4XWxOoCejN3RpFvP/ToSJ1NVDTyIXI3MvSCUgKdzy1iJwvsteA RXY8HFT1HRd3ohbUSFfkNvXEqsTLjkBYL/3YMAoXIgxxQiqaWZtx3GHjHUhemuts3BiO PLRwgrcycdvNAUPeeT45SwcgW5Q+Fb5aCsLl3ZntJouNWeJTKjYN2yLhzuQ+qa6wEsE+ jpL66mcT3saMLYrejYuBFBbphgjYmZupShkxfqAJRj2xhV8jQnXrk8EFjYwvorFj+gbt RSj+JFph/D9fiRaNIV1jAv3GepwTbbXXuGYuTQeMsaDXlJEPPuonA7LaOCN9+/AftWMv Ao0A== X-Gm-Message-State: AOAM531WBVUj+kaj23xt8cxaPJ2OHAJ+1bCWPBLZGF6IyetzNK5T9YKP aX9DQDa+xYtZHfMCAQV0lppIqQ== X-Google-Smtp-Source: ABdhPJweLwpH+LK2WC+hqgLh2yOEQnDfys9j/Rb4mPq/eEV9MtvV9gf8qkxMr4as02ywmDWN7/jipA== X-Received: by 2002:a17:903:22d1:: with SMTP id y17mr1363563plg.107.1644401498344; Wed, 09 Feb 2022 02:11:38 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:38 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 4/9] doc: update UEFI document for usage of mkeficapsule Date: Wed, 9 Feb 2022 19:10:37 +0900 Message-Id: <20220209101042.78036-5-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Now we can use mkeficapsule command instead of EDK-II's script to create a signed capsule file. So update the instruction for capsule authentication. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass Acked-by: Ilias Apalodimas --- doc/develop/uefi/uefi.rst | 151 +++++++++++++++++++------------------- 1 file changed, 76 insertions(+), 75 deletions(-) diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index 43fb10f7978e..52a38c6b231c 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -284,37 +284,56 @@ Support has been added for the UEFI capsule update feature which enables updating the U-Boot image using the UEFI firmware management protocol (FMP). The capsules are not passed to the firmware through the UpdateCapsule runtime service. Instead, capsule-on-disk -functionality is used for fetching the capsule from the EFI System -Partition (ESP) by placing the capsule file under the -\EFI\UpdateCapsule directory. - -The directory \EFI\UpdateCapsule is checked for capsules only within the -EFI system partition on the device specified in the active boot option -determined by reference to BootNext variable or BootOrder variable processing. -The active Boot Variable is the variable with highest priority BootNext or -within BootOrder that refers to a device found to be present. Boot variables -in BootOrder but referring to devices not present are ignored when determining -active boot variable. -Before starting a capsule update make sure your capsules are installed in the -correct ESP partition or set BootNext. +functionality is used for fetching capsules from the EFI System +Partition (ESP) by placing capsule files under the directory:: + + \EFI\UpdateCapsule + +The directory is checked for capsules only within the +EFI system partition on the device specified in the active boot option, +which is determined by BootXXXX variable in BootNext, or if not, the highest +priority one within BootOrder. Any BootXXXX variables referring to devices +not present are ignored when determining the active boot option. + +Please note that capsules will be applied in the alphabetic order of +capsule file names. + +Creating a capsule file +*********************** + +A capsule file can be created by using tools/mkeficapsule. +To build this tool, enable:: + + CONFIG_TOOLS_MKEFICAPSULE=y + CONFIG_TOOLS_LIBCRYPTO=y + +Run the following command + +.. code-block:: console + + $ mkeficapsule \ + --index 1 --instance 0 \ + [--fit | --raw ] \ + Performing the update ********************* -Since U-boot doesn't currently support SetVariable at runtime there's a Kconfig -option (CONFIG_EFI_IGNORE_OSINDICATIONS) to disable the OsIndications variable -check. If that option is enabled just copy your capsule to \EFI\UpdateCapsule. +Put capsule files under the directory mentioned above. +Then, following the UEFI specification, you'll need to set +the EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED +bit in OsIndications variable with -If that option is disabled, you'll need to set the OsIndications variable with:: +.. code-block:: console => setenv -e -nv -bs -rt -v OsIndications =0x04 -Finally, the capsule update can be initiated either by rebooting the board, -which is the preferred method, or by issuing the following command:: - - => efidebug capsule disk-update +Since U-boot doesn't currently support SetVariable at runtime, its value +won't be taken over across the reboot. If this is the case, you can skip +this feature check with the Kconfig option (CONFIG_EFI_IGNORE_OSINDICATIONS) +set. -**The efidebug command is should only be used during debugging/development.** +Finally, the capsule update can be initiated by rebooting the board. Enabling Capsule Authentication ******************************* @@ -324,82 +343,64 @@ be updated by verifying the capsule signature. The capsule signature is computed and prepended to the capsule payload at the time of capsule generation. This signature is then verified by using the public key stored as part of the X509 certificate. This certificate is -in the form of an efi signature list (esl) file, which is embedded as -part of U-Boot. +in the form of an efi signature list (esl) file, which is embedded in +a device tree. The capsule authentication feature can be enabled through the following config, in addition to the configs listed above for capsule update:: CONFIG_EFI_CAPSULE_AUTHENTICATE=y - CONFIG_EFI_CAPSULE_KEY_PATH= The public and private keys used for the signing process are generated -and used by the steps highlighted below:: +and used by the steps highlighted below. - 1. Install utility commands on your host - * OPENSSL +1. Install utility commands on your host + * openssl * efitools - 2. Create signing keys and certificate files on your host +2. Create signing keys and certificate files on your host - $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ - -keyout CRT.key -out CRT.crt -nodes -days 365 - $ cert-to-efi-sig-list CRT.crt CRT.esl +.. code-block:: console - $ openssl x509 -in CRT.crt -out CRT.cer -outform DER - $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem + $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ + -keyout CRT.key -out CRT.crt -nodes -days 365 + $ cert-to-efi-sig-list CRT.crt CRT.esl - $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt - $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem +3. Run the following command to create and sign the capsule file -The capsule file can be generated by using the GenerateCapsule.py -script in EDKII:: +.. code-block:: console - $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ - --monotonic-count --fw-version \ - --lsv --guid \ - e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ - --update-image-index --signer-private-cert \ - /path/to/CRT.pem --trusted-public-cert \ - /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ - + $ mkeficapsule --monotonic-count 1 \ + --private-key CRT.key \ + --certificate CRT.crt \ + --index 1 --instance 0 \ + [--fit | --raw ] \ + -Place the capsule generated in the above step on the EFI System -Partition under the EFI/UpdateCapsule directory +4. Insert the signature list into a device tree in the following format:: -Testing on QEMU -*************** + { + signature { + capsule-key = [ ]; + } + ... + } -Currently, support has been added on the QEMU ARM64 virt platform for -updating the U-Boot binary as a raw image when the platform is booted -in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this -configuration, the QEMU platform needs to be booted with -'secure=off'. The U-Boot binary placed on the first bank of the NOR -flash at offset 0x0. The U-Boot environment is placed on the second -NOR flash bank at offset 0x4000000. +You can do step-4 manually with -The capsule update feature is enabled with the following configuration -settings:: +.. code-block:: console - CONFIG_MTD=y - CONFIG_FLASH_CFI_MTD=y - CONFIG_CMD_MTDPARTS=y - CONFIG_CMD_DFU=y - CONFIG_DFU_MTD=y - CONFIG_PCI_INIT_R=y - CONFIG_EFI_CAPSULE_ON_DISK=y - CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y - CONFIG_EFI_CAPSULE_FIRMWARE=y - CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y + $ dtc -@ -I dts -O dtb -o signature.dtbo signature.dts + $ fdtoverlay -i orig.dtb -o new.dtb -v signature.dtbo -In addition, the following config needs to be disabled(QEMU ARM specific):: +where signature.dts looks like:: - CONFIG_TFABOOT - -The capsule file can be generated by using the tools/mkeficapsule:: - - $ mkeficapsule --raw --index 1 + &{/} { + signature { + capsule-key = /incbin/("CRT.esl"); + }; + }; Executing the boot manager ~~~~~~~~~~~~~~~~~~~~~~~~~~ From patchwork Wed Feb 9 10:10:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590303 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=TsKitc/J; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jtwfr14KDz9sFv for ; Wed, 9 Feb 2022 21:12:36 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BC82F83E49; Wed, 9 Feb 2022 11:12:09 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="TsKitc/J"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E274083DEE; Wed, 9 Feb 2022 11:11:54 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CF61683E2B for ; Wed, 9 Feb 2022 11:11:43 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pl1-x62c.google.com with SMTP id z17so1774023plb.9 for ; Wed, 09 Feb 2022 02:11:43 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=l5pyl4PszqgCXNE7g0e6sPzj586sukrANNeq6Nk+tdM=; b=TsKitc/JmSyxwhcIk8QtDKd4NFZG/etIFy72+XBpttHDkyDQClbiz9t1uRMAURm5ae bp1N4cMWo6/+Q7oPRM1ALawljgsfQaNoBw6shmrAgq24SRERhTB6Ec3f+7TUYlP+T8Pr Uwyv5yAyf5qXR1guR48lnqIHOssZTN26bokaFIVCEBPj69oR1vu5KtQdoFLQJ7kpEqoc F6NcZHdyNyPJ4DM9s0rwvJoZ89DL4OwKethTDomsp3jz3R2yRyxYYwwbSW9d27jbUn2Q X8VcSwnHuEKtPUPatQmmbJ0bgH9g+AjJ/vD3JXrvLlyQXiVFYJTHaloBrpXY/RY4Wddc M5og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l5pyl4PszqgCXNE7g0e6sPzj586sukrANNeq6Nk+tdM=; b=AU5rokY9grAygwozJR5n85zxiktlggvovgwy33DjKitbPQXHhIo9RhOc2V+teCjKik SZO2G5gMu1/reBToJyny++/ra/NcBWLlLbBKszdzrhLy1K0eZvJ4su9/O4NHPA69/Kbj 4XTpydHcR3fNcWZimVJ5N6TF4uezOiOSKP9IdhxrgyqfumysoO5+dFlXQhCLAOUhpSab tB8HSQAOyN0ekXD5048/YL2oz93zU5fls+qICkfSCDWv5zoMV/Q4gZyXT5dyPUCEAQDF CU6f2cW0gUP/2dQEuH2Jp6ZbmAh2/lEaXyldwKGeEMpvBwosvbJp2RpX7rjR5bhrPeCv WKkg== X-Gm-Message-State: AOAM5315yaWcSbfNGPuiTSGXwoklF9HmsHes4XPz74VlKoIyME/V57rC VfbVB7Vg4ScD3BSviwNGmaTKPg== X-Google-Smtp-Source: ABdhPJxErGGevnlgZvjboqQAM6aXfhB8h7h7fHMNjkrkInkcIFhtFygCAm4hygMgZO1Rs7ci4hNZnQ== X-Received: by 2002:a17:90b:1b52:: with SMTP id nv18mr2600194pjb.136.1644401501226; Wed, 09 Feb 2022 02:11:41 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:40 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 5/9] test/py: efi_capsule: add image authentication test Date: Wed, 9 Feb 2022 19:10:38 +0900 Message-Id: <20220209101042.78036-6-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Add a couple of test cases against capsule image authentication for capsule-on-disk, where only a signed capsule file with the verified signature will be applied to the system. Due to the difficulty of embedding a public key (esl file) in U-Boot binary during pytest setup time, all the keys/certificates are pre-created. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass Acked-by: Ilias Apalodimas --- .../py/tests/test_efi_capsule/capsule_defs.py | 5 + test/py/tests/test_efi_capsule/conftest.py | 52 +++- test/py/tests/test_efi_capsule/signature.dts | 10 + .../test_capsule_firmware_signed.py | 254 ++++++++++++++++++ 4 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 test/py/tests/test_efi_capsule/signature.dts create mode 100644 test/py/tests/test_efi_capsule/test_capsule_firmware_signed.py diff --git a/test/py/tests/test_efi_capsule/capsule_defs.py b/test/py/tests/test_efi_capsule/capsule_defs.py index 4fd6353c2040..59b40f11bd1d 100644 --- a/test/py/tests/test_efi_capsule/capsule_defs.py +++ b/test/py/tests/test_efi_capsule/capsule_defs.py @@ -3,3 +3,8 @@ # Directories CAPSULE_DATA_DIR = '/EFI/CapsuleTestData' CAPSULE_INSTALL_DIR = '/EFI/UpdateCapsule' + +# v1.5.1 or earlier of efitools has a bug in sha256 calculation, and +# you need build a newer version on your own. +# The path must terminate with '/' if it is not null. +EFITOOLS_PATH = '' diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 6ad5608cd71c..27c05971ca32 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -10,13 +10,13 @@ import pytest from capsule_defs import * # -# Fixture for UEFI secure boot test +# Fixture for UEFI capsule test # - @pytest.fixture(scope='session') def efi_capsule_data(request, u_boot_config): - """Set up a file system to be used in UEFI capsule test. + """Set up a file system to be used in UEFI capsule and + authentication test. Args: request: Pytest request object. @@ -40,6 +40,36 @@ def efi_capsule_data(request, u_boot_config): check_call('mkdir -p %s' % data_dir, shell=True) check_call('mkdir -p %s' % install_dir, shell=True) + capsule_auth_enabled = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') + if capsule_auth_enabled: + # Create private key (SIGNER.key) and certificate (SIGNER.crt) + check_call('cd %s; ' + 'openssl req -x509 -sha256 -newkey rsa:2048 ' + '-subj /CN=TEST_SIGNER/ -keyout SIGNER.key ' + '-out SIGNER.crt -nodes -days 365' + % data_dir, shell=True) + check_call('cd %s; %scert-to-efi-sig-list SIGNER.crt SIGNER.esl' + % (data_dir, EFITOOLS_PATH), shell=True) + + # Update dtb adding capsule certificate + check_call('cd %s; ' + 'cp %s/test/py/tests/test_efi_capsule/signature.dts .' + % (data_dir, u_boot_config.source_dir), shell=True) + check_call('cd %s; ' + 'dtc -@ -I dts -O dtb -o signature.dtbo signature.dts; ' + 'fdtoverlay -i %s/arch/sandbox/dts/test.dtb ' + '-o test_sig.dtb signature.dtbo' + % (data_dir, u_boot_config.build_dir), shell=True) + + # Create *malicious* private key (SIGNER2.key) and certificate + # (SIGNER2.crt) + check_call('cd %s; ' + 'openssl req -x509 -sha256 -newkey rsa:2048 ' + '-subj /CN=TEST_SIGNER/ -keyout SIGNER2.key ' + '-out SIGNER2.crt -nodes -days 365' + % data_dir, shell=True) + # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old -> u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, @@ -56,6 +86,22 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkeficapsule --raw u-boot.bin.new --index 1 Test02' % (data_dir, u_boot_config.build_dir), shell=True) + if capsule_auth_enabled: + # firmware signed with proper key + check_call('cd %s; ' + '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' + '--private-key SIGNER.key --certificate SIGNER.crt ' + '--raw u-boot.bin.new Test11' + % (data_dir, u_boot_config.build_dir), + shell=True) + # firmware signed with *mal* key + check_call('cd %s; ' + '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' + '--private-key SIGNER2.key ' + '--certificate SIGNER2.crt ' + '--raw u-boot.bin.new Test12' + % (data_dir, u_boot_config.build_dir), + shell=True) # Create a disk image with EFI system partition check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat %s %s' % diff --git a/test/py/tests/test_efi_capsule/signature.dts b/test/py/tests/test_efi_capsule/signature.dts new file mode 100644 index 000000000000..078cfc76c93c --- /dev/null +++ b/test/py/tests/test_efi_capsule/signature.dts @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; +/plugin/; + +&{/} { + signature { + capsule-key = /incbin/("SIGNER.esl"); + }; +}; diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed.py new file mode 100644 index 000000000000..593b032e9015 --- /dev/null +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed.py @@ -0,0 +1,254 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2021, Linaro Limited +# Author: AKASHI Takahiro +# +# U-Boot UEFI: Firmware Update (Signed capsule) Test + +""" +This test verifies capsule-on-disk firmware update +with signed capsule files +""" + +import pytest +from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('efi_capsule_firmware_raw') +@pytest.mark.buildconfigspec('efi_capsule_authenticate') +@pytest.mark.buildconfigspec('dfu') +@pytest.mark.buildconfigspec('dfu_sf') +@pytest.mark.buildconfigspec('cmd_efidebug') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +@pytest.mark.buildconfigspec('cmd_nvedit_efi') +@pytest.mark.buildconfigspec('cmd_sf') +@pytest.mark.slow +class TestEfiCapsuleFirmwareSigned(object): + def test_efi_capsule_auth1( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 1 - Update U-Boot on SPI Flash, raw image format + 0x100000-0x150000: U-Boot binary (but dummy) + + If the capsule is properly signed, the authentication + should pass and the firmware be updated. + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 1-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi', + 'efidebug boot order 1', + 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', + 'env set dfu_alt_info ' + '"sf 0:0=u-boot-bin raw 0x100000 ' + '0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize content + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' + % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test11' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test11 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test11' in ''.join(output) + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_sig.dtb' + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 1-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info ' + '"sf 0:0=u-boot-bin raw 0x100000 ' + '0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test11' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000') + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test11' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:New' in ''.join(output) + + def test_efi_capsule_auth2( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 2 - Update U-Boot on SPI Flash, raw image format + 0x100000-0x150000: U-Boot binary (but dummy) + + If the capsule is signed but with an invalid key, + the authentication should fail and the firmware + not be updated. + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 2-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi', + 'efidebug boot order 1', + 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', + 'env set dfu_alt_info ' + '"sf 0:0=u-boot-bin raw 0x100000 ' + '0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize content + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' + % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test12' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test12 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test12' in ''.join(output) + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_sig.dtb' + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 2-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info ' + '"sf 0:0=u-boot-bin raw 0x100000 ' + '0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test12' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000') + + # deleted any way + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test12' not in ''.join(output) + + # TODO: check CapsuleStatus in CapsuleXXXX + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:Old' in ''.join(output) + + def test_efi_capsule_auth3( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 3 - Update U-Boot on SPI Flash, raw image format + 0x100000-0x150000: U-Boot binary (but dummy) + + If the capsule is not signed, the authentication + should fail and the firmware not be updated. + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 3-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi', + 'efidebug boot order 1', + 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', + 'env set dfu_alt_info ' + '"sf 0:0=u-boot-bin raw 0x100000 ' + '0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize content + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' + % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test02' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test02 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test02' in ''.join(output) + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_sig.dtb' + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 3-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info ' + '"sf 0:0=u-boot-bin raw 0x100000 ' + '0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test02' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000') + + # deleted any way + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test02' not in ''.join(output) + + # TODO: check CapsuleStatus in CapsuleXXXX + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:Old' in ''.join(output) From patchwork Wed Feb 9 10:10:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590304 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=NIv32O87; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jtwg367TKz9sFv for ; Wed, 9 Feb 2022 21:12:47 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EED3583E69; Wed, 9 Feb 2022 11:12:12 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="NIv32O87"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D3C9C83DF0; Wed, 9 Feb 2022 11:11:53 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id DC22383DEE for ; Wed, 9 Feb 2022 11:11:45 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x102c.google.com with SMTP id v13-20020a17090ac90d00b001b87bc106bdso4613408pjt.4 for ; Wed, 09 Feb 2022 02:11:45 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=jeNCFvUVoZN0BxazhRkEJAvtg+ZnIg4eXpZO26VBEQE=; b=NIv32O873D7g1iLweNioCqnE/miOdW/rF5Zev+JIRY/QGWWtn+9m1p9Ltae91jTtiM jjP+w56tfe+OgRyQ0r19IbUa5z97IK71DYnsQCMSavv15Ks8QtlSJgD8OwR2aokHywED oaovxEriBqqd83tDzmgy1MmjBkMcyHNIQ3z1YFeB49giZXWG1xyIsS1x42oo7ZIkkOCi pJp9YwgcI9HKSi2A/zAT3ek2LlV52XdEu3oQ3Sen3QCpaUpkrXC4R4JzwLfBMyW0yMuu zmM2t963MZ9s3Pfin6PBDNh9TBSEXwDRnFX7mgtn+cXDyc8Po3Pugt8WHzolu5D3fvtn fvuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jeNCFvUVoZN0BxazhRkEJAvtg+ZnIg4eXpZO26VBEQE=; b=25uwobeRwpkf5yhD9uMVXgQxdQ2LuISN6aqDThEt8oeXMCbV1ApOMHLdU8jRv3Lzzm h7HLl+KdxjG2ycnJksPO6E+3/fHwmShlR7jWwTgM2SvC+7mUkM2peThYbvyGBIzn/noL cePIhTPo9JwobLFB3X8geBo9gETV2iAPAbdQ3y6gE248QKB5T/KuuXIQHsus5LNnIIVq YWVNkzqubtb3KLwxISAHUKETZ+u46DXlk/BkDMm+eMr79W9xHolkU7TqazOJIyZOIPU1 fMZlEqSeIsrnNbyruf7to9Ca0B6+UTGl2AEII1pXUu7Dh7kh1H8UHj5oTvVTpcHbM+nO SQHQ== X-Gm-Message-State: AOAM531vPay+l45faQUWVOarAubErE/CTGcLXt+dwCL07afYXO3ekqs2 q+1N9n+VLMQ4QD1VmAX8ojRNDx9iBETn1g== X-Google-Smtp-Source: ABdhPJxN/+dgaCAs/sg/NPeEYf301MaHHJLEHin1a14uljQVc0s/shxxA2cdRvHkcgsVhugW199cLQ== X-Received: by 2002:a17:902:f549:: with SMTP id h9mr1676624plf.62.1644401504089; Wed, 09 Feb 2022 02:11:44 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:43 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 6/9] tools: mkeficapsule: allow for specifying GUID explicitly Date: Wed, 9 Feb 2022 19:10:39 +0900 Message-Id: <20220209101042.78036-7-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean The existing options, "--fit" and "--raw," are only used to put a proper GUID in a capsule header, where GUID identifies a particular FMP (Firmware Management Protocol) driver which then would handle the firmware binary in a capsule. In fact, mkeficapsule does the exact same job in creating a capsule file whatever the firmware binary type is. To prepare for the future extension, the command syntax will be a bit modified to allow users to specify arbitrary GUID for their own FMP driver. OLD: [--fit | --raw ] NEW: [--fit | --raw | --guid ] Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass --- .azure-pipelines.yml | 4 +- doc/develop/uefi/uefi.rst | 4 +- doc/mkeficapsule.1 | 26 ++++++++---- tools/Makefile | 2 +- tools/mkeficapsule.c | 85 ++++++++++++++++++++++++++++----------- 5 files changed, 86 insertions(+), 35 deletions(-) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index aecc9cb88441..eb8ec630a593 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -25,7 +25,7 @@ stages: %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Syyuu" displayName: 'Update MSYS2' - script: | - %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm --needed -Sy make gcc bison flex diffutils openssl-devel libgnutls-devel" + %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm --needed -Sy make gcc bison flex diffutils openssl-devel libgnutls-devel libutil-linux-devel" displayName: 'Install Toolchain' - script: | echo make tools-only_defconfig tools-only NO_SDL=1 > build-tools.sh @@ -42,7 +42,7 @@ stages: pool: vmImage: $(macos_vm) steps: - - script: brew install make + - script: brew install make ossp-uuid displayName: Brew install dependencies - script: | gmake tools-only_config tools-only NO_SDL=1 \ diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index 52a38c6b231c..b7bf1356276d 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -375,8 +375,8 @@ and used by the steps highlighted below. --private-key CRT.key \ --certificate CRT.crt \ --index 1 --instance 0 \ - [--fit | --raw ] \ - + [--fit | --raw | --guid 4. Insert the signature list into a device tree in the following format:: diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index 680362f5c4e9..8babb27ee8b2 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -8,7 +8,7 @@ mkeficapsule \- Generate EFI capsule file for U-Boot .SH SYNOPSIS .B mkeficapsule -.RI [ options "] " capsule-file +.RI [ options "] " image-blob " " capsule-file .SH "DESCRIPTION" .B mkeficapsule @@ -24,7 +24,7 @@ In this case, the update will be authenticated by verifying the signature before applying. .B mkeficapsule -supports two different format of image files: +takes any type of image files, including: .TP .I raw image format is a single binary blob of any type of firmware. @@ -36,18 +36,30 @@ multiple binary blobs in a single capsule file. This type of image file can be generated by .BR mkimage . +.PP +If you want to use other types than above two, you should explicitly +specify a guid for the FMP driver. + .SH "OPTIONS" One of -.BR --fit " or " --raw +.BR --fit ", " --raw " or " --guid option must be specified. .TP -.BI "-f\fR,\fB --fit " fit-image-file -Specify a FIT image file +.BR -f ", " --fit +Indicate that the blob is a FIT image file .TP -.BI "-r\fR,\fB --raw " raw-image-file -Specify a raw image file +.BR -r ", " --raw +Indicate that the blob is a raw image file + +.TP +.BI "-g\fR,\fB --guid " guid-string +Specify guid for image blob type. The format is: + xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + +The first three elements are in little endian, while the rest +is in big endian. .TP .BI "-i\fR,\fB --index " index diff --git a/tools/Makefile b/tools/Makefile index 8da07d60a755..5409ff2879c6 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -238,7 +238,7 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include -HOSTLDLIBS_mkeficapsule += -lgnutls +HOSTLDLIBS_mkeficapsule += -lgnutls -luuid hostprogs-$(CONFIG_TOOLS_MKEFICAPSULE) += mkeficapsule # We build some files with extra pedantic flags to try to minimize things diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index b996c66ad26a..7ff1f999db85 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -15,7 +15,7 @@ #include #include - +#include #include #include @@ -33,11 +33,12 @@ efi_guid_t efi_guid_image_type_uboot_raw = EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "f:r:i:I:v:p:c:m:dh"; +static const char *opts_short = "frg:i:I:v:p:c:m:dh"; static struct option options[] = { - {"fit", required_argument, NULL, 'f'}, - {"raw", required_argument, NULL, 'r'}, + {"fit", no_argument, NULL, 'f'}, + {"raw", no_argument, NULL, 'r'}, + {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, {"private-key", required_argument, NULL, 'p'}, @@ -50,11 +51,12 @@ static struct option options[] = { static void print_usage(void) { - printf("Usage: %s [options] \n" + fprintf(stderr, "Usage: %s [options] \n" "Options:\n" - "\t-f, --fit new FIT image file\n" - "\t-r, --raw new raw image file\n" + "\t-f, --fit FIT image type\n" + "\t-r, --raw raw image type\n" + "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instance update hardware instance\n" "\t-p, --private-key private key file\n" @@ -541,6 +543,37 @@ err: return ret; } +/** + * convert_uuid_to_guid() - convert UUID to GUID + * @buf: UUID binary + * + * UUID and GUID have the same data structure, but their binary + * formats are different due to the endianness. See lib/uuid.c. + * Since uuid_parse() can handle only UUID, this function must + * be called to get correct data for GUID when parsing a string. + * + * The correct data will be returned in @buf. + */ +void convert_uuid_to_guid(unsigned char *buf) +{ + unsigned char c; + + c = buf[0]; + buf[0] = buf[3]; + buf[3] = c; + c = buf[1]; + buf[1] = buf[2]; + buf[2] = c; + + c = buf[4]; + buf[4] = buf[5]; + buf[5] = c; + + c = buf[6]; + buf[6] = buf[7]; + buf[7] = c; +} + /** * main - main entry function of mkeficapsule * @argc: Number of arguments @@ -555,14 +588,13 @@ err: */ int main(int argc, char **argv) { - char *file; efi_guid_t *guid; + unsigned char uuid_buf[16]; unsigned long index, instance; uint64_t mcount; char *privkey_file, *cert_file; int c, idx; - file = NULL; guid = NULL; index = 0; instance = 0; @@ -577,21 +609,34 @@ int main(int argc, char **argv) switch (c) { case 'f': - if (file) { - fprintf(stderr, "Image already specified\n"); + if (guid) { + fprintf(stderr, + "Image type already specified\n"); exit(EXIT_FAILURE); } - file = optarg; guid = &efi_guid_image_type_uboot_fit; break; case 'r': - if (file) { - fprintf(stderr, "Image already specified\n"); + if (guid) { + fprintf(stderr, + "Image type already specified\n"); exit(EXIT_FAILURE); } - file = optarg; guid = &efi_guid_image_type_uboot_raw; break; + case 'g': + if (guid) { + fprintf(stderr, + "Image type already specified\n"); + exit(EXIT_FAILURE); + } + if (uuid_parse(optarg, uuid_buf)) { + fprintf(stderr, "Wrong guid format\n"); + exit(EXIT_FAILURE); + } + convert_uuid_to_guid(uuid_buf); + guid = (efi_guid_t *)uuid_buf; + break; case 'i': index = strtoul(optarg, NULL, 0); break; @@ -627,20 +672,14 @@ int main(int argc, char **argv) } /* check necessary parameters */ - if ((argc != optind + 1) || !file || + if ((argc != optind + 2) || !guid || ((privkey_file && !cert_file) || (!privkey_file && cert_file))) { print_usage(); exit(EXIT_FAILURE); } - /* need a fit image file or raw image file */ - if (!file) { - print_usage(); - exit(EXIT_SUCCESS); - } - - if (create_fwbin(argv[optind], file, guid, index, instance, + if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, index, instance, mcount, privkey_file, cert_file) < 0) { fprintf(stderr, "Creating firmware capsule failed\n"); exit(EXIT_FAILURE); From patchwork Wed Feb 9 10:10:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590305 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=MOayV7r5; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JtwgH4FTcz9sFv for ; Wed, 9 Feb 2022 21:12:59 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5537983E7E; Wed, 9 Feb 2022 11:12:16 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="MOayV7r5"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EAA3983DF0; Wed, 9 Feb 2022 11:11:57 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E2EA383E45 for ; Wed, 9 Feb 2022 11:11:48 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x434.google.com with SMTP id d187so3373473pfa.10 for ; Wed, 09 Feb 2022 02:11:48 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=dRz+pYre7G66GxmnD4c+PKAAw7SxJFLHJCc2sklu4uM=; b=MOayV7r5sbkWCAYqfaHsgvxekSN+VqOzCyrzkilz56KVhQLj2SCfcBGM0e7gqzBrnX ekeSZFvjlcJOLluNlJUeFkPj35gucVBV/dSz7fLYNrctCCz1AN4X8SwdjRRSyi1rY7dh UCBZ6WoAaexlIet3OXV/hBKWpndB/AOLnrq0OagAug6Ta7StdecbQ6o4fSJn9gDhbu0r 5UyjKf+l5fFW08/xU9EK+g8UW3/CwkFbmsqNKE6dpaTNFQOmoo/wN11DqLkkMY9RYnUe dEIhKdKefYxgJ5dKQSqRHW4DTxPhKOLmC5GgqPqi10buSpbUNY2P4qp8z8dX+yemSmc7 fCWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dRz+pYre7G66GxmnD4c+PKAAw7SxJFLHJCc2sklu4uM=; b=t36UQ45RZi3RvvIEalK2k1aA9AgJEohao0ZG57r/4otlpaWD1pObLVIInhqVgnh53Z 4Ppfhc43tye5OB22AWhJEWSHRb13vXplP5ZnhNRQEnE29rFVNE7eZS92Jd4Q5V2zyBj9 abOlO0Y4JjmSSEoWG42FT79h5XPOP8xE4BciEziWX/G2AC7XxQcB4c4wD0j1LeTbElW+ 7JedLb6sorG1o0nNf1QzE2/g+1UcknsxBaF3o7HFa+/t4IAsMwxa7wPS4LGZL93E8ElX qRr+0u5cqzrT1kKkK8701Okxtd45YKJTOD/Cb3uqhphup0B2uI5BSGom1rQPQdGh6eB1 xIwg== X-Gm-Message-State: AOAM532Ah8/zclt52bTp2wxL+LlSmKXgQp6LGx+Gta7KoEHmbHGkXGDT P5mEmuMWnkIU9mD3TTdvbXp26Q== X-Google-Smtp-Source: ABdhPJwHtt3z5ROGpXd0+ZdZCpVlzI8XmkThQu91bO/U+SnrtQ9CYAKVQl8mKB3ltLlN3d5gvhZqpA== X-Received: by 2002:a05:6a00:1c77:: with SMTP id s55mr1459282pfw.3.1644401506960; Wed, 09 Feb 2022 02:11:46 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:46 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 7/9] test/py: efi_capsule: align with the syntax change of mkeficapsule Date: Wed, 9 Feb 2022 19:10:40 +0900 Message-Id: <20220209101042.78036-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Since the syntax of mkeficapsule was changed in the previous commit, we need to modify command line arguments in a pytest script. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass --- test/py/tests/test_efi_capsule/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 27c05971ca32..a5a25c53dcb4 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -80,10 +80,10 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkimage -f uboot_bin_env.its uboot_bin_env.itb' % (data_dir, u_boot_config.build_dir), shell=True) - check_call('cd %s; %s/tools/mkeficapsule --fit uboot_bin_env.itb --index 1 Test01' % + check_call('cd %s; %s/tools/mkeficapsule --index 1 --fit uboot_bin_env.itb Test01' % (data_dir, u_boot_config.build_dir), shell=True) - check_call('cd %s; %s/tools/mkeficapsule --raw u-boot.bin.new --index 1 Test02' % + check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) if capsule_auth_enabled: From patchwork Wed Feb 9 10:10:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590307 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=EilEImLS; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Jtwgq6L3Kz9sFr for ; Wed, 9 Feb 2022 21:13:27 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id DBF3083E3C; Wed, 9 Feb 2022 11:12:21 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="EilEImLS"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 155DF83E1D; Wed, 9 Feb 2022 11:12:03 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 5171E83E4E for ; Wed, 9 Feb 2022 11:11:52 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x432.google.com with SMTP id i21so1925963pfd.13 for ; Wed, 09 Feb 2022 02:11:52 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=37b4CbGVq2vXfUQd07BoRyvPsjDtxkfVdV+ImREOVoM=; b=EilEImLSg8+QV3WM8+oPHvkF/MTWTYiN6P5FpElhe8RuX2bd1mfA+fy9+wLoE3WDHr /e54L4dpuCXay9zKpk5n07LtRjyWCPvk/2RHT0aTyUUz1VQlwTVLF6Km2B98sUPmb53j /rUJCvSS6+IJFLSuVqwzvSddBL3FQXYavQrMDOLuJyA/cqc+sV0ot2fNPZMPLn1jbY5f GIaiNHNfmHIFZ8GeORAdD47mpnz1CYVePEZVJuZInyxjUvJxkDl/M0tfwD7MPlmF8Ksf WKXOVs85CASVKBW6+jeE2bnUDsyP/h6/MdT7GtAWE9McvcsAP6ECP29O27KlErLDBrJm 1JMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=37b4CbGVq2vXfUQd07BoRyvPsjDtxkfVdV+ImREOVoM=; b=MIJ66UWAQqMUiTJExYO0UBcKdJNXbvoQBnesiYEmSyqIBJRTIPPB1FkYReUP5sjzv7 BEh0icY4QmW5zCyLrmMFvjrJocwTtQXXnC6qBkA3thFx2S8wNFtJkx9an01QsmYk0ll9 g72aTsR64uUp0V/f5hMVAGESGAP0MQC/Zwfw1ziL11KXiphuW4UtgoSxrgAAmw7fPXwe 62oZpE6CfHHeRCgZ0VHxs+R/4DFbdcmsv5VfpTDauGkjhukgO4cYkXHdOMz9ygOAwUT7 WSF0VRK8YpTujFXOAGVHwPtvmbjspJcdvip+rETQx9HPUmbX1y4p+aAxRmy4N/rBVLqN aULQ== X-Gm-Message-State: AOAM530mCxNJdHZHCCrRdQS7vYAe6A9ONCNkx543C97ujJWCfT4C4xlb 10eJ0t0SHoWtdiqLK/MkbocfCA== X-Google-Smtp-Source: ABdhPJxSwlcMH4DVZDhFE1NtkJAZGeebrRaUPpk9n7qYLLr5RyGta+X+EzEixhPQJI8fWQuNfQ0AKQ== X-Received: by 2002:a63:1266:: with SMTP id 38mr1291607pgs.261.1644401509724; Wed, 09 Feb 2022 02:11:49 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:49 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 8/9] test/py: efi_capsule: add a test for "--guid" option Date: Wed, 9 Feb 2022 19:10:41 +0900 Message-Id: <20220209101042.78036-9-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean This test scenario tests a new feature of mkeficapsule, "--guid" option, which allows us to specify FMP driver's guid explicitly at the command line. Signed-off-by: AKASHI Takahiro --- test/py/tests/test_efi_capsule/conftest.py | 3 + .../test_efi_capsule/test_capsule_firmware.py | 67 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index a5a25c53dcb4..9076087a12b7 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -86,6 +86,9 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkeficapsule --index 1 --raw u-boot.bin.new Test02' % (data_dir, u_boot_config.build_dir), shell=True) + check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid E2BB9C06-70E9-4B14-97A3-5A7913176E3F u-boot.bin.new Test03' % + (data_dir, u_boot_config.build_dir), + shell=True) if capsule_auth_enabled: # firmware signed with proper key check_call('cd %s; ' diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py index 9eeaae27d626..9cc973560fa1 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py @@ -247,3 +247,70 @@ class TestEfiCapsuleFirmwareFit(object): 'sf read 4000000 100000 10', 'md.b 4000000 10']) assert 'u-boot:New' in ''.join(output) + + def test_efi_capsule_fw4( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 4 - Test "--guid" option of mkeficapsule + The test scenario is the same as Case 3. + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 4-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'efidebug boot add -b 1 TEST host 0:1 /helloworld.efi -s ""', + 'efidebug boot order 1', + 'env set -e -nv -bs -rt OsIndications =0x0000000000000004', + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'env save']) + + # initialize content + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.bin.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 100000 10', + 'sf read 5000000 100000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place a capsule file + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test03' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test03 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test03' in ''.join(output) + + # reboot + u_boot_console.restart_uboot() + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + with u_boot_console.log.section('Test Case 4-b, after reboot'): + if not capsule_early: + # make sure that dfu_alt_info exists even persistent variables + # are not available. + output = u_boot_console.run_command_list([ + 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"', + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test03' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000') + + output = u_boot_console.run_command_list(['efidebug capsule esrt']) + + # ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT. + assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test03' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + assert 'u-boot:New' in ''.join(output) From patchwork Wed Feb 9 10:10:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1590306 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=OlFp+ib7; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JtwgZ0bnWz9sFr for ; Wed, 9 Feb 2022 21:13:14 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1C21883E88; Wed, 9 Feb 2022 11:12:19 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="OlFp+ib7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8F92D83E38; Wed, 9 Feb 2022 11:12:00 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3484D83E1D for ; Wed, 9 Feb 2022 11:11:54 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pf1-x42d.google.com with SMTP id n23so3470500pfo.1 for ; Wed, 09 Feb 2022 02:11:54 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=IWerVfIYQG4PYlCT6/iZD5GfRSLOO0VoGD6nCIjvwMk=; b=OlFp+ib7CvOVWG7DZrXJdYOKMgbG40jQYZ1d9UW4/bmDB/QGFXplWzsW3eGuCB79Do MRrqCZnPxnZ3smYMJAc0sW0KmIDcypBqQqz4LRmwNPY06zyCiFG3CRLWPR2k2L7kkhLx Gh5yY9kkODkVvWfYSMoDSMRxdJXfYDeG8b5fYy+IXKs0KWF7YTGQzKn5D6Tvss1LKl2G V3E2cbucfMVicBk/rV9rhaWxdAol7MfTq9NkiSTkhSxv2WY0mWH6a98lf0cU7uSlhEhi Ot/md5/IcchSw0lGv0UV6Q2ncS5xPKFyH6yxR73gkezHOmP2YI0gUf5visvzJ1kEUDhd cNhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IWerVfIYQG4PYlCT6/iZD5GfRSLOO0VoGD6nCIjvwMk=; b=sC5H+Xl6RUeH5q1LyRzkIGJ6ELQlcbCOYY+flUpwqeVQ9VuFNmYh/KP/x7S7+eBHqG jgyruRJCPcZTs/CdGn39jMsBJpkb4ufZy1LFpzbyoIvq7LaOfTi66AG8aOS8afD6lomc t6BXKN23ZJTCcvFi5MZcExfJpSdQ8U9pztF9jGBgbvztvXwSx8tc315xtOh/6aHH2qKn MKDRmUhiKMCvbmCA2aXEw+s0X1oDoACv31dNRjIN2qBX2NhOnhgiKRZcLr6iA30r+T1S 7K30E9Cocaw2TuRhZOSqd8B11FZT9J3FhPduT95O9HZLElojrUPygdenQ3hhfVyXAdZY uJ7g== X-Gm-Message-State: AOAM532eS5CiJZ7g7eAoc76Yt9kIoJ+p3ZMPCPL6VBHVGhjVOhh6dWz8 tU+SjNCFI5+8kMGP8ZB+Wn5r6g== X-Google-Smtp-Source: ABdhPJxHV1PBrBTPnS8MQnBA0QuVPP7oQ3ZGUFF6YfLmatkBPI4S27ura6wOgMG1fyiLB46/72C80A== X-Received: by 2002:a63:ed13:: with SMTP id d19mr1301178pgi.335.1644401512370; Wed, 09 Feb 2022 02:11:52 -0800 (PST) Received: from localhost.localdomain ([2400:4050:c3e1:100:d885:543e:bfe4:9eb5]) by smtp.gmail.com with ESMTPSA id mi18sm5143303pjb.35.2022.02.09.02.11.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Feb 2022 02:11:52 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de Cc: sjg@chromium.org, ilias.apalodimas@linaro.org, sughosh.ganu@linaro.org, masami.hiramatsu@linaro.org, mark.kettenis@xs4all.nl, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v11 9/9] test/py: efi_capsule: check the results in case of CAPSULE_AUTHENTICATE Date: Wed, 9 Feb 2022 19:10:42 +0900 Message-Id: <20220209101042.78036-10-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20220209101042.78036-1-takahiro.akashi@linaro.org> References: <20220209101042.78036-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Before the capsule authentication is supported, this test script works correctly, but with the feature enabled, most tests will fail due to unsigned capsules. So check the results depending on CAPSULE_AUTHENTICATE or not. Signed-off-by: AKASHI Takahiro Reviewed-by: Simon Glass --- .../test_efi_capsule/test_capsule_firmware.py | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py index 9cc973560fa1..6e803f699f2f 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py @@ -148,6 +148,8 @@ class TestEfiCapsuleFirmwareFit(object): capsule_early = u_boot_config.buildconfig.get( 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') with u_boot_console.log.section('Test Case 2-b, after reboot'): if not capsule_early: # make sure that dfu_alt_info exists even persistent variables @@ -171,12 +173,18 @@ class TestEfiCapsuleFirmwareFit(object): 'sf probe 0:0', 'sf read 4000000 100000 10', 'md.b 4000000 10']) - assert 'u-boot:New' in ''.join(output) + if capsule_auth: + assert 'u-boot:Old' in ''.join(output) + else: + assert 'u-boot:New' in ''.join(output) output = u_boot_console.run_command_list([ 'sf read 4000000 150000 10', 'md.b 4000000 10']) - assert 'u-boot-env:New' in ''.join(output) + if capsule_auth: + assert 'u-boot-env:Old' in ''.join(output) + else: + assert 'u-boot-env:New' in ''.join(output) def test_efi_capsule_fw3( self, u_boot_config, u_boot_console, efi_capsule_data): @@ -215,6 +223,8 @@ class TestEfiCapsuleFirmwareFit(object): capsule_early = u_boot_config.buildconfig.get( 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') with u_boot_console.log.section('Test Case 3-b, after reboot'): if not capsule_early: # make sure that dfu_alt_info exists even persistent variables @@ -246,7 +256,10 @@ class TestEfiCapsuleFirmwareFit(object): 'sf probe 0:0', 'sf read 4000000 100000 10', 'md.b 4000000 10']) - assert 'u-boot:New' in ''.join(output) + if capsule_auth: + assert 'u-boot:Old' in ''.join(output) + else: + assert 'u-boot:New' in ''.join(output) def test_efi_capsule_fw4( self, u_boot_config, u_boot_console, efi_capsule_data): @@ -285,6 +298,8 @@ class TestEfiCapsuleFirmwareFit(object): capsule_early = u_boot_config.buildconfig.get( 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') with u_boot_console.log.section('Test Case 4-b, after reboot'): if not capsule_early: # make sure that dfu_alt_info exists even persistent variables @@ -313,4 +328,7 @@ class TestEfiCapsuleFirmwareFit(object): 'sf probe 0:0', 'sf read 4000000 100000 10', 'md.b 4000000 10']) - assert 'u-boot:New' in ''.join(output) + if capsule_auth: + assert 'u-boot:Old' in ''.join(output) + else: + assert 'u-boot:New' in ''.join(output)