From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web09.14342.1661141108560339422 for ; Sun, 21 Aug 2022 21:05:08 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=mUNHMkv4; spf=pass (domain: intel.com, ip: 134.134.136.24, 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=1661141108; x=1692677108; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=zZmb5bCFuS0++YAfB6rQVVA35QlWCchYcFQQLuvrrno=; b=mUNHMkv4+BLOUso4njwAEeJMnlKXidr2atROwpTRClsvCcLDt6EtMoLp oLjYf+Mz0yB01Pwu31oni+s/LemvzejzOB7QfFHpPRXfaYyTZqw/wqCwZ BBEAni/h7bV8VEHICRpLb3/Zd5ySnAGxgBHaTwxZGh4rW7oY+OV9sdLKk Qbmwlbtn+8hbv1eHpSHisddJ8k/eC5tuZ36Q3BsJuQIC9Q3b4JZeGlC3s WwsVmHp+sebWd5PnHY07C3kuBsaTcb898C7AoTmFnvZ+DHn88SZmIM3Hu zUcrucSb8uKtfBBOiaje+WgpgYy/w+319UuOnVSZ6x1ae6DNHGtXe5jfA Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10446"; a="294103064" X-IronPort-AV: E=Sophos;i="5.93,254,1654585200"; d="scan'208";a="294103064" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Aug 2022 21:05:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,254,1654585200"; d="scan'208";a="585348046" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by orsmga006.jf.intel.com with ESMTP; 21 Aug 2022 21:05:07 -0700 Received: from fmsmsx611.amr.corp.intel.com (10.18.126.91) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Sun, 21 Aug 2022 21:05:07 -0700 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx611.amr.corp.intel.com (10.18.126.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Sun, 21 Aug 2022 21:05:06 -0700 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31 via Frontend Transport; Sun, 21 Aug 2022 21:05:06 -0700 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.172) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Sun, 21 Aug 2022 21:05:06 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kyiBHasNkfKB4RaM0moQWy27dQzDYL3S9e74Gv3mr1CbifIDl/kmfGTcrDHztnAN1fo8wkzCubo4Wj7VDswqJv6MefcDY4/vVBFX/a7InGCJSlo7UNlspXBPEIlKJhw+Oxjbfen5AoGDFYRoqXOtHx6SKdW7tX8BO7YJNLa6la03Iald+sIwiWBTURqJegmJ21Wbj7dF+gTr2X32XkvrxM4YKVolenq61jl51EWxvJ1T01AH4ez5zQjoEcOSXEAFNe4tffjTRvKt4K9KAfCzs0bH8o9S6cPI3F8scl7w2INI1nLhBLpe4bcQ+/WATd/ChhPbHKL2RyeCs4bIOyKnnQ== 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=wvMu1nvIXB5w1dT1wZ36JU6qFfNYp2gXRlsEMfSkt00=; b=Dfv45WEV3J01rbiExFWmAOoKtMQtLIq7ZrbH4BGee4dXONXBPEjVcDCbjyNGxKBkoF6lM23q7XXmrNGX3fJMiarAz7C7Y7fXRMgrXoc5IbrR/5b/Aa0cucSYS+t/nF5pvBICiQaCkkGQxXbhnwC377HZV1B2ClPczTIKNndiI4j32v2NV49UgF7nsp+NN8ybBmWX1a3lkTklbL2Kpu8BfLb2u6VJRJME+oyVmc5MkoqUWkv0XWBNhoKAsx0IE00FXOQ17KRx1iqh91MXV6Lm5LmDappMmFFoU4NS6sherOAHl1Us8dg4QLp87b2LVcpOWbqSJWvitspcSr5EyqCBWQ== 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 CO1PR11MB4945.namprd11.prod.outlook.com (2603:10b6:303:9c::8) by PH0PR11MB5644.namprd11.prod.outlook.com (2603:10b6:510:ef::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.16; Mon, 22 Aug 2022 04:05:04 +0000 Received: from CO1PR11MB4945.namprd11.prod.outlook.com ([fe80::ece8:740d:999a:e17d]) by CO1PR11MB4945.namprd11.prod.outlook.com ([fe80::ece8:740d:999a:e17d%5]) with mapi id 15.20.5546.022; Mon, 22 Aug 2022 04:05:04 +0000 From: "Wang, Jian J" To: "Vang, Judah" , "devel@edk2.groups.io" CC: "Yao, Jiewen" , "Xu, Min M" , "Mistry, Nishant C" Subject: Re: [PATCH v4 17/28] SecurityPkg: Add EncryptionVariable lib with AES Thread-Topic: [PATCH v4 17/28] SecurityPkg: Add EncryptionVariable lib with AES Thread-Index: AQHYrU81BPN1Ta+/VUirSmbhbHcOCq26XgiA Date: Mon, 22 Aug 2022 04:05:04 +0000 Message-ID: References: <20220811065337.2068-1-judah.vang@intel.com> <20220811065337.2068-18-judah.vang@intel.com> In-Reply-To: <20220811065337.2068-18-judah.vang@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-reaction: no-action dlp-version: 11.6.500.17 dlp-product: dlpe-windows authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: fd80a041-ca34-4ac4-1d9f-08da83f37e21 x-ms-traffictypediagnostic: PH0PR11MB5644:EE_ x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: h4hBWNo/lBHuHepv5/A27oRJMEpBGjhheHLyr+DohM6b2aK/ZBqtjm9ouoZfgGuuBKVu98VnXEwUZAwSLepgaRZnkxcKi4CfocPxZZDTsUP1VfMuP0pBOMAaNUGdi/e1ewvXEj6lezaku8aBSKKt1CJ7+vYwremQxB5/0bNbxLxlR3+7TC6AaQTF8kxXx1uKjMP94AAiC/qzQUOG910swYnqhc5JmTlE6A7qg/jfKSb7ujZP19IIncilDMoYsjxQIKky1HYLq2hhRPbiC1g6U024YaO4pAyg3E1TBxjcc8JfJM11WZehw6m2DAlXbxu7NfeFwnItQJNTYWy5QQUeAhsTVIz8ckwwiB8qyW6nv8BevaLFm1yecaYdSlr3JGQOY+lWC2ZIy6/eKaFf389sc7Zud1+GID9q8sHGPnfjPhFr2V5FbO4Ff9XiPiIDEg0iM7TSU3SK/bBO0u20vVW0wKwc2bpcxnXjsApAUWuYHzN3PsAcRNIHHIFtgDt+9KJrtIyIr4ZD6WyNroKLH+ItoydMvoMUMO7EB5LHIpN3jnbEad5Fr4PYampauDb/dwWYKEPGNh29e0DHUMGfuNW11DwOZ4d3huTKyiPkow3BDyK4WrLMerfxujW9t1PbSBAEzCOhWHRfdIKIPnM0F0uDMvqXiwxw5TN7B0GRpmeQ0ETCna26nrYAltemVcydrfnrJBLbEtZIVvj86LgV/0VpPnAIACCJpMZfPW0ReDNyeAkwBycau2N7TOk8cZpc6A0b3Jts+Uu0wGs0qVPD/2+0MjLjFdTUDKRt57QL/rlf614= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO1PR11MB4945.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(346002)(366004)(376002)(39860400002)(136003)(396003)(122000001)(5660300002)(66446008)(64756008)(66556008)(66946007)(66476007)(8676002)(82960400001)(38070700005)(4326008)(38100700002)(76116006)(478600001)(316002)(7696005)(6506007)(41300700001)(30864003)(966005)(19627235002)(71200400001)(52536014)(2906002)(54906003)(83380400001)(15650500001)(9686003)(53546011)(107886003)(186003)(110136005)(33656002)(8936002)(86362001)(55016003)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?j4zvVQ2bmkPuy0UIjApQeNmfteUEWSMy9yhYRxHVy7kIESuqp4Fajynsiy5c?= =?us-ascii?Q?tSqX73pFwZ4g1jE8n5+fZD9AC0jCS0JnJ5ptxDSWPnHgPASYo//YaX8+5Vhc?= =?us-ascii?Q?lyLrtjNzigw91Pzs7DoVe7nXlzehe5zMwMeEpo2mQR4/FbePuesaZiuwMM/F?= =?us-ascii?Q?mDoDmLN2l9gDyipwuWkvjDXuSvvpN3qQJFRYOmxIDicElwW2oM58Tt7mBcHa?= =?us-ascii?Q?n/OceVrynz65Q7VtBSZ2t3igMWTBL4rcm3VInJk92G4PUi3cDUuVWMfY8WiZ?= =?us-ascii?Q?gtPBFw+w9yx9wtKmfdZ4K4wgeUNVkF4MyS6kPpDbM4n5/WvdTW/vcC+fbo3R?= =?us-ascii?Q?d5/0pS4spuDjWGamwYlVOmXpulFNhbdAYEUETtMUOtQPx68eHRlLIy+9lmzu?= =?us-ascii?Q?uF7QBn52aVK6qJlJVWt2o5Y1QnnMghXLflP5Ae93JkEl1AX8RyAwMjylPjCv?= =?us-ascii?Q?OkkOdrdvo9/iP329OCct8orfyoeVBBJ/2LvvBsIsfX4+6wfKA19m5E+Ls+L7?= =?us-ascii?Q?kRfxSkmJApe29Blzi3d11Dy6aNeyWHVIg0wNrNh25E7E7F9StM3TdZd7b8mJ?= =?us-ascii?Q?27boy9H+JqJWK1o6IHjkSDviyesGuFHTy1MN1m+neoAY+9jZnB/2P0KQThWi?= =?us-ascii?Q?l6bwSPn9C9CRO15neRh4SUHtEu8FJj1wIA25rIlHXUiTxRSWlCB+gmfBHFtC?= =?us-ascii?Q?aXMHBy4j2jaU5IJLhx3YiBoxHwRi7qP3PfciPAwq1MS1BpVBYfQ99J61/qfq?= =?us-ascii?Q?BtuTcAcVnq/RPLu/lw9TWktjYUr79lNh1w13sXn+WMuMuxAeSktwpmf286as?= =?us-ascii?Q?fHP/n2O0QZoPERX7tuseS6zAAjv/MJC+7btH3xVp6DZVh1GS95uLMB+7HIuP?= =?us-ascii?Q?RdXoss/d1N/Muc+ZAYaDETAuoVYLkswuKXbbY8zhFeUJhBiDhUgSyT0/MCQD?= =?us-ascii?Q?h1CTl/Z8Q7QGSMjE3aeQ6xC2sEe44JNoo1jk11GZ6vTQxMt9Wol9s1H2owDl?= =?us-ascii?Q?EpRq316fgD2CJ7OGW6hD5k9xJF1wqDJmNDzB+QqpAvUD2wDD2aPEIOWRBVD8?= =?us-ascii?Q?R8WAd/whpzhh5OVBq7BssDYrD6WC2O6mW+XBBOv/26cy6Hd5+BJcoT0fyOH7?= =?us-ascii?Q?JeBzYKJB3So4v9Dgj3pJIrZffCZLBiie4E0TTdPhT7GQOVji6R4mrRUCmi8J?= =?us-ascii?Q?XKPxoooRpl0D/0SY1H+3i8c7vs2ZP+qwbH07P0oWBFbXt1FnFLgYP0VRGojp?= =?us-ascii?Q?HzfrzoBpvLqwwhmaQlS32GMJ7WKeh7gznGfiAWwomh2j89nKCmndkH03xTuS?= =?us-ascii?Q?8EQ2u6dZl/URGBW7ytSHmi2IZi/+UduMi9Or3WGo7pYpjALdBQo1ovHv+j1K?= =?us-ascii?Q?Qc6ehEtXzp4EoyTT9vOWRcpoavqdQi2hq4GpdWeV/t2E7nK7r5KSbF+TLCeY?= =?us-ascii?Q?DPPtSiL4ArEcL9eRzJk9ECQ6UODuSCS04m6kMR5ZZNAxUk5suUgcXwHEJF3G?= =?us-ascii?Q?h+kFxfweqLBhVxVGXqOQEnDXxzCG3cClcfidVWKMuTrdL0YUENC4tM9N0Qw+?= =?us-ascii?Q?u+maoD6/+fTfixLrVgmOoafhvUIhXft1FLCsaJPu9JgHOlAt8jJFEATGlYLO?= =?us-ascii?Q?aQoxx9180+mh5l7LwgHnHmWnQbfLmuATtBsfsEoDEbB3?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CO1PR11MB4945.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: fd80a041-ca34-4ac4-1d9f-08da83f37e21 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Aug 2022 04:05:04.2581 (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: diRr66j0+77E/7lz1j04pht5ntJKpNZaXfRR+IsMB7DSU21o/+2KvuPZormMQojWdIybWfraDUDC2AlhYUZbDA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5644 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 Reviewed-by: Jian J Wang Regards, Jian > -----Original Message----- > From: Vang, Judah > Sent: Thursday, August 11, 2022 2:53 PM > To: devel@edk2.groups.io > Cc: Wang, Jian J ; Yao, Jiewen ; > Xu, Min M ; Mistry, Nishant C > > Subject: [PATCH v4 17/28] 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. > + > + @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 ( > + 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. > + > + 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. > + > + @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