From patchwork Mon Apr 10 09:07:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 672029 Delivered-To: patch@linaro.org Received: by 2002:a05:6000:184:0:0:0:0 with SMTP id p4csp151434wrx; Mon, 10 Apr 2023 02:07:09 -0700 (PDT) X-Google-Smtp-Source: AKy350YPpgH5vbyLZd86imG2rKyOo28TRPVTgcGHVOriEGL8d0A7UUGiIwutIwOFlq8Vhi8Jl2pM X-Received: by 2002:a05:622a:547:b0:3e6:332a:70df with SMTP id m7-20020a05622a054700b003e6332a70dfmr14629075qtx.44.1681117629124; Mon, 10 Apr 2023 02:07:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681117629; cv=none; d=google.com; s=arc-20160816; b=uIB9uq8k98a5bmYQQm+8gKc19NPu+fPy7KyIFuJa/jVEoArLMkjVzkyhRZTkRatEdo 5QH1/VY8TzrIg+n0HFbHVf+M6jeVALKV/cmvEe5vveEV92U8pMUFGMjvY1m+7uvrEMAk MmCz1SSqz0buwd4HEVEjyOrYYDJ0MK+IOg3evtUwtEgbal100o07OAs9cCbMZHnnzz3m SsRWOmmnSseRT1Lt27IFRynLoYvOVAntk5Fg5d8L/km4iGTQ9SblkhbuBCMPSHRTF+Yt z6NQwPlYTEfTtZwVerEHbi5OdhoNLo9yOWBnGz5hPBNDbkv90Gm2ZxSyWryhLUICwaKZ AUag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=OQiWnUThY2ZRwn3oVvt9AoGOhbrdwXS/0URdWJqiJys=; b=WM3HEX9+yd0lGJHfkaJW7/hw9smeLRqnnjk9u5j3Y8bSmlkH6pja8L3oyJpofgPCpl bCxjA43X1OAze1N4lAzWextTwuR0NaPwyu0PZbfd1FmhVEMz450ZUXbHuA9RQawy0XFO ILHhy40vNplNJC38cLtmTw8K1pTa44jb+jCouWXoYEBb1/S6zO3j1iAz3U6thqSQLNWo 4wLhxRXGahfcd0LAGV8At97LiZ4CQgFIpylU3ISEjgNF/3FJQoilzGWJmimYtOeC+TeR IrzGx3WOehRP7A1qjc+rvgignvkBfGc57D4l+uYldS71kfQJsK/QHL7R3XUVSWsh0kRf C61Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CKnU+yCZ; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id a6-20020ae9e806000000b0074a4dbc4cc9si6855671qkg.667.2023.04.10.02.07.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:07:09 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CKnU+yCZ; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7A249856B2; Mon, 10 Apr 2023 11:06:52 +0200 (CEST) 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="CKnU+yCZ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id DAA3680B9E; Mon, 10 Apr 2023 11:06:35 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) (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 0905683981 for ; Mon, 10 Apr 2023 11:06:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pl1-x629.google.com with SMTP id y6so3081127plp.2 for ; Mon, 10 Apr 2023 02:06:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1681117589; x=1683709589; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=OQiWnUThY2ZRwn3oVvt9AoGOhbrdwXS/0URdWJqiJys=; b=CKnU+yCZklzHu7qSkSdIsZEdvRjp8AdOVUzqXwosNEuxZfWvrOb7kUePJcooLBVZ6h cre9etlGD5EkDOAdWOL8wDYETfUsgNyDxWeBlACWJsmvgOPxEfR4l0+XRqcuGxOaAsgn a2mwakljc1WsHacRy9yuUTv1oaSnLjybNJd0G2NiuNNjHSsx38MV5QSWduZJB4eOS41d TGBasST8Y3hPEW0c6B0YX6csTtLqquJN/rlvDwWkA+X3acQ+J06C2zZ756dFdzIA0a1w NCg/MfT74cD9Kkdnm2MqpCLPL4CChkEaSmLWtMAgIH0NJua2OMj1zrOYMNPNy8pb/YKB yTuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681117589; x=1683709589; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=OQiWnUThY2ZRwn3oVvt9AoGOhbrdwXS/0URdWJqiJys=; b=HGnsCvwpWNLrg4bUKKIwsMZdWIafdi9yfNp4vp2hknZoxOJalYVgzOZArQjZlvnVwb m3RC/hPQ+7FmQuArYkm5JLAT6zr3yr2mExyZ7UcfL4ViLXmH3L/aoWI9VWBzh6lv+6G9 MzLCaGxyyp7WGtnS3+ayW3VuLP9b+6Q3Ogfpvqzhg2Dt034vaqftzeVyxc0m5hqsDmRf 4S5lPght/ZwG5nTd7JhtXDPgSGyAI/IB3AD50omCV8K2bpFbhxbflgHivneBK0PFNvbw idWgMj82TfWgYNDR73rMEpm3kTZQMMsKCJLQgraK8ZPvgSTZyXm6DCOCQ3dKN7LKsqmF 89EQ== X-Gm-Message-State: AAQBX9dsOjoP4Gc7mqiduY+ByxgoUbbHI6s3OdMwb+DxAoQMqmkD4H4Q ZG7kTM1+7pkJveE98FuQsH34vTrU8St0Q5BOrrw= X-Received: by 2002:a17:90a:f197:b0:246:594d:3b05 with SMTP id bv23-20020a17090af19700b00246594d3b05mr11746937pjb.17.1681117589022; Mon, 10 Apr 2023 02:06:29 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0023f8bdc4a7fsm7189279pji.14.2023.04.10.02.06.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:06:28 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v5 1/4] efi_loader: get version information from device tree Date: Mon, 10 Apr 2023 18:07:29 +0900 Message-Id: <20230410090732.1676-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230410090732.1676-1-masahisa.kojima@linaro.org> References: <20230410090732.1676-1-masahisa.kojima@linaro.org> 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.8 at phobos.denx.de X-Virus-Status: Clean Current FMP->GetImageInfo() always return 0 for the firmware version, user can not identify which firmware version is currently running through the EFI interface. This commit gets the version information from device tree, then fills the firmware version, lowest supported version in FMP->GetImageInfo(). Now FMP->GetImageInfo() and ESRT have the meaningful version number. Signed-off-by: Masahisa Kojima --- Changes in v5: - newly implement a device tree based versioning .../firmware/firmware-version.txt | 25 ++++++++ lib/efi_loader/efi_firmware.c | 63 +++++++++++++++++-- 2 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 doc/device-tree-bindings/firmware/firmware-version.txt diff --git a/doc/device-tree-bindings/firmware/firmware-version.txt b/doc/device-tree-bindings/firmware/firmware-version.txt new file mode 100644 index 0000000000..6112de4a1d --- /dev/null +++ b/doc/device-tree-bindings/firmware/firmware-version.txt @@ -0,0 +1,25 @@ +firmware-version bindings +------------------------------- + +Required properties: +- image-type-id : guid for image blob type +- image-index : image index +- fw-version : firmware version +- lowest-supported-version : lowest supported version + +Example: + + firmware-version { + image1 { + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + image-index = <1>; + fw-version = <5>; + lowest-supported-version = <3>; + }; + image2 { + image-type-id = "5A7021F5-FEF2-48B4-AABA-832E777418C0"; + image-index = <2>; + fw-version = <10>; + lowest-supported-version = <7>; + }; + }; diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 93e2b01c07..1c6ef468bf 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -102,6 +102,56 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( return EFI_EXIT(EFI_UNSUPPORTED); } +/** + * efi_firmware_get_firmware_version - get firmware version from dtb + * @image_index: Image index + * @image_type_id: Image type id + * @fw_version: Pointer to store the version number + * @lsv: Pointer to store the lowest supported version + * + * Authenticate the capsule if authentication is enabled. + * The image pointer and the image size are updated in case of success. + */ +void efi_firmware_get_firmware_version(u8 image_index, + efi_guid_t *image_type_id, + u32 *fw_version, u32 *lsv) +{ + const void *fdt = gd->fdt_blob; + const fdt32_t *val; + const char *guid_str; + int len, offset, index; + int parent; + + parent = fdt_subnode_offset(fdt, 0, "firmware-version"); + if (parent < 0) + return; + + fdt_for_each_subnode(offset, fdt, parent) { + efi_guid_t guid; + + guid_str = fdt_getprop(fdt, offset, "image-type-id", &len); + if (!guid_str) + continue; + uuid_str_to_bin(guid_str, guid.b, UUID_STR_FORMAT_GUID); + + val = fdt_getprop(fdt, offset, "image-index", &len); + if (!val) + continue; + index = fdt32_to_cpu(*val); + + if (!guidcmp(&guid, image_type_id) && index == image_index) { + val = fdt_getprop(fdt, offset, "fw-version", &len); + if (val) + *fw_version = fdt32_to_cpu(*val); + + val = fdt_getprop(fdt, offset, + "lowest-supported-version", &len); + if (val) + *lsv = fdt32_to_cpu(*val); + } + } +} + /** * efi_fill_image_desc_array - populate image descriptor array * @image_info_size: Size of @image_info @@ -148,13 +198,19 @@ static efi_status_t efi_fill_image_desc_array( *package_version_name = NULL; /* not supported */ for (i = 0; i < num_image_type_guids; i++) { + u32 fw_version = 0; + u32 lowest_supported_version = 0; + image_info[i].image_index = fw_array[i].image_index; image_info[i].image_type_id = fw_array[i].image_type_id; image_info[i].image_id = fw_array[i].image_index; image_info[i].image_id_name = fw_array[i].fw_name; - - image_info[i].version = 0; /* not supported */ + efi_firmware_get_firmware_version(fw_array[i].image_index, + &fw_array[i].image_type_id, + &fw_version, + &lowest_supported_version); + image_info[i].version = fw_version; image_info[i].version_name = NULL; /* not supported */ image_info[i].size = 0; image_info[i].attributes_supported = @@ -168,7 +224,7 @@ static efi_status_t efi_fill_image_desc_array( image_info[0].attributes_setting |= IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED; - image_info[i].lowest_supported_image_version = 0; + image_info[i].lowest_supported_image_version = lowest_supported_version; image_info[i].last_attempt_version = 0; image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; image_info[i].hardware_instance = 1; @@ -290,7 +346,6 @@ efi_status_t EFIAPI efi_firmware_get_image_info( descriptor_version, descriptor_count, descriptor_size, package_version, package_version_name); - return EFI_EXIT(ret); } From patchwork Mon Apr 10 09:07:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 672028 Delivered-To: patch@linaro.org Received: by 2002:a05:6000:184:0:0:0:0 with SMTP id p4csp151372wrx; Mon, 10 Apr 2023 02:06:57 -0700 (PDT) X-Google-Smtp-Source: AKy350YPK65yPQ1kANZX7igSOTki1svuJeSSmuUFF1kGqH6+PI6BHlS6ZGPdGWyi5XgQUzOU5aRB X-Received: by 2002:ac8:5e4f:0:b0:3a8:a84:7ffa with SMTP id i15-20020ac85e4f000000b003a80a847ffamr14343388qtx.57.1681117617730; Mon, 10 Apr 2023 02:06:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681117617; cv=none; d=google.com; s=arc-20160816; b=XFRRK5DHFyJksVvRSnMjSJ4o6E7I6cEC3DDTtoiXYalWgLp7uLvL0kbgMFsDPcrTsv vZr6lmOOrG21ZJsLJAg1VcD9hPQzvcpKa+EkV1lAnnuGBiNLV305h6+ND1Wi5UpWeNHo PUbVdbXz2rkFT0a+kP9hD9SdAFAgw4txd6ZJnUoYMBUsH6RlbTVOdZDpPQ98ykBrPXdN tprzpb9JmnpvxNz8/A1Cjj9COdRShoWgyMUA3JFfOxiv4+2waLYYxpfnBlk6OGrSJ0vl JQuZiJX9Vyoyc2f8NZ1kiCk+gwDzZDu6uMl+ld13rFl4FKEQJUt50dB2JsCqH982STnp 14ew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=nYK+0kicbkNfPxAK91H5Y4Ki7NxoPhVLEX+uFEt+/70=; b=rxhlvo0yhtMTN4vjpzGEqT0CP7lCCydnJhS/ZxBBiuCeP/iWkqJUDVeaSmEfN8MgJu K4BxS/QwxgYeE2SrR/tHuyPkK/cy7AHMnZpnoQwkVBMYNRhgIo70LiGsLlYXR/LnshPe hDOuD0cjYPG44wOEgsT/jVLaekwGPfH6JSLDlww030EJdnYOnCdC+/o31u9trtrM114L E+J6LD2RCxLhOoiU8WT6y/cmwigaxcKH36K7pxBk7ZSeEQ1W43XzufvwDcW4xNqY+mQd exxwCU9+AVBvfwNUNqOGrjrshRiJTnn6ECxQbUDxAjUz3L10WkPC3fIZEvP+/U7ZsrHn BrLQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AKZxglh3; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id r23-20020ae9d617000000b0070652e85653si7200139qkk.569.2023.04.10.02.06.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:06:57 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AKZxglh3; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 34A9F82160; Mon, 10 Apr 2023 11:06:47 +0200 (CEST) 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="AKZxglh3"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D52DC850DB; Mon, 10 Apr 2023 11:06:36 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) (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 5A66F82160 for ; Mon, 10 Apr 2023 11:06:33 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pl1-x635.google.com with SMTP id o2so4152914plg.4 for ; Mon, 10 Apr 2023 02:06:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1681117591; x=1683709591; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=nYK+0kicbkNfPxAK91H5Y4Ki7NxoPhVLEX+uFEt+/70=; b=AKZxglh3J3O8Ceh+WrofvsAUaMkVTZCs+VnTRfynI2yH0hvbOVTCtWiHAgFk5IZ8u5 yRCAmmiNrxvgM4KvfC0IvFnbHMuDl6VY+lEpS6KhZIqgzNplNGMNCotod3IUsl31bRJU B6A7X9vBQJ6fbXigRgf/ks2+U+61wsCTOvBHwtbIWkB/Iof4GAl16ztRTI6ibl3whhOS r7+oOf+hbzvdbngO1OujLnlsgUmUr4SAyA8yWagOUYrIGQSBY0KslSKa1mDrjZDBArDz 9GSD3hYgnj+vQPHxAG1ZtQYOvn/II5SI224RDWZWdxKe08Wal+rhrzO3vt2kZMKmjnno ifxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681117591; x=1683709591; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nYK+0kicbkNfPxAK91H5Y4Ki7NxoPhVLEX+uFEt+/70=; b=l/AfCdwUU73x/dyfA32qvd0qqDgQNrkP6IgkFUZ8wHmVAWfPN/KlKmnr/YH9Oy5nY3 ECiNZplhe5p+pSselYMqzGht5x3SkmpOJgfbQXT3PH35PZwfx/pk68t7SiH4ItW3NK1C wljLGmp4VBt86dbQS+29dTG+jzaKy8zz7tLeuP5RNN2pHLP0f12rqBZ9TsH1vz7EXcUR 4oPh4GF6cVrL8aGT9+fP3FOXuKXrs6/AZ4VGp58zBtb+qfkiq5hR3iH1P5h6FM4K4UtF o+HXXEzCNwSOy24aodzu8vY6LvGlJ/AwOnp1amtr4ZmAgHNMXmF/McSC6Jam79OE5/cZ ShYw== X-Gm-Message-State: AAQBX9cECuZj9SKyUiXy/U4wit+adzzdU1IL/94OcxMDx86bBKbyUCTb y2mSz2Te2+fz+UUNmDn+Ls73LSuY42KWhAyjLUM= X-Received: by 2002:a17:90b:1bd1:b0:23c:fef0:d441 with SMTP id oa17-20020a17090b1bd100b0023cfef0d441mr12578430pjb.33.1681117591447; Mon, 10 Apr 2023 02:06:31 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0023f8bdc4a7fsm7189279pji.14.2023.04.10.02.06.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:06:30 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v5 2/4] efi_loader: check lowest supported version Date: Mon, 10 Apr 2023 18:07:30 +0900 Message-Id: <20230410090732.1676-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230410090732.1676-1-masahisa.kojima@linaro.org> References: <20230410090732.1676-1-masahisa.kojima@linaro.org> 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.8 at phobos.denx.de X-Virus-Status: Clean The FMP Payload Header which EDK II capsule generation scripts insert has a firmware version. This commit reads the lowest supported version stored in the device tree, then check if the firmware version in FMP payload header of the ongoing capsule is equal or greater than the lowest supported version. If the firmware version is lower than lowest supported version, capsule update fails. Signed-off-by: Masahisa Kojima --- Changes in v5: - newly implement the device tree based versioning Changes in v4: - use log_err() instead of printf() Changes in v2: - add error message when the firmware version is lower than lowest supported version lib/efi_loader/efi_firmware.c | 124 ++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 21 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 1c6ef468bf..c88c1bb364 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -33,7 +33,7 @@ struct fmp_payload_header { u32 signature; u32 header_size; u32 fw_version; - u32 lowest_supported_version; + u32 lowest_supported_version; /* not used */ }; __weak void set_dfu_alt_info(char *interface, char *devstr) @@ -250,8 +250,6 @@ efi_status_t efi_firmware_capsule_authenticate(const void **p_image, { const void *image = *p_image; efi_uintn_t image_size = *p_image_size; - u32 fmp_hdr_signature; - struct fmp_payload_header *header; void *capsule_payload; efi_status_t status; efi_uintn_t capsule_payload_size; @@ -264,7 +262,7 @@ efi_status_t efi_firmware_capsule_authenticate(const void **p_image, &capsule_payload_size); if (status == EFI_SECURITY_VIOLATION) { - printf("Capsule authentication check failed. Aborting update\n"); + log_err("Capsule authentication check failed. Aborting update\n"); return status; } else if (status != EFI_SUCCESS) { return status; @@ -278,21 +276,6 @@ efi_status_t efi_firmware_capsule_authenticate(const void **p_image, debug("Updating capsule without authenticating.\n"); } - fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE; - header = (void *)image; - - if (!memcmp(&header->signature, &fmp_hdr_signature, - sizeof(fmp_hdr_signature))) { - /* - * When building the capsule with the scripts in - * edk2, a FMP header is inserted above the capsule - * payload. Compensate for this header to get the - * actual payload that is to be updated. - */ - image += header->header_size; - image_size -= header->header_size; - } - *p_image = image; *p_image_size = image_size; return EFI_SUCCESS; @@ -349,6 +332,105 @@ efi_status_t EFIAPI efi_firmware_get_image_info( return EFI_EXIT(ret); } +/** + * efi_firmware_get_image_type_id - get image_type_id + * @image_index: image index + * + * Return the image_type_id identified by the image index. + * + * Return: pointer to the image_type_id, NULL if image_index is invalid + */ +static +efi_guid_t *efi_firmware_get_image_type_id(u8 image_index) +{ + int i; + struct efi_fw_image *fw_array; + + fw_array = update_info.images; + for (i = 0; i < num_image_type_guids; i++) { + if (fw_array[i].image_index == image_index) + return &fw_array[i].image_type_id; + } + + return NULL; +} + +/** + * efi_firmware_check_lowest_supported_version - check the lowest supported version + * @p_image: Pointer to new image + * @p_image_size: Pointer to size of new image + * @image_index: image_index + * + * Check the fw_version in FMP payload header is equal to or greather than the + * lowest_supported_version stored in the device tree + * + * Return: status code + */ +static +efi_status_t efi_firmware_check_lowest_supported_version(const void **p_image, + efi_uintn_t *p_image_size, + u8 image_index) +{ + const void *image = *p_image; + efi_uintn_t image_size = *p_image_size; + const struct fmp_payload_header *header; + u32 fmp_hdr_signature = FMP_PAYLOAD_HDR_SIGNATURE; + + /* FMP header is inserted above the capsule payload */ + header = image; + if (header->signature == fmp_hdr_signature) { + efi_guid_t *image_type_id; + u32 version = 0, lsv = 0; + + image_type_id = efi_firmware_get_image_type_id(image_index); + if (!image_type_id) + return EFI_INVALID_PARAMETER; + + efi_firmware_get_firmware_version(image_index, image_type_id, + &version, &lsv); + + if (header->fw_version >= lsv) { + image += header->header_size; + image_size -= header->header_size; + } else { + log_err("Firmware version %u too low. Expecting >= %u. Aborting update\n", + header->fw_version, lsv); + return EFI_INCOMPATIBLE_VERSION; + } + } + + *p_image = image; + *p_image_size = image_size; + + return EFI_SUCCESS; +} + +/** + * efi_firmware_verify_image - verify image + * @p_image: Pointer to new image + * @p_image_size: Pointer to size of new image + * @image_index Image index + * + * Verify the capsule file + * + * Return: status code + */ +static +efi_status_t efi_firmware_verify_image(const void **p_image, + efi_uintn_t *p_image_size, + u8 image_index) +{ + efi_status_t ret; + + ret = efi_firmware_capsule_authenticate(p_image, p_image_size); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_firmware_check_lowest_supported_version(p_image, p_image_size, image_index); + + return ret; +} + #ifdef CONFIG_EFI_CAPSULE_FIRMWARE_FIT /* * This FIRMWARE_MANAGEMENT_PROTOCOL driver provides a firmware update @@ -393,7 +475,7 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( if (!image || image_index != 1) return EFI_EXIT(EFI_INVALID_PARAMETER); - status = efi_firmware_capsule_authenticate(&image, &image_size); + status = efi_firmware_verify_image(&image, &image_size, image_index); if (status != EFI_SUCCESS) return EFI_EXIT(status); @@ -454,7 +536,7 @@ efi_status_t EFIAPI efi_firmware_raw_set_image( if (!image) return EFI_EXIT(EFI_INVALID_PARAMETER); - status = efi_firmware_capsule_authenticate(&image, &image_size); + status = efi_firmware_verify_image(&image, &image_size, image_index); if (status != EFI_SUCCESS) return EFI_EXIT(status); From patchwork Mon Apr 10 09:07:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 672030 Delivered-To: patch@linaro.org Received: by 2002:a05:6000:184:0:0:0:0 with SMTP id p4csp151488wrx; Mon, 10 Apr 2023 02:07:21 -0700 (PDT) X-Google-Smtp-Source: AKy350ahgjMjYaoRC8VO+eom9xNDIJOJInb8xmfAxyTdj+oDr4zcYqqv+CBTOugZSdUmeT8pbgkE X-Received: by 2002:ac8:578b:0:b0:3e4:db72:2fe9 with SMTP id v11-20020ac8578b000000b003e4db722fe9mr15717582qta.36.1681117641734; Mon, 10 Apr 2023 02:07:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681117641; cv=none; d=google.com; s=arc-20160816; b=dkF+A5lsaQDv6c+ltmwpX4F7XurxTsR2kqopXv3vFpkCFylicJ0nWmYJyv7KiRPdlC PMyMuXkpI/K9X4guHVwb6AsEdUQ7BW4Q7zp5wAg4JkwrvYyk2ru9Vx5fRvsBCzQxlqW6 ZB65sw45mW340HscPpxy2rEv5thxB1HfzlCXXkV7jTLqQRoEiJw8Xr5XDF86DjXuUDM0 lh0q7TpoVwTDEPb2kTf6jivN7vu5HrlyZW4pm3NmGj+HeqCek8mmhGV9L/RkqzQ/O8wL 2x9uadjCmCtYgjyUY973wk8H33ShVtAK0ZPsnvsPJzP4pU0iEMVm8przk33vJa4qAp02 LWhQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=laqvbMIFVHCxf0D+6WhzWnSYDCqK3CrK04IQP/TDYVw=; b=IsaDQjZUlFXthy3Zf1zb4rKBJf85CgBIqBt0ESchAQGk8hrasV0qOIyGTD5RfirbxL TyHK5U+cxlDndRI3jze9SbZ+U897nlho8Ir/IQISsTDCqPjsMrZ0ROZ84yA1FzfTOi2e r7zSvbicEhMMI4sZqWozXNJ07YpEnOonBRdsVwicemE928ILtn5yppndymWeg5H3+KWS EjUVsR7TDp79naJaGnoIoS4e8obET56gBbSBIULqJv/N2b8uH6if4jP5dCbCpqHv+NsS PgVAtd2a6kOYoeYoPyG6QBiytPF29DrRCI0huXB32si7Tuzkv6JwfSek1n8WT1IaJRxv HEPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wAMyYUXN; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id h2-20020a05620a244200b0074680b0320esi7368652qkn.520.2023.04.10.02.07.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:07:21 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=wAMyYUXN; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BB97785798; Mon, 10 Apr 2023 11:06:56 +0200 (CEST) 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="wAMyYUXN"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B095880B9E; Mon, 10 Apr 2023 11:06:44 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) (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 44C8B850CF for ; Mon, 10 Apr 2023 11:06:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pj1-x1036.google.com with SMTP id 60-20020a17090a09c200b0023fcc8ce113so6672032pjo.4 for ; Mon, 10 Apr 2023 02:06:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1681117594; x=1683709594; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=laqvbMIFVHCxf0D+6WhzWnSYDCqK3CrK04IQP/TDYVw=; b=wAMyYUXN+FiFjEWRke456ycwYTMDfdgwlIthbVDXKo59EMxckeSuvKKgA691xfKVBS NTdR1LQTWf6wA0me3K1O1AmudVPxVffd2JQbg/I0BB/juWX43Qr92OTDtOlFxLFNEue6 qQAkU48aGCfSzaIvVQpmNM0xFK/WXragmg8+cjXinAmoEoV+1VXpKe2nlY3AQJP+/aeD VQV0oJTyYd9sVHXyUqBuAp7zIwlpAje3g7Xlnn/vxbd1TXmkFmBeqsldkkSBerdBNZ70 a2CthJHeicx2R7vnBZpg4cu15bMPyViw3py3fofuCPl9xX98Yh93AtEtoKT9rJD8QJ6r 1J3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681117594; x=1683709594; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=laqvbMIFVHCxf0D+6WhzWnSYDCqK3CrK04IQP/TDYVw=; b=FffuB7+SVOBncSvG/pNfPbitjYN/9Ti/SaPJOBVZ4NbFtiCRO1jOymATlyJAoIH35C Q498Q+9rGteMrVKjK07SdQ4ogXOYaTWIEXY8eKdnEDw6zdYF/wzXy9mE72Be6iCcN7Gy e3vcrsIqmM2F5BrGMkNKKtvKA8ddL5/IRLn1Z4ApAbIT6mvxn80huIi1SIMgE980Rtx5 52+RmPaFs/mxEP6Qs6blbxq9k6EYcBvXQQ8WgwNoIqWMjP//vvsnlrGH3yqL0YrR09j9 hqt02UEpr2SRssz5c/wzQ4aG50xOp0DciEvOU9qPAS6LrVA0pFjmBXJrwLw4pUiMos9W JO9A== X-Gm-Message-State: AAQBX9dxywQeI9q8bnrRtzDFx6oLM226fiBcl+7AkRAYa8qtMdxixRWT Pn4RFBfM9948T6kvd1OttYM4aq0JEHU4c0548zo= X-Received: by 2002:a17:90b:4b90:b0:246:9f27:fa6b with SMTP id lr16-20020a17090b4b9000b002469f27fa6bmr4330696pjb.37.1681117594419; Mon, 10 Apr 2023 02:06:34 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0023f8bdc4a7fsm7189279pji.14.2023.04.10.02.06.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:06:33 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima , Sughosh Ganu , Etienne Carriere Subject: [PATCH v5 3/4] mkeficapsule: add FMP Payload Header Date: Mon, 10 Apr 2023 18:07:31 +0900 Message-Id: <20230410090732.1676-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230410090732.1676-1-masahisa.kojima@linaro.org> References: <20230410090732.1676-1-masahisa.kojima@linaro.org> 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.8 at phobos.denx.de X-Virus-Status: Clean Current mkeficapsule tool does not provide firmware version management. EDK II reference implementation inserts the FMP Payload Header right before the payload. It coutains the fw_version and lowest supported version. This commit adds a new parameters required to generate the FMP Payload Header for mkeficapsule tool. '-v' indicates the firmware version. When mkeficapsule tool is invoked without '-v' option, FMP Payload Header is not inserted, the behavior is same as current implementation. The lowest supported version included in the FMP Payload Header is not used in the current versioning support, the value stored in the device tree is used. Signed-off-by: Masahisa Kojima --- Changes in v5: - remove --lsv since we use the lowest_supported_version in the dtb Changes in v3: - remove '-f' option - move some definitions into tools/eficapsule.h - add dependency check of fw_version and lowest_supported_version - remove unexpected modification of existing fprintf() call - add documentation Newly created in v2 doc/mkeficapsule.1 | 10 ++++++++++ tools/eficapsule.h | 30 ++++++++++++++++++++++++++++++ tools/mkeficapsule.c | 37 +++++++++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index 1ca245a10f..c4c2057d5c 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -61,6 +61,16 @@ Specify an image index .BI "-I\fR,\fB --instance " instance Specify a hardware instance +.PP +FMP Payload Header is inserted right before the payload if +.BR --fw-version +is specified + + +.TP +.BI "-v\fR,\fB --fw-version " firmware-version +Specify a firmware version, 0 if omitted + .PP For generation of firmware accept empty capsule .BR --guid diff --git a/tools/eficapsule.h b/tools/eficapsule.h index 072a4b5598..753fb73313 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -113,4 +113,34 @@ struct efi_firmware_image_authentication { struct win_certificate_uefi_guid auth_info; } __packed; +/* fmp payload header */ +#define SIGNATURE_16(A, B) ((A) | ((B) << 8)) +#define SIGNATURE_32(A, B, C, D) \ + (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) + +#define FMP_PAYLOAD_HDR_SIGNATURE SIGNATURE_32('M', 'S', 'S', '1') + +/** + * struct fmp_payload_header - EDK2 header for the FMP payload + * + * This structure describes the header which is preprended to the + * FMP payload by the edk2 capsule generation scripts. + * + * @signature: Header signature used to identify the header + * @header_size: Size of the structure + * @fw_version: Firmware versions used + * @lowest_supported_version: Lowest supported version (not used) + */ +struct fmp_payload_header { + uint32_t signature; + uint32_t header_size; + uint32_t fw_version; + uint32_t lowest_supported_version; +}; + +struct fmp_payload_header_params { + bool have_header; + uint32_t fw_version; +}; + #endif /* _EFI_CAPSULE_H */ diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index b71537beee..52be1f122e 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -41,6 +41,7 @@ static struct option options[] = { {"guid", required_argument, NULL, 'g'}, {"index", required_argument, NULL, 'i'}, {"instance", required_argument, NULL, 'I'}, + {"fw-version", required_argument, NULL, 'v'}, {"private-key", required_argument, NULL, 'p'}, {"certificate", required_argument, NULL, 'c'}, {"monotonic-count", required_argument, NULL, 'm'}, @@ -60,6 +61,7 @@ static void print_usage(void) "\t-g, --guid guid for image blob type\n" "\t-i, --index update image index\n" "\t-I, --instance update hardware instance\n" + "\t-v, --fw-version firmware version\n" "\t-p, --private-key private key file\n" "\t-c, --certificate signer's certificate file\n" "\t-m, --monotonic-count monotonic count\n" @@ -402,6 +404,7 @@ static void free_sig_data(struct auth_context *ctx) */ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, unsigned long index, unsigned long instance, + struct fmp_payload_header_params *fmp_ph_params, uint64_t mcount, char *privkey_file, char *cert_file, uint16_t oemflags) { @@ -410,10 +413,11 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, struct efi_firmware_management_capsule_image_header image; struct auth_context auth_context; FILE *f; - uint8_t *data; + uint8_t *data, *new_data, *buf; off_t bin_size; uint64_t offset; int ret; + struct fmp_payload_header payload_header; #ifdef DEBUG fprintf(stderr, "For output: %s\n", path); @@ -423,6 +427,7 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, auth_context.sig_size = 0; f = NULL; data = NULL; + new_data = NULL; ret = -1; /* @@ -431,12 +436,30 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, if (read_bin_file(bin, &data, &bin_size)) goto err; + buf = data; + + /* insert fmp payload header right before the payload */ + if (fmp_ph_params->have_header) { + new_data = malloc(bin_size + sizeof(payload_header)); + if (!new_data) + goto err; + + payload_header.signature = FMP_PAYLOAD_HDR_SIGNATURE; + payload_header.header_size = sizeof(payload_header); + payload_header.fw_version = fmp_ph_params->fw_version; + payload_header.lowest_supported_version = 0; /* not used */ + memcpy(new_data, &payload_header, sizeof(payload_header)); + memcpy(new_data + sizeof(payload_header), data, bin_size); + buf = new_data; + bin_size += sizeof(payload_header); + } + /* 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_data = buf; auth_context.image_size = bin_size; if (create_auth_data(&auth_context)) { @@ -536,7 +559,7 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid, /* * firmware binary */ - if (write_capsule_file(f, data, bin_size, "Firmware binary")) + if (write_capsule_file(f, buf, bin_size, "Firmware binary")) goto err; ret = 0; @@ -545,6 +568,7 @@ err: fclose(f); free_sig_data(&auth_context); free(data); + free(new_data); return ret; } @@ -644,6 +668,7 @@ int main(int argc, char **argv) unsigned long oemflags; char *privkey_file, *cert_file; int c, idx; + struct fmp_payload_header_params fmp_ph_params = { 0 }; guid = NULL; index = 0; @@ -679,6 +704,10 @@ int main(int argc, char **argv) case 'I': instance = strtoul(optarg, NULL, 0); break; + case 'v': + fmp_ph_params.fw_version = strtoul(optarg, NULL, 0); + fmp_ph_params.have_header = true; + break; case 'p': if (privkey_file) { fprintf(stderr, @@ -751,7 +780,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } } else if (create_fwbin(argv[argc - 1], argv[argc - 2], guid, - index, instance, mcount, privkey_file, + index, instance, &fmp_ph_params, mcount, privkey_file, cert_file, (uint16_t)oemflags) < 0) { fprintf(stderr, "Creating firmware capsule failed\n"); exit(EXIT_FAILURE); From patchwork Mon Apr 10 09:07:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 672031 Delivered-To: patch@linaro.org Received: by 2002:a05:6000:184:0:0:0:0 with SMTP id p4csp151551wrx; Mon, 10 Apr 2023 02:07:34 -0700 (PDT) X-Google-Smtp-Source: AKy350YB/U1LSXsALok+5/dl/P4wxD34pcAlTOl25toW8EbNKOdnyHe8fl+37Y9cNRPW6g0A1RjR X-Received: by 2002:a05:6214:21c1:b0:5cc:277c:b5e with SMTP id d1-20020a05621421c100b005cc277c0b5emr18588492qvh.33.1681117654577; Mon, 10 Apr 2023 02:07:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681117654; cv=none; d=google.com; s=arc-20160816; b=ng9CkA48LNc0ohH6l6uGLXgwIyNpSrSw076plbApKdyazZNy8ZaaBzwczebaEtTBuP tZqBJmJMWLi2UuhJBbpIaN8sM91jx3d7Lr9/DR0ejN7GXke5IFFHUoBRfDPEctYTzgtn RtSMgGh8uRRzJOIeHoRHkgwh8eS7RsG1SMA0R9Cvo7zwUH/RjD4uznNAmchXMVu8Y8dM g8/LNJEQGrA0npf+taLYJp1ZkQYhIKN/ozWT2RmFS/pStcHFWJen9dlgwfRUwGAf0ajw c6YYCtj3wUaV3YbhotACWh1T+VEZ0iH1SLM8OH6wB6Cgd6MLTQBhDqpRfR3nv9251BSU Y54w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=gpSS4+QOlwJDqjcaFMQualiJiWhx/jEqsh9sxiW1Jjw=; b=c7IoO0nX1ceyck2hK5FNWuA9CT3iQQ34u4MSYSkYIN2pz+EnaXCaFfFEhn3pFtX3Ma vELzu/RxtqvsMrHfqCH2CVmm+ZX3xR5qkiQU2Ujhf7gNl2/cx4DjNgzHEBSYs1F6aDbo +eS8lMBlOSpeYx+JuhuMg52afjcDbUF2iEUPVGXdB21Ht5HmBdCMi+mj50uhid50wWXH Q+2WOgG2blIAldjvuGOsi4mJywdTLStoJUDHluPpHIYvsStyWJbYWvjN4yDwi9rv5hq0 NEQPPtuqOrLdIVhlrYaS15u+Hzw9Iccl/OsljMISjzzSxI2pp2TnQtjIRe6l3dXc9vtm VyPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MNWzko6P; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id e6-20020a05622a110600b003dc38b8676fsi7348787qty.168.2023.04.10.02.07.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:07:34 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MNWzko6P; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C524385816; Mon, 10 Apr 2023 11:07:02 +0200 (CEST) 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="MNWzko6P"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 325E0855D9; Mon, 10 Apr 2023 11:06:49 +0200 (CEST) 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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) (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 32AE8854CF for ; Mon, 10 Apr 2023 11:06:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-pj1-x1032.google.com with SMTP id nh20-20020a17090b365400b0024496d637e1so9302390pjb.5 for ; Mon, 10 Apr 2023 02:06:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1681117597; x=1683709597; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=gpSS4+QOlwJDqjcaFMQualiJiWhx/jEqsh9sxiW1Jjw=; b=MNWzko6PInjDv8bnjN+2vRPSIHb8txGkAIuI7mMhp44Id830LmNtvubcHZud3gq6/p OpMSQPQzflZNkWtXCMklX96CGqr72DeYHKUOns3EOUps4x2rEITnq9DK/jOX4btApPWi WC9ynFu/t6SS2hJb4vJn1acRQx5Ozutf3mYd6+DVTCCehefPnHNv5Tiuxyz3LQCP/7kb Q312WZ/+8/jdoPPzHDZEX4ED8JRdy7XYT/brWC+bT/LvUSdRHkDBo4piujrR8w+brHRM jPtYijTEaTX9/V4V8nzymP+lKWSfLK+k1KMuvcQdEc7gfjo6PQSMaHZVILSvnkcgkKpU a+vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1681117597; x=1683709597; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gpSS4+QOlwJDqjcaFMQualiJiWhx/jEqsh9sxiW1Jjw=; b=K+jsswqjg7cCVCh7DS6+DRR25vhsaBHN8lYZMl+PktbxRiILj2AgJ9N/wxKYrcnOxX 2dDHdrvoXWOTn/DIx3ixBvhsRzdB0ZrSV13VZxuSIj18eWyLNbHc/3OPBAd7Avs5Dr/J mPAM9QUQKM6gj+55atcvyX0IiXXKSxOp0rBniLXuavzEjLfQPqivkwhW8scepcaqiod5 EALUXDKAOzP4fBgg3NTHtlMIXC5LbGn5drLVC6tUub9Nq0DLsXZvetOmYp9pptO3ekd6 mDJJ9y86n0T+iunz6h7dxWQMwAmYpKKMPP7oVYMdxrPoUKXzK2bdnYh3iXQY1U26eCpO +h8w== X-Gm-Message-State: AAQBX9fw1TVejaCM78FfUzC7Ha1xXZ0Dirs2+VvJtW1sUapYuStriTyC iawC9ii85vYgDg4TLb8F5nY2z/+6a5lLnmKWzjM= X-Received: by 2002:a17:90b:390d:b0:240:b3ae:d890 with SMTP id ob13-20020a17090b390d00b00240b3aed890mr13133976pjb.19.1681117597028; Mon, 10 Apr 2023 02:06:37 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id s15-20020a17090a5d0f00b0023f8bdc4a7fsm7189279pji.14.2023.04.10.02.06.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Apr 2023 02:06:36 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v5 4/4] test/py: efi_capsule: test for FMP versioning Date: Mon, 10 Apr 2023 18:07:32 +0900 Message-Id: <20230410090732.1676-5-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230410090732.1676-1-masahisa.kojima@linaro.org> References: <20230410090732.1676-1-masahisa.kojima@linaro.org> 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.8 at phobos.denx.de X-Virus-Status: Clean This test covers FMP versioning for both raw and FIT image, and both signed and non-signed capsule update. Signed-off-by: Masahisa Kojima --- Changes in v5: - get aligned to the device tree based versioning Newly created in v4 test/py/tests/test_efi_capsule/conftest.py | 73 +++++++ .../test_capsule_firmware_fit.py | 187 ++++++++++++++++ .../test_capsule_firmware_raw.py | 201 ++++++++++++++++++ .../test_capsule_firmware_signed_fit.py | 165 ++++++++++++++ .../test_capsule_firmware_signed_raw.py | 169 +++++++++++++++ test/py/tests/test_efi_capsule/version.dts | 27 +++ 6 files changed, 822 insertions(+) create mode 100644 test/py/tests/test_efi_capsule/version.dts diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index 4879f2b5c2..9655e5ec1f 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -70,6 +70,23 @@ def efi_capsule_data(request, u_boot_config): '-out SIGNER2.crt -nodes -days 365' % data_dir, shell=True) + # Update dtb adding version information + check_call('cd %s; ' + 'cp %s/test/py/tests/test_efi_capsule/version.dts .' + % (data_dir, u_boot_config.source_dir), shell=True) + if capsule_auth_enabled: + check_call('cd %s; ' + 'dtc -@ -I dts -O dtb -o version.dtbo version.dts; ' + 'fdtoverlay -i test_sig.dtb ' + '-o test_ver.dtb version.dtbo' + % (data_dir), shell=True) + else: + check_call('cd %s; ' + 'dtc -@ -I dts -O dtb -o version.dtbo version.dts; ' + 'fdtoverlay -i %s/arch/sandbox/dts/test.dtb ' + '-o test_ver.dtb version.dtbo' + % (data_dir, u_boot_config.build_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, @@ -95,6 +112,26 @@ def efi_capsule_data(request, u_boot_config): check_call('cd %s; %s/tools/mkeficapsule --index 1 --guid 058B7D83-50D5-4C47-A195-60D86AD341C4 uboot_bin_env.itb Test05' % (data_dir, u_boot_config.build_dir), shell=True) + check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 ' + '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test101' % + (data_dir, u_boot_config.build_dir), + shell=True) + check_call('cd %s; %s/tools/mkeficapsule --index 2 --fw-version 10 ' + '--guid 5A7021F5-FEF2-48B4-AABA-832E777418C0 u-boot.env.new Test102' % + (data_dir, u_boot_config.build_dir), + shell=True) + check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 ' + '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 u-boot.bin.new Test103' % + (data_dir, u_boot_config.build_dir), + shell=True) + check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 5 ' + '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test104' % + (data_dir, u_boot_config.build_dir), + shell=True) + check_call('cd %s; %s/tools/mkeficapsule --index 1 --fw-version 2 ' + '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 uboot_bin_env.itb Test105' % + (data_dir, u_boot_config.build_dir), + shell=True) if capsule_auth_enabled: # raw firmware signed with proper key @@ -131,6 +168,42 @@ def efi_capsule_data(request, u_boot_config): 'uboot_bin_env.itb Test14' % (data_dir, u_boot_config.build_dir), shell=True) + # raw firmware signed with proper key with version information + check_call('cd %s; ' + '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' + '--fw-version 5 ' + '--private-key SIGNER.key --certificate SIGNER.crt ' + '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 ' + 'u-boot.bin.new Test111' + % (data_dir, u_boot_config.build_dir), + shell=True) + # raw firmware signed with *mal* key with version information + check_call('cd %s; ' + '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' + '--fw-version 2 ' + '--private-key SIGNER.key --certificate SIGNER.crt ' + '--guid 09D7CF52-0720-4710-91D1-08469B7FE9C8 ' + 'u-boot.bin.new Test112' + % (data_dir, u_boot_config.build_dir), + shell=True) + # FIT firmware signed with proper key with version information + check_call('cd %s; ' + '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' + '--fw-version 5 ' + '--private-key SIGNER.key --certificate SIGNER.crt ' + '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 ' + 'uboot_bin_env.itb Test113' + % (data_dir, u_boot_config.build_dir), + shell=True) + # FIT firmware signed with *mal* key with version information + check_call('cd %s; ' + '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' + '--fw-version 2 ' + '--private-key SIGNER.key --certificate SIGNER.crt ' + '--guid 3673B45D-6A7C-46F3-9E60-ADABB03F7937 ' + 'uboot_bin_env.itb Test114' + % (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/test_capsule_firmware_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py index d28b53a1a1..e774a06d10 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py @@ -189,3 +189,190 @@ class TestEfiCapsuleFirmwareFit(object): 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): + """ + Test Case 3 - Update U-Boot and U-Boot environment on SPI Flash with version information + 0x100000-0x150000: U-Boot binary (but dummy) + 0x150000-0x200000: U-Boot environment (but dummy) + """ + 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, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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 contents + 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) + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 150000 10', + 'sf read 5000000 150000 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/Test104' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test104 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test104' in ''.join(output) + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_ver.dtb' + u_boot_console.restart_uboot(expect_reset = capsule_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 'Test104' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test104' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + 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']) + if capsule_auth: + assert 'u-boot-env:Old' in ''.join(output) + else: + assert 'u-boot-env:New' in ''.join(output) + + def test_efi_capsule_fw4( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 4 - Update U-Boot and U-Boot environment on SPI Flash with version information + but fw_version is lower than lowest_supported_version + No update should happen + 0x100000-0x150000: U-Boot binary (but dummy) + 0x150000-0x200000: U-Boot environment (but dummy) + """ + 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, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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 contents + 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) + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 150000 10', + 'sf read 5000000 150000 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/Test105' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test105 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test105' in ''.join(output) + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_ver.dtb' + u_boot_console.restart_uboot(expect_reset = capsule_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 'Test105' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test105' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output) + + # make sure capsule update failed + 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) + + output = u_boot_console.run_command_list([ + 'sf read 4000000 150000 10', + 'md.b 4000000 10']) + assert 'u-boot-env:Old' in ''.join(output) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py index 92bfb14932..bd6419bcc3 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py @@ -292,3 +292,204 @@ class TestEfiCapsuleFirmwareRaw: assert 'u-boot-env:Old' in ''.join(output) else: assert 'u-boot-env:New' in ''.join(output) + + def test_efi_capsule_fw4( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ Test Case 4 + Update U-Boot on SPI Flash, raw image format with fw_version and lowest_supported_version + 0x100000-0x150000: U-Boot binary (but dummy) + 0x150000-0x200000: U-Boot environment (but dummy) + """ + 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, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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 contents + 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) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'fatload host 0:1 4000000 %s/u-boot.env.old' % CAPSULE_DATA_DIR, + 'sf write 4000000 150000 10', + 'sf read 5000000 150000 10', + 'md.b 5000000 10']) + assert 'Old' in ''.join(output) + + # place the capsule files + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test101' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test101 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test101' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test102' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test102 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test102' in ''.join(output) + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_ver.dtb' + u_boot_console.restart_uboot(expect_reset = capsule_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 'Test101' in ''.join(output) + assert 'Test102' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test101' not in ''.join(output) + assert 'Test102' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + + # ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. + assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output) + + # ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT. + assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output) + assert 'ESRT: fw_version=10' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output) + + output = u_boot_console.run_command_list([ + 'sf probe 0:0', + 'sf read 4000000 100000 10', + 'md.b 4000000 10']) + 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 probe 0:0', + 'sf read 4000000 150000 10', + 'md.b 4000000 10']) + + if capsule_auth: + assert 'u-boot-env:Old' in ''.join(output) + else: + assert 'u-boot-env:New' in ''.join(output) + + def test_efi_capsule_fw5( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ Test Case 5 + Update U-Boot on SPI Flash, raw image format with fw_version and lowest_supported_version + but fw_version is lower than lowest_supported_version + No update should happen + 0x100000-0x150000: U-Boot binary (but dummy) + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 5-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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 contents + 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 the capsule files + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 %s/Test103' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test103 $filesize' % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test103' in ''.join(output) + + capsule_early = u_boot_config.buildconfig.get( + 'config_efi_capsule_on_disk_early') + capsule_auth = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') + + # reboot + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_capsule' + u_boot_console.config.dtb = mnt_point + CAPSULE_DATA_DIR \ + + '/test_ver.dtb' + u_boot_console.restart_uboot(expect_reset = capsule_early) + + with u_boot_console.log.section('Test Case 5-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 'Test103' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test103' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + + # ensure that SANDBOX_UBOOT_IMAGE_GUID is in the ESRT. + assert '09D7CF52-0720-4710-91D1-08469B7FE9C8' in ''.join(output) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output) + + # ensure that SANDBOX_UBOOT_ENV_IMAGE_GUID is in the ESRT. + assert '5A7021F5-FEF2-48B4-AABA-832E777418C0' in ''.join(output) + assert 'ESRT: fw_version=10' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=7' in ''.join(output) + + # make sure capsule update failed + 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) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py index 8c2d616fd0..4696ad962a 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py @@ -257,3 +257,168 @@ class TestEfiCapsuleFirmwareSignedFit(object): 'sf read 4000000 100000 10', 'md.b 4000000 10']) assert 'u-boot:Old' in ''.join(output) + + def test_efi_capsule_auth4( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 4 - Update U-Boot on SPI Flash, FIT image format + 0x100000-0x150000: U-Boot binary (but dummy) + + If the capsule is properly signed with version information, + the authentication should pass and the firmware be updated. + """ + 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, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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/Test113' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test113 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test113' 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_ver.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 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 'Test113' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test113' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' 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_auth5( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 5 - Update U-Boot on SPI Flash, FIT image format + 0x100000-0x150000: U-Boot binary (but dummy) + + If the capsule is signed but fw_version is lower than lowest + supported version, the authentication should fail and the firmware + not be updated. + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 5-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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/Test114' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test114 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test114' 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_ver.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 5-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 'Test114' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test114' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' 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:Old' in ''.join(output) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py index 2bbaa9cc55..98ce9c9afd 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py @@ -254,3 +254,172 @@ class TestEfiCapsuleFirmwareSignedRaw(object): 'sf read 4000000 100000 10', 'md.b 4000000 10']) assert 'u-boot:Old' in ''.join(output) + + def test_efi_capsule_auth4( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 4 - Update U-Boot on SPI Flash, raw image format with version information + 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 4-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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']) + + + output = u_boot_console.run_command('efidebug capsule esrt') + + + + # 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/Test111' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test111 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test111' 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_ver.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 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 'Test111' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test111' 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) + + 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"', + 'efidebug capsule esrt']) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' in ''.join(output) + + def test_efi_capsule_auth5( + self, u_boot_config, u_boot_console, efi_capsule_data): + """ + Test Case 5 - Update U-Boot on SPI Flash, raw image format with version information + 0x100000-0x150000: U-Boot binary (but dummy) + + If the capsule is signed but fw_version is lower than lowest + supported version, the authentication should fail and the firmware + not be updated. + """ + disk_img = efi_capsule_data + with u_boot_console.log.section('Test Case 5-a, before reboot'): + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'printenv -e PlatformLangCodes', # workaround for terminal size determination + '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/Test112' % CAPSULE_DATA_DIR, + 'fatwrite host 0:1 4000000 %s/Test112 $filesize' + % CAPSULE_INSTALL_DIR, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test112' 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_ver.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 5-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 'Test112' in ''.join(output) + + # need to run uefi command to initiate capsule handling + output = u_boot_console.run_command( + 'env print -e Capsule0000', wait_for_reboot = True) + + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR]) + assert 'Test112' not in ''.join(output) + + # make sure the dfu_alt_info exists because it is required for making ESRT. + 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"', + 'efidebug capsule esrt']) + assert 'ESRT: fw_version=5' in ''.join(output) + assert 'ESRT: lowest_supported_fw_version=3' 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:Old' in ''.join(output) diff --git a/test/py/tests/test_efi_capsule/version.dts b/test/py/tests/test_efi_capsule/version.dts new file mode 100644 index 0000000000..0e544524e3 --- /dev/null +++ b/test/py/tests/test_efi_capsule/version.dts @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; +/plugin/; + +&{/} { + firmware-version { + image1 { + lowest-supported-version = <3>; + fw-version = <5>; + image-index = <1>; + image-type-id = "09D7CF52-0720-4710-91D1-08469B7FE9C8"; + }; + image2 { + lowest-supported-version = <7>; + fw-version = <10>; + image-index = <2>; + image-type-id = "5A7021F5-FEF2-48B4-AABA-832E777418C0"; + }; + image3 { + lowest-supported-version = <3>; + fw-version = <5>; + image-index = <1>; + image-type-id = "3673B45D-6A7C-46F3-9E60-ADABB03F7937"; + }; + }; +};