From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (NAM10-MW2-obe.outbound.protection.outlook.com [40.92.42.34]) by mx.groups.io with SMTP id smtpd.web12.3396.1601086820249183922 for ; Fri, 25 Sep 2020 19:20:20 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@outlook.com header.s=selector1 header.b=jiIwgIc3; spf=pass (domain: outlook.com, ip: 40.92.42.34, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=VhcuuOWHuVoJho1bWojrt5TMdvyIeaHm5Cr3AL1NNW8nGRG6gtyhuAQ/u3oFv191XxX7X3V53qkUj2t6izRgUH82xLpBtqxu2Zx7ko9CKngrjqPae38gzhYfblBN4PM049JaNmaP95pORS7Q715ADxILqDBtUTzc+zY9jqe0DAturlvpYckDBjECQKJaWzBxXDYiXwmxGzSKfaZS1gTORJGe+a3GcHgyrAnepZkj5tShNw0TdppuykI0MRtmBml8tdwNQ5inNghSPByYGMlVPNWKilXutULpwgNnIhav9q5C78JWPzAU0tR6+GIcbd7C6N8Jy9A3lfHOzhhjCcsdDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Su5xAQfIwvnxUu2nW0Ny4NwJUwS70B8gKT/XyOM+eb0=; b=Ez3foWNd0fJSL0TsiQCNLhZcWhW5qZLSMDxTXm3bJAcJza5egiAIHTpAEXRHy7ClNRjk2A2c6BHxtMHEjOffQ9QcVrX/s3YSV86DKyu6lBnoowQIJOGQUrj2lpfUNAZ49Ol+Za4URHFfQyg7ia93AfziGMoG9wP5QT36zgF3+6EY+Ri1m7yO4j47MlJaWU9HBGc5NpsZF16MgZzLEcmuhvdNV0c2OizJqfRsGMgdcajPk6bWHlOD08j73EDDM4dGWedPtIGkJ/gwgVFGA5b3DUjDS2Xm7/hkTRWHGFXe7d8Jl3RXfyW00q0/8ulGhBbacebxC3Uyyn89kprAJyb1wA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Su5xAQfIwvnxUu2nW0Ny4NwJUwS70B8gKT/XyOM+eb0=; b=jiIwgIc3txebZd88F8vtktllDWmHWAoRUY7oJbc7jP6O2cfvbH5MvYYYIOwVTBu76/+Z9nvjj/FI5Etyiyow+mVRVTvkKSlTRqbV2dYJTN2PQMvc/k9WdHSBGq9SKJBoYZc/4NWFMyRavhUEa2Uk5qf227RoQzsmlnfEf6KuWe9+a8Xmq+y5G6esj/yIz5ByEJXqMWu75eWG6ZPvEMOqMyLCJsVh72vMmZgsqL0FTjqsMkO2Kbzw/4etgVuANusCHKF3rYdrKyAOfhuSMi7bCwX/TSGRvXM2ucoqJ87/0YQfTZNOpUN+R9MJo5hHnjIfFE1bR/jclcuRbbVVdM2xqg== Received: from MW2NAM10FT023.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e87::42) by MW2NAM10HT211.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e87::193) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.21; Sat, 26 Sep 2020 02:20:19 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:7e87::4c) by MW2NAM10FT023.mail.protection.outlook.com (2a01:111:e400:7e87::154) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3412.21 via Frontend Transport; Sat, 26 Sep 2020 02:20:19 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:F1579A468FA91AA513233C477067816268A6C4412CD134053F9AD4DCC68EF351;UpperCasedChecksum:B0CCE6ED4488751B7F8CE75D0035FEA97966C42B3DFFDF0ACCDCAB642D7A002B;SizeAsReceived:7802;Count:49 Received: from MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::eda9:ccc8:2ef:2471]) by MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::eda9:ccc8:2ef:2471%7]) with mapi id 15.20.3391.026; Sat, 26 Sep 2020 02:20:19 +0000 From: "Michael Kubacki" To: devel@edk2.groups.io CC: Liming Gao , Michael D Kinney , Guomin Jiang , Wei6 Xu Subject: [PATCH v4 3/6] FmpDevicePkg/FmpDxe: Add check image path Last Attempt Status capability Date: Fri, 25 Sep 2020 19:19:41 -0700 Message-ID: X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20200926021944.3575-1-michael.kubacki@outlook.com> References: <20200926021944.3575-1-michael.kubacki@outlook.com> X-ClientProxiedBy: CO2PR04CA0154.namprd04.prod.outlook.com (2603:10b6:104::32) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: <20200926021944.3575-4-michael.kubacki@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2001:4898:80e8:1:9df7:74f4:6652:1fbe) by CO2PR04CA0154.namprd04.prod.outlook.com (2603:10b6:104::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3391.14 via Frontend Transport; Sat, 26 Sep 2020 02:20:18 +0000 X-Mailer: git-send-email 2.28.0.windows.1 X-Microsoft-Original-Message-ID: <20200926021944.3575-4-michael.kubacki@outlook.com> X-TMN: [pOTXRnLkI8FYVIBG2X0AUfz3dPVmlcvtGN8ouHRNeQBoEEIpuZRO5o95+3CcZtdu] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 49 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: ec01cddf-8389-4aea-a3a5-08d861c2b690 X-MS-TrafficTypeDiagnostic: MW2NAM10HT211: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: p02F4uloCRs7MKb0Ppfs0NROdAE5WG6g/8dRTp67f2LxB8lXgQZGIFS7GDEdTE8gr5kYsJAF+0zNPrCJ4Zhd6zZG34mBv5yGKzOzUMbQjNO9yYetQFnphgeVCzJA49iMvldZG8md2YSVZlLCgJPz5ZraqgL+D1GhuXiHvLWvHMn1JhyS4W8GjetJTlVm4YY2eXefOef5trPVCGk48dtZsw== X-MS-Exchange-AntiSpam-MessageData: J1m8old+kQipKASgx8Qk8AUhlTpnaGiC9TTXGCducLme1QCCpa0fZiQizulb0ti4IAUBF3Kj5Ayfph5Ibt3ZMTYLVCu9DR2ThK79HJI3nCBjkqmh6SsP1OgyA3P4m1jg2AHSLQx7VXWZix+EFhXwgIGlxKWTedQj/nLmeFZQWnKXO8LuHOOh1EQt9pzBwCGhCHOc8cDp31o1oganH/gQnQ== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ec01cddf-8389-4aea-a3a5-08d861c2b690 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Sep 2020 02:20:19.0215 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: MW2NAM10FT023.eop-nam10.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW2NAM10HT211 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Michael Kubacki CheckTheImage() is currently used to provide the CheckImage() implementation for the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance produced by FmpDxe in addition to being called internally in the SetImage() path. Since CheckTheImage() plays a major role in determining the validity of a given firmware image, an internal version of the function is introduced - CheckTheImageInternal() that is capable of returning a Last Attempt Status code to internal callers such as SetTheImage(). The CheckImage() API as defined in the UEFI Specification for EFI_FIRMWARE_MANAGEMENT_PROTOCOL is not impacted by this change. CheckTheImageInternal() contains unique Last Attempt Status codes during error paths in the function so it is easier to identify the issue with a particular image through the Last Attempt Status code value. Cc: Liming Gao Cc: Michael D Kinney Cc: Guomin Jiang Cc: Wei6 Xu Signed-off-by: Michael Kubacki --- FmpDevicePkg/FmpDxe/FmpDxe.c | 98 +++++++++++++++++--- FmpDevicePkg/FmpDxe/FmpDxe.h | 4 +- 2 files changed, 90 insertions(+), 12 deletions(-) diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 427b215ddc5f..858cffd8e5bd 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -721,6 +721,14 @@ GetAllHeaderSize ( @param[in] ImageSize Size of the new image in bytes. @param[out] ImageUpdatable Indicates if the new image is valid for u= pdate. It also provides, if available, additional information if t= he image is invalid. + @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last= attempt status to report + back to the ESRT table in case of error. = If an error does not occur, + this function will set the value to LAST_= ATTEMPT_STATUS_SUCCESS. + + This function will return error codes tha= t occur within this function + implementation within a driver range of l= ast attempt error codes from + LAST_ATTEMPT_STATUS_DRIVER_MIN_ERROR_CODE= _VALUE + to LAST_ATTEMPT_STATUS_DRIVER_MAX_ERROR_C= ODE_VALUE. =20 @retval EFI_SUCCESS The image was successfully checked. @retval EFI_ABORTED The operation is aborted. @@ -731,15 +739,17 @@ GetAllHeaderSize ( **/ EFI_STATUS EFIAPI -CheckTheImage ( +CheckTheImageInternal ( IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, IN UINT8 ImageIndex, IN CONST VOID *Image, IN UINTN ImageSize, - OUT UINT32 *ImageUpdatable + OUT UINT32 *ImageUpdatable, + OUT UINT32 *LastAttemptStatus ) { EFI_STATUS Status; + UINT32 LocalLastAttemptStatus; FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private; UINTN RawSize; VOID *FmpPayloadHeader; @@ -755,23 +765,37 @@ CheckTheImage ( EFI_FIRMWARE_IMAGE_DEP *Dependencies; UINT32 DependenciesSize; =20 - Status =3D EFI_SUCCESS; - RawSize =3D 0; - FmpPayloadHeader =3D NULL; - FmpPayloadSize =3D 0; - Version =3D 0; - FmpHeaderSize =3D 0; - AllHeaderSize =3D 0; - Dependencies =3D NULL; - DependenciesSize =3D 0; + Status =3D EFI_SUCCESS; + LocalLastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; + RawSize =3D 0; + FmpPayloadHeader =3D NULL; + FmpPayloadSize =3D 0; + Version =3D 0; + FmpHeaderSize =3D 0; + AllHeaderSize =3D 0; + Dependencies =3D NULL; + DependenciesSize =3D 0; =20 if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } =20 + if (LastAttemptStatus =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImageInternal() - LastAttemp= tStatus is NULL.\n", mImageIdName)); + Status =3D EFI_INVALID_PARAMETER; + goto cleanup; + } + + // + // A last attempt status error code will always override the success + // value before returning from the function + // + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; + if (This =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - This is NULL.\n", mIm= ageIdName)); Status =3D EFI_INVALID_PARAMETER; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_PROTOCOL_ARG_M= ISSING; goto cleanup; } =20 @@ -789,6 +813,7 @@ CheckTheImage ( if (ImageUpdatable =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - ImageUpdatable Pointe= r Parameter is NULL.\n", mImageIdName)); Status =3D EFI_INVALID_PARAMETER; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_IMAGE_NOT_UPDA= TABLE; goto cleanup; } =20 @@ -808,6 +833,7 @@ CheckTheImage ( // not sure if this is needed // *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_IMAGE_NOT_PROV= IDED; return EFI_INVALID_PARAMETER; } =20 @@ -817,6 +843,7 @@ CheckTheImage ( if (PublicKeyDataXdr =3D=3D NULL || (PublicKeyDataXdr =3D=3D PublicKeyDa= taXdrEnd)) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\n"= , mImageIdName)); Status =3D EFI_ABORTED; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALID_CERTIF= ICATE; } else { // // Try each key from PcdFmpDevicePkcs7CertBufferXdr @@ -839,6 +866,7 @@ CheckTheImage ( // DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Certificate size extends beyond = end of PCD, skipping it.\n", mImageIdName)); Status =3D EFI_ABORTED; + LocalLastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALI= D_KEY_LENGTH_VALUE; break; } // @@ -855,6 +883,7 @@ CheckTheImage ( // DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Certificate extends beyond end o= f PCD, skipping it.\n", mImageIdName)); Status =3D EFI_ABORTED; + LocalLastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALI= D_KEY_LENGTH; break; } PublicKeyData =3D PublicKeyDataXdr; @@ -874,6 +903,11 @@ CheckTheImage ( =20 if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Authentication Fai= led %r.\n", mImageIdName, Status)); + if (LocalLastAttemptStatus !=3D LAST_ATTEMPT_STATUS_SUCCESS) { + *LastAttemptStatus =3D LocalLastAttemptStatus; + } else { + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_IMAGE_AUTH_F= AILURE; + } goto cleanup; } =20 @@ -884,6 +918,7 @@ CheckTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Index Invalid.\= n", mImageIdName)); *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID_TYPE; Status =3D EFI_INVALID_PARAMETER; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_INVALID_IMAGE_= INDEX; goto cleanup; } =20 @@ -899,6 +934,7 @@ CheckTheImage ( if (FmpPayloadHeader =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpHeader faile= d.\n", mImageIdName)); Status =3D EFI_ABORTED; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER= ; goto cleanup; } Status =3D GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize,= &Version); @@ -906,6 +942,7 @@ CheckTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeade= rVersion failed %r.\n", mImageIdName, Status)); *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; Status =3D EFI_SUCCESS; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER= _VERSION; goto cleanup; } =20 @@ -920,6 +957,7 @@ CheckTheImage ( ); *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID_OLD; Status =3D EFI_SUCCESS; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_VERSION_TOO_LO= W; goto cleanup; } =20 @@ -942,6 +980,7 @@ CheckTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe: CheckTheImage() - GetFmpPayloadHeaderSiz= e failed %r.\n", Status)); *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; Status =3D EFI_SUCCESS; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_FMP_HEADER= _SIZE; goto cleanup; } =20 @@ -953,6 +992,7 @@ CheckTheImage ( if (AllHeaderSize =3D=3D 0) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetAllHeaderSize f= ailed.\n", mImageIdName)); Status =3D EFI_ABORTED; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DRIVER_ERROR_GET_ALL_HEADER= _SIZE; goto cleanup; } RawSize =3D ImageSize - AllHeaderSize; @@ -969,6 +1009,42 @@ CheckTheImage ( return Status; } =20 +/** + Checks if the firmware image is valid for the device. + + This function allows firmware update application to validate the firmwar= e image without + invoking the SetImage() first. + + @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_= PROTOCOL instance. + @param[in] ImageIndex A unique number identifying the firmware = image(s) within the device. + The number is between 1 and DescriptorCou= nt. + @param[in] Image Points to the new image. + @param[in] ImageSize Size of the new image in bytes. + @param[out] ImageUpdatable Indicates if the new image is valid for u= pdate. It also provides, + if available, additional information if t= he image is invalid. + + @retval EFI_SUCCESS The image was successfully checked. + @retval EFI_ABORTED The operation is aborted. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SECURITY_VIOLATION The operation could not be performed due = to an authentication failure. + +**/ +EFI_STATUS +EFIAPI +CheckTheImage ( + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, + IN UINT8 ImageIndex, + IN CONST VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *ImageUpdatable + ) +{ + UINT32 LastAttemptStatus; + + return CheckTheImageInternal (This, ImageIndex, Image, ImageSize, ImageU= pdatable, &LastAttemptStatus); +} + /** Updates the firmware image of the device. =20 diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h index 30754dea495e..1177b1828e9a 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.h +++ b/FmpDevicePkg/FmpDxe/FmpDxe.h @@ -3,7 +3,7 @@ image stored in a firmware device with platform and firmware device spec= ific information provided through PCDs and libraries. =20 - Copyright (c) 2016, Microsoft Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent @@ -36,6 +36,8 @@ #include #include #include +#include +#include =20 #define VERSION_STRING_NOT_SUPPORTED L"VERSION STRING NOT SUPPORTED" #define VERSION_STRING_NOT_AVAILABLE L"VERSION STRING NOT AVAILABLE" --=20 2.28.0.windows.1