From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.92.40.95]) by mx.groups.io with SMTP id smtpd.web12.704.1597091317352330969 for ; Mon, 10 Aug 2020 13:28:37 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@outlook.com header.s=selector1 header.b=cVgH0P+j; spf=pass (domain: outlook.com, ip: 40.92.40.95, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EUlXSaPvD3ZXG6dkVlvCRPa+ZlMatv/FOP9HLzp5buW8g53S+Ywg+JzzwKIlOWKYtEIObUtZqKzMXYB6VLZmx8ZBB+zV9OGzYGS//seP/viEP8CGQkYHQ2rz51J22Z6T4sPTcmjeR9FxgvKWkMBW3FB3TRC/XGp9cEdYIpjYvcEG+eON+rHu0O+W+LxPud2o26+zzQAHbXxQVaT/2oDw65OPg57bu/dD3/QfO98SB8kgebaa/SgEXPSnbiPYA1m1g2rzA3HfD3O1jU0OjDStuluYiAs+bmR4/KeEcztzSAgyMXnqLH0MktOj7cKEUoVCyx6N1RV8o/vio6ankAmb8A== 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=x1FtDTCvXRGTUW1hY5DPdZ3e1hLOzWyjkDjvs8U/yWo=; b=F4nnGnrzM/kV8NnRgM0igGRmoYUeBmfHOXPZo/3y6CcRxygws6l2WEUqgR+z/2JIftQxO7vexCdVFtvI7CDKUrR0yr+j4Y10a9jycir2Z2eedTZ4N66s8hd4WEn6UD+07cJm3CvkXbFsUS8yLKymdzc88Em6SQzeMb8v8Mh1ZloWNvxSCCJjwR8UKp9NQLa13cPPnwIESrl6p99m6cUHKt2DvfWEhKAp2NINCmqHan2iHpnzRSPPOs3/cMkFSrpxLQDUtGIHEz+2RrUxjpa9UYUROWmn1SD7OzPvSVKIt00IaaJVaEAXTLOmy+va6s3TvauZS1PwXVvJYZJ42kr6iQ== 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=x1FtDTCvXRGTUW1hY5DPdZ3e1hLOzWyjkDjvs8U/yWo=; b=cVgH0P+jyHeuheWBz01+fm2ss/VmdBEZc5hLiYJFPmqMDF8y52jZzhntR0Vr2oBk7POJq4ZCmMy+uxLRM8QYa0y8vGeuB7hl86M65evi9DHarovP0qnw0PcLSH1rVf4lB2THEqG5WBK7MZjLNjkNOikkJ8UGZ4mB2FFJMVQbGETOlMrKeG/0v1czEJz0uW/U6Sh92WgjQ46/S5EZ3yl4B2+MrmnEPlkLf0+3w0YfoZ5W0Hp9gfVNadY/1BaGH5buXvZe3WVuTs/z3KP9l5W657k1PlSNIS1bXxlm/dM67fjLYqMlwhxYs13xVfmTkQcbdke98bw+CeAQHMLXChyghg== Received: from MW2NAM10FT048.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e87::4f) by MW2NAM10HT223.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e87::308) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.16; Mon, 10 Aug 2020 20:28:36 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:7e87::44) by MW2NAM10FT048.mail.protection.outlook.com (2a01:111:e400:7e87::98) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3261.16 via Frontend Transport; Mon, 10 Aug 2020 20:28:35 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:5A22876DBBF406F8CF992B27AD04DA9505BF7FFFB07751B1F885093A4931926B;UpperCasedChecksum:8FBCB69B4513B30F51A5A35A9948D189250CF1C0FE933F813D9538CB9403B053;SizeAsReceived:7827;Count:49 Received: from MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::9856:570e:1735:974e]) by MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::9856:570e:1735:974e%7]) with mapi id 15.20.3261.024; Mon, 10 Aug 2020 20:28:36 +0000 From: "Michael Kubacki" To: devel@edk2.groups.io CC: Liming Gao , Michael D Kinney , Guomin Jiang , Wei6 Xu Subject: [PATCH v2 3/6] FmpDevicePkg/FmpDxe: Add check image path Last Attempt Status capability Date: Mon, 10 Aug 2020 13:27:50 -0700 Message-ID: X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20200810202753.1318-1-michael.kubacki@outlook.com> References: <20200810202753.1318-1-michael.kubacki@outlook.com> X-ClientProxiedBy: MWHPR13CA0008.namprd13.prod.outlook.com (2603:10b6:300:16::18) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: <20200810202753.1318-4-michael.kubacki@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2001:4898:80e8:1:cc6:648f:7db1:5bf9) by MWHPR13CA0008.namprd13.prod.outlook.com (2603:10b6:300:16::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.10 via Frontend Transport; Mon, 10 Aug 2020 20:28:34 +0000 X-Mailer: git-send-email 2.28.0.windows.1 X-Microsoft-Original-Message-ID: <20200810202753.1318-4-michael.kubacki@outlook.com> X-TMN: [7hOJFUFQBXqPwSHhItevHQsqQvGEoSImnklgZ3L030y6vQTvOfRvvkc+JraLRTBc] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 49 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: e7ab5337-5db0-4637-d486-08d83d6bf4ad X-MS-TrafficTypeDiagnostic: MW2NAM10HT223: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: vyFhpZyEConNnPlyfCyOOqsp6zDj0WK9MRsNXM/QOV7Z0CMehgvcayLsNRwLXnFP6WzO0sM9WLA0+DUBlV8cSYnGCdomzr43/Vt8W3ItC8/81JzIjg0JLucAxFbjIuRGKq9GJQ3HsS5PDOkL4gPEk7aTifCimgteyVl1z3K5/wyhJPyBHwZjjGY/0oq31vnILfmfaewXEfoGgB8Coxt1OA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:0;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR07MB3440.namprd07.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:;DIR:OUT;SFP:1901; X-MS-Exchange-AntiSpam-MessageData: IpfF2k2l8OZF32tfuFDBqspxVX7XmfKO3uXw++8p6OjTH1bUgCcLQAilOG1rLNLUWDShSST1W7UWG+43c1wxTWVukthHj28RQY9WR+D8v9xjQOq4qLi/q/Uq1yCtKhZzGi58w+g8eO2L6hG8/HahUFCBjdlHko/fQYkB9x8VQIFJF4L1Y57az9LLJBjAHvK85o7f9fOYZ4+oT7WKFj5rNg== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: e7ab5337-5db0-4637-d486-08d83d6bf4ad X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Aug 2020 20:28:35.9017 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: MW2NAM10FT048.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: MW2NAM10HT223 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Michael Kubacki CheckTheImage() is 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 | 102 +++++++++++++++++--- FmpDevicePkg/FmpDxe/FmpDxe.h | 3 +- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 854feec0a162..dc714f7e9cd4 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -721,6 +721,24 @@ 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 i= n case + of error. + + 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_ERROR_UNSUCCESSFUL_VE= NDOR_RANGE_MIN + to LAST_ATTEMPT_STATUS_DRIVER_MAX_ERROR_C= ODE_VALUE. + + This function will return error codes tha= t occur within FMP dependency + related functionality used by this functi= on within a dependency range of + last attempt error codes from LAST_ATTEMP= T_STATUS_DRIVER_MAX_ERROR_CODE_VALUE + to LAST_ATTEMPT_STATUS_DEPENDENCY_MAX_ERR= OR_CODE_VALUE. + + This function will additionally return er= ror codes that are returned + from a device-specific CheckImage () impl= ementation in the range of + LAST_ATTEMPT_STATUS_DEPENDENCY_MAX_ERROR_= CODE_VALUE to + LAST_ATTEMPT_STATUS_LIBRARY_MAX_ERROR_COD= E_VALUE. =20 @retval EFI_SUCCESS The image was successfully checked. @retval EFI_ABORTED The operation is aborted. @@ -731,15 +749,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 +775,31 @@ 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; + } + 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 +817,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 +837,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 +847,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 +870,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 +887,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 +907,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 +922,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 +938,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 +946,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 +961,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 +984,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 +996,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 +1013,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..91e9e51f1484 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,7 @@ #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