From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM02-CY1-obe.outbound.protection.outlook.com (NAM02-CY1-obe.outbound.protection.outlook.com [40.92.4.80]) by mx.groups.io with SMTP id smtpd.web12.75524.1597785431674297186 for ; Tue, 18 Aug 2020 14:17:11 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@outlook.com header.s=selector1 header.b=B+hF4m/B; spf=pass (domain: outlook.com, ip: 40.92.4.80, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=I5IIADM58/Z6jkVAuYWOFyST7q83Gci/3Yw/2CONDpzM1pJ+z4WVMHiC4iIsXcVvk2Uq9gn4qZPYx4oGEQed6YyqvwB6UJfnwywAuBdJmZ2//khx6lL/FFuHRr8rWqIWvCNwyyFlGwH8CESl9ETEFx44bWIh4G20MSTXPAfYEpMUuUUhwxVxdh6Yvxl2LZcsSLo4wZGLPDrnq242Y3VmWP1KQocgheI1aih/PyaaKdytc0/siIcJtsPssf0RTBRPdzwKKfGIFLmuLv3NCwOJ4iitojHRS2rEgRG1c5EvF7v39qQk717WIiMurR6Rrx7KuQdDQzpSdSh41vPZ7MPj1g== 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=hbvGYZ6EIzDc9l3mt4nTo6AecGxqtdO5NOvbNeVy6JQ=; b=E+oZfHTR74QdLx/+JoHl685hLzStnz5L4btH4gcmK08RHID0wvQbO0b9I6MAS21GiYLC66OimT+RqZNwAMoEHC4Uo62CijjTN+j1ZCWxk+xnsQ7L7gXwDAJBTTsB8CwlYJmpBRglskxQqEZuhwSOszSJlk+lpcVCHH5I8/jGir4rYYmfkP/jso8+OlrMV7nIWTDuM2L61djBU5IWHD94kd8+5iesHBuFjqpSqj02A0JbDG9eCfE9sRayQiARsf+5wDMc1cV3MFvWgXBpACfNpWcdmOzL28gguLzY05lg7B2HOkbQLiZVRRywyk4XWHiy16JXalxfGQ0atbRES6KeTw== 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=hbvGYZ6EIzDc9l3mt4nTo6AecGxqtdO5NOvbNeVy6JQ=; b=B+hF4m/BlMQqlbR1gaCegJjO3M83brgg5fTMi6cumnIfkT5wVqEqZe/3A/eqsEv83HveqzHTpS0rZUDlFEXyeRCkSZojUkPE8MgviAXzDiVkd/46SDwERpdNCiLzwHLpCHaiOWyBHSvLNHaWnM9YLZCp1w+8oBFJpA3n45tZCJQfZeejG/QxTzryjF+ShIPZVLGWcDCL/sMhjrF/tZZvwlGY4HvsqE0wsh3Ha6Iq6Brn6EB9kG0lq7vW6M6ifLhzlRy4HaBNPd1ocEuOof6Gp/uiEG9RI5cyo4zpz26Sb3+c99I8lLQYNQL++H+AQS0zlMZA0YO26vpkiBlEVPubRQ== Received: from SN1NAM02FT007.eop-nam02.prod.protection.outlook.com (10.152.72.53) by SN1NAM02HT152.eop-nam02.prod.protection.outlook.com (10.152.73.53) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.16; Tue, 18 Aug 2020 21:17:10 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:7e44::4e) by SN1NAM02FT007.mail.protection.outlook.com (2a01:111:e400:7e44::88) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3283.16 via Frontend Transport; Tue, 18 Aug 2020 21:17:10 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:8C3C950C3AA75E5F5E9728328AA02561E78D3E2602E0D59FDD0BF697E2237931;UpperCasedChecksum:9FAE405AC7290613B7D3B5B74CBD5AB0EF5992D566143B202D9EE9B2DABDA33A;SizeAsReceived:7816;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.3283.027; Tue, 18 Aug 2020 21:17:10 +0000 From: "Michael Kubacki" To: devel@edk2.groups.io CC: Liming Gao , Michael D Kinney , Guomin Jiang , Wei6 Xu Subject: [PATCH v3 3/6] FmpDevicePkg/FmpDxe: Add check image path Last Attempt Status capability Date: Tue, 18 Aug 2020 14:16:26 -0700 Message-ID: X-Mailer: git-send-email 2.28.0.windows.1 In-Reply-To: <20200818211629.1193-1-michael.kubacki@outlook.com> References: <20200818211629.1193-1-michael.kubacki@outlook.com> X-ClientProxiedBy: MWHPR14CA0033.namprd14.prod.outlook.com (2603:10b6:300:12b::19) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: <20200818211629.1193-4-michael.kubacki@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2001:4898:80e8:1:e4ef:ebe4:8509:47e7) by MWHPR14CA0033.namprd14.prod.outlook.com (2603:10b6:300:12b::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3305.24 via Frontend Transport; Tue, 18 Aug 2020 21:17:09 +0000 X-Mailer: git-send-email 2.28.0.windows.1 X-Microsoft-Original-Message-ID: <20200818211629.1193-4-michael.kubacki@outlook.com> X-TMN: [oy6BCIBZVxlGHYjdrRX4BXP7pLj0xe2SDvQFnS8y00jBgavZffuzBTfNK0d/pHwa] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 49 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 745a3073-995f-46a7-e7c3-08d843bc117f X-MS-TrafficTypeDiagnostic: SN1NAM02HT152: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: d09IBF4CaZuks6HZ6dQQDPEsZq60SBAaeLFzuc3ok8mi4lP0R8dcN3wcgT+6UCwDES6Lk5/aZRw/YfYWaKZVQVMGdKAQXFi/u96QpIGSlPpldCH3cVBj4Pj5XSzcGQxHBhXs8QT4m9QuzriHty+GcRqjtduG7zDb3NfBB7uYXeWF+Vn/18Qox4UNv5vgO9i4Zf8xA02gltOXmLOKZif/LA== 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;SFS:;DIR:OUT;SFP:1901; X-MS-Exchange-AntiSpam-MessageData: SKnM6PRX6N5N9KOCSyI8g264DlEJ2t1vYvLnfuzIG+McRwRwRWodV4SP/FUrptoh0ujIvIFmv1gqCLpLUbsoqY0PGTJPutjPjFIxwG5EuPLr8JFnZ+6qc3hp55HUBJ57g+Fe43ie34rbQnu7VDibFqeXhbmshn0jsgMGuhnmnne44lrmyYTAT2Ps9Y3Qu8tXgj37H7MgXOcltm8iIlxnzw== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 745a3073-995f-46a7-e7c3-08d843bc117f X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Aug 2020 21:17:10.1641 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: SN1NAM02FT007.eop-nam02.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: SN1NAM02HT152 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 | 101 +++++++++++++++++--- FmpDevicePkg/FmpDxe/FmpDxe.h | 4 +- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index 427b215ddc5f..75ae2b0a1c7e 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -721,6 +721,23 @@ 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. + + 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_FMP_RESERVED_MIN_ERRO= R_CODE_VALUE + 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 + 1 + 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_DEVICE_LIBRARY_MIN_ER= ROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ER= ROR_CODE_VALUE. =20 @retval EFI_SUCCESS The image was successfully checked. @retval EFI_ABORTED The operation is aborted. @@ -731,15 +748,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 +774,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 +816,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 +836,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 +846,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 +869,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 +886,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 +906,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 +921,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 +937,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 +945,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 +960,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 +983,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 +995,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 +1012,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