From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web10.13062.1669101372166754089 for ; Mon, 21 Nov 2022 23:16:12 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=GByqUP82; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: jian.j.wang@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669101372; x=1700637372; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=Vp8VcldNsG9w9XY3Qd5yJrWnXgt8ojEe1aaYmcV1fS0=; b=GByqUP82aKGsnTVLAG20HsQ5OZzwVkFOnBn5z27eQsedF0bABPAUq6P2 OASKbx1KT0D/JK2iEOBwHjyR7C+z57kbdmA7xhsCKy4ZAiqw9CwSFPoxd sx7kqdpD/s91VcYZAmKlFqcqH/CVc0j/oZmbqUJWkiQjeLlrDT6IsIMEg ROpl9V6XuA9SQsHY/+AwDJd2cAkoMkoghthK0TeBm5QQww/8x64rUbE82 kMwNm80zPCw+y9n47cv9bo+a7deBsw7hu9H+znRuzDSQHTW6IXZc0Asb+ 1TW2NkG1OAtK04vztSeTOUVq3fIFUvCTjc8OIxDbsKGeyvkiWBGbJin6H A==; X-IronPort-AV: E=McAfee;i="6500,9779,10538"; a="311381236" X-IronPort-AV: E=Sophos;i="5.96,183,1665471600"; d="scan'208";a="311381236" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Nov 2022 23:15:59 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10538"; a="641317917" X-IronPort-AV: E=Sophos;i="5.96,183,1665471600"; d="scan'208";a="641317917" Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by orsmga002.jf.intel.com with ESMTP; 21 Nov 2022 23:15:59 -0800 Received: from fmsmsx610.amr.corp.intel.com (10.18.126.90) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Mon, 21 Nov 2022 23:15:58 -0800 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx610.amr.corp.intel.com (10.18.126.90) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31 via Frontend Transport; Mon, 21 Nov 2022 23:15:58 -0800 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (104.47.66.40) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Mon, 21 Nov 2022 23:15:57 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hVHkh/so+b8UGpqjr9MnF1OvzfWvwKizg8ByWW4OsEHi66xqx3A2rGBFOrzn9PN3MGRob2PgBVIilmrcYg28i0sPhLYNLSPxes9oA2O1+m8s5RZPM9Lh5gufUl3e0Jb7bMbMWseCnVbUqSK53ZELiFeu6cJlDRTTtAF/pQThKxNP3Tc/uKwacZBfglvVUh6Zyb240zfnhyCkch+8zl4tl/IZ0W3SPDOuQUEYoIj5jB/1TxKQ/S4a3ZHfTqofwTPbgwCCK9vch9v8NjxvGbHpmkbJChxn1hRhtAy46tNJG8WPljiIBwKXR/g/l/hPSyjZDBIaJYGmN1RTTPhjwLSiEA== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ibQGG77TAWsJ8DZAIXnzPDx/bEkUnYhUPHpU7BggxCE=; b=ZJhapP5Nt6qJf+3b6p4kVv711xxeH92jnDEEoLlMaXyStolM4RKrvVG6uApoRHAtednDzxmvw/Js/OlcZGQCmE1ci5DqkxoUMQET+G9uBFBHWlGBTJm6dbsvT1lb/7yOHSSto2zOLCP9UFrbjAel+c+Fr/1Ld4WNVHjq5jUePT9K2//dM21ffs5SMOX21ZuE9/wFADZAhvyAj9sRpo1xvePtAw3SvL56q/6EYakyYtyB67iVEPzeyrvrhIsRPKtTxjw2phq8mCOw+nMwFO7Zn+cGgBPg1ik97ajiymfcS3tL6Wep2OXEXS9MZJBUc7xwwHhoN6067OnHTV6zCYDDmg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from MW4PR11MB6763.namprd11.prod.outlook.com (2603:10b6:303:20b::7) by BL3PR11MB6529.namprd11.prod.outlook.com (2603:10b6:208:38c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5834.11; Tue, 22 Nov 2022 07:15:55 +0000 Received: from MW4PR11MB6763.namprd11.prod.outlook.com ([fe80::1440:650:6a28:88d9]) by MW4PR11MB6763.namprd11.prod.outlook.com ([fe80::1440:650:6a28:88d9%4]) with mapi id 15.20.5834.015; Tue, 22 Nov 2022 07:15:55 +0000 From: "Wang, Jian J" To: "Vang, Judah" , "devel@edk2.groups.io" CC: "Yao, Jiewen" , "Xu, Min M" , "Mistry, Nishant C" Subject: Re: [PATCH v5 17/19] SecurityPkg: Add EncryptionVariable lib with AES Thread-Topic: [PATCH v5 17/19] SecurityPkg: Add EncryptionVariable lib with AES Thread-Index: AQHY8bJegEAXrqICgka384RcWnJjmq5Kn8IQ Date: Tue, 22 Nov 2022 07:15:54 +0000 Message-ID: References: <20221106073509.3071-1-judah.vang@intel.com> <20221106073509.3071-18-judah.vang@intel.com> In-Reply-To: <20221106073509.3071-18-judah.vang@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MW4PR11MB6763:EE_|BL3PR11MB6529:EE_ x-ms-office365-filtering-correlation-id: dd2e1d9b-cabd-4e24-c169-08dacc596545 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 6rUs/bAHvOdtPVIaTiYw65ZQ9B+jz3pHIWgo5N6nHbToapp/CICtVbuWIFGCZtT8AmJXm26gjDOss2HeGhLOez0T6hsBYGjQQwLrmVt1iXIcrj2vs+kBxCuUU1J5ocPSnRmMKUvZHmnEhhl+jrDhJ7CeoHfbInEcLX1aDyip5APpSxi1Aj4OeTZv8UTxn/MegCE9nOqVxVn92rGvmoqWW02p3bwoC7MNDyNM1yypEBL2dcve/GNkr2NAQoW6GcqNvLPXziAyo3rA18mNCTWC2JTHq/1gJ7ksvne7vKK9mkEC9JZS0o3S261KI+qBr4wcbkjRAbnvw6XQUC8Lt2EFn44zsBSezpf60UCq9IvWlJBW+EnDl0arviS11xOVLJ4DQq1UCO044VcKim8YJqmeKPJ+SGODYNyl/2a39NMB7cMFgPxwtlK32X+0HJgqU+FAsqQBRCA8Zz68vW6biC7OvsPk1gbIJ/fmlJta7WX/JHm17wuXNUh7a9bTIWVQ/yr3ev9B0VKOqwtwm9YdZB5E4BcubuVojiCDJP7WYUWFiKiwvjMQ2qDF9GiI4cLpWy5rcUjsPGJAh9R3Hy6KmvVxOuJF0meU3guJnLHAqrvkCKTrcEZic2SuMYIvSzqoCjk9+Lyexi0bxuWnGABxeQ2SEhd7FENY1WESPfe3IAwviLmf8pY0XgwFna+E5HuIvOPPejltoieNAL5HaHlSt3hv/ndRgpecWNMMVBwIOt2h6BA= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MW4PR11MB6763.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(366004)(136003)(376002)(346002)(396003)(39860400002)(451199015)(186003)(107886003)(6506007)(7696005)(53546011)(19627235002)(9686003)(966005)(2906002)(478600001)(110136005)(71200400001)(122000001)(38070700005)(82960400001)(55016003)(33656002)(86362001)(83380400001)(38100700002)(26005)(8936002)(15650500001)(41300700001)(66556008)(76116006)(30864003)(66946007)(66446008)(66476007)(52536014)(8676002)(64756008)(5660300002)(316002)(4326008)(54906003)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?EnYEN+jgYxcyaMC+wPPw172aytkDVKjb3hgYQPClPVm1SCODWuPOTwdjBEK8?= =?us-ascii?Q?ZICCXi3UGoDkztbVhqZtQlGKFP2XEVrpAiTrxCMBubeBtBqHW5CCn/tQEdOX?= =?us-ascii?Q?yZRr1gn/XqJg8iutdv/ErnMrfUPx6FHUjXhW+3D24MIcAcKayVYsrw/A4bOG?= =?us-ascii?Q?Jq9xdPU5O9UfjtoUhjGXZpHGPHSB/0RqKw+IY56MLummuYizE5KzWgjj5oVm?= =?us-ascii?Q?0iCBnVNoSWLgV24iJDVl7R4/0HoV8363o/iXe+PGw9RqquHrXJvvPzVkZNs7?= =?us-ascii?Q?tHv4/W8DFLB2sIpbLXNFi1jbBMkv1Wpz550PGTP6PrsalndH9NjZJiyRuH8q?= =?us-ascii?Q?F/Wxn2/dSFwaDYzZjkb0LV8z3hxwaa7mF4w26nBfMnoW1nntc+cmfCZsEiIL?= =?us-ascii?Q?/LH7HrEyf3qPQNAiPewz1TjemHS7v4E2qeuUwjbVJhhxkpExRAQEjPCgiHML?= =?us-ascii?Q?VYJyiwAhB1gdrs9VIFat93f/fKXlGgP1ndLY2XpdFUWZIVLB9adhSarRUuEQ?= =?us-ascii?Q?4LT7eI0b2W5Eq6ijVVADURibtkIJE3mMk8ayWNMzy2EHxfD6wuTIvvCfoVBK?= =?us-ascii?Q?B4n6oeX6lheI2MKdWeUXJo3869CVTEA1d69vPJjWGnY+zSMLkL0jBTEPRGXJ?= =?us-ascii?Q?Xe0S6fm3d9UVplVnReals1V5zPQDvG0clPL4ZEgucFDysVdH59LM81tFDous?= =?us-ascii?Q?7ijR79/GZv5v+aLUb5m7raOVPyBCW/U5bUkksjfxB/xoxdGeANzWlTTAl0rR?= =?us-ascii?Q?oygBEFrUy0/D4aXRBpyY7bABzhsG3vM+Qc4EYocyd/Hd4+AqBgoFv/rj9kph?= =?us-ascii?Q?OidwC1bDaXcNGZ3ijs2tOMLdLsZAW/fKGcU2LAjpom4Hw8R9ahgRqIWAz3kE?= =?us-ascii?Q?JYboisOkvxBO+9eakXKFPnHIssPn7AHrTnSpLl0m9rW4Y7ZlIRiJQpecdvfd?= =?us-ascii?Q?agKPGZfGmzUlSKQTwSRAvGEdYfD+TbAhu/rtEyjb8HKaGm4OzEQoXT2KeqLZ?= =?us-ascii?Q?lccZS6k3joJ6wI0b6475pnht2Jq3YvtNPLZI9AJel6KOYDcjGD8hzRM9MYuE?= =?us-ascii?Q?BXM+O83Sa434l8HsmX/xXfwxqkyaNqy5pqc3qbosjUSrdOeameW+dfQXYMVI?= =?us-ascii?Q?iWYEqvDyAC4oSF/4kWGj7mQPEILVLDVJu664VACVHNSW95PNfn1DqdM7gcEd?= =?us-ascii?Q?OuRlPuG1jh/zjFsPv8AAS6k76+0rT9GWVcWjvcYtCSLu3fq9+xjizgZ49GUh?= =?us-ascii?Q?1LV96DWBd2yt28t7qtyXNeTOMmonepoqonfebrkJQ/xjmT7nzEY3vPJGF2A4?= =?us-ascii?Q?hhpbEO3m/+yPzsRlP3qg0ad5hhuYGM7NgxPQMQN5QL+Qyq0lSHAlkNStmLBg?= =?us-ascii?Q?qajEqexN2WmBzpTRyKE/BZhcAs6sb/rSRid2rtOxHrc62Jo3vQteD3Bs7wSe?= =?us-ascii?Q?iAJua2b297evBcPdnhnfBbnRqBsHhbuQPaMFcCPfonsCO/wK64jg79N6DlcC?= =?us-ascii?Q?fqneMrE7WAbApAnHKJbNTJ1Tis5RCuRenr/veTzj1d8xqPvZqnk8KRGrLJiD?= =?us-ascii?Q?Z+agEj4GLw54gaOIn18lcgOVfMEQdFsQhJKgiQUU?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MW4PR11MB6763.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: dd2e1d9b-cabd-4e24-c169-08dacc596545 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Nov 2022 07:15:54.8964 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 1pFKF0v52LN0+ATwwTBjS1bd6kGs6TF2usjf/8W1MTeKFUbDJh6LTDkE9Y2o7RnJWkkCf/9r0yWcELST26nG8g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL3PR11MB6529 Return-Path: jian.j.wang@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Judah, Just some typos found. See inline comments below starting with "[JianJW]". With them addressed, Reviewed-by: Jian J Wang Regards, Jian > -----Original Message----- > From: Vang, Judah > Sent: Sunday, November 06, 2022 3:35 PM > To: devel@edk2.groups.io > Cc: Wang, Jian J ; Yao, Jiewen ; > Xu, Min M ; Mistry, Nishant C > > Subject: [PATCH v5 17/19] SecurityPkg: Add EncryptionVariable lib with AE= S >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2594 >=20 > V3: Change AllocateZeroPool() with AllocatePages() and FreePool() > with FreePages(). FreePool() is not supported in PEI phase so this was > causing a memory leak. Reverse the order of the FreePages() call. >=20 > V1: Add encryption/decryption of protected variable functionality. > Add functions to get/set cipher data of a protected variable. > This is use for supporting confidentiality for protected > variables. >=20 > Cc: Jian J Wang > Cc: Jiewen Yao > Cc: Min Xu > Cc: Nishant C Mistry > Signed-off-by: Jian J Wang > Signed-off-by: Nishant C Mistry > Signed-off-by: Judah Vang > --- > SecurityPkg/Library/EncryptionVariableLib/EncryptionVariableLib.inf | 4= 3 ++ > SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable.h | 4= 9 ++ > SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable.c | 73= 4 > ++++++++++++++++++++ > 3 files changed, 826 insertions(+) >=20 > diff --git a/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable= Lib.inf > b/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariableLib.inf > new file mode 100644 > index 000000000000..7ece52f2fb58 > --- /dev/null > +++ b/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariableLib.inf > @@ -0,0 +1,43 @@ > +## @file > +# Provides variable encryption/decryption services. > +# > +# Copyright (c) 2022, Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010029 > + BASE_NAME =3D EncryptionVariableLib > + FILE_GUID =3D 459E2CB0-AF4B-4415-B6A1-335E71FD8B8= 5 > + MODULE_TYPE =3D BASE > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D EncryptionVariableLib > + > +# > +# The following information is for reference only and not required by th= e build > tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[Sources] > + EncryptionVariable.c > + EncryptionVariable.h > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + SecurityPkg/SecurityPkg.dec > + CryptoPkg/CryptoPkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + MemoryAllocationLib > + BaseCryptLib > + > +[Guids] > + gEfiVariableGuid > + gEfiAuthenticatedVariableGuid > diff --git a/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable= .h > b/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable.h > new file mode 100644 > index 000000000000..f35f9f9e3ad7 > --- /dev/null > +++ b/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable.h > @@ -0,0 +1,49 @@ > +/** @file > + Definitions used by this library implementation. > + > +Copyright (c) 2022, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef ENCRYPTION_VARIABLE_H_ > +#define ENCRYPTION_VARIABLE_H_ > + > +#define ENC_KEY_SEP L":" > +#define ENC_KEY_SEP_SIZE 2 > +#define ENC_KEY_NAME L"VAR_ENC_KEY" > +#define ENC_KEY_NAME_SIZE 22 > + > +#define ENC_KEY_SIZE (256/8) > +#define ENC_BLOCK_SIZE AES_BLOCK_SIZE > +#define ENC_IVEC_SIZE ENC_BLOCK_SIZE > + > +#define ENC_PADDING_BYTE 0x0F > + > +// > +// PKCS#5 padding > +// > +// #define AES_CIPHER_DATA_SIZE(PlainDataSize) > +// (AES_BLOCK_SIZE + (PlainDataSize)) & (~(AES_BLOCK_SIZE - 1)) > +// > +#define AES_CIPHER_DATA_SIZE(PlainDataSize) ALIGN_VALUE (PlainDataSize, > AES_BLOCK_SIZE) > + > +#define FREE_POOL(Address) \ > + if ((Address) !=3D NULL) { \ > + FreePool (Address); \ > + (Address) =3D NULL; \ > + } > + > +#pragma pack(1) > + > +typedef struct { > + UINT32 DataType; // SYM_TYPE_AES > + UINT32 HeaderSize; // sizeof(VARIABLE_ENCRYPTION_HEADER) > + UINT32 PlainDataSize; // Plain data size > + UINT32 CipherDataSize; // Cipher data size > + UINT8 KeyIvec[ENC_IVEC_SIZE]; > +} VARIABLE_ENCRYPTION_HEADER; > + > +#pragma pack() > + > +#endif // _ENCRYPTION_VARIABLE_H_ > diff --git a/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable= .c > b/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable.c > new file mode 100644 > index 000000000000..d128b32f93e0 > --- /dev/null > +++ b/SecurityPkg/Library/EncryptionVariableLib/EncryptionVariable.c > @@ -0,0 +1,734 @@ > +/** @file > + Implementation of EncryptionVariableLib with AES algorithm support. > + > +Copyright (c) 2022, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "EncryptionVariable.h" > + > +/** > + Derive encryption key for given variable from variable root key. > + > + The derivation algorithm is depicted below > + > + HKDF_Expand(SHA256, RootKey, > Name||':'||Guid||':'||Attr||"VAR_ENC_KEY") > + > + @param[in] VarEncInfo Pointer to structure containing detailed > + information about a variable. > + @param[in] EncKeySize Size of key requested. > + @param[out] EncKey Buffer of key. > + > + @retval TRUE The key was derived successfully. > + @retval FALSE Failed to generate encryption key. > + > +**/ > +STATIC > +BOOLEAN > +EncVarLibGenEncKey ( > + IN VARIABLE_ENCRYPTION_INFO *VarEncInfo, > + IN UINTN EncKeySize, > + OUT UINT8 *EncKey > + ) > +{ > + BOOLEAN Status; > + > + struct { > + VOID *Data; > + UINTN Size; > + } InfoGroup[6]; > + UINT8 *Info; > + UINTN InfoSize; > + UINTN Index; > + UINT8 Salt[16]; > + > + // > + // info: Name||':'||Guid||':'||Attr||"VAR_ENC_KEY" > + // > + InfoGroup[0].Size =3D VarEncInfo->Header.NameSize; > + InfoGroup[0].Data =3D VarEncInfo->Header.VariableName; > + > + InfoGroup[1].Size =3D ENC_KEY_SEP_SIZE; > + InfoGroup[1].Data =3D ENC_KEY_SEP; > + > + InfoGroup[2].Size =3D sizeof (*VarEncInfo->Header.VendorGuid); > + InfoGroup[2].Data =3D VarEncInfo->Header.VendorGuid; > + > + InfoGroup[3].Size =3D ENC_KEY_SEP_SIZE; > + InfoGroup[3].Data =3D ENC_KEY_SEP; > + > + InfoGroup[4].Size =3D sizeof (VarEncInfo->Header.Attributes); > + InfoGroup[4].Data =3D &VarEncInfo->Header.Attributes; > + > + InfoGroup[5].Size =3D ENC_KEY_NAME_SIZE; > + InfoGroup[5].Data =3D ENC_KEY_NAME; > + > + for (InfoSize =3D 0, Index =3D 0; Index < ARRAY_SIZE (InfoGroup); ++In= dex) { > + InfoSize +=3D InfoGroup[Index].Size; > + } > + > + Info =3D AllocatePages (EFI_SIZE_TO_PAGES (InfoSize)); > + if (Info =3D=3D NULL) { > + ASSERT (Info !=3D NULL); > + return FALSE; > + } > + > + for (InfoSize =3D 0, Index =3D 0; Index < ARRAY_SIZE (InfoGroup); ++In= dex) { > + CopyMem (Info + InfoSize, InfoGroup[Index].Data, InfoGroup[Index].Si= ze); > + InfoSize +=3D InfoGroup[Index].Size; > + } > + > + Status =3D HkdfSha256ExtractAndExpand ( > + VarEncInfo->Key, > + VarEncInfo->KeySize, > + Salt, > + 0, > + Info, > + InfoSize, > + EncKey, > + EncKeySize > + ); > + > + FreePages (Info, EFI_SIZE_TO_PAGES (InfoSize)); > + > + return Status; > +} > + > +/** > + Generate init-vector for AES encryption. > + > + @param[out] InitVector IVEC buffer. > + @param[in] Size Size of IVEC requested. > + > + @retval TRUE IVEC was generated successfully. > + @retval FALSE Failed to generate IVEC. > + > +**/ > +STATIC > +BOOLEAN > +EncVarLibGenIvec ( > + OUT UINT8 *InitVector, > + IN UINTN Size > + ) > +{ > + return RandomBytes (InitVector, Size); > +} > + > +/** > + Check if there's valid variable information needed by encrypting or de= crypting. > + > + @param[in] VarEncInfo Buffer conveying details about a variable. > + @param[in] CheckForEnc Flag indicating check for encrypting (TRUE= ) or > + decrypting (FALSE). > + > + @retval TRUE VarEncInfo is valid. > + @retval FALSE VarEncInfo is invalid. > + > +**/ > +STATIC > +BOOLEAN > +IsValidVariableInfo ( > + IN VARIABLE_ENCRYPTION_INFO *VarEncInfo, > + IN BOOLEAN CheckForEnc > + ) > +{ > + BOOLEAN Valid; > + > + if (CheckForEnc) { > + Valid =3D (VarEncInfo->Header.Data !=3D NULL && VarEncInfo->Header.D= ataSize > > 0) > + || (VarEncInfo->PlainData !=3D NULL && VarEncInfo->PlainData= Size > 0); > + if (!Valid) { > + ASSERT ( > + (VarEncInfo->Header.Data !=3D NULL && VarEncInfo->Header.DataSiz= e > 0) > + || (VarEncInfo->PlainData !=3D NULL && VarEncInfo->PlainDat= aSize > 0) > + ); > + } > + } else { > + Valid =3D (VarEncInfo->Header.Data !=3D NULL && VarEncInfo->Header.D= ataSize > > 0) > + || (VarEncInfo->CipherData !=3D NULL && VarEncInfo->CipherDa= taSize > > 0); > + if (!Valid) { > + ASSERT ( > + (VarEncInfo->Header.Data !=3D NULL && VarEncInfo->Header.DataSiz= e > 0) > + || (VarEncInfo->CipherData !=3D NULL && VarEncInfo->CipherD= ataSize > > 0) > + ); > + } > + } > + > + Valid =3D Valid > + && VarEncInfo->Header.VariableName !=3D NULL > + && VarEncInfo->Header.NameSize > 0 > + && VarEncInfo->Header.VendorGuid !=3D NULL > + && VarEncInfo->Key !=3D NULL > + && VarEncInfo->KeySize > 0; > + if (!Valid) { > + ASSERT (VarEncInfo->Header.VariableName !=3D NULL); > + ASSERT (VarEncInfo->Header.NameSize !=3D 0); > + ASSERT (VarEncInfo->Header.VendorGuid !=3D NULL); > + ASSERT (VarEncInfo->Key !=3D NULL); > + ASSERT (VarEncInfo->KeySize > 0); > + } > + > + return Valid; > +} > + > +/** > + Sanity check of encrption header prefixed to encrypted data. [JianJW] typo: " encrption" -> "encryption" > + > + @param[in] EncHeader Pointer to VARIABLE_ENCRYPTION_HEADER. > + @param[in] DataSize Size of variable data payload. > + > + @retval TRUE EncHeader is valid. > + @retval FALSE EncHeader is invalid. > + > +**/ > +STATIC > +BOOLEAN > +IsValidEncrptionHeader ( [JianJW] "IsValidEncrptionHeader" -> " IsValidEncryptionHeader" > + IN VARIABLE_ENCRYPTION_HEADER *EncHeader, > + IN UINT32 DataSize > + ) > +{ > + if ( (DataSize > sizeof (VARIABLE_ENCRYPTION_HEADER)) > + && ((EncHeader->DataType =3D=3D ENC_TYPE_AES) || (EncHeader->DataTy= pe > =3D=3D ENC_TYPE_NULL)) > + && (EncHeader->HeaderSize >=3D sizeof (VARIABLE_ENCRYPTION_HEADER)) > + && (EncHeader->CipherDataSize > 0) > + && ((EncHeader->CipherDataSize % ENC_BLOCK_SIZE) =3D=3D 0) > + && (EncHeader->PlainDataSize > 0) > + && (EncHeader->PlainDataSize <=3D EncHeader->CipherDataSize) > + && ((EncHeader->CipherDataSize + EncHeader->HeaderSize) <=3D DataSi= ze)) > + { > + return TRUE; > + } > + > + return FALSE; > +} > + > +/** > + Encrypt variable data. > + > + If VarEncInfo->PlainData is not NULL, VarEncInfo->PlainData holds the = plain > + data. Otherwise, VarEncInfo->Headr.Data is supposed to be the plain da= ta. [JianJW] "Headr" -> "Header" > + > + If VarEncInfo->CipherData is not NULL, The encrypted data is stored in > + VarEncInfo->CipherData. Otherwise, the encrypted data is stored direct= ly > + in variable data buffer, i.e. VarEncInfo->Headr.Data. [JianJW] "Headr" -> "Header" > + > + @param[in, out] VarEncInfo Pointer to structure containing detaile= d > + information about a variable. > + > + @retval EFI_SUCCESS Variable was encrypted successfully. > + @retval EFI_INVALID_PARAMETER Variable information in VarEncInfo is > invalid. > + @retval EFI_BUFFER_TOO_SMALL VarEncInfo->CipherData is not NULL but > + VarEncInfo->CipherDataSize is too smal= l. > + @retval EFI_ABORTED Uknown error occurred during encryptin= g. > + @retval EFI_OUT_OF_RESOURCES Fail to allocate enough resource. > + @retval EFI_UNSUPPORTED Unsupported to encrypt variable. > + > +**/ > +EFI_STATUS > +EFIAPI > +EncryptVariable ( > + IN OUT VARIABLE_ENCRYPTION_INFO *VarEncInfo > + ) > +{ > + EFI_STATUS Status; > + VOID *AesContext; > + UINT8 EncKey[ENC_KEY_SIZE]; > + UINT8 Ivec[ENC_IVEC_SIZE]; > + UINT8 *PlainBuffer; > + UINT8 *CipherBuffer; > + UINT8 *PlainData; > + UINT32 PlainDataSize; > + VARIABLE_ENCRYPTION_HEADER *CipherData; > + UINT32 CipherDataSize; > + UINT32 PaddingBytes; > + > + Status =3D EFI_ABORTED; > + AesContext =3D NULL; > + PlainBuffer =3D NULL; > + CipherBuffer =3D NULL; > + > + if (!IsValidVariableInfo (VarEncInfo, TRUE)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (VarEncInfo->PlainData !=3D NULL) { > + PlainData =3D VarEncInfo->PlainData; > + PlainDataSize =3D VarEncInfo->PlainDataSize; > + } else { > + PlainData =3D VarEncInfo->Header.Data; > + PlainDataSize =3D (UINT32)VarEncInfo->Header.DataSize; > + } > + > + CipherDataSize =3D AES_CIPHER_DATA_SIZE (PlainDataSize); > + if (VarEncInfo->CipherData !=3D NULL) { > + if (VarEncInfo->CipherDataSize > + < (CipherDataSize + sizeof (VARIABLE_ENCRYPTION_HEADER))) > + { > + VarEncInfo->CipherDataSize =3D CipherDataSize > + + sizeof (VARIABLE_ENCRYPTION_HEADER)= ; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + CipherData =3D VarEncInfo->CipherData; > + } else { > + CipherData =3D VarEncInfo->Header.Data; > + } > + > + // > + // Prepare buffer for encrypted data. > + // > + if ((UINTN)CipherData =3D=3D (UINTN)PlainData) { > + // > + // Need buffer to store the encrypted data temporarily. > + // > + CipherBuffer =3D (UINT8 *)AllocateZeroPool ( > + CipherDataSize > + + sizeof (VARIABLE_ENCRYPTION_HEADER) > + ); > + if (CipherBuffer =3D=3D NULL) { > + ASSERT (CipherBuffer !=3D NULL); > + return EFI_OUT_OF_RESOURCES; > + } > + } else { > + CipherBuffer =3D (UINT8 *)CipherData; > + } > + > + // > + // Plain variable data must also be multiple of ENC_BLOCK_SIZE. > + // > + PaddingBytes =3D ALIGN_VALUE (PlainDataSize, ENC_BLOCK_SIZE) - > PlainDataSize; > + if (PaddingBytes !=3D 0) { > + // > + // Since the plain data size will be saved in the > VARIABLE_ENCRYPTION_HEADER, > + // there's no need to do PKCS way of padding. To save space, just pa= dding > + // the plain data to be of the nearest n*ENC_BLOCK_SIZE. > + // > + PlainBuffer =3D AllocateZeroPool (PlainDataSize + PaddingBytes); > + if (PlainBuffer =3D=3D NULL) { > + ASSERT (PlainBuffer !=3D NULL); > + goto Done; > + } > + > + CopyMem (PlainBuffer, PlainData, PlainDataSize); > + SetMem (PlainBuffer + PlainDataSize, PaddingBytes, ENC_PADDING_BYTE)= ; > + } else { > + PlainBuffer =3D PlainData; > + } > + > + // > + // Skip EFI_VARIABLE_APPEND_WRITE bit in generating encryption key. > + // > + VarEncInfo->Header.Attributes &=3D (~EFI_VARIABLE_APPEND_WRITE); > + if (!EncVarLibGenEncKey (VarEncInfo, ENC_KEY_SIZE, EncKey)) { > + ASSERT (FALSE); > + return EFI_ABORTED; > + } > + > + if (!EncVarLibGenIvec (Ivec, ENC_IVEC_SIZE)) { > + ASSERT (FALSE); > + return EFI_ABORTED; > + } > + > + AesContext =3D AllocateZeroPool (AesGetContextSize ()); > + if (AesContext =3D=3D NULL) { > + ASSERT (AesContext !=3D NULL); > + return EFI_OUT_OF_RESOURCES; > + } > + > + if (!AesInit (AesContext, EncKey, ENC_KEY_SIZE * 8)) { > + ASSERT (FALSE); > + goto Done; > + } > + > + if (AesCbcEncrypt ( > + AesContext, > + PlainBuffer, > + PlainDataSize + PaddingBytes, > + Ivec, > + CipherBuffer + sizeof (VARIABLE_ENCRYPTION_HEADER) > + )) > + { > + // > + // Keep the IV for decryption. > + // > + CopyMem (CipherData->KeyIvec, Ivec, ENC_BLOCK_SIZE); > + > + if ((UINTN)CipherBuffer !=3D (UINTN)CipherData) { > + CopyMem ( > + CipherData + 1, > + CipherBuffer + sizeof (VARIABLE_ENCRYPTION_HEADER), > + CipherDataSize > + ); > + } > + > + CipherData->CipherDataSize =3D CipherDataSize; > + CipherData->PlainDataSize =3D PlainDataSize; > + CipherData->DataType =3D ENC_TYPE_AES; > + CipherData->HeaderSize =3D sizeof (VARIABLE_ENCRYPTION_HEADER); > + > + VarEncInfo->CipherData =3D CipherData; > + VarEncInfo->CipherDataSize =3D CipherDataSize + sizeof > (VARIABLE_ENCRYPTION_HEADER); > + VarEncInfo->CipherHeaderSize =3D sizeof (VARIABLE_ENCRYPTION_HEADER)= ; > + VarEncInfo->CipherDataType =3D ENC_TYPE_AES; > + > + Status =3D EFI_SUCCESS; > + } else { > + VarEncInfo->CipherData =3D NULL; > + VarEncInfo->CipherDataSize =3D 0; > + VarEncInfo->CipherHeaderSize =3D 0; > + VarEncInfo->CipherDataType =3D ENC_TYPE_NULL; > + > + ASSERT (FALSE); > + } > + > +Done: > + FREE_POOL (AesContext); > + if (PlainBuffer !=3D PlainData) { > + FREE_POOL (PlainBuffer); > + } > + > + if (CipherBuffer !=3D (UINT8 *)CipherData) { > + FREE_POOL (CipherBuffer); > + } > + > + return Status; > +} > + > +/** > + Decrypt variable data. > + > + If VarEncInfo->CipherData is not NULL, it must holds the cipher data t= o be > + decrypted. Otherwise, assume the cipher data from variable data buffer= , i.e. > + VarEncInfo->Header.Data. > + > + If VarEncInfo->Flags.DecryptInPlace is TRUE, the decrypted data will b= e put > + back in the same buffer as cipher buffer got above, after encryption h= eader, > + which helps to identify later if the data in buffer is decrypted or no= t. This > + can avoid repeat decryption when accessing the same variable more than > once. > + > + If VarEncInfo->Flags.DecryptInPlace is FALSE, VarEncInfo->PlainData mu= st be > + passed in with a valid buffer with VarEncInfo->PlainDataSize set corre= ctly > + with its size. > + > + Note the VarEncInfo->PlainData is always pointing to the buffer addres= s with > + decrypted data without encryption header, and VarEncInfo->PlainDataSiz= e is > + always the size of original variable data, if this function returned > + successfully. > + > + @param[in, out] VarEncInfo Pointer to structure containing detaile= d > + information about a variable. > + > + @retval EFI_SUCCESS Variable was decrypted successfully. > + @retval EFI_INVALID_PARAMETER Variable information in VarEncInfo is > invalid. > + @retval EFI_BUFFER_TOO_SMALL VarEncInfo->PlainData is not NULL but > + VarEncInfo->PlainDataSize is too small= . > + @retval EFI_ABORTED Uknown error occurred during decryptin= g. > + @retval EFI_OUT_OF_RESOURCES Fail to allocate enough resource. > + @retval EFI_COMPROMISED_DATA The cipher header is not valid. > + @retval EFI_UNSUPPORTED Unsupported to encrypt variable. > + > +**/ > +EFI_STATUS > +EFIAPI > +DecryptVariable ( > + IN OUT VARIABLE_ENCRYPTION_INFO *VarEncInfo > + ) > +{ > + VOID *AesContext; > + UINT8 EncKey[ENC_KEY_SIZE]; > + UINT8 *PlainBuffer; > + UINT8 *PlainData; > + VARIABLE_ENCRYPTION_HEADER *CipherData; > + UINT32 CipherDataSize; > + EFI_STATUS Status; > + > + Status =3D EFI_ABORTED; > + AesContext =3D NULL; > + PlainBuffer =3D NULL; > + > + if (!IsValidVariableInfo (VarEncInfo, FALSE)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (VarEncInfo->CipherData !=3D NULL) { > + CipherData =3D VarEncInfo->CipherData; > + CipherDataSize =3D VarEncInfo->CipherDataSize; > + } else { > + CipherData =3D VarEncInfo->Header.Data; > + CipherDataSize =3D (UINT32)VarEncInfo->Header.DataSize; > + } > + > + // > + // Sanity check of cipher header. > + // > + if (!IsValidEncrptionHeader (CipherData, CipherDataSize)) { > + return EFI_COMPROMISED_DATA; > + } > + > + if ( (VarEncInfo->PlainData !=3D NULL) > + && (VarEncInfo->PlainDataSize < CipherData->PlainDataSize)) > + { > + VarEncInfo->PlainDataSize =3D CipherData->PlainDataSize; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + if (CipherData->DataType =3D=3D ENC_TYPE_AES) { > + if (VarEncInfo->Flags.DecryptInPlace) { > + // > + // Reusing cipher data buffer needs to keep the encryption header. > + // > + PlainData =3D (UINT8 *)CipherData + CipherData->HeaderSize; > + } else { > + PlainData =3D VarEncInfo->PlainData; > + } > + > + if (PlainData =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Always need buffer to store the decrypted data temporarily, due t= o > + // padding bytes or buffer reuse. Then the buffer must be larger tha= n > + // CipherData->PlainDataSize. > + // > + PlainBuffer =3D AllocatePages (EFI_SIZE_TO_PAGES (CipherDataSize)); > + if (PlainBuffer =3D=3D NULL) { > + ASSERT (PlainBuffer !=3D NULL); > + return EFI_OUT_OF_RESOURCES; > + } > + > + if (!EncVarLibGenEncKey (VarEncInfo, ENC_KEY_SIZE, EncKey)) { > + ASSERT (FALSE); > + goto Done; > + } > + > + AesContext =3D AllocatePages (EFI_SIZE_TO_PAGES (AesGetContextSize (= ))); > + if (AesContext =3D=3D NULL) { > + ASSERT (AesContext !=3D NULL); > + Status =3D EFI_OUT_OF_RESOURCES; > + goto Done; > + } > + > + if (!AesInit (AesContext, EncKey, ENC_KEY_SIZE * 8)) { > + ASSERT (FALSE); > + goto Done; > + } > + > + if (AesCbcDecrypt ( > + AesContext, > + (UINT8 *)CipherData + CipherData->HeaderSize, > + CipherDataSize - CipherData->HeaderSize, > + CipherData->KeyIvec, > + PlainBuffer > + )) > + { > + Status =3D EFI_SUCCESS; > + } else { > + Status =3D EFI_COMPROMISED_DATA; > + } > + } else { > + // > + // The data has been decrypted already. > + // > + PlainBuffer =3D (UINT8 *)CipherData + CipherData->HeaderSize; > + > + if (VarEncInfo->PlainData !=3D NULL) { > + PlainData =3D VarEncInfo->PlainData; > + } else { > + PlainData =3D PlainBuffer; > + } > + > + Status =3D EFI_SUCCESS; > + } > + > + if (!EFI_ERROR (Status)) { > + if (PlainBuffer !=3D PlainData) { > + CopyMem (PlainData, PlainBuffer, CipherData->PlainDataSize); > + } > + > + if (VarEncInfo->PlainData !=3D NULL) { > + if (VarEncInfo->PlainData !=3D PlainBuffer) { > + CopyMem (VarEncInfo->PlainData, PlainBuffer, CipherData- > >PlainDataSize); > + } > + } else { > + VarEncInfo->PlainData =3D PlainData; > + } > + > + VarEncInfo->PlainDataSize =3D CipherData->PlainDataSize; > + VarEncInfo->CipherHeaderSize =3D CipherData->HeaderSize; > + VarEncInfo->CipherDataType =3D CipherData->DataType; > + > + if (VarEncInfo->Flags.DecryptInPlace) { > + CipherData->DataType =3D ENC_TYPE_NULL; > + } > + } > + > +Done: > + if (AesContext !=3D NULL) { > + FreePages (AesContext, EFI_SIZE_TO_PAGES (AesGetContextSize ())); > + } > + > + if (PlainBuffer !=3D NULL) { > + FreePages (PlainBuffer, EFI_SIZE_TO_PAGES ((CipherDataSize))); > + } > + > + return Status; > +} > + > +/** > + Get cipher information about a variable, including plaindata size, > + cipher algorithm type, etc. > + > + For data passed in with VarEncInfo, > + > + VarEncInfo->Header.Data > + - The variable data in normal variable structure. > + VarEncInfo->Header.DataSize > + - The size of variable data. > + > + For data passed out with VarEncInfo (valid only if EFI_SUCCESS is retu= rned), > + > + VarEncInfo->CipherDataType > + - ENC_TYPE_NULL, if the variable is not encrypted or has been decr= ypted; > + - ENC_TYPE_AES, if the variable is encrypted. > + VarEncInfo->CipherHeaderSize > + - Size of cipher header put before encrypted or decrypted data. > + VarEncInfo->PlainData > + - NULL, if the variable is encrypted; Or > + - pointer to original variable data, if the variable has been decr= ypted. > + VarEncInfo->PlainDataSize > + - The size of original variable data > + VarEncInfo->CipherData > + - NULL, if the variable is decrypted; Or > + - pointer to start of encrypted variable data, including encryptio= n header; > + VarEncInfo->CipherDataSize > + - The size of encrypted variable data, including encryption header= . > + > + @param[in] VarEncInfo Pointer to structure containing detailed > + information about a variable. > + > + @retval EFI_SUCCESS The information was retrieved successf= ully. > + @retval EFI_INVALID_PARAMETER Variable information in VarEncInfo is > invalid. > + @retval EFI_NOT_FOUND No cipher information recognized. > + @retval EFI_UNSUPPORTED Unsupported interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetCipherDataInfo ( > + IN VARIABLE_ENCRYPTION_INFO *VarEncInfo > + ) > +{ > + VARIABLE_ENCRYPTION_HEADER *EncHeader; > + > + if ((VarEncInfo->Header.Data =3D=3D NULL) || (VarEncInfo->Header.DataS= ize =3D=3D 0)) > { > + ASSERT (VarEncInfo->Header.Data !=3D NULL); > + ASSERT (VarEncInfo->Header.DataSize !=3D 0); > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Validate encryption header. > + // > + EncHeader =3D (VARIABLE_ENCRYPTION_HEADER *)VarEncInfo->Header.Data; > + if (!IsValidEncrptionHeader (EncHeader, (UINT32)VarEncInfo- > >Header.DataSize)) { > + // > + // Not an encrypted variable. > + // > + return EFI_NOT_FOUND; > + } > + > + if (EncHeader->DataType =3D=3D ENC_TYPE_NULL) { > + // > + // The data must have been decrypted. > + // > + VarEncInfo->PlainData =3D (UINT8 *)VarEncInfo->Header.Dat= a + > EncHeader->HeaderSize; > + VarEncInfo->CipherData =3D NULL; > + VarEncInfo->Flags.DecryptInPlace =3D TRUE; > + } else { > + // > + // The data is encrypted. > + // > + VarEncInfo->CipherData =3D VarEncInfo->Header.Data; > + VarEncInfo->PlainData =3D NULL; > + VarEncInfo->Flags.DecryptInPlace =3D FALSE; > + } > + > + VarEncInfo->PlainDataSize =3D EncHeader->PlainDataSize; > + VarEncInfo->CipherDataSize =3D EncHeader->CipherDataSize + EncHeader= - > >HeaderSize; > + VarEncInfo->CipherDataType =3D EncHeader->DataType; > + VarEncInfo->CipherHeaderSize =3D EncHeader->HeaderSize; > + > + return EFI_SUCCESS; > +} > + > +/** > + Force set cipher information for a variable, like plaindata size, > + cipher algorithm type, cipher data etc. > + > + The destination buffer must be passed via VarEncInfo->Header.Data. > + > + This method is only used to update and/or change plain data informatio= n. > + > + @param[in] VarEncInfo Pointer to structure containing detailed > + information about a variable. > + > + @retval EFI_SUCCESS The information was updated successful= ly. > + @retval EFI_INVALID_PARAMETER Variable information in VarEncInfo is > invalid. > + @retval EFI_UNSUPPORTED If this method is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SetCipherDataInfo ( > + IN VARIABLE_ENCRYPTION_INFO *VarEncInfo > + ) > +{ > + VARIABLE_ENCRYPTION_HEADER *EncHeader; > + UINT8 *Data; > + > + if ( (VarEncInfo->Header.Data =3D=3D NULL) > + || (VarEncInfo->Header.DataSize < sizeof > (VARIABLE_ENCRYPTION_HEADER)) > + || (VarEncInfo->CipherDataType !=3D ENC_TYPE_NULL)) > + { > + ASSERT (VarEncInfo->Header.Data !=3D NULL); > + ASSERT (VarEncInfo->Header.DataSize >=3D sizeof > (VARIABLE_ENCRYPTION_HEADER)); > + ASSERT (VarEncInfo->CipherDataType =3D=3D ENC_TYPE_NULL); > + return EFI_INVALID_PARAMETER; > + } > + > + Data =3D VarEncInfo->Header.Data; > + EncHeader =3D (VARIABLE_ENCRYPTION_HEADER *)Data; > + > + if ( !IsValidEncrptionHeader (EncHeader, (UINT32)VarEncInfo- > >Header.DataSize) > + || (VarEncInfo->PlainDataSize > EncHeader->CipherDataSize)) > + { > + return EFI_INVALID_PARAMETER; > + } > + > + if ((VarEncInfo->PlainData !=3D NULL) && (VarEncInfo->PlainDataSize > = 0)) { > + CopyMem ( > + Data + EncHeader->HeaderSize, > + VarEncInfo->PlainData, > + VarEncInfo->PlainDataSize > + ); > + } > + > + EncHeader->DataType =3D VarEncInfo->CipherDataType; > + if (VarEncInfo->PlainDataSize !=3D 0) { > + EncHeader->PlainDataSize =3D VarEncInfo->PlainDataSize; > + } > + > + return EFI_SUCCESS; > +} > -- > 2.35.1.windows.2