From patchwork Mon Mar 20 05:54:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 665176 Delivered-To: patch@linaro.org Received: by 2002:a5d:5602:0:0:0:0:0 with SMTP id l2csp958033wrv; Sun, 19 Mar 2023 22:55:26 -0700 (PDT) X-Google-Smtp-Source: AK7set+JLrVADsZ9UtS0ZRV6Vrz0pZ3XsxkQvustHYq+411pMgN7OVV5WnUL8CLpOdz9fbM2dc21 X-Received: by 2002:a05:6214:76c:b0:5c5:95db:858a with SMTP id f12-20020a056214076c00b005c595db858amr8990806qvz.31.1679291726068; Sun, 19 Mar 2023 22:55:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679291726; cv=none; d=google.com; s=arc-20160816; b=UPyvY1zuaOLLN5cG4GKLlO3wJZhown6R4FQqi/TSpFHJQZD4pPCry0S2Ng2OwPPCus PfuTPDemYUMf1JfnPW+vjQ3tvcmyLZLBbFCe5zvWP4y7xvCUeiEpDeqT2cTrs5z/T+lf wbhBpqx0EeATy21Tgaptoled/M0uQICYvwm6xPAr7uSg6GDmVm/wapkUuJW/H0dwqpZi 2PFQXad+x5QP3SUbCjFRa6g8j0cM12cOeDjDr7NIpctpaiYmTU/LEC/ujE/i5+x5a0j/ 8bOSbGT6MjJf04ULUpvJbRvrd7XybyD8dyT45MmjjasJvn1P83Fxiu4s0WmtBmVBCOzX XB4w== 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=ARiWgUnM6ZoPlQ7wNeXNp1AAEkEh5NdNCC8ZMffKhWc=; b=B5Djut743ouRKL0Qz9gU7wP/d+q5YcquLGUfU3rGoP3hjUKoLa0gChzhQOhTwHKDL9 tNR8degamfMM3q8hNP/nPaDqVmNjIz27PgWzH5hdRN09aeTHjluFqFJueL57TwhgD+SQ NLbZ335X0h0My7J5qDf6JjTWKBIydpV/iwyoUD4/3o+ZnkzIyZB9iRP2qoRPv9iG8dyv w71zkpgLJaMTwbpRTQu6yUtxcgCKt1s6a2/Vp/BsgFfpwai9FHZtSHJeSVxCr8ORUQJF GmooiWFfp4O2sNrRaIpVhqSYTc0ATS2ia74mkYiHNiHQwYwFDIoHckTLjnEIcTzRaopw 0YFA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=HEfKX5Nu; 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 c5-20020a05621401e500b0053717829134si5035983qvu.325.2023.03.19.22.55.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:55:26 -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=HEfKX5Nu; 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 452A785AC0; Mon, 20 Mar 2023 06:55:14 +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="HEfKX5Nu"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6E0DD85A48; Mon, 20 Mar 2023 06:55:05 +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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) (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 6103A80A52 for ; Mon, 20 Mar 2023 06:54:59 +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=masahisa.kojima@linaro.org Received: by mail-pj1-x1033.google.com with SMTP id f6-20020a17090ac28600b0023b9bf9eb63so11182986pjt.5 for ; Sun, 19 Mar 2023 22:54:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679291697; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=ARiWgUnM6ZoPlQ7wNeXNp1AAEkEh5NdNCC8ZMffKhWc=; b=HEfKX5NuBhJWTzbgijZDrXBlF4sxZC82e8EvFSR4vFadwiT8Mq6V/PrykN/I/WYH2e BPPgbBJW9GKg69F4My4VgEmhZ+Azvl3XpkstdgYYIEJ/y4WRfh6QtuChh5Tttk/L5oiU EPZPiGsC0vTBU//eL615DsxQZCjXDJ+k4imyZ6SM2OF55PP6yXsvAPLLdF6V3H2vjLo/ J2ycpGHscYOvP/DwFSKtugcaYTFN/P7qKU0mquQ7nINul4eBdPh5YdbqKKEZ5VJuvZlb +RZqpgYneFzfyEUMq1G0FZBROBfMKvo2Qp8nuQAyWPj564QFRq3uDJHf61wzKIDXsnIr lclA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679291697; 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=ARiWgUnM6ZoPlQ7wNeXNp1AAEkEh5NdNCC8ZMffKhWc=; b=AgaV5mTcNICdHgurjBqbjAv3IFeCBdmkVywoE9Sn8YOs5ezGgNKaoOvmn4LPatZ0O7 9rkMiGb30zhBJVM0vfoJ7/pTamVcIIb5s9UCPrsSSxdAeb6MScwa4yH+9HY54eptI33O ZJwkHU3/+XgAXvhIHkooRczF3Z/hbXs/xWi1GJTkyFfF4gvQ92ss9fDOJTZv7fWTGEjz Wy4WfqXNixYmv/kmKjIlivSFlGpcMlu+JjpF1LEunasCA3wdL/fSHavdxCMKSNCTdPIp 7cQF1dLP0mGuWC0IFOZ1cV/LfxmqXdsSYNjq5tQRhOhClMnQwjt6m0f1VGhzVn9PE2UZ ufrQ== X-Gm-Message-State: AO0yUKUc/2GsyqqCaXvPx8rP0q/cWWN+97wbma7QAx6Mq0jTAts9jvoK e5Ju2T+X5Hm5UmqarK/wLMgFNW6ayFmdf50B4lE= X-Received: by 2002:a17:903:41c4:b0:19d:1720:3873 with SMTP id u4-20020a17090341c400b0019d17203873mr21387404ple.57.1679291697320; Sun, 19 Mar 2023 22:54:57 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id h6-20020a170902eec600b0019cb131b89csm4826718plb.254.2023.03.19.22.54.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:54:56 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v3 1/4] efi_loader: store firmware version into FmpState variable Date: Mon, 20 Mar 2023 14:54:44 +0900 Message-Id: <20230320055448.12439-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230320055448.12439-1-masahisa.kojima@linaro.org> References: <20230320055448.12439-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 Firmware version management is not implemented in the current FMP protocol. EDK2 reference implementation capsule generation script inserts the FMP Payload Header right before the payload, it contains the firmware version and lowest supported version. This commit utilizes the FMP Payload Header, read the header and stores the firmware version, lowest supported version, last attempt version and last attempt status into "FmpStateXXXX" EFI non-volatile variable. XXXX indicates the image index, since FMP protocol handles multiple image indexes. This change is compatible with the existing FMP implementation. This change does not mandate the FMP Payload Header. If no FMP Payload Header is found in the capsule file, fw_version, lowest supported version, last attempt version and last attempt status is 0 and this is the same behavior as existing FMP implementation. Signed-off-by: Masahisa Kojima --- Changes in v3: - exclude CONFIG_FWU_MULTI_BANK_UPDATE case - set image_type_id as a vendor field of FmpStateXXXX variable - set READ_ONLY flag for FmpStateXXXX variable - add error code for FIT image case Changes in v2: - modify indent lib/efi_loader/efi_firmware.c | 224 ++++++++++++++++++++++++++++++---- 1 file changed, 201 insertions(+), 23 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 93e2b01c07..d6f3741024 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,24 @@ struct fmp_payload_header { u32 lowest_supported_version; }; +/** + * struct fmp_state - fmp firmware update state + * + * This structure describes the state of the firmware update + * through FMP protocol. + * + * @fw_version: Firmware versions used + * @lowest_supported_version: Lowest supported version + * @last_attempt_version: Last attempt version + * @last_attempt_status: Last attempt status + */ +struct fmp_state { + u32 fw_version; + u32 lowest_supported_version; + u32 last_attempt_version; + u32 last_attempt_status; +}; + __weak void set_dfu_alt_info(char *interface, char *devstr) { env_set("dfu_alt_info", update_info.dfu_string); @@ -102,6 +121,29 @@ efi_status_t EFIAPI efi_firmware_set_package_info_unsupported( return EFI_EXIT(EFI_UNSUPPORTED); } +/** + * 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_fill_image_desc_array - populate image descriptor array * @image_info_size: Size of @image_info @@ -182,6 +224,7 @@ static efi_status_t efi_fill_image_desc_array( * efi_firmware_capsule_authenticate - authenticate the capsule if enabled * @p_image: Pointer to new image * @p_image_size: Pointer to size of new image + * @state Pointer to fmp state * * Authenticate the capsule if authentication is enabled. * The image pointer and the image size are updated in case of success. @@ -190,12 +233,11 @@ static efi_status_t efi_fill_image_desc_array( */ static efi_status_t efi_firmware_capsule_authenticate(const void **p_image, - efi_uintn_t *p_image_size) + efi_uintn_t *p_image_size, + struct fmp_state *state) { 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; @@ -209,8 +251,12 @@ efi_status_t efi_firmware_capsule_authenticate(const void **p_image, if (status == EFI_SECURITY_VIOLATION) { printf("Capsule authentication check failed. Aborting update\n"); + state->last_attempt_status = + LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR; return status; } else if (status != EFI_SUCCESS) { + state->last_attempt_status = + LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; return status; } @@ -222,24 +268,130 @@ 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; + *p_image = image; + *p_image_size = image_size; + + return EFI_SUCCESS; +} +/** + * efi_firmware_set_fmp_state_var - set FmpStateXXXX variable + * @state: Pointer to fmp state + * @image_index: image index + * @updated: flag to indicate firmware update is successful + * + * Update the FmpStateXXXX variable with the firmware update state. + * + * Return: status code + */ +static +efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 image_index, + bool updated) +{ + u16 varname[13]; /* u"FmpStateXXXX" */ + efi_status_t ret; + efi_uintn_t size; + efi_guid_t *image_type_id; + struct fmp_state var_state = { 0 }; + + image_type_id = efi_firmware_get_image_type_id(image_index); + if (!image_type_id) + return EFI_INVALID_PARAMETER; + + efi_create_indexed_name(varname, sizeof(varname), "FmpState", + image_index); + size = sizeof(var_state); + ret = efi_get_variable_int(varname, image_type_id, NULL, &size, + &var_state, NULL); + if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND) + return ret; + + /* + * When the capsule update is successful, FmpStateXXXX variable is set + * according to the fmp payload header information. If there is no fmp payload + * header in the capsule file, all values are set to 0. + * When the capsule update fails, only last attempt information of FmpStateXXXX + * variable is updated, fw_version and lowest_supported_version keep original + * value or 0(in case no FmpStateXXXX variable found). + */ + if (updated) { + var_state.fw_version = state->fw_version; + var_state.lowest_supported_version = state->lowest_supported_version; + var_state.last_attempt_version = state->last_attempt_version; + var_state.last_attempt_status = state->last_attempt_status; + } else { + var_state.last_attempt_version = state->last_attempt_version; + var_state.last_attempt_status = state->last_attempt_status; + } + + ret = efi_set_variable_int(varname, image_type_id, + EFI_VARIABLE_READ_ONLY | + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(var_state), &var_state, false); + + return ret; +} + +/** + * efi_firmware_parse_payload_header - parse FMP payload header + * @p_image: Pointer to new image + * @p_image_size: Pointer to size of new image + * @state Pointer to fmp state + * + * Parse the FMP payload header and fill the fmp_state structure. + * If no FMP payload header is found, fmp_state structure is not updated. + * + */ +static +void efi_firmware_parse_payload_header(const void **p_image, + efi_uintn_t *p_image_size, + struct fmp_state *state) +{ + 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; + + header = 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. - */ + /* FMP header is inserted above the capsule payload */ + state->fw_version = header->fw_version; + state->lowest_supported_version = header->lowest_supported_version; + state->last_attempt_version = header->fw_version; image += header->header_size; image_size -= header->header_size; } *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 + * @state Pointer to fmp state + * + * 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, + struct fmp_state *state) +{ + efi_status_t ret; + + ret = efi_firmware_capsule_authenticate(p_image, p_image_size, state); + efi_firmware_parse_payload_header(p_image, p_image_size, state); + + return ret; } /** @@ -330,7 +482,9 @@ efi_status_t EFIAPI efi_firmware_fit_set_image( efi_status_t (*progress)(efi_uintn_t completion), u16 **abort_reason) { + bool updated; efi_status_t status; + struct fmp_state state = { 0 }; EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); @@ -338,14 +492,23 @@ 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, + &state); if (status != EFI_SUCCESS) - return EFI_EXIT(status); + goto err; - if (fit_update(image)) - return EFI_EXIT(EFI_DEVICE_ERROR); + if (fit_update(image)) { + status = EFI_DEVICE_ERROR; + state.last_attempt_status = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; + goto err; + } - return EFI_EXIT(EFI_SUCCESS); + state.last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; +err: + updated = (status == EFI_SUCCESS) ? true : false; + efi_firmware_set_fmp_state_var(&state, image_index, updated); + + return EFI_EXIT(status); } const struct efi_firmware_management_protocol efi_fmp_fit = { @@ -391,7 +554,9 @@ efi_status_t EFIAPI efi_firmware_raw_set_image( u16 **abort_reason) { int ret; + bool updated; efi_status_t status; + struct fmp_state state = { 0 }; EFI_ENTRY("%p %d %p %zu %p %p %p\n", this, image_index, image, image_size, vendor_code, progress, abort_reason); @@ -399,9 +564,10 @@ 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, + &state); if (status != EFI_SUCCESS) - return EFI_EXIT(status); + goto err; if (IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) { /* @@ -411,15 +577,27 @@ efi_status_t EFIAPI efi_firmware_raw_set_image( ret = fwu_get_image_index(&image_index); if (ret) { log_debug("Unable to get FWU image_index\n"); - return EFI_EXIT(EFI_DEVICE_ERROR); + status = EFI_DEVICE_ERROR; + goto err; } } if (dfu_write_by_alt(image_index - 1, (void *)image, image_size, - NULL, NULL)) - return EFI_EXIT(EFI_DEVICE_ERROR); + NULL, NULL)) { + status = EFI_DEVICE_ERROR; + state.last_attempt_status = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; + goto err; + } + + state.last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; +err: + updated = (status == EFI_SUCCESS) ? true : false; + + /* TODO: implement versioning for FWU multi bank update */ + if (!IS_ENABLED(CONFIG_FWU_MULTI_BANK_UPDATE)) + efi_firmware_set_fmp_state_var(&state, image_index, updated); - return EFI_EXIT(EFI_SUCCESS); + return EFI_EXIT(status); } const struct efi_firmware_management_protocol efi_fmp_raw = { From patchwork Mon Mar 20 05:54:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 665177 Delivered-To: patch@linaro.org Received: by 2002:a5d:5602:0:0:0:0:0 with SMTP id l2csp958068wrv; Sun, 19 Mar 2023 22:55:36 -0700 (PDT) X-Google-Smtp-Source: AK7set+CXriP83FpLsP1+U9S/ZezYgRUXb16GOWtvQw7ffUiQ1colQ9kHrWtBOOndCYbhyQsW4+U X-Received: by 2002:a05:6214:5284:b0:5ab:af50:eb36 with SMTP id kj4-20020a056214528400b005abaf50eb36mr37934183qvb.45.1679291736099; Sun, 19 Mar 2023 22:55:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679291736; cv=none; d=google.com; s=arc-20160816; b=TqzMzmg8hD+0u90bGOtG9lS9ayi1M00KLdm6ySlE6ovgDmWJinO47OgxKVXRmaI6Xl wH5vc6lOTxm6r2lXF1BJaVFfCpCycy2LWojYNXZ9OMbzXDShMe3V21n5wGtorgxmf6WS WszBGY5HdkUkpx6mKF92ybNWq5bB3hIvQ8Sp3kLHZYLMViVLO7uEMuMDykSLWH2ij/b1 YmBHJP8I7tWCP/8RzdaE9eVjR0wJBW4d7WsNyRwPAmc3M5bhlAXKBrvNfOAhoP3HbuNs EkEH82N5BzadpslvNn3bvsA2Bjbk6zjkC3M9XWg04jurGIwA/2OozvoLZsZ+Ka5Yl1wV /MBg== 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=8cV95/lP8lmMyT89SuJ1JbF4cgBxYpvW/XdEdWca0pQ=; b=N3fB80MrKZOxgxiPCkX2TFH0oIEzoiipTnm/DDiAZQ/LIyhvXZAngBDBmS6g6qDkU9 vUqG081E5LNvSL1NJXD06sHalVuVOKMRJPVYyIOAdq2lMOgs5Q1R+SUoGvuEJen4Yw1E ijAFifFWiEQmyXfJTaKZqgrkOdDYGgPR/wAORJGDlR1X5nmagqqoldiNY0Iz3seG2zB9 B8X4iXIuL5ccfrUHwi4ovovCs+wmf/3peb30q47w/xxWOhdvp0YHTHLFfGO8tY5iuZ+K 6oRY+af6F/72/FvOD6AgH4DQ9hJjvWbkwLur6r3eiWXr+OknQACkcPJRTG2Sf+RKDcVA V/KQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Aq8TgvjC; 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 y18-20020ad457d2000000b005b3a4d92f2fsi5170923qvx.587.2023.03.19.22.55.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:55:36 -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=Aq8TgvjC; 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 0283785B23; Mon, 20 Mar 2023 06:55: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="Aq8TgvjC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2B70885A48; Mon, 20 Mar 2023 06:55:09 +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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) (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 5EC468584D for ; Mon, 20 Mar 2023 06:55: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=masahisa.kojima@linaro.org Received: by mail-pl1-x632.google.com with SMTP id o11so11340189ple.1 for ; Sun, 19 Mar 2023 22:55:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679291699; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=8cV95/lP8lmMyT89SuJ1JbF4cgBxYpvW/XdEdWca0pQ=; b=Aq8TgvjCKGjT5978B3ALDnQcy38xWNfd7VUc37yDKdMjggO2LBpMy5RJQF+FCwdrdW 0fvJkLE05XE7PvOUK/jxqpMvyqJYHpaBaGwIp49Qi1O1rJDzilKFo/Pr2t59zUP9PE9C Nsv/SAS3BvLoUC1AwCUlI4UBsX4taFKSl1YALuKYTSG/E+Ac5HMd+hqMEC8jClibSgIE EMfSvzsk1PhO9ZLDKLaBSbCzKNsedSER6ybp4kxyk1SUSG6YmbaDzdF5TwUtmber2xvW q/y3TjqVPuikBPrQOAJObNa3dUzujm72UV8gUt89cVsccMjabW5iIWn/dSt/jwMMmcT/ qGqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679291699; 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=8cV95/lP8lmMyT89SuJ1JbF4cgBxYpvW/XdEdWca0pQ=; b=y32j3P6Ru+k1HcxtYuGh7PIqRcyQr4sbH70/gOqjSjIo5vGZSlUaf84F7olVg02/ks AT3KnXpw43ZFxYwubPHggfQq9IxQa973/xAeFWGG4jTTJIwiIiSqDURzaADMxl/++IBi 7/FFogpj5RzRTpOWkLTbR9kUP1efGNgb3Z14y3L0gi6MyR5p37nVwyL/2VImiE0VfcLp sznFXk8yjOixcM/hfhRmAE33rVhT+z4tBgcj9qyWes7+hV7c0NpZX6BJ1mV26C9hDmwo TytLo9tL0V36gza3AeS1j7tH0Al+Zq6KxFWwUcGEXco/pvFJ5/QuLKuQB5DHErx0LX0+ MzeQ== X-Gm-Message-State: AO0yUKWIMSyWJKddFlZvdrPx/3kT0nDW533T+Ys0XFSN07df1lEwtJTa SfksskIvdiaE9kF+TbqyOzcpF/cGpuzhKVUc8sc= X-Received: by 2002:a17:903:138f:b0:1a1:b313:718f with SMTP id jx15-20020a170903138f00b001a1b313718fmr7217756plb.22.1679291699559; Sun, 19 Mar 2023 22:54:59 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id h6-20020a170902eec600b0019cb131b89csm4826718plb.254.2023.03.19.22.54.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:54:59 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v3 2/4] efi_loader: versioning support in GetImageInfo Date: Mon, 20 Mar 2023 14:54:45 +0900 Message-Id: <20230320055448.12439-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230320055448.12439-1-masahisa.kojima@linaro.org> References: <20230320055448.12439-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 reads the "FmpStateXXXX" EFI variable, then fills the firmware version, lowest supported version, last attempt version and last attempt status in FMP->GetImageInfo(). Now FMP->GetImageInfo() and ESRT have the meaningful version number. Signed-off-by: Masahisa Kojima --- No update since v1 lib/efi_loader/efi_firmware.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index d6f3741024..289456ecbb 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -190,13 +190,38 @@ static efi_status_t efi_fill_image_desc_array( *package_version_name = NULL; /* not supported */ for (i = 0; i < num_image_type_guids; i++) { + u16 varname[13]; /* u"FmpStateXXXX" */ + efi_status_t ret; + efi_uintn_t size; + struct fmp_state var_state = { 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_create_indexed_name(varname, sizeof(varname), "FmpState", + fw_array[i].image_index); + size = sizeof(var_state); + ret = efi_get_variable_int(varname, &fw_array[i].image_type_id, + NULL, &size, &var_state, NULL); + if (ret == EFI_SUCCESS) { + image_info[i].version = var_state.fw_version; + image_info[i].lowest_supported_image_version = + var_state.lowest_supported_version; + image_info[i].last_attempt_version = + var_state.last_attempt_version; + image_info[i].last_attempt_status = + var_state.last_attempt_status; + } else { + image_info[i].version = 0; + image_info[i].lowest_supported_image_version = 0; + image_info[i].last_attempt_version = 0; + image_info[i].last_attempt_status = + LAST_ATTEMPT_STATUS_SUCCESS; + } + image_info[i].version_name = NULL; /* not supported */ image_info[i].size = 0; image_info[i].attributes_supported = @@ -210,9 +235,6 @@ 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].last_attempt_version = 0; - image_info[i].last_attempt_status = LAST_ATTEMPT_STATUS_SUCCESS; image_info[i].hardware_instance = 1; image_info[i].dependencies = NULL; } From patchwork Mon Mar 20 05:54:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 665178 Delivered-To: patch@linaro.org Received: by 2002:a5d:5602:0:0:0:0:0 with SMTP id l2csp958126wrv; Sun, 19 Mar 2023 22:55:48 -0700 (PDT) X-Google-Smtp-Source: AK7set9nR+0YvJ237VVYehLkt4lOvlGnvCy6NbQSpR9c6hTclYWndcvGjryy4zKuYLsHIoLf0q2J X-Received: by 2002:a05:622a:110c:b0:3bd:1bbc:8d8e with SMTP id e12-20020a05622a110c00b003bd1bbc8d8emr26149238qty.0.1679291748092; Sun, 19 Mar 2023 22:55:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679291748; cv=none; d=google.com; s=arc-20160816; b=g0cFAx52yS0kBf7MG99d/WWWtopKM2lYerYSDHWl3lb1jeqi0fUzqbi1/UVHRGf1Vb UjDS9JXueG53eLogN++jmi5xcNUSas65JlV1IP4xh0Me2ssnNqQNKpitCrw+HSJKwDuP o/1YwS85bq8XsrDLfGD1kWhnMIX6sYzJaKu3K9HsazUFveyxaMiQkxUYWBvOcobVDxc2 Jo+3YzVmzlRfFIabKiSxCQyicTBZIFWqXDLf+h2JAf78uvNVdkuOOAADma+BSdYk7dd8 P8OlFQ5ZLQQKMh9Uk+HcGXsgGGbbeH2a8uU6cIvws49zoT5Ayf7yAGFD7i8HgDHQpE+V rPyA== 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=36xDDela0eAJXRcqva0QdwKAeoM57B0OShAZWqdtv04=; b=GedXG7OkYHh3zBZ1mp8AH/oCM9oPB9nZCvI1QYyWHgKsVvoE6TNQY02eoKziXnIT3D AH8O+w58C0z1p4y+HKVtUdyp8Uh3AJedg2A4tGaWgoq38wih3d/dab33xU795MXfRSWv k0MEg8uBCZaDR547oKLwf9g1RL65FqkooU/v0Bm1XwojQB0FaGPA1zhyJuGWDByb5y0Y yiqrX+Jw8NDsFwplHh4qx10xahOlTqOijRXZ9rMlNw/NO6LsMs4uuMF1rWOEkwaYEybf 59o10PY9IK14MIAfMKrld64NVuS+dQvmhFHbIVFxpkAsUIv3QfX3r/K+4BuHwto7MAq1 hp2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=RKO6+gOn; 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 g20-20020ac87f54000000b003d511c18987si5205817qtk.513.2023.03.19.22.55.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:55:48 -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=RKO6+gOn; 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 0283885BAC; Mon, 20 Mar 2023 06:55:22 +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="RKO6+gOn"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8EA2D85B34; Mon, 20 Mar 2023 06:55:11 +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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) (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 A72D685AA2 for ; Mon, 20 Mar 2023 06:55:03 +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=masahisa.kojima@linaro.org Received: by mail-pl1-x633.google.com with SMTP id bc12so10719274plb.0 for ; Sun, 19 Mar 2023 22:55:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679291702; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=36xDDela0eAJXRcqva0QdwKAeoM57B0OShAZWqdtv04=; b=RKO6+gOnPO3X+0OnqJ/t7/9B3jiyDVzl+YSUrhk27J2nQAd06ADjDgRuKFuyfsyUIb IQ+ilCEhQ2TmGmd9Rv1i/HxKljuv6hLTz5kLKPLQF5NONcsgQcPSNlzVzAd/Rrt9OUCL jvAorIy3A5obiA0l2MXdmEgKF0ZhXc1iebHueA7y5PQ11P7P+uoBW7F3zEuGzL2FPANT Czj3RmQp31ZVwmY0DYV80EScUpfxxBkWn1G6Twrws9whflVyI0mPZ3hoSOVUYo2SaT1H a5XawxBsBBePyoWdaCUOOW25edfcM4omKMsAKf+pFBvdKiERUgSn5km5Bdi8DNAo64Zh 8T7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679291702; 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=36xDDela0eAJXRcqva0QdwKAeoM57B0OShAZWqdtv04=; b=WPalMwKO6wxqqSleJdnoMMJSpNKn1GQ8lhtGr1bI4WrA9d3jrSh1yKLUpt3n31fvEc UpQSejXl56eCz9LX1VjCnfVbfGbwFs4bxCS+64OH+SsmPFyzudsmmZ0UOcSaMczifFN/ JbD3qrcHWMRHz8lmgLEsXxIlGez3jyS1+L60wQI3KYdmafCnT7fzbzz0fvJH7omMWUB/ U5nF2toJSMunuoGqWuT9lztwMRukGjn4Iv7pdXGMgcsME5wb7CsuL2rovyKmL8bLnh8e NXlI3pVt0Yqw91m9wfliNjm/L8Ns8SO/zmGZvulB9RfyQOHw/b+Q2ETgu1ZXmULp0DKS rXUA== X-Gm-Message-State: AO0yUKVdT9DjAHWqoB52J/3nDniXmZMMTRyHXR1Mz9xfKqK+WxSdBY1A xNyb9ote/cTGBfQokZRA2MAlrVrTZGCkLrZbP+4= X-Received: by 2002:a17:903:2109:b0:19e:5cc3:8289 with SMTP id o9-20020a170903210900b0019e5cc38289mr12081483ple.34.1679291701747; Sun, 19 Mar 2023 22:55:01 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id h6-20020a170902eec600b0019cb131b89csm4826718plb.254.2023.03.19.22.55.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:55:01 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Takahiro Akashi , Masahisa Kojima Subject: [PATCH v3 3/4] efi_loader: check lowest supported version in capsule update Date: Mon, 20 Mar 2023 14:54:46 +0900 Message-Id: <20230320055448.12439-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230320055448.12439-1-masahisa.kojima@linaro.org> References: <20230320055448.12439-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 EDK2 capsule generation scripts insert contains lowest supported version. This commit reads the lowest supported version stored in the "FmpStateXXXX" EFI non-volatile variable, then check if the firmware version of ongoing capsule is equal or greater than the lowest supported version. Signed-off-by: Masahisa Kojima --- No changes since v2 Changes in v2: - add error message when the firmware version is lower than lowest supported version lib/efi_loader/efi_firmware.c | 50 ++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 289456ecbb..8d6e32006d 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -391,6 +391,39 @@ void efi_firmware_parse_payload_header(const void **p_image, *p_image_size = image_size; } +/** + * efi_firmware_get_lowest_supported_version - get the lowest supported version + * @image_index: image_index + * + * Get the lowest supported version from FmpStateXXXX variable. + * + * Return: lowest supported version, return 0 if reading FmpStateXXXX + * variable failed + */ +static +u32 efi_firmware_get_lowest_supported_version(u8 image_index) +{ + u16 varname[13]; /* u"FmpStateXXXX" */ + efi_status_t ret; + efi_uintn_t size; + efi_guid_t *image_type_id; + struct fmp_state var_state = { 0 }; + + image_type_id = efi_firmware_get_image_type_id(image_index); + if (!image_type_id) + return 0; + + efi_create_indexed_name(varname, sizeof(varname), "FmpState", + image_index); + size = sizeof(var_state); + ret = efi_get_variable_int(varname, image_type_id, NULL, &size, + &var_state, NULL); + if (ret != EFI_SUCCESS) + return 0; + + return var_state.lowest_supported_version; +} + /** * efi_firmware_verify_image - verify image * @p_image: Pointer to new image @@ -398,7 +431,8 @@ void efi_firmware_parse_payload_header(const void **p_image, * @image_index Image index * @state Pointer to fmp state * - * Verify the capsule file + * Verify the capsule authentication and check if the fw_version + * is equal or greater than the lowest supported version. * * Return: status code */ @@ -409,10 +443,24 @@ efi_status_t efi_firmware_verify_image(const void **p_image, struct fmp_state *state) { efi_status_t ret; + u32 lowest_supported_version; ret = efi_firmware_capsule_authenticate(p_image, p_image_size, state); efi_firmware_parse_payload_header(p_image, p_image_size, state); + /* check lowest_supported_version if capsule authentication passes */ + if (ret == EFI_SUCCESS) { + lowest_supported_version = + efi_firmware_get_lowest_supported_version(image_index); + if (lowest_supported_version > state->fw_version) { + printf("fw_version(%u) is too low(expected >%u). Aborting update\n", + state->fw_version, lowest_supported_version); + state->last_attempt_status = + LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION; + ret = EFI_INVALID_PARAMETER; + } + } + return ret; } From patchwork Mon Mar 20 05:54:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 665179 Delivered-To: patch@linaro.org Received: by 2002:a5d:5602:0:0:0:0:0 with SMTP id l2csp958185wrv; Sun, 19 Mar 2023 22:55:59 -0700 (PDT) X-Google-Smtp-Source: AK7set9UCMWuAEIPNdmJpG9T8lGwjuvhGAKWAf+godb6ADyMCzRk5NQQ8L3ApCMqwECqsXu7JqHA X-Received: by 2002:a05:622a:1214:b0:3e0:8c58:1dd with SMTP id y20-20020a05622a121400b003e08c5801ddmr5136280qtx.55.1679291759268; Sun, 19 Mar 2023 22:55:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679291759; cv=none; d=google.com; s=arc-20160816; b=YQ1upWHah65oYm8GCxb63LtzGOz2Y2QlT8PmieDzKBWQcyS49ghbOC+pB0mYex4kbt X1bgXzZRjjlxqPLQyMi0VgKFmHD4P8bX+V2VnGoPkbfd4CpY4TfstykXYQ0WYUlZNpFB yOymJhgzoBQzNXm5scc59KpQ29pAW0vvh5zsJPIC5tQxMofBz9K/VuBbVpXdqQ7Kwcw4 lxuji9F4sTbO6EntLmsBUbVBahSFgTFHTAUps0FtTa4STDj1+vG8jTffghxEy0z4/B5b kYqeis2xF1GeSeTYlT5osKyFNtyzoq4jnhAq3/F7Bv38NNSlGlAOs4PKzvzH9CJO0rSp k9/Q== 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=pEIt3FJyp+Umr6jRB2lh5v6AmlFjCqZfI6WOhOuwZ5M=; b=LvXCr1EpRw2wFntiYtpv2h+UqgPN5xOuKAr9Pl9VJxnBqEq5Onx5Cqf6cgq3k+x43F WMPGo2dHzLRsczzSwQMftoRgXZNBHwPLTjncDYQ05/k9AUrh6c3FFCpOFEiq0fI+HmTB VpluvtQKFgaqt8kYITMPNPTQ9rZChFV5xdt+zbb24mcvm/cZPHLoP69Ji76MTiyd7uXR 62xTuoWOT9RIdcC7ZS6tH9spJhw5l413quTh7qxcMW5B7Nell8wq0C8NPzUIAT+RbBa9 XU9UOKmvfQi/8Gs1Afz7Q8E/5ScvrRwTvYVcSlk/05sRJ9s6mTBZG5MNIrIkhGq5XV5V PDug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SmvtnBg2; 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 bn45-20020a05620a2aed00b0074691447263si58652qkb.731.2023.03.19.22.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:55:59 -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=SmvtnBg2; 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 D6A5285B70; Mon, 20 Mar 2023 06:55:29 +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="SmvtnBg2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id B1C0085A48; Mon, 20 Mar 2023 06:55:12 +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 autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) (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 478AA85AC0 for ; Mon, 20 Mar 2023 06:55:05 +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=masahisa.kojima@linaro.org Received: by mail-pl1-x634.google.com with SMTP id h8so11301959plf.10 for ; Sun, 19 Mar 2023 22:55:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1679291704; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=pEIt3FJyp+Umr6jRB2lh5v6AmlFjCqZfI6WOhOuwZ5M=; b=SmvtnBg29MJqjFPfSi2ao84x+mRrb1nSBhRmVn922qPAy27iLxHpq1KrwVlbgbXhBv Fn9aPNFZ51EIXw2Ay6BBw7y94wyXWptx+h22KNPphBnMpl9wlXoSHDOjLksCVfwMV031 Nlo7iNNY9ufjExSRBLB0nupGNu8gSD5kJcfjq0Ofezn8pMZc/jmD7F4hyKj2WnJpzFfO FEzau1XSVlL6fCHuJTwegjmi8zA6BEf+MUgillMQUa1Yl6slBxTn4fmSCUIpoZz4Rzm+ fg00UAF9+kVpbbSWNK/RWgfXVNpjKv35PnS/LclEidkM8jogOlbYAxuLPqt7qkab1ocr 8FDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679291704; 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=pEIt3FJyp+Umr6jRB2lh5v6AmlFjCqZfI6WOhOuwZ5M=; b=fxWVcoRMwHZ2HPtx5KI83KwjRJ4Sya5tKoVyhC064mGXxaCJ+sOVc7mz4oj9I8TJj9 RKujz9gbL2IfCCB/d5S1zM0CC9e5tr47dTNePyqHswcZp4EKE9as/A7ILWu7j5aL165L E2K/WqyGJI1HdfAyWgGyaC2Ao2FJvoBE/RQlR2OzOltyUhsVz47MjCqYjOjX6Rs55LDd P8Oq2o5UWWjiIva4u7xBmLwzmZ9CffnCueCDmcfCIdSsv5kK6rldq6XfGXwNfir08dae SkB6i9gxGdSV/4CP4rlZmBlrkoM+FwWF2/zU55qnDbY7UBgpBtufTLbJViTUSj/09u2k GBOw== X-Gm-Message-State: AO0yUKV5YF4mMPz4Cmh/z+h/2kaGxUQri+PaFC5Dn0pOeVXq1dvBzFY9 4rXCv8ZqyloUTNHQaahtfF9SGrZcNHXQTOLA6s4= X-Received: by 2002:a17:902:db0f:b0:1a1:8edc:c5f8 with SMTP id m15-20020a170902db0f00b001a18edcc5f8mr19211043plx.56.1679291704526; Sun, 19 Mar 2023 22:55:04 -0700 (PDT) Received: from localhost.localdomain ([240d:1a:cf7:5800:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id h6-20020a170902eec600b0019cb131b89csm4826718plb.254.2023.03.19.22.55.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Mar 2023 22:55:03 -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 v3 4/4] mkeficapsule: add FMP Payload Header Date: Mon, 20 Mar 2023 14:54:47 +0900 Message-Id: <20230320055448.12439-5-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230320055448.12439-1-masahisa.kojima@linaro.org> References: <20230320055448.12439-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. EDK2 reference implementation inserts the FMP Payload Header right before the payload. It coutains the fw_version and lowest supported version. This commit adds two new parameters required to generate the FMP Payload Header for mkeficapsule tool. '-v' indicates the firmware version. '-l' indicates the lowest supported version. When mkeficapsule tool is invoked with neither '-v' nor '-l' option, FMP Payload Header is not inserted, the behavior is same as current implementation. Signed-off-by: Masahisa Kojima --- 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 | 16 ++++++++++++++ tools/eficapsule.h | 32 +++++++++++++++++++++++++++ tools/mkeficapsule.c | 51 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/doc/mkeficapsule.1 b/doc/mkeficapsule.1 index 1ca245a10f..7c62b03c73 100644 --- a/doc/mkeficapsule.1 +++ b/doc/mkeficapsule.1 @@ -61,6 +61,22 @@ 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 +or +.BR --lsv +are specified + + +.TP +.BI "-v\fR,\fB --fw-version " firmware-version +Specify a firmware version, 0 if omitted + +.TP +.BI "-l\fR,\fB --lsv " lowest-supported-version +Specify a lowest supported 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..72500d1f84 100644 --- a/tools/eficapsule.h +++ b/tools/eficapsule.h @@ -113,4 +113,36 @@ 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 + */ +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; + uint32_t lowest_supported_version; +}; + #endif /* _EFI_CAPSULE_H */ diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c index b71537beee..e50e6a8ed7 100644 --- a/tools/mkeficapsule.c +++ b/tools/mkeficapsule.c @@ -29,7 +29,7 @@ static const char *tool_name = "mkeficapsule"; efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; efi_guid_t efi_guid_cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID; -static const char *opts_short = "g:i:I:v:p:c:m:o:dhAR"; +static const char *opts_short = "g:i:I:v:l:p:c:m:o:dhAR"; enum { CAPSULE_NORMAL_BLOB = 0, @@ -41,6 +41,8 @@ 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'}, + {"lsv", required_argument, NULL, 'l'}, {"private-key", required_argument, NULL, 'p'}, {"certificate", required_argument, NULL, 'c'}, {"monotonic-count", required_argument, NULL, 'm'}, @@ -60,6 +62,8 @@ 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-l, --lsv lowest supported 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 +406,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 +415,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 +429,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 +438,31 @@ 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 = + fmp_ph_params->lowest_supported_version; + 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 +562,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 +571,7 @@ err: fclose(f); free_sig_data(&auth_context); free(data); + free(new_data); return ret; } @@ -644,6 +671,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 +707,14 @@ 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 'l': + fmp_ph_params.lowest_supported_version = strtoul(optarg, NULL, 0); + fmp_ph_params.have_header = true; + break; case 'p': if (privkey_file) { fprintf(stderr, @@ -744,6 +780,11 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } + if (fmp_ph_params.fw_version < fmp_ph_params.lowest_supported_version) { + fprintf(stderr, "fw_version is lower than lowest_supported_version\n"); + exit(EXIT_FAILURE); + } + if (capsule_type != CAPSULE_NORMAL_BLOB) { if (create_empty_capsule(argv[argc - 1], guid, capsule_type == CAPSULE_ACCEPT) < 0) { @@ -751,7 +792,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);