From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90899+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90899+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530367; cv=none; d=zohomail.com; s=zohoarc; b=e+vxA8rgeu+mEWVg6nlIWH/3gDEL8UbBDzo5SirzbvG0ErIg4obOBbaJwV3l4agpVWYPFQoozkPmKDqvoGNhQDXZf1x5vLIGmfvkwYH+T8T/iAT5X9YzeX0QdOt9RGTQ86IVf2jZBDEG32gwoJPWPLnGdt3o5ZQDJHIyqJrxiy4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530367; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=aXX+3Dn4BaQJBMymn5JgNkPHGli5zexu6Du+8NBjisE=; b=H+nOEcWmQeO4BRHKOcgf78zAFaWG20dQSX3gqUd2MdrYff2zKssWDRBG4vZd9gh8TBIWTRIfc57qvg79jCvW8OkChyyZx2K4iezfuUS0xNqeeAR66r1HKfVn3A/NRbFeoVjeAeKsUdmhED16Q2gW1nk5Cb9HKNxCcWcZaH9IqBo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90899+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530367466225.83749394709332; Wed, 29 Jun 2022 12:19:27 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id KnuAYY1788612xAlkRXjFwf6; Wed, 29 Jun 2022 12:19:27 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.15929.1656530366289552746 for ; Wed, 29 Jun 2022 12:19:26 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3305714BF; Wed, 29 Jun 2022 12:19:26 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id F201B3F792; Wed, 29 Jun 2022 12:19:23 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 1/9] MdePkg/DrbgLib: Drbg library interface definition Date: Wed, 29 Jun 2022 21:18:38 +0200 Message-Id: <20220629191848.2619317-2-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: 7UEMlRzAqJm4fVHNmIP8KJC1x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530367; bh=wEuD5Z+gX9dxghT1S20DOpFatWideF+q1ymvl3b5xA4=; h=Cc:Date:From:Reply-To:Subject:To; b=HYkyCYnMZzDq+1Qzjy4Mx4AlCzXXBrpbUXRPnAVdM/j/p6XyC9TBD57PhHAW1PkfWjO DtNFyxMSw5o/B51+gNdnicFNR9Ha3V+UaznkjtNW9t0m7Rccz8QGZ4CEyuERHUYz6omb8 IUR/CAVryDpIsf4z2iJgtGAbKg0YeORadO8= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530368207100001 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois The NIST Special Publication 800-90A, 800-90B and 800-90C details how to implement a Deterministic Random Bits Generator (DRBG). Add a library interface definition for interacting with a Drbg. Signed-off-by: Pierre Gondois Signed-off-by: Sami Mujawar --- MdePkg/Include/Library/DrbgLib.h | 172 +++++++++++++++++++++++++++++++ MdePkg/MdePkg.dec | 4 + 2 files changed, 176 insertions(+) create mode 100644 MdePkg/Include/Library/DrbgLib.h diff --git a/MdePkg/Include/Library/DrbgLib.h b/MdePkg/Include/Library/Drbg= Lib.h new file mode 100644 index 000000000000..aad46dbec228 --- /dev/null +++ b/MdePkg/Include/Library/DrbgLib.h @@ -0,0 +1,172 @@ +/** @file + DRBG library. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#ifndef DRBG_LIB_H_ +#define DRBG_LIB_H_ + +/** Drbg Mechanisms. +*/ +typedef enum { + DrbgMechansimHash =3D 0, ///< Hash (not supported yet) + DrbgMechansimHmac, ///< HMAC (not supported yet) + DrbgMechansimCtr, ///< CTR + DrbgMechansimMax ///< Maximum value. +} DRBG_MECHANISM; + +/** Drbg Entropy sources. +*/ +typedef enum { + /// Cf. [3] s10.3.3.1 + /// Construction When a Conditioning Function is not Used + DrbgEntropyNoCondFn =3D 0, + /// Cf. [3] s10.3.3.2 (no supported yet) + /// Construction When a Vetted Conditioning Function is Used + /// and Full Entropy is Not Required) + DrbgEntropyNoFullEntropy, + /// Cf. [3] s10.3.3.3 (no supported yet) + /// Construction When a Vetted Conditioning Function is Used + /// to Obtain Full Entropy Bitstrings + DrbgEntropyFullEntropy, + /// Maximum value. + DrbgEntropyMax +} DRBG_ENTROPY_SRC; + +/** Reseed a DRBG instance. + + Implementation of Reseed_function. + Cf. [1] s9.2 'Reseeding a DRBG Instantiation' + + @param [in] PredResRequest Indicates whether prediction resistance + is to be provided during the request. + Might not be supported by all Drbgs. + @param [in] AddInput An optional additional input. + Might not be supported by all Drbgs. + @param [in] AddInputLen Additional input length (in bits). + Might not be supported by all Drbgs. + @param [in, out] Handle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgReseedFn ( + IN BOOLEAN PredResRequest, + IN CONST CHAR8 *AddInput, + IN UINTN AddInputLen, + IN OUT VOID *Handle + ); + +/** Create a Drbg instance. + + Implementation of Instantiate_function. + Cf. [1] s9.1 Instantiating a DRBG + + @param [in] DrbgMechanism DRBG mechanism chosen. + @param [in] DrbgEntropySrc Entropy source chosen. + @param [in] ReqSecStrength Requested security strength (in bits). + The security strenght granted can be diffe= rent. + @param [in] PredRes Prediction resistance flag. + If relevant, instantiate a DRBG that suppo= rts + prediction resistance. + Might not be supported by all Drbgs. + @param [in] PersStr Personnalization string. + Might not be supported by all Drbgs. + @param [in] PersStrLen Personnalization string length (in bits). + Might not be supported by all Drbgs. + @param [out] HandlePtr Pointer containting the created Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgInstantiateFn ( + IN DRBG_MECHANISM DrbgMechanism, + IN DRBG_ENTROPY_SRC DrbgEntropySrc, + IN UINTN ReqSecStrength, + IN BOOLEAN PredRes, + IN CONST CHAR8 *PersStr, + IN UINTN PersStrLen, + OUT VOID **HandlePtr + ); + +/** Generate a random number. + + Implementation of Generate_function. + Cf. [1] s9.3.1 The Generate Function + + @param [in] ReqSecStrength Requested security strength (in bits). + If the DrbgHandle cannot satisfy the reque= st, + an error is returned. + @param [in] PredResReq Request prediction resistance. + If the DrbgHandle cannot satisfy the reque= st, + an error is returned. + @param [in] AddInput Additional input. + Might not be supported by all Drbgs. + @param [in] AddInputLen Additional input length (in bits). + Might not be supported by all Drbgs. + @param [in] ReqNbBits Number of random bits requested. + @param [in, out] OutBuffer If success, contains the random bits. + The buffer must be at least ReqNbBits bits + long. + @param [in, out] Handle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgGenerateFn ( + IN UINTN ReqSecStrength, + IN BOOLEAN PredResReq, + IN CONST CHAR8 *AddInput, + IN UINTN AddInputLen, + IN UINTN ReqNbBits, + IN OUT UINT8 *OutBuffer, + IN OUT VOID *Handle + ); + +/** Remove a DRBG instance. + + Implementation of Uninstantiate_function. + Cf. [1] s9.4 Removing a DRBG Instantiation + + @param [in, out] Handle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +DrbgUninstantiateFn ( + IN OUT VOID *Handle + ); + +#endif // DRBG_LIB_H_ diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 078ae9323ba6..e96f875f1e91 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -284,6 +284,10 @@ [LibraryClasses] # AesLib|Include/Library/AesLib.h =20 + ## @libraryclass A library to have a Deterministic Random Bits Generat= or (DRBG). + # + DrbgLib|Include/Library/DrbgLib.h + [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] ## @libraryclass Provides services to generate random number. # --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90899): https://edk2.groups.io/g/devel/message/90899 Mute This Topic: https://groups.io/mt/92072284/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90900+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90900+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530369; cv=none; d=zohomail.com; s=zohoarc; b=WwOwWgRiX18KBK2bjDIqT3QTJToHkGO8tYxXjDidxTTyDX0qKYuWmu1RnLiK4jDSE39kwW3SRIxZkNQPzWYHdiKpw9n9OBHueeKwEu6xHocoVoveJLEgrZgZLB4p6vQOzh2vqPwQVFgmxxckkHtadJoLKunTpGjtvEVAFFeGuiA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530369; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=uUDnbUJJHz6r6xaR9PjhhFjTT6DwV61OjxJTDb2Hw5g=; b=jnwLT7q0tjguX5yYFF1tRFeL5B1Y5N90e25J76uGalQfJPg4mh+VhuZCUKINHoJPp+FeSOSw3XN5lFrgcvN8t0sqpgHM43jcnatTH98tWX835LC2NdbsTDWpTzrnNDmZHY6WrcYc45vMMTA/NFPVPMkXSCbGOgfelJqrkETYUlQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90900+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530369789719.4780144849237; Wed, 29 Jun 2022 12:19:29 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id iXFRYY1788612xrzWwZ73wlK; Wed, 29 Jun 2022 12:19:29 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.15930.1656530368715647399 for ; Wed, 29 Jun 2022 12:19:28 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9E335152B; Wed, 29 Jun 2022 12:19:28 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 549FA3F792; Wed, 29 Jun 2022 12:19:26 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 2/9] MdePkg/DrbgLib: Add NULL instance of Drbg Library Date: Wed, 29 Jun 2022 21:18:39 +0200 Message-Id: <20220629191848.2619317-3-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: hkCIHLMAgA18Nvh4jYbJuGtYx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530369; bh=4lH8R1wjO8tRGkfuWpu1/PE4Z8jZM020K+gNHDtjebw=; h=Cc:Date:From:Reply-To:Subject:To; b=PUBHJZHDNxN1Ies64FIdG1H3PTQZERT7VreJVfXdzx2gTBp24fzMgKyjBgGuKP4TGth MKAQCEDa1YzE5kQx/QOaOP3dG2D8bNicRI09F3l7dscE0pB8Gqyn3/9mNhovhuX908EO7 YpmA0kFmGyIoSn5mmYi9QxTeFxtqgO5jdjw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530370158100005 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois Add a Null instance of the DrbgLib satisfy potential build dependencies issues. Signed-off-by: Pierre Gondois --- MdePkg/Library/DrbgLibNull/DrbgLib.c | 165 +++++++++++++++++++++ MdePkg/Library/DrbgLibNull/DrbgLibNull.inf | 21 +++ MdePkg/MdePkg.dsc | 1 + 3 files changed, 187 insertions(+) create mode 100644 MdePkg/Library/DrbgLibNull/DrbgLib.c create mode 100644 MdePkg/Library/DrbgLibNull/DrbgLibNull.inf diff --git a/MdePkg/Library/DrbgLibNull/DrbgLib.c b/MdePkg/Library/DrbgLibN= ull/DrbgLib.c new file mode 100644 index 000000000000..e366843b03f0 --- /dev/null +++ b/MdePkg/Library/DrbgLibNull/DrbgLib.c @@ -0,0 +1,165 @@ +/** @file + Drbg library. + Cf. [1] s9 DRBG Mechanism Functions + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + - [5] Unified Extensible Firmware Interface (UEFI) Specification, + Version 2.8 Errata B, May 2020 + (https://www.uefi.org/specifications) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#include +#include +#include + +/** Reseed a DRBG instance. + + Implementation of Reseed_function. + Cf. [1] s9.2 'Reseeding a DRBG Instantiation' + + @param [in] PredResRequest Indicates whether prediction resistance + is to be provided during the request. + Might not be supported by all Drbgs. + @param [in] AddInput An optional additional input. + Might not be supported by all Drbgs. + @param [in] AddInputLen Additional input length (in bits). + Might not be supported by all Drbgs. + @param [in, out] Handle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgReseedFn ( + IN BOOLEAN PredResRequest, + IN CONST CHAR8 *AddInput, + IN UINTN AddInputLen, + IN OUT VOID *Handle + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +/** Create a Drbg instance. + + Implementation of Instantiate_function. + Cf. [1] s9.1 Instantiating a DRBG + + @param [in] DrbgMechanism DRBG mechanism chosen. + @param [in] DrbgEntropySrc Entropy source chosen. + @param [in] ReqSecStrength Requested security strength (in bits). + The security strenght granted can be diffe= rent. + @param [in] PredRes Prediction resistance flag. + If relevant, instantiate a DRBG that suppo= rts + prediction resistance. + Might not be supported by all Drbgs. + @param [in] PersStr Personnalization string. + Might not be supported by all Drbgs. + @param [in] PersStrLen Personnalization string length (in bits). + Might not be supported by all Drbgs. + @param [out] HandlePtr Pointer containting the created Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgInstantiateFn ( + IN DRBG_MECHANISM DrbgMechanism, + IN DRBG_ENTROPY_SRC DrbgEntropySrc, + IN UINTN ReqSecStrength, + IN BOOLEAN PredRes, + IN CONST CHAR8 *PersStr, + IN UINTN PersStrLen, + OUT VOID **HandlePtr + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +/** Generate a random number. + + Implementation of Generate_function. + Cf. [1] s9.3.1 The Generate Function + + @param [in] ReqSecStrength Requested security strength (in bits). + If the DrbgHandle cannot satisfy the reque= st, + an error is returned. + @param [in] PredResReq Request prediction resistance. + If the DrbgHandle cannot satisfy the reque= st, + an error is returned. + @param [in] AddInput Additional input. + Might not be supported by all Drbgs. + @param [in] AddInputLen Additional input length (in bits). + Might not be supported by all Drbgs. + @param [in] ReqNbBits Number of random bits requested. + @param [in, out] OutBuffer If success, contains the random bits. + The buffer must be at least ReqNbBits bits + long. + @param [in, out] Handle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgGenerateFn ( + IN UINTN ReqSecStrength, + IN BOOLEAN PredResReq, + IN CONST CHAR8 *AddInput, + IN UINTN AddInputLen, + IN UINTN ReqNbBits, + IN OUT UINT8 *OutBuffer, + IN OUT VOID *Handle + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} + +/** Remove a DRBG instance. + + Implementation of Uninstantiate_function. + Cf. [1] s9.4 Removing a DRBG Instantiation + + @param [in, out] Handle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +DrbgUninstantiateFn ( + IN OUT VOID *Handle + ) +{ + ASSERT (FALSE); + return EFI_UNSUPPORTED; +} diff --git a/MdePkg/Library/DrbgLibNull/DrbgLibNull.inf b/MdePkg/Library/Dr= bgLibNull/DrbgLibNull.inf new file mode 100644 index 000000000000..6e17af4390fc --- /dev/null +++ b/MdePkg/Library/DrbgLibNull/DrbgLibNull.inf @@ -0,0 +1,21 @@ +## @file +# Drbg Null library +# +# Copyright (c) 2022, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D DrbgLib + FILE_GUID =3D B8A688E5-C31A-4CF8-9A76-B31211D292DE + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + LIBRARY_CLASS =3D DrbgLib + +[Sources] + DrbgLib.c + +[Packages] + MdePkg/MdePkg.dec diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 726350c215e5..4820cecd0db8 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -69,6 +69,7 @@ [Components] MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf MdePkg/Library/BaseTrngLibNull/BaseTrngLibNull.inf MdePkg/Library/AesLibNull/AesLibNull.inf + MdePkg/Library/DrbgLibNull/DrbgLibNull.inf =20 MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90900): https://edk2.groups.io/g/devel/message/90900 Mute This Topic: https://groups.io/mt/92072285/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90901+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90901+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530372; cv=none; d=zohomail.com; s=zohoarc; b=F62QtZTJoogPWG0siaIfJTuq03pRCxyO9olO3VvvbPxIhXDhitCwtvqkM6pNnxcFosV9WyFJiuUVyxqfjAOMczelDBIyK9SG3K2BlZeQxaQABpXgCUci/OAPKt3CytEwQipNlrdBJNhlq+LOnYyeNNkaNRghOmNApzvW2Q557gw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530372; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=Cfh+0eW/wYBJDSkd2EAyOqvG+99dv4dJxE/tOTlwJkU=; b=e9WTppSIsST1u1NthpMxnVNQBwf85YfTmuYEbX1Jdst9S/EOWAsY8v0vDo8DhEtITl7fU6+fC1DJLtKvkqc6vcMf6bpY4RRSsOL1qUx97Wd4+u+rQb0NpiyfL+k99aDJHB2gy+6SbUh2JWW9ibgjjpcC04FnNd0Ut443PSM5qT8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90901+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530372583498.01477691433456; Wed, 29 Jun 2022 12:19:32 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id H1vuYY1788612x7aQoqOJ8dX; Wed, 29 Jun 2022 12:19:32 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.15689.1656530371400271688 for ; Wed, 29 Jun 2022 12:19:31 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4D85B1480; Wed, 29 Jun 2022 12:19:31 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C44F93F792; Wed, 29 Jun 2022 12:19:28 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 3/9] MdePkg/DrbgLib: Add BitStream implementation Date: Wed, 29 Jun 2022 21:18:40 +0200 Message-Id: <20220629191848.2619317-4-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: IM4JX1Oc4OIpfm3f4UFvRhHjx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530372; bh=BCs3J9HchKAEKXWQQzPcLtJ1P2zQymAKspDNjX75oDE=; h=Cc:Date:From:Reply-To:Subject:To; b=YfbLzS877SIiNf6kjc0KT44wmyxlt7sM3W3TzSFqHasOijdFExSDOTcqPDx33RcUwo+ RMLq2wddQvIjZmWGslJQzYiuSXidwAFWO0ISN+TFNrT72LfkIAGXxuZHzxGdA8zWVBoKQ Q2arDDl0SCrnwze18uCaZbl98VV7iMMU+po= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530374248100002 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois The Ctr Drbg does bitstream operations (additions, right/left shifting, ...). To have a clearer implementation of the NIST specifications, add a BitStream representation. Signed-off-by: Pierre Gondois Signed-off-by: Sami Mujawar --- MdePkg/Library/DrbgLib/BitStream.c | 1114 ++++++++++++++++++++++++++++ MdePkg/Library/DrbgLib/BitStream.h | 366 +++++++++ 2 files changed, 1480 insertions(+) create mode 100644 MdePkg/Library/DrbgLib/BitStream.c create mode 100644 MdePkg/Library/DrbgLib/BitStream.h diff --git a/MdePkg/Library/DrbgLib/BitStream.c b/MdePkg/Library/DrbgLib/Bi= tStream.c new file mode 100644 index 000000000000..1ae114fef803 --- /dev/null +++ b/MdePkg/Library/DrbgLib/BitStream.c @@ -0,0 +1,1114 @@ +/** @file + BitStream utility. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +#include "BitStream.h" + +/** Check whether a BitStream is NULL (null length). + + @param [in] Stream The BitStream. + + @retval TRUE if the BitStream is NULL (null length). + @retval FALSE otherwise. +**/ +BOOLEAN +EFIAPI +IsBitStreamEmpty ( + IN BIT_STREAM *Stream + ) +{ + return ((Stream =3D=3D NULL) || + (Stream->BitLen =3D=3D 0) || + (Stream->Data =3D=3D NULL)); +} + +/** Convert bits to bytes (rounds down). + + @param [in] Bits Bits. + + @return Bytes. +**/ +UINTN +EFIAPI +BitsToLowerBytes ( + IN UINTN Bits + ) +{ + return Bits >> 3; +} + +/** Convert bits to bytes (rounds up). + + @param [in] Bits Bits. + + @return Bytes. +**/ +UINTN +EFIAPI +BitsToUpperBytes ( + IN UINTN Bits + ) +{ + return ((Bits + 0x7) >> 3); +} + +/** Get the BitStream length (in bits). + + @param [in] Stream The BitStream. + + @return Length of the BitStream (in bits). +**/ +UINTN +EFIAPI +BitStreamBitLen ( + IN BIT_STREAM *Stream + ) +{ + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return 0; + } + + return Stream->BitLen; +} + +/** Get the BitStream length (in bytes). + + @param [in] Stream The BitStream. + + @return Length of the BitStream (in bytes). +**/ +UINTN +EFIAPI +BitStreamByteLen ( + IN BIT_STREAM *Stream + ) +{ + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return 0; + } + + return Stream->ByteLen; +} + +/** Get the BitStream data buffer. + + @param [in] Stream The BitStream. + + @return Data buffer of the BitStream (can be NULL). +**/ +UINT8 * +EFIAPI +BitStreamData ( + IN BIT_STREAM *Stream + ) +{ + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return 0; + } + + return Stream->Data; +} + +/** Clear the unsused bits of a Stream. + + For instance, if a stream is 5 bits long, then: + - bits[7:5] must be cleared. + - bits[4:0] must be preserved. + + @param [in, out] Stream The BitStream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +BitStreamClearUnusedBits ( + IN OUT BIT_STREAM *Stream + ) +{ + UINT8 UsedBits; + + if (IsBitStreamEmpty (Stream)) { + ASSERT (!IsBitStreamEmpty (Stream)); + return EFI_INVALID_PARAMETER; + } + + // Clear the unsused bits of the Stream. + // BitStream are big-endian, so MSByte is at index 0. + UsedBits =3D Stream->BitLen & 0x7; + if (UsedBits !=3D 0) { + Stream->Data[0] &=3D (0XFF >> (8 - UsedBits)); + } + + return EFI_SUCCESS; +} + +/** Allocate a buffer of BitLen (bits) for BitStream. + + @param [in] BitLen Length of the buffer to allocate (in bits). + @param [out] Stream The BitStream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +STATIC +EFI_STATUS +EFIAPI +BitStreamShallowAlloc ( + IN UINTN BitLen, + OUT BIT_STREAM *Stream + ) +{ + UINTN ByteLen; + + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + ZeroMem (Stream, sizeof (BIT_STREAM)); + + if (BitLen =3D=3D 0) { + return EFI_SUCCESS; + } + + ByteLen =3D BitsToUpperBytes (BitLen); + Stream->Data =3D (UINT8 *)AllocateZeroPool (ByteLen); + if (Stream->Data =3D=3D NULL) { + ASSERT (Stream->Data !=3D NULL); + return EFI_OUT_OF_RESOURCES; + } + + Stream->BitLen =3D BitLen; + Stream->ByteLen =3D ByteLen; + + return EFI_SUCCESS; +} + +/** Allocate a BitStream of BitLen (bits). + + @param [in] BitLen Length of the BitStream (in bits). + @param [out] Stream The BitStream to allocate. + Must be NULL initialized. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamAlloc ( + IN UINTN BitLen, + OUT BIT_STREAM **Stream + ) +{ + EFI_STATUS Status; + BIT_STREAM *LocStream; + + // Non NULL initialized pointers are considered invalid. + if ((Stream =3D=3D NULL) || + (*Stream !=3D NULL)) + { + ASSERT (Stream !=3D NULL); + ASSERT (*Stream =3D=3D NULL); + return EFI_INVALID_PARAMETER; + } + + LocStream =3D AllocateZeroPool (sizeof (BIT_STREAM)); + if (LocStream =3D=3D NULL) { + ASSERT (LocStream !=3D NULL); + return EFI_OUT_OF_RESOURCES; + } + + Status =3D BitStreamShallowAlloc (BitLen, LocStream); + if (EFI_ERROR (Status)) { + FreePool (LocStream); + ASSERT_EFI_ERROR (Status); + return Status; + } + + *Stream =3D LocStream; + + return EFI_SUCCESS; +} + +/** Free the buffer of the BitStream. + + This is a shallow free, so the BitStream structure itself if not freed. + + @param [in, out] Stream BitStream to free the buffer of. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +BitStreamShallowFree ( + IN OUT BIT_STREAM *Stream + ) +{ + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + if (Stream->Data !=3D NULL) { + FreePool (Stream->Data); + } + + ZeroMem (Stream, sizeof (BIT_STREAM)); + + return EFI_SUCCESS; +} + +/** Free a BitStream. + + @param [in, out] Stream BitStream to free. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +BitStreamFree ( + IN OUT BIT_STREAM **Stream + ) +{ + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + BitStreamShallowFree (*Stream); + FreePool (*Stream); + *Stream =3D NULL; + + return EFI_SUCCESS; +} + +/** Initialize a BitStream with a buffer. + + The input Buffer is copied to a BitStream buffer. + + @param [in] Buffer Buffer to init the Data of the BitStream with. + The Buffer must be big-endian (MSByte at index 0= ). + @param [in] BitLen Length of the Buffer (in bits). + @param [out] Stream BitStream to initialize. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamInit ( + IN CONST UINT8 *Buffer, + IN UINTN BitLen, + OUT BIT_STREAM **Stream + ) +{ + EFI_STATUS Status; + + // Non NULL initialized pointers are considered invalid. + if ((Stream =3D=3D NULL) || + (*Stream !=3D NULL) || + ((Buffer =3D=3D NULL) ^ (BitLen =3D=3D 0))) + { + ASSERT (Stream !=3D NULL); + ASSERT (*Stream =3D=3D NULL); + ASSERT (!((Buffer =3D=3D NULL) ^ (BitLen =3D=3D 0))); + return EFI_INVALID_PARAMETER; + } + + Status =3D BitStreamAlloc (BitLen, Stream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // BitStream are big-endian, i.e. MSByte is at index 0, + // so just copy the input Buffer. + CopyMem ((*Stream)->Data, Buffer, (*Stream)->ByteLen); + + return EFI_SUCCESS; +} + +/** Fill a Buffer with a Stream Data. + + The Buffer will be big-endian. + + @param [in] Stream Stream to take the Data from. + @param [out] Buffer Buffer where to write the Data. + Must be at least BitStreamByteLen (Stream) + bytes long. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +BitStreamToBuffer ( + IN BIT_STREAM *Stream, + OUT UINT8 *Buffer + ) +{ + if (IsBitStreamEmpty (Stream) || + (Buffer =3D=3D NULL)) + { + ASSERT (!IsBitStreamEmpty (Stream)); + ASSERT (Buffer !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + CopyMem (Buffer, Stream->Data, Stream->ByteLen); + + return EFI_SUCCESS; +} + +/** Shallow clone a BitStream. + + @param [out] StreamDest Shallow cloned BiStream. + @param [in] StreamSrc Source BitStream to shallow clone. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +BitStreamShallowClone ( + OUT BIT_STREAM *StreamDest, + IN BIT_STREAM *StreamSrc + ) +{ + if ((StreamDest =3D=3D NULL) || + (StreamSrc =3D=3D NULL)) + { + ASSERT (StreamDest !=3D NULL); + ASSERT (StreamSrc !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + CopyMem (StreamDest, StreamSrc, sizeof (BIT_STREAM)); + return EFI_SUCCESS; +} + +/** Clone a BitStream. + + @param [out] StreamDest Cloned BiStream. + @param [in] StreamSrc Source BitStream to clone. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamClone ( + OUT BIT_STREAM **StreamDest, + IN BIT_STREAM *StreamSrc + ) +{ + EFI_STATUS Status; + + if ((StreamDest =3D=3D NULL) || + (StreamSrc =3D=3D NULL)) + { + ASSERT (StreamDest !=3D NULL); + ASSERT (StreamSrc !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + Status =3D BitStreamInit (StreamSrc->Data, StreamSrc->BitLen, StreamDest= ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall through. + } + + return Status; +} + +/** Replace an initialized BitStream with another. + + This function frees StreamRepl's Data if success. + + @param [in, out] StreamRepl Stream whose content is replaced. + @param [in] StreamData Stream containing the Data to use. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamReplace ( + IN OUT BIT_STREAM *StreamRepl, + IN BIT_STREAM *StreamData + ) +{ + EFI_STATUS Status; + + if ((StreamRepl =3D=3D NULL) || + (StreamData =3D=3D NULL)) + { + ASSERT (StreamRepl !=3D NULL); + ASSERT (StreamData !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + Status =3D BitStreamShallowFree (StreamRepl); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamShallowClone (StreamRepl, StreamData); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // StreamRepl's content was freed. Can't do much now. + // Fall through. + } + + return Status; +} + +/** Write a buffer to a BitStream. + + @param [in] Buffer Buffer to write to the BitStream. + Buffer is big-endian. + @param [in] StartBitIndex Bit index to start writing from. + @param [in] BitCount Count of bits to write. + @param [in, out] Stream BitStream to write to. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamWrite ( + IN UINT8 *Buffer, + IN UINTN StartBitIndex, + IN UINTN BitCount, + IN OUT BIT_STREAM *Stream + ) +{ + UINTN EndByteIndex; + UINTN EndBitIndex; + UINT8 StartBitRemainder; + UINT8 EndBitRemainder; + UINT8 *Data; + UINT8 ShiftR; + UINT8 ShiftL; + UINT8 BitMask; + UINTN ByteCount; + + if (((Buffer !=3D NULL) ^ (BitCount !=3D 0)) || + IsBitStreamEmpty (Stream) || + (StartBitIndex > (MAX_UINTN - BitCount)) || + ((StartBitIndex + BitCount) > Stream->BitLen)) + { + ASSERT (!((Buffer !=3D NULL) ^ (BitCount !=3D 0))); + ASSERT (!IsBitStreamEmpty (Stream)); + ASSERT (StartBitIndex <=3D (MAX_UINTN - BitCount)); + ASSERT ((StartBitIndex + BitCount) <=3D Stream->BitLen); + return EFI_INVALID_PARAMETER; + } + + ByteCount =3D BitsToUpperBytes (BitCount); + + if (BitCount =3D=3D 0) { + // Nothing to do. + return EFI_SUCCESS; + } + + EndByteIndex =3D Stream->ByteLen - 1 - + BitsToLowerBytes (StartBitIndex + BitCount - 1); + EndBitIndex =3D StartBitIndex + BitCount; + Data =3D &Stream->Data[EndByteIndex]; + + StartBitRemainder =3D StartBitIndex & 0x7; + EndBitRemainder =3D EndBitIndex & 0x7; + + ShiftL =3D StartBitRemainder; + ShiftR =3D 8 - ShiftL; + + // BitCount might not be a multiple of 8. These MsBits can also + // be spread on 2 bytes (in StreamIn). + if ((StartBitRemainder < EndBitRemainder) || (EndBitRemainder =3D=3D 0))= { + BitMask =3D 0xFF << StartBitRemainder; + if (EndBitRemainder !=3D 0) { + BitMask ^=3D 0xFF << EndBitRemainder; + } + + *Data =3D (*Data & ~BitMask) | ((*Buffer++ << ShiftL) & BitMask); + + ByteCount--; + BitCount -=3D (BitCount & 0x7); + + if (StartBitRemainder =3D=3D 0) { + Data++; + } + } else if (StartBitRemainder > EndBitRemainder) { + BitMask =3D ~(0xFF << EndBitRemainder); + *Data =3D (*Data & ~BitMask) | ((*Buffer >> ShiftR) & BitMask); + Data++; + + BitMask =3D 0xFF << StartBitRemainder; + *Data =3D (*Data & ~BitMask) | ((*Buffer++ << ShiftL) & BitMask); + + ByteCount--; + BitCount -=3D (ShiftR + 8 - EndBitRemainder); + } + + // else (StartBitRemainder =3D=3D EndBitRemainder), nothing to do + + // From here, (BitCount % 8) =3D=3D 0 so we copy whole bytes from the Bu= ffer. + // It doesn't mean we are byte-aligned, so check if the alignment of + // StartBitIndex. + if (ShiftL =3D=3D 0) { + // StartBitIndex is byte aligned, + if (ByteCount) { + CopyMem (Data, Buffer, ByteCount); + } + } else { + // StartBitIndex is not byte aligned. + BitMask =3D 0xFF << (StartBitIndex & 0x7); + while (ByteCount--) { + *Data =3D (*Data & BitMask) | ((*Buffer >> ShiftR) & ~BitMask); + Data++; + *Data =3D (*Data & ~BitMask) | ((*Buffer++ << ShiftL) & BitMask); + } + } + + return EFI_SUCCESS; +} + +/** XoR two BitStreams. + + We must have len(StremA) =3D len(StreamB) + + @param [in] StreamA BitStream A. + @param [in] StreamB BitStream B. + @param [out] StreamOut Output BitStream. + Can be *StreamA or *StreamB to replace their + content with the new stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamXor ( + IN BIT_STREAM *StreamA, + IN BIT_STREAM *StreamB, + OUT BIT_STREAM **StreamOut + ) +{ + EFI_STATUS Status; + BIT_STREAM *LocStream; + UINTN ByteLen; + UINTN *DataLocN; + UINT8 *DataLoc8; + UINTN *DataAN; + UINT8 *DataA8; + UINTN *DataBN; + UINT8 *DataB8; + UINTN ByteLenN; + UINTN ByteLen8; + UINTN Offset; + + if ((StreamA =3D=3D NULL) || + (StreamB =3D=3D NULL) || + (StreamOut =3D=3D NULL) || + (StreamA->BitLen !=3D StreamB->BitLen)) + { + ASSERT (StreamA !=3D NULL); + ASSERT (StreamB !=3D NULL); + ASSERT (StreamOut !=3D NULL); + ASSERT (StreamA->BitLen =3D=3D StreamB->BitLen); + return EFI_INVALID_PARAMETER; + } + + if (StreamB->BitLen =3D=3D 0) { + // Nothing to do. + return EFI_SUCCESS; + } + + if (*StreamOut =3D=3D StreamA) { + LocStream =3D StreamA; + } else if (*StreamOut =3D=3D StreamB) { + LocStream =3D StreamB; + } else { + LocStream =3D NULL; + + Status =3D BitStreamAlloc (StreamA->BitLen, &LocStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + ByteLen =3D StreamA->ByteLen; + + DataLocN =3D (UINTN *)LocStream->Data; + DataAN =3D (UINTN *)StreamA->Data; + DataBN =3D (UINTN *)StreamB->Data; + // Speed up the process by taking chunks of UINTN instead of UINT8. + // ((sizeof (UINTN) >> 2) + 1) is 3 or 2 depending on the size of UINTN. + ByteLenN =3D ByteLen >> (((sizeof (UINTN) >> 2) + 1)); + ByteLen8 =3D ByteLen & ((sizeof (UINTN) - 1)); + while (ByteLenN-- > 0) { + DataLocN[ByteLenN] =3D DataAN[ByteLenN] ^ DataBN[ByteLenN]; + } + + // XOR remaining UINT8 chunks. + if (ByteLen8 !=3D 0) { + Offset =3D ByteLen - ByteLen8; + DataLoc8 =3D (UINT8 *)DataLocN + Offset; + DataA8 =3D (UINT8 *)DataAN + Offset; + DataB8 =3D (UINT8 *)DataBN + Offset; + while (ByteLen8-- > 0) { + DataLoc8[ByteLen8] =3D DataA8[ByteLen8] ^ DataB8[ByteLen8]; + } + } + + *StreamOut =3D LocStream; + return EFI_SUCCESS; +} + +/** Concatenate two BitStreams. + + @param [in] StreamHigh BitStream containing the MSBytes. + @param [in] StreamLow BitStream containing the LSBytes. + @param [out] StreamOut Output BitStream. + Can be *StreamHigh or *StreamLow to replace the= ir + content with the new concatenated stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamConcat ( + IN BIT_STREAM *StreamHigh, + IN BIT_STREAM *StreamLow, + OUT BIT_STREAM **StreamOut + ) +{ + EFI_STATUS Status; + BIT_STREAM LocStream; + UINTN TotalBitLen; + + if ((StreamHigh =3D=3D NULL) || + (StreamLow =3D=3D NULL) || + (StreamOut =3D=3D NULL)) + { + ASSERT (StreamHigh !=3D NULL); + ASSERT (StreamLow !=3D NULL); + ASSERT (StreamOut !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + TotalBitLen =3D StreamHigh->BitLen + StreamLow->BitLen; + + Status =3D BitStreamShallowAlloc (TotalBitLen, &LocStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Write StreamLow data. + Status =3D BitStreamWrite ( + StreamLow->Data, + 0, + StreamLow->BitLen, + &LocStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // Write StreamHigh data. + Status =3D BitStreamWrite ( + StreamHigh->Data, + StreamLow->BitLen, + StreamHigh->BitLen, + &LocStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + if (*StreamOut =3D=3D StreamHigh) { + Status =3D BitStreamReplace (StreamHigh, &LocStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + } else if (*StreamOut =3D=3D StreamLow) { + Status =3D BitStreamReplace (StreamLow, &LocStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + } else { + Status =3D BitStreamClone (StreamOut, &LocStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + } + + return Status; + +ErrorHandler: + BitStreamShallowFree (&LocStream); + return Status; +} + +/** Select bits in a BitStream. + + @param [in] StreamIn Input BitStream. + @param [in] StartBitIndex Bit index to start the copy from. + @param [in] BitCount Count of bits to copy. + @param [out] StreamOut Output BitStream. + Can be *StreamIn to replace its + content with the new concatenated stream. + Otherwise, it is initialized and contains = the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamSelect ( + IN BIT_STREAM *StreamIn, + IN UINTN StartBitIndex, + IN UINTN BitCount, + OUT BIT_STREAM **StreamOut + ) +{ + EFI_STATUS Status; + BIT_STREAM StreamDest; + UINTN ByteCount; + UINTN EndByteIndex; + UINTN EndBitCountRemainder; + UINT8 *DataDest; + UINT8 *DataIn; + UINT8 ShiftR; + UINT8 ShiftL; + + if ((StreamIn =3D=3D NULL) || + (StartBitIndex > (MAX_UINTN - BitCount)) || + ((StartBitIndex + BitCount) > StreamIn->BitLen) || + (StreamOut =3D=3D NULL)) + { + ASSERT (StreamIn !=3D NULL); + ASSERT (StartBitIndex <=3D (MAX_UINTN - BitCount)); + ASSERT ((StartBitIndex + BitCount) <=3D StreamIn->BitLen); + ASSERT (StreamOut !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + if (BitCount =3D=3D 0) { + if (*StreamOut =3D=3D StreamIn) { + Status =3D BitStreamShallowAlloc (0, &StreamDest); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamReplace (StreamIn, &StreamDest); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + BitStreamShallowFree (&StreamDest); + // Fall through. + } + } else { + Status =3D BitStreamAlloc (0, StreamOut); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall through. + } + } + + return Status; + } + + ByteCount =3D BitsToUpperBytes (BitCount); + + // Alloc StreamDest. + Status =3D BitStreamShallowAlloc (BitCount, &StreamDest); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + DataDest =3D StreamDest.Data; + + EndByteIndex =3D StreamIn->ByteLen - 1 - + BitsToLowerBytes (StartBitIndex + BitCount - 1); + DataIn =3D &StreamIn->Data[EndByteIndex]; + + ShiftR =3D StartBitIndex & 0x7; + if (ShiftR =3D=3D 0) { + // StartBitIndex is byte aligned. + CopyMem (DataDest, DataIn, ByteCount); + // Unused bits are cleared later. + } else { + // StartBitIndex is not byte aligned. + ShiftL =3D 8 - ShiftR; + + // BitCount might not be a multiple of 8. These MsBits can also + // be spread on 2 bytes (in StreamIn). + EndBitCountRemainder =3D BitCount & 0x7; + if ((ShiftR <=3D EndBitCountRemainder) || (EndBitCountRemainder =3D=3D= 0)) { + *DataDest |=3D (*DataIn++ << ShiftL); + } + + *DataDest++ |=3D (*DataIn >> ShiftR); + ByteCount -=3D 1; + + // Then copy 8 bits chunks. + while (ByteCount--) { + *DataDest |=3D (*DataIn++ << ShiftL); + *DataDest++ |=3D (*DataIn >> ShiftR); + } + } + + Status =3D BitStreamClearUnusedBits (&StreamDest); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + if (*StreamOut =3D=3D StreamIn) { + Status =3D BitStreamReplace (StreamIn, &StreamDest); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + } else { + Status =3D BitStreamClone (StreamOut, &StreamDest); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall through. + } + } + + return Status; + +ErrorHandler: + BitStreamShallowFree (&StreamDest); + return Status; +} + +/** Get leftmost (i.e. MSBytes) BitLen bits of a BitStream. + + @param [in] StreamIn Input BitStream. + @param [in] BitCount Count of leftmost bits to copy. + @param [out] StreamOut Output BitStream. + Can be *StreamIn to replace its + content with the new concatenated stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamLeftmost ( + IN BIT_STREAM *StreamIn, + IN UINTN BitCount, + OUT BIT_STREAM **StreamOut + ) +{ + if ((StreamIn =3D=3D NULL) || + (BitCount > StreamIn->BitLen)) + { + ASSERT (StreamIn !=3D NULL); + ASSERT (BitCount <=3D StreamIn->BitLen); + return EFI_INVALID_PARAMETER; + } + + return BitStreamSelect ( + StreamIn, + StreamIn->BitLen - BitCount, + BitCount, + StreamOut + ); +} + +/** Get rightmost (i.e. LSBytes) BitLen bits of a BitStream. + + @param [in] StreamIn Input BitStream. + @param [in] BitCount Count of righttmost bits to copy. + @param [out] StreamOut Output BitStream. + Can be *StreamIn to replace its + content with the new concatenated stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamRightmost ( + IN BIT_STREAM *StreamIn, + IN UINTN BitCount, + OUT BIT_STREAM **StreamOut + ) +{ + return BitStreamSelect (StreamIn, 0, BitCount, StreamOut); +} + +/** Add a value modulo 2^n to a BitStream. + + @param [in] Val Value to add. + @param [in] Modulo Modulo of the addition (2^Modulo). + @param [in, out] Stream BitStream where the addition happens. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamAddModulo ( + IN UINTN Val, + IN UINTN Modulo, + IN OUT BIT_STREAM *Stream + ) +{ + UINTN Index; + UINTN ByteLen; + UINT8 Carry; + UINT8 Trunc8Val; + UINT8 *Data; + + if (IsBitStreamEmpty (Stream) || + (Stream->BitLen !=3D Modulo)) + { + // Additions with BitLen !=3D Modulo are not handled for now. + ASSERT (!IsBitStreamEmpty (Stream)); + ASSERT (Stream->BitLen =3D=3D Modulo); + return EFI_INVALID_PARAMETER; + } + + Index =3D 0; + ByteLen =3D Stream->ByteLen; + while ((Val !=3D 0) && (Index < ByteLen)) { + Data =3D &Stream->Data[ByteLen - Index - 1]; + + // Only check for 8-bits overflow. If we exit the loop with Carry =3D= =3D 1, + // then this was an actual addition modulo X. + // [1-7]-bits overflows are cleared with BitStreamClearUnusedBits(). + Trunc8Val =3D (UINT8)Val; + Carry =3D (*Data > MAX_UINT8 - Trunc8Val) ? 1 : 0; + *Data +=3D Trunc8Val; + + Val >>=3D 8; + Val +=3D Carry; + + Index++; + } + + return BitStreamClearUnusedBits (Stream); +} + +/** Print a BitStream. + + @param [in] Stream Stream to print. +**/ +VOID +EFIAPI +BitStreamPrint ( + IN BIT_STREAM *Stream + ) +{ + UINTN ByteLen; + UINTN Index; + UINT8 HeadBits; + UINT8 Data; + UINT8 Bit; + + if (Stream =3D=3D NULL) { + ASSERT (Stream !=3D NULL); + return; + } + + HeadBits =3D Stream->BitLen & 0x7; + ByteLen =3D Stream->ByteLen; + Print (L"BitStream(%lu): {\n", Stream->BitLen); + Print (L" [Index] < 7 6 5 4 3 2 1 0 >\n"); + + if (Stream->BitLen =3D=3D 0) { + return; + } + + // Print most significant byte. + Data =3D Stream->Data[0]; + + Print (L" [%02lu] (0x%02x) <", ByteLen - 1, Data); + for (Index =3D 7; Index >=3D 0; Index--) { + if ((Index >=3D HeadBits) && (HeadBits !=3D 0)) { + Bit =3D 'x'; + } else { + Bit =3D '0' + ((Data & (1 << Index)) >> Index); + } + + Print (L" %c", Bit); + } + + Print (L" >\n"); + + // Print other bytes. + for (Index =3D 1; Index < ByteLen; Index++) { + Data =3D Stream->Data[Index]; + Print ( + L" [%02ld] (0x%02x) < %d %d %d %d %d %d %d %d >\n", + ByteLen - Index - 1, + Data, + Data >> 7, + (Data & 0x40) >> 6, + (Data & 0x20) >> 5, + (Data & 0x10) >> 4, + (Data & 0x8) >> 3, + (Data & 0x4) >> 2, + (Data & 0x2) >> 1, + (Data & 0x1) + ); + } + + Print (L"}\n"); +} diff --git a/MdePkg/Library/DrbgLib/BitStream.h b/MdePkg/Library/DrbgLib/Bi= tStream.h new file mode 100644 index 000000000000..6f0c7732b2a5 --- /dev/null +++ b/MdePkg/Library/DrbgLib/BitStream.h @@ -0,0 +1,366 @@ +/** @file + BitStream utility. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef BIT_STREAM_H_ +#define BIT_STREAM_H_ + +/** BitStream. + + Struct holding a buffer of data and allowing to do operations + on them (concatenation, selecting rightmost bits, addition, ...). + BitStream are big-endian (MSByte at index 0). +*/ +typedef struct BitStream { + /// Length of BitStream in bits. + UINTN BitLen; + /// Length of BitStream in bytes. + UINTN ByteLen; + /// Buffer holding the data. + UINT8 *Data; +} BIT_STREAM; + +/** Check whether a BitStream is NULL (null length). + + @param [in] Stream The BitStream. + + @retval TRUE if the BitStream is NULL (null length). + @retval FALSE otherwise. +**/ +BOOLEAN +EFIAPI +IsBitStreamEmpty ( + IN BIT_STREAM *Stream + ); + +/** Convert bits to bytes (rounds down). + + @param [in] Bits Bits. + + @return Bytes. +**/ +UINTN +EFIAPI +BitsToLowerBytes ( + IN UINTN Bits + ); + +/** Convert bits to bytes (rounds up). + + @param [in] Bits Bits. + + @return Bytes. +**/ +UINTN +EFIAPI +BitsToUpperBytes ( + IN UINTN Bits + ); + +/** Get the BitStream length (in bits). + + @param [in] Stream The BitStream. + + @return Length of the BitStream (in bits). +**/ +UINTN +EFIAPI +BitStreamBitLen ( + IN BIT_STREAM *Stream + ); + +/** Get the BitStream length (in bytes). + + @param [in] Stream The BitStream. + + @return Length of the BitStream (in bytes). +**/ +UINTN +EFIAPI +BitStreamByteLen ( + IN BIT_STREAM *Stream + ); + +/** Get the BitStream data buffer. + + @param [in] Stream The BitStream. + + @return Data buffer of the BitStream (can be NULL). +**/ +UINT8 * +EFIAPI +BitStreamData ( + IN BIT_STREAM *Stream + ); + +/** Allocate a BitStream of BitLen (bits). + + @param [in] BitLen Length of the BitStream (in bits). + @param [out] Stream The BitStream to allocate. + Must be NULL initialized. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamAlloc ( + IN UINTN BitLen, + OUT BIT_STREAM **Stream + ); + +/** Free a BitStream. + + @param [in, out] Stream BitStream to free. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +BitStreamFree ( + IN OUT BIT_STREAM **Stream + ); + +/** Initialize a BitStream with a buffer. + + The input Buffer is copied to a BitStream buffer. + + @param [in] Buffer Buffer to init the Data of the BitStream with. + The Buffer must be big-endian (MSByte at index 0= ). + @param [in] BitLen Length of the Buffer (in bits). + @param [out] Stream BitStream to initialize. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamInit ( + IN CONST UINT8 *Buffer, + IN UINTN BitLen, + OUT BIT_STREAM **Stream + ); + +/** Fill a Buffer with a Stream Data. + + The Buffer will be big-endian. + + @param [in] Stream Stream to take the Data from. + @param [out] Buffer Buffer where to write the Data. + Must be at least BitStreamByteLen (Stream) + bytes long. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +BitStreamToBuffer ( + IN BIT_STREAM *Stream, + OUT UINT8 *Buffer + ); + +/** Clone a BitStream. + + @param [out] StreamDest Cloned BiStream. + @param [in] StreamSrc Source BitStream to clone. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamClone ( + OUT BIT_STREAM **StreamDest, + IN BIT_STREAM *StreamSrc + ); + +/** Replace an initialized BitStream with another. + + This function frees StreamRepl's Data if success. + + @param [out] StreamRepl Stream whose content is replaced. + @param [in] StreamData Stream containing the Data to use. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamReplace ( + IN OUT BIT_STREAM *StreamRepl, + IN BIT_STREAM *StreamData + ); + +/** Write a buffer to a BitStream. + + @param [in] Buffer Buffer to write to the BitStream. + Buffer is big-endian. + @param [in] StartBitIndex Bit index to start writing from. + @param [in] BitCount Count of bits to write. + @param [in, out] Stream BitStream to write to. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamWrite ( + IN UINT8 *Buffer, + IN UINTN StartBitIndex, + IN UINTN BitCount, + IN OUT BIT_STREAM *Stream + ); + +/** XoR two BitStreams. + + We must have len(StremA) =3D len(StreamB) + + @param [in] StreamA BitStream A. + @param [in] StreamB BitStream B. + @param [out] StreamOut Output BitStream. + Can be *StreamA or *StreamB to replace their + content with the new stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamXor ( + IN BIT_STREAM *StreamA, + IN BIT_STREAM *StreamB, + OUT BIT_STREAM **StreamOut + ); + +/** Concatenate two BitStreams. + + @param [in] StreamHigh BitStream containing the MSBytes. + @param [in] StreamLow BitStream containing the LSBytes. + @param [out] StreamOut Output BitStream. + Can be *StreamHigh or *StreamLow to replace the= ir + content with the new concatenated stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamConcat ( + IN BIT_STREAM *StreamHigh, + IN BIT_STREAM *StreamLow, + OUT BIT_STREAM **StreamOut + ); + +/** Select bits in a BitStream. + + @param [in] StreamIn Input BitStream. + @param [in] StartBitIndex Bit index to start the copy from. + @param [in] BitCount Count of bits to copy. + @param [out] StreamOut Output BitStream. + Can be *StreamIn to replace its + content with the new concatenated stream. + Otherwise, it is initialized and contains = the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamSelect ( + IN BIT_STREAM *StreamIn, + IN UINTN StartBitIndex, + IN UINTN BitCount, + OUT BIT_STREAM **StreamOut + ); + +/** Get leftmost (i.e. MSBytes) BitLen bits of a BitStream. + + @param [in] StreamIn Input BitStream. + @param [in] BitCount Count of leftmost bits to copy. + @param [out] StreamOut Output BitStream. + Can be *StreamIn to replace its + content with the new concatenated stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamLeftmost ( + IN BIT_STREAM *StreamIn, + IN UINTN BitCount, + OUT BIT_STREAM **StreamOut + ); + +/** Get rightmost (i.e. LSBytes) BitLen bits of a BitStream. + + @param [in] StreamIn Input BitStream. + @param [in] BitCount Count of righttmost bits to copy. + @param [out] StreamOut Output BitStream. + Can be *StreamIn to replace its + content with the new concatenated stream. + Otherwise, it is initialized and contains the + resulting stream. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamRightmost ( + IN BIT_STREAM *StreamIn, + IN UINTN BitCount, + OUT BIT_STREAM **StreamOut + ); + +/** Add a value modulo 2^n to a BitStream. + + @param [in] Val Value to add. + @param [in] Modulo Modulo of the addition (2^Modulo). + @param [in, out] Stream BitStream where the addition happens. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BitStreamAddModulo ( + IN UINTN Val, + IN UINTN Modulo, + IN OUT BIT_STREAM *Stream + ); + +/** Print a BitStream. + + @param [in] Stream Stream to print. +**/ +VOID +EFIAPI +BitStreamPrint ( + IN BIT_STREAM *Stream + ); + +#endif // BIT_STREAM_H_ --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90901): https://edk2.groups.io/g/devel/message/90901 Mute This Topic: https://groups.io/mt/92072288/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90902+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90902+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530375; cv=none; d=zohomail.com; s=zohoarc; b=joGMZXj/oM8FycHiU2tc3W8+UgMEPQE6hgQvHD3G/m7Syzb/E4sK94zdGAaWcLufuYRs/0TP3R7I8Wjdc4S2xP7anFt9/CmxjOph1ZzyBrqkjOaGBofiFxANpQb/APWsaxJJ9zAOHwYygJGj6y6CmKMezgae1vfFTpo/4Bgq1f8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530375; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=YZ0FEV86gMFbM/2LiPyjT8YVvwVca3/c9H3ZYToiTEQ=; b=eyCr1qS1nPafHg8frjuGpbpSDyvntN/VKIukkNU5mfGn4aiPlsxoR3amTt2QQAnDK/M98YSPwkNrRmBZsds6LLTd2C3KSfSI7ktPqUzqLnWxvNhAccCiDpquhztoD3KAtjYkOd21ZCLIFY/17IsUiC2lBetiuu3mEJ3cxRGE36k= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90902+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530375699318.1832381860605; Wed, 29 Jun 2022 12:19:35 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 1qgBYY1788612xksG7bVln1C; Wed, 29 Jun 2022 12:19:34 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web08.15827.1656530373964459523 for ; Wed, 29 Jun 2022 12:19:34 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DE60414BF; Wed, 29 Jun 2022 12:19:33 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 72ABD3F792; Wed, 29 Jun 2022 12:19:31 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 4/9] MdePkg/DrbgLib: Add Get_entropy_input() implementation Date: Wed, 29 Jun 2022 21:18:41 +0200 Message-Id: <20220629191848.2619317-5-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: sg31x2SzimI5GmlMtzXTrd66x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530374; bh=yjsokSHA9kEaIr4sRYZ2sQmJCiYuE/igTvY0KGl82ts=; h=Cc:Date:From:Reply-To:Subject:To; b=fJ1OMjA0h67mbYoqoUuia71AFkR+Wbj+XdoNMhrJO+pOScO39EOTfpLKCfebNHh/+XJ fAwnpol6WWDSj5kqe973EqAFW3zzKsDobR5Q0+PH3QIZVpy2kF98TdbcRLHb0sQErkSeK HllpGVlsJ2Q7MHbHmVfHlNDSBsRnpvWKWZ0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530376147100006 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois NIST Special Publication 800-90C, s10.3.3 'Get_entropy_input Constructions for Accessing Entropy Sources' specifies multiple way to implement the Get_entropy_input() function. Implement s10.3.3.1 'Construction When a Conditioning Function is not Used' in a separate file to let room for other potential implementations. Signed-off-by: Pierre Gondois --- MdePkg/Library/DrbgLib/GetEntropyInput.c | 72 ++++++++++++++++++++++++ MdePkg/Library/DrbgLib/GetEntropyInput.h | 48 ++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 MdePkg/Library/DrbgLib/GetEntropyInput.c create mode 100644 MdePkg/Library/DrbgLib/GetEntropyInput.h diff --git a/MdePkg/Library/DrbgLib/GetEntropyInput.c b/MdePkg/Library/Drbg= Lib/GetEntropyInput.c new file mode 100644 index 000000000000..6257bc9093dd --- /dev/null +++ b/MdePkg/Library/DrbgLib/GetEntropyInput.c @@ -0,0 +1,72 @@ +/** @file + GetEntropyInput function implementation. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#include +#include + +#include "Common.h" + +/** GetEntropyInput implementation (no conditionning function). + + Cf. [3] 10.3.3.1 Construction When a Conditioning Function is not Used + + @param [in] DrbgHandle The Drbg hanble. + @param [in] MinEntropy Minimum entropy. + @param [out] EntropyBitsStream Stream containing the generated entropy. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +GetEntropyInputNoCondFn ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN MinEntropy, + OUT BIT_STREAM **EntropyBitsStream + ) +{ + EFI_STATUS Status; + + if ((DrbgHandle =3D=3D NULL) || + (EntropyBitsStream =3D=3D NULL) || + (*EntropyBitsStream !=3D NULL)) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT (EntropyBitsStream !=3D NULL); + ASSERT (*EntropyBitsStream =3D=3D NULL); + return EFI_INVALID_PARAMETER; + } + + // 1. (status, entropy_bitstring) =3D Get_Entropy(min_entropy, max_lengt= h). + // 2. If (status !=3D SUCCESS), then return (status, Null). + // 3. Return SUCCESS, entropy_bitstring. + Status =3D GetEntropy (DrbgHandle, MinEntropy, EntropyBitsStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall through. + } + + return Status; +} diff --git a/MdePkg/Library/DrbgLib/GetEntropyInput.h b/MdePkg/Library/Drbg= Lib/GetEntropyInput.h new file mode 100644 index 000000000000..336fbc3826c0 --- /dev/null +++ b/MdePkg/Library/DrbgLib/GetEntropyInput.h @@ -0,0 +1,48 @@ +/** @file + GetEntropyInput function implementation. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#ifndef GET_ENTROPY_INPUT_H_ +#define GET_ENTROPY_INPUT_H_ + +/** GetEntropyInput implementation (no conditionning function). + + Cf. [3] 10.3.3.1 Construction When a Conditioning Function is not Used + + @param [in] DrbgHandle The Drbg hanble. + @param [in] MinEntropy Minimum entropy. + @param [out] EntropyBitsStream Stream containing the generated entropy. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +GetEntropyInputNoCondFn ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN MinEntropy, + OUT BIT_STREAM **EntropyBitsStream + ); + +#endif // GET_ENTROPY_INPUT_H_ --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90902): https://edk2.groups.io/g/devel/message/90902 Mute This Topic: https://groups.io/mt/92072290/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90903+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90903+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530382; cv=none; d=zohomail.com; s=zohoarc; b=B+47qoMPi6uDgci0t28Epek5yq0UpssZoVXxOz9DrTfGzf9lu7sP9bAJoyPmMm31XY81AZsGRp8aXXyvDrFbPULdQ7UHpFQfXZh8v02TCJI8xOLyrwR6Q3urg+BrhBq48wEtuFeWDd9YU+ssqWNuXVQIwJhW6g8NcJb+TfRUcBU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530382; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=k4Tyf1eijg1P3pLGErQOQzRtpxS4sOXSnRkuErFKtVk=; b=W3Dr6dwl+Qy9E23qFuLgxcj8rZz68yUYtIGHRzs4q9YL/INycj63fZNXTMFi7w3mPHqofm6y28Bjoxwu2AfyFEX2V+9ew4uHeF7jVi11jE46/teRf5JZkeWomWKfj43C57EebRZsbXPof1O/23aB/l5VFGeO0cIJcITkZEC5evQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90903+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 165653038255447.55382513423501; Wed, 29 Jun 2022 12:19:42 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ISxdYY1788612xNvr9CAt8Xx; Wed, 29 Jun 2022 12:19:42 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web09.16025.1656530376328534640 for ; Wed, 29 Jun 2022 12:19:36 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 35FC2152B; Wed, 29 Jun 2022 12:19:36 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 067423F792; Wed, 29 Jun 2022 12:19:33 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 5/9] MdePkg/DrbgLib: Add common wrappers Date: Wed, 29 Jun 2022 21:18:42 +0200 Message-Id: <20220629191848.2619317-6-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: GghudKzyg7R9SjqUkw27A1Kxx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530382; bh=Pxf/qjOCFiKeK9F2y7QooFLkFFyvaFQwFqzGF6wCH0Y=; h=Cc:Date:From:Reply-To:Subject:To; b=oqw8X8BCkjo+GNyg5OWjUGnNAvgzHk9OvJUcpTcuHSox3X0TVFw+2AH9ty/IQYTyG8d DGT6cw5V5ZDWf99oC8i7l7x+auu9+MJ4XQKxF6HC92cT5M2VgBs2rTivxZvl30I02n7GU 7dpTijUle5H4UnRnZQRPi1kxqGSr70OFPDw= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530384211100004 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois Add common wrappers around the TRNG and AES libraries: - GetEntropy() relies an Arm Trng - BlockEncrypt relies on Arm implementation of the AES library Signed-off-by: Pierre Gondois --- MdePkg/Library/DrbgLib/Common.c | 249 ++++++++++++++++++++++++++++++++ MdePkg/Library/DrbgLib/Common.h | 74 ++++++++++ 2 files changed, 323 insertions(+) create mode 100644 MdePkg/Library/DrbgLib/Common.c create mode 100644 MdePkg/Library/DrbgLib/Common.h diff --git a/MdePkg/Library/DrbgLib/Common.c b/MdePkg/Library/DrbgLib/Commo= n.c new file mode 100644 index 000000000000..0aa0459f0b0f --- /dev/null +++ b/MdePkg/Library/DrbgLib/Common.c @@ -0,0 +1,249 @@ +/** @file + Implementation of arch specific functions for the Drbg library. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#include +#include +#include +#include +#include +#include + +#include "Common.h" +#include "CtrDrbg.h" + +/** GetEntropy implementation using Arm Trng. + + Cf. [3] 10.3.1.2 Condensing After Entropy Collection + + The min and max entropy length are in the DrbgHandle. + + @param [in] DrbgHandle The Drbg hanble. + @param [in] ReqEntropy Requested entropy. + @param [out] EntropyBitsStream Stream containing the generated entropy. + + @retval EFI_SUCCESS Success. + @retval EFI_ABORTED An error occured. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +GetEntropy ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN ReqEntropy, + OUT BIT_STREAM **EntropyBitsStream + ) +{ + EFI_STATUS Status; + UINTN TrngCollectedEntropy; + UINTN TrngReqBits; + UINTN TrngMaxBits; + UINTN TrngMaxBytes; + UINTN MinLen; + UINT8 *QueriedBitsBuff; + + if ((DrbgHandle =3D=3D NULL) || + (EntropyBitsStream =3D=3D NULL) || + (*EntropyBitsStream !=3D NULL)) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT (EntropyBitsStream !=3D NULL); + ASSERT (*EntropyBitsStream =3D=3D NULL); + return EFI_INVALID_PARAMETER; + } + + MinLen =3D 0; + TrngMaxBits =3D GetTrngMaxSupportedEntropyBits (); + TrngMaxBytes =3D BitsToUpperBytes (TrngMaxBits); + QueriedBitsBuff =3D NULL; + + // 1. If requested_entropy > max_length, return an error indication + // and a null value for the entropy_bitstring. + // + // Note: we also check for MinLen + if ((ReqEntropy > DrbgHandle->DrbgVal.MaxLen) || + (ReqEntropy < DrbgHandle->DrbgVal.MinLen)) + { + ASSERT (0); + return EFI_INVALID_PARAMETER; + } + + // 2. collected_entropy =3D 0. + TrngCollectedEntropy =3D 0; + + // 3. entropy_bitstring =3D the Null string. + Status =3D BitStreamAlloc (ReqEntropy, EntropyBitsStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + QueriedBitsBuff =3D (UINT8 *)AllocateZeroPool (TrngMaxBytes); + if (QueriedBitsBuff =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // 4. While collected_entropy < requested_entropy + while (TrngCollectedEntropy < ReqEntropy) { + TrngReqBits =3D MIN ((MinLen - TrngCollectedEntropy), TrngMaxBits); + + // 4.1 Query one or more entropy sources to obtain queried_bits and the + // assessed_entropy for those bits. + // + // Cf. Arm True Random Number Generator Firmware, Interface 1.0, + // s2.4.2 Usage, the number of bits requested to the TRNG equals the + // number of bits returned. So assessed_entropy =3D=3D #queried_bits + Status =3D GetTrngEntropy (TrngReqBits, TrngMaxBytes, QueriedBitsBuff); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // 4.2 entropy_bitstring =3D entropy_bitstring || queried_bits. + // + // We are concatenating the other way around. Since this is a TRNG and + // the endianness of queried_bits is meaningless, this is the same. + Status =3D BitStreamWrite ( + QueriedBitsBuff, + TrngCollectedEntropy, + TrngReqBits, + *EntropyBitsStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + // 4.3 collected_entropy =3D collected_entropy + assessed_entropy. + // + // Cf above, for Arm TRNG, assessed_entropy =3D=3D #queried_bits + TrngCollectedEntropy +=3D TrngReqBits; + } // while + + // 6. If (n > max_length), then + // entropy_bitstring =3D df(entropy_bitstring, max_length). + // + // Note: This cannot happen. + if (DrbgHandle->DrbgVal.MaxLen !=3D 0) { + Status =3D EFI_ABORTED; + ASSERT_EFI_ERROR (Status); + goto ErrorHandler; + } + + FreePool (QueriedBitsBuff); + + // 7. Return (SUCCESS, entropy_bitstring). + return Status; + +ErrorHandler: + if (QueriedBitsBuff) { + FreePool (QueriedBitsBuff); + } + + BitStreamFree (EntropyBitsStream); + return Status; +} + +/** Block encryption (for AES). + + Cf. [1] s10.3.3 'BCC and Block_Encrypt'. + + @param [in] DrbgHandle The Drbg hanble. + @param [out] OutBlockStream Stream containing the encrypted block. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BlockEncrypt ( + IN DRBG_HANDLE DrbgHandle, + OUT BIT_STREAM **OutBlockStream + ) +{ + EFI_STATUS Status; + AES_CTX AesCtx; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + + if ((DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL) || + (OutBlockStream =3D=3D NULL) || + (*OutBlockStream !=3D NULL)) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + ASSERT (OutBlockStream !=3D NULL); + ASSERT (*OutBlockStream =3D=3D NULL); + return EFI_INVALID_PARAMETER; + } + + CtrVal =3D (CTR_VALUE_DEFINITIONS *)DrbgHandle->DrbgVal.DrbgAlgoVal; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntSt= ate; + if (IsBitStreamEmpty (CtrIntState->Key) || + IsBitStreamEmpty (CtrIntState->Val) + ) + { + ASSERT (!IsBitStreamEmpty (CtrIntState->Key)); + ASSERT (!IsBitStreamEmpty (CtrIntState->Val)); + return EFI_INVALID_PARAMETER; + } + + Status =3D AesInitCtx ( + BitStreamData (CtrIntState->Key), + BitStreamBitLen (CtrIntState->Key), + &AesCtx + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamAlloc (CtrVal->BlockLen, OutBlockStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AesEncrypt ( + &AesCtx, + BitStreamData (CtrIntState->Val), + BitStreamData (*OutBlockStream) + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + BitStreamFree (OutBlockStream); + // Fall through. + } + + return Status; +} diff --git a/MdePkg/Library/DrbgLib/Common.h b/MdePkg/Library/DrbgLib/Commo= n.h new file mode 100644 index 000000000000..f226528bc5c2 --- /dev/null +++ b/MdePkg/Library/DrbgLib/Common.h @@ -0,0 +1,74 @@ +/** @file + Implementation of arch specific functions for the Drbg library. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#ifndef ARCH_IMPLEM_H_ +#define ARCH_IMPLEM_H_ + +#include "DrbgLibInternal.h" + +/** GetEntropy implementation using Arm Trng. + + Cf. [3] 10.3.1.2 Condensing After Entropy Collection + + The min and max entropy length are in the DrbgHandle. + + @param [in] DrbgHandle The Drbg hanble. + @param [in] ReqEntropy Requested entropy. + @param [out] EntropyBitsStream Stream containing the generated entropy. + + @retval EFI_SUCCESS Success. + @retval EFI_ABORTED An error occured. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +GetEntropy ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN ReqEntropy, + OUT BIT_STREAM **EntropyBitsStream + ); + +/** Block encryption (for AES). + + Cf. [1] s10.3.3 'BCC and Block_Encrypt'. + + @param [in] DrbgHandle The Drbg hanble. + @param [out] OutBlockStream Stream containing the encrypted block. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +BlockEncrypt ( + IN DRBG_HANDLE DrbgHandle, + OUT BIT_STREAM **OutBlockStream + ); + +#endif // ARCH_IMPLEM_H_ --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90903): https://edk2.groups.io/g/devel/message/90903 Mute This Topic: https://groups.io/mt/92072291/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90904+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90904+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530380; cv=none; d=zohomail.com; s=zohoarc; b=f19HeuiVp8MOIt35PCGn9C/EPVOo6sTFMLP2Zcse/HMzpH6kmY7epFDFaOrlzBcHKosK2gLRZs2Fh+k7uOEfQGaGutbmJ/hGpkZ/fm9pHXFqur9cMTzXZ0fwlXgZ596ciOOCDty66TWhTZQM2yQRFiLt07LMiSWa6maOxrLoiy8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530380; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=4kE5xc0bpKpWMuAbFMbpDsDhvp8HW1mp/KfDfrxZLj0=; b=ULecAZB+Uk8qRsWgs5JskoKlmnoHQkancn2UwtIOriCz5NOP0DlX/KJrd7xiUCaBjcWFVEYyFN8U4PliyYfiDvdKT7MSwR0lgW07PALf/n/10IZmn3zWjJo+3BkqvGJCijdhureD/tosJWkiIrmK/0VlAUc0bvDApZMD5385JXQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90904+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530380199542.0631635138229; Wed, 29 Jun 2022 12:19:40 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id bBT3YY1788612xIw3dGMyAIR; Wed, 29 Jun 2022 12:19:39 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web09.16026.1656530378849059963 for ; Wed, 29 Jun 2022 12:19:39 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BEAB61480; Wed, 29 Jun 2022 12:19:38 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5D2323F792; Wed, 29 Jun 2022 12:19:36 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 6/9] MdePkg/DrbgLib: Add Ctr Drbg mechanism functions Date: Wed, 29 Jun 2022 21:18:43 +0200 Message-Id: <20220629191848.2619317-7-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: 8dj49HAetWIO3ZOjfazxJlAQx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530379; bh=ujewfyUQT/eNBSeKnteOx4Ll6Hbl0oOT1umhvT0Z+yo=; h=Cc:Date:From:Reply-To:Subject:To; b=sW8Nt92yLOBvhCN1blD73TGaKFMxBCU57nlZxatjWwhffh8Nn5GUGitnUL8+CaxITer /2Ny6DJwVfUAEYuEfVWNwAHx1GLEoYwpdWnCFWZlGh7f1ARYQDKd+RVfPoKR3JgPuKiDv kY0emQ3dXsouUvAdxvXHz+lbTyzU/qf3Dbs= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530382190100001 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois From the NIST Special Publication 800-90A, the implementation of a Drbg can be split into: 1. DRBG Mechanism Functions (s9 of the spec), describing the operations generic to all the mechanisms. 2. DRBG Algorithm Specifications (s10 of the spec), describing the operations specific to each mechanisms (CTR, HMAC, ...) This patch implements the 2., i.e. the operations specific to the Ctr Drbg mechanism. Signed-off-by: Pierre Gondois --- MdePkg/Library/DrbgLib/CtrDrbg.c | 899 +++++++++++++++++++++++++++++++ MdePkg/Library/DrbgLib/CtrDrbg.h | 100 ++++ 2 files changed, 999 insertions(+) create mode 100644 MdePkg/Library/DrbgLib/CtrDrbg.c create mode 100644 MdePkg/Library/DrbgLib/CtrDrbg.h diff --git a/MdePkg/Library/DrbgLib/CtrDrbg.c b/MdePkg/Library/DrbgLib/CtrD= rbg.c new file mode 100644 index 000000000000..7db4d724086a --- /dev/null +++ b/MdePkg/Library/DrbgLib/CtrDrbg.c @@ -0,0 +1,899 @@ +/** @file + Ctr Drbg implementation. + (Counter Deterministic Random Bit Generator) + Cf. [1] s10.2.1 CTR_DRBG + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + - [5] Unified Extensible Firmware Interface (UEFI) Specification, + Version 2.8 Errata B, May 2020 + (https://www.uefi.org/specifications) + - [6] FIPS 197 November 26, 2001: + Specification for the ADVANCED ENCRYPTION STANDARD (AES) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#include +#include +#include +#include + +#include "Common.h" +#include "CtrDrbg.h" + +/** Get a nonce. + + [1] s10.2.1.3.1 Instantiation When a Derivation Function is Not Used + + When instantiation is performed using this method, full-entropy input + is required, and a nonce is not used. + + @param [in, out] DrbgHandle The Drbg handle. + @param [out] NonceStream Stream containing the Nonce. + + @retval EFI_SUCCESS Success. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgGetNonce ( + IN OUT DRBG_HANDLE DrbgHandle, + OUT BIT_STREAM *NonceStream + ) +{ + // Nothing to do. + return EFI_SUCCESS; +} + +/** Check the internal state. + + @param [in] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgCheckInternalState ( + IN DRBG_HANDLE DrbgHandle + ) +{ + CTR_INTERNAL_STATE *CtrIntState; + + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntSt= ate; + + // Just check that key and value BitStreams are still ok. + if ((IsBitStreamEmpty (CtrIntState->Val) || + (IsBitStreamEmpty (CtrIntState->Key)))) + { + ASSERT (!IsBitStreamEmpty (CtrIntState->Val)); + ASSERT (!IsBitStreamEmpty (CtrIntState->Key)); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** Update algorithm. + + CTR_DRBG_Update implementation. + + Cf. [1] s10.2.1.2 The Update Function (CTR_DRBG_Update) + + @param [in] ProvidedData The data to be used. This must be exactly + seedlen bits in length. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgUpdate ( + IN BIT_STREAM *ProvidedData, + IN OUT DRBG_HANDLE DrbgHandle + ) +{ + EFI_STATUS Status; + BIT_STREAM *IncStream; + BIT_STREAM *OutBlkStream; + BIT_STREAM *TempStream; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + + if (IsBitStreamEmpty (ProvidedData) || + (DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL)) + { + ASSERT (!IsBitStreamEmpty (ProvidedData)); + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + IncStream =3D NULL; + OutBlkStream =3D NULL; + TempStream =3D NULL; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntS= tate; + CtrVal =3D (CTR_VALUE_DEFINITIONS *)DrbgHandle->DrbgVal.DrbgAlgoVa= l; + + if (BitStreamBitLen (ProvidedData) !=3D CtrVal->SeedLen) { + ASSERT (BitStreamBitLen (ProvidedData) =3D=3D CtrVal->SeedLen); + return EFI_INVALID_PARAMETER; + } + + // 1. temp =3D Null. + Status =3D BitStreamAlloc (0, &TempStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // 2. While (len (temp) < seedlen) do + while (BitStreamBitLen (TempStream) < CtrVal->SeedLen) { + // 2.1 If ctr_len < blocklen + if (CtrVal->CtrLen < CtrVal->SeedLen) { + // 2.1.1 inc =3D (rightmost (V, ctr_len) + 1) mod 2 ^ ctr_len. + Status =3D BitStreamRightmost ( + CtrIntState->Val, + CtrVal->CtrLen, + &IncStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamAddModulo (1, CtrVal->CtrLen, IncStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 2.1.2 V =3D leftmost (V, blocklen - ctr_len) || inc. + Status =3D BitStreamLeftmost ( + CtrIntState->Val, + CtrVal->BlockLen - CtrVal->CtrLen, + &CtrIntState->Val + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamConcat ( + CtrIntState->Val, + IncStream, + &CtrIntState->Val + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamFree (&IncStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } else { + // (2.1) Else V =3D (V+1) mod 2 ^ blocklen. + Status =3D BitStreamAddModulo (1, CtrVal->BlockLen, CtrIntState->Val= ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } + + // 2.2 output_block =3D Block_Encrypt (Key, V). + Status =3D BlockEncrypt (DrbgHandle, &OutBlkStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 2.3 temp =3D temp || output_block. + Status =3D BitStreamConcat (TempStream, OutBlkStream, &TempStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamFree (&OutBlkStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } // while + + // 3. temp =3D leftmost (temp, seedlen). + Status =3D BitStreamLeftmost (TempStream, CtrVal->SeedLen, &TempStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 4. temp =3D temp XoR provided_data. + Status =3D BitStreamXor (TempStream, ProvidedData, &TempStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 5. Key =3D leftmost (temp, keylen). + Status =3D BitStreamFree (&CtrIntState->Key); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamLeftmost (TempStream, CtrVal->KeyLen, &CtrIntState->= Key); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 6. V =3D rightmost (temp, blocklen). + Status =3D BitStreamFree (&CtrIntState->Val); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamRightmost ( + TempStream, + CtrVal->BlockLen, + &CtrIntState->Val + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall through. + } + +ExitHandler: + if (IncStream !=3D NULL) { + BitStreamFree (&IncStream); + } + + if (OutBlkStream !=3D NULL) { + BitStreamFree (&OutBlkStream); + } + + if (TempStream !=3D NULL) { + BitStreamFree (&TempStream); + } + + // 7. Return (Key, V). + return Status; +} + +/** Instantiate algorithm. + + CTR_DRBG_Instantiate_algorithm implementation. + + Cf. [1] s10.2.1.3.1 Instantiation When a Derivation Function is Not Used + + @param [in] EntropyInput The string of bits obtained from the + randomness source. + @param [in] PersStrBitStream The personalization string received from= the + consuming application. Note that the len= gth + of the personalization_string may be zer= o. + Note: PersStrBitStream must be initializ= ed, + even with a NULL BitStream. + @param [out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgInstantiateAlgo ( + IN BIT_STREAM *EntropyInput, + IN BIT_STREAM *PersStrBitStream, + OUT DRBG_HANDLE DrbgHandle + ) +{ + EFI_STATUS Status; + BIT_STREAM *LocalStream; + BIT_STREAM *SeedMaterial; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + UINTN Temp; + + if (IsBitStreamEmpty (EntropyInput) || + (PersStrBitStream =3D=3D NULL) || + (DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL)) + { + ASSERT (!IsBitStreamEmpty (EntropyInput)); + ASSERT (PersStrBitStream !=3D NULL); + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + LocalStream =3D NULL; + SeedMaterial =3D NULL; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntS= tate; + CtrVal =3D (CTR_VALUE_DEFINITIONS *)DrbgHandle->DrbgVal.DrbgAlgoVa= l; + + // 1. temp =3D len (personalization_string). + Temp =3D BitStreamBitLen (PersStrBitStream); + + // 2. If (temp < seedlen), then + // personalization_string =3D personalization_string || 0 ^ seedlen - te= mp. + if (Temp < CtrVal->SeedLen) { + Status =3D BitStreamAlloc (CtrVal->SeedLen - Temp, &LocalStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamConcat ( + PersStrBitStream, + LocalStream, + &PersStrBitStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } + + // 3. seed_material =3D entropy_input XoR personalization_string. + Status =3D BitStreamXor (EntropyInput, PersStrBitStream, &SeedMaterial); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 4. Key =3D 0 ^ keylen. + Status =3D BitStreamAlloc (CtrVal->KeyLen, &CtrIntState->Key); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 5. V =3D 0 ^ blocklen. + Status =3D BitStreamAlloc (CtrVal->BlockLen, &CtrIntState->Val); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 6. (Key, V) =3D CTR_DRBG_Update (seed_material, Key, V). + Status =3D CtrDrbgUpdate (SeedMaterial, DrbgHandle); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 7. reseed_counter =3D 1. + CtrIntState->ReseedCounter =3D 1; + +ExitHandler: + if (SeedMaterial !=3D NULL) { + BitStreamFree (&SeedMaterial); + } + + if (LocalStream !=3D NULL) { + BitStreamFree (&LocalStream); + } + + // 8. Return (V, Key, reseed_counter). + return Status; +} + +/** Reseed algorithm + + CTR_DRBG_Reseed_algorithm implementation. + + Cf. [1] s10.2.1.4.1 Reseeding When a Derivation Function is Not Used + + @param [in] EntropyInput The string of bits obtained from the + randomness source. + @param [in] AddInput The additional input string received + from the consuming application. Note + that the length of the additional_input + string may be zero. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgReseedAlgo ( + IN BIT_STREAM *EntropyInput, + IN BIT_STREAM *AddInput, + IN OUT DRBG_HANDLE DrbgHandle + ) +{ + EFI_STATUS Status; + UINTN Temp; + BIT_STREAM *LocalStream; + BIT_STREAM *SeedMaterial; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + + if (IsBitStreamEmpty (EntropyInput) || + (AddInput =3D=3D NULL) || + (DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL)) + { + ASSERT (!IsBitStreamEmpty (EntropyInput)); + ASSERT (AddInput !=3D NULL); + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + LocalStream =3D NULL; + SeedMaterial =3D NULL; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntS= tate; + CtrVal =3D (CTR_VALUE_DEFINITIONS *)DrbgHandle->DrbgVal.DrbgAlgoVa= l; + + // 1. temp =3D len (additional_input). + Temp =3D BitStreamBitLen (AddInput); + + // 2. If (temp < seedlen), + // then additional_input =3D additional_input || 0 ^ (seedlen - temp). + if (Temp < CtrVal->SeedLen) { + Status =3D BitStreamAlloc (CtrVal->SeedLen - Temp, &LocalStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamConcat ( + AddInput, + LocalStream, + &AddInput + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } + + // 3. seed_material =3D entropy_input XoR additional_input. + Status =3D BitStreamXor (EntropyInput, AddInput, &SeedMaterial); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 4. (Key, V) =3D CTR_DRBG_Update (seed_material, Key, V). + Status =3D CtrDrbgUpdate (SeedMaterial, DrbgHandle); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 5. reseed_counter =3D 1. + CtrIntState->ReseedCounter =3D 1; + +ExitHandler: + if (LocalStream !=3D NULL) { + BitStreamFree (&LocalStream); + } + + if (SeedMaterial !=3D NULL) { + BitStreamFree (&SeedMaterial); + } + + // 6. Return (V, Key, reseed_counter). + return Status; +} + +/** Generate algorithm. + + CTR_DRBG_Generate_algorithm implementation. + + Cf. s10.2.1.5.1 Generating Pseudorandom Bits When a Derivation Function + is Not Used + + To reflect that 'a reseed is required before the requested pseudorandom = bits + can be generated', the EFI_NOT_READY return code is used. + + @param [in] AddInput The additional input string received= from + the consuming application. Note that= the + length of the additional_input string + may be zero. + @param [in] RequestedNbBits The number of pseudorandom bits to be + returned to the generate function. + @param [out] RndBitStream BitStream containing the random bits. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. + @retval EFI_NOT_READY A reseed is required before the requested + pseudorandom bits can be generated. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgGenerateAlgo ( + IN BIT_STREAM *AddInput, + IN UINTN RequestedNbBits, + OUT BIT_STREAM **RndBitStream, + IN OUT DRBG_HANDLE DrbgHandle + ) +{ + EFI_STATUS Status; + UINTN Temp; + BIT_STREAM *IncStream; + BIT_STREAM *LocalStream; + BIT_STREAM *OutBlkStream; + BIT_STREAM *TempStream; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + + if ((AddInput =3D=3D NULL) || + (RequestedNbBits =3D=3D 0) || + (RndBitStream =3D=3D NULL) || + (*RndBitStream !=3D NULL) || + (DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL)) + { + ASSERT (AddInput !=3D NULL); + ASSERT (RequestedNbBits !=3D 0); + ASSERT (RndBitStream !=3D NULL); + ASSERT (*RndBitStream =3D=3D NULL); + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + IncStream =3D NULL; + LocalStream =3D NULL; + OutBlkStream =3D NULL; + TempStream =3D NULL; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntS= tate; + CtrVal =3D (CTR_VALUE_DEFINITIONS *)DrbgHandle->DrbgVal.DrbgAlgoVa= l; + + // 1. If reseed_counter > reseed_interval, + // then return an indication that a reseed is required. + if (CtrIntState->ReseedCounter > CtrVal->ReseedInterval) { + return EFI_NOT_READY; + } + + // 2. If (additional_input !=3D Null), then + if (!IsBitStreamEmpty (AddInput)) { + // 2.1 temp =3D len (additional_input). + Temp =3D BitStreamBitLen (AddInput); + + // 2.2 If (temp < seedlen), then + // additional_input =3D additional_input || 0 seedlen - temp . + if (Temp < CtrVal->SeedLen) { + Status =3D BitStreamAlloc (CtrVal->SeedLen - Temp, &LocalStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D BitStreamConcat (AddInput, LocalStream, &AddInput); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } + + // 2.3 (Key, V) =3D CTR_DRBG_Update (additional_input, Key, V). + Status =3D CtrDrbgUpdate (AddInput, DrbgHandle); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } else { + // (2.) Else additional_input =3D 0 ^ seedlen. + Status =3D BitStreamFree (&AddInput); // Freeing &AddInput, this is wr= ong, AddInput is now a local parameter + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamAlloc (CtrVal->SeedLen, &AddInput); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } + + // 3. temp =3D Null. + Status =3D BitStreamAlloc (0, &TempStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 4. While (len (temp) < requested_number_of_bits) do: + while (BitStreamBitLen (TempStream) < RequestedNbBits) { + // 4.1 If ctr_len < blocklen + if (CtrVal->CtrLen < CtrVal->BlockLen) { + // 4.1.1 inc =3D (rightmost (V, ctr_len) + 1) mod 2 ^ ctr_len. + Status =3D BitStreamRightmost ( + CtrIntState->Val, + CtrVal->CtrLen, + &IncStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamAddModulo (1, CtrVal->CtrLen, IncStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 4.1.2 V =3D leftmost (V, blocklen-ctr_len) || inc. + Status =3D BitStreamLeftmost ( + CtrIntState->Val, + CtrVal->BlockLen - CtrVal->CtrLen, + &CtrIntState->Val + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamConcat ( + CtrIntState->Val, + IncStream, + &CtrIntState->Val + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamFree (&IncStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } else { + // (4.1) Else V =3D (V+1) mod 2 ^ blocklen. + Status =3D BitStreamAddModulo (1, CtrVal->BlockLen, CtrIntState->Val= ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } + + // 4.2 output_block =3D Block_Encrypt (Key, V). + Status =3D BlockEncrypt (DrbgHandle, &OutBlkStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 4.3 temp =3D temp || output_block. + Status =3D BitStreamConcat (TempStream, OutBlkStream, &TempStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + Status =3D BitStreamFree (&OutBlkStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + } // while + + // 5. returned_bits =3D leftmost (temp, requested_number_of_bits). + Status =3D BitStreamLeftmost (TempStream, RequestedNbBits, RndBitStream); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 6. (Key, V) =3D CTR_DRBG_Update (additional_input, Key, V). + Status =3D CtrDrbgUpdate (AddInput, DrbgHandle); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 7. reseed_counter =3D reseed_counter + 1. + CtrIntState->ReseedCounter +=3D 1; + +ExitHandler: + if (IncStream !=3D NULL) { + BitStreamFree (&IncStream); + } + + if (LocalStream !=3D NULL) { + BitStreamFree (&LocalStream); + } + + if (OutBlkStream !=3D NULL) { + BitStreamFree (&OutBlkStream); + } + + if (TempStream !=3D NULL) { + BitStreamFree (&TempStream); + } + + // 8. Return (SUCCESS, returned_bits, Key, V, reseed_counter). + return Status; +} + +/** Uninstantiate a DRBG instance. + + [1] s9.4 Removing a DRBG Instantiation + + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +STATIC +EFI_STATUS +EFIAPI +CtrDrbgUninstantiateFn ( + IN OUT DRBG_HANDLE DrbgHandle + ) +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + CTR_INTERNAL_STATE *CtrIntState; + + if ((DrbgHandle =3D=3D NULL) || + (DrbgHandle->IntState.DrbgAlgoIntState =3D=3D NULL) || + (DrbgHandle->DrbgVal.DrbgAlgoVal =3D=3D NULL)) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT (DrbgHandle->IntState.DrbgAlgoIntState !=3D NULL); + ASSERT (DrbgHandle->DrbgVal.DrbgAlgoVal !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + ReturnStatus =3D EFI_SUCCESS; + CtrIntState =3D (CTR_INTERNAL_STATE *)DrbgHandle->IntState.DrbgAlgoIntS= tate; + + // 1. If state_handle indicates an invalid state, then return (ERROR_FLA= G). + // 2. Erase the contents of the internal state indicated by state_handle. + + Status =3D BitStreamFree (&CtrIntState->Key); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + ReturnStatus =3D Status; + } + + Status =3D BitStreamFree (&CtrIntState->Val); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + ReturnStatus =3D Status; + } + + FreePool (DrbgHandle); + + // 3. Return (SUCCESS). + return ReturnStatus; +} + +/** Drbg mechanism specific instantiation steps. + + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +CtrInitHandle ( + IN OUT DRBG_HANDLE DrbgHandle + ) +{ + DRBG_VALUE_DEFINITIONS *DrbgVal; + CTR_INTERNAL_STATE *CtrIntState; + CTR_VALUE_DEFINITIONS *CtrVal; + + if (DrbgHandle =3D=3D NULL) { + ASSERT (DrbgHandle !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + CopyMem ( + &DrbgHandle->Algo, + &gEfiRngAlgorithmSp80090Ctr256Guid, + sizeof (EFI_RNG_ALGORITHM) + ); + + // Allocate CtrIntState. Fields are init to 0. + CtrIntState =3D AllocateZeroPool (sizeof (CTR_INTERNAL_STATE)); + if (CtrIntState =3D=3D NULL) { + ASSERT (CtrIntState !=3D NULL); + return EFI_OUT_OF_RESOURCES; + } + + DrbgHandle->IntState.DrbgAlgoIntState =3D CtrIntState; + + // Allocate CtrVal. Fields are init to 0. + CtrVal =3D AllocateZeroPool (sizeof (CTR_VALUE_DEFINITIONS)); + if (CtrVal =3D=3D NULL) { + ASSERT (CtrVal !=3D NULL); + FreePool (CtrIntState); + return EFI_OUT_OF_RESOURCES; + } + + DrbgHandle->DrbgVal.DrbgAlgoVal =3D CtrVal; + + // CTR DRBG definitions, cf [1] Table 3 'Definitions for the CTR_DRBG'. + // No derivation function is used. + // Only 256 bits AES is allowed (Cf. [5] 'Section 37.5 Random Number + // Generator Protocol') + + // Drbg generic values. + DrbgVal =3D &DrbgHandle->DrbgVal; + DrbgVal->HighestSuppSecStrength =3D 256; + DrbgVal->MinLen =3D CTR_DRBG_AES_256_SEEDLEN; + DrbgVal->MaxLen =3D CTR_DRBG_AES_256_SEEDLEN; + DrbgVal->MaxPersStrLen =3D CTR_DRBG_AES_256_SEEDLEN; + DrbgVal->MaxAddInputLen =3D CTR_DRBG_AES_256_SEEDLEN; + DrbgVal->MaxNbBitsPerRequest =3D 1 << 19; + + // Ctr specific values. + CtrVal->BlockLen =3D CTR_DRBG_AES_BLOCKLEN; + // 4 <=3D ctr_len <=3D blocklen. Choose blocklen to be faster. + CtrVal->CtrLen =3D CTR_DRBG_AES_BLOCKLEN; + CtrVal->KeyLen =3D CTR_DRBG_AES_256_KEYLEN; + CtrVal->MinRequiredEntropy =3D SecStrength256bits; + CtrVal->SeedLen =3D CTR_DRBG_AES_256_SEEDLEN; + CtrVal->ReseedInterval =3D (UINT64)1 << 48; + + // CtrDrbg supports both mechanisms. + DrbgHandle->PredResSupported =3D TRUE; + DrbgHandle->ReseedSupported =3D TRUE; + + // CtrDrbg specific implementations. + DrbgHandle->DrbgGetNonce =3D CtrDrbgGetNonce; + DrbgHandle->DrbgCheckInternalState =3D CtrDrbgCheckInternalState; + DrbgHandle->DrbgUpdate =3D CtrDrbgUpdate; + DrbgHandle->DrbgReseedAlgo =3D CtrDrbgReseedAlgo; + DrbgHandle->DrbgGenerateAlgo =3D CtrDrbgGenerateAlgo; + DrbgHandle->DrbgInstantiateAlgo =3D CtrDrbgInstantiateAlgo; + DrbgHandle->DrbgUninstantiateFn =3D CtrDrbgUninstantiateFn; + + return EFI_SUCCESS; +} diff --git a/MdePkg/Library/DrbgLib/CtrDrbg.h b/MdePkg/Library/DrbgLib/CtrD= rbg.h new file mode 100644 index 000000000000..df9c5108388a --- /dev/null +++ b/MdePkg/Library/DrbgLib/CtrDrbg.h @@ -0,0 +1,100 @@ +/** @file + Ctr Drbg implementation. + (Counter Deterministic Random Bit Generator) + Cf. [1] s10.2.1 CTR_DRBG + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + - [5] Unified Extensible Firmware Interface (UEFI) Specification, + Version 2.8 Errata B, May 2020 + (https://www.uefi.org/specifications) + - [6] FIPS 197 November 26, 2001: + Specification for the ADVANCED ENCRYPTION STANDARD (AES) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#ifndef CTR_DRBG_LIB_H_ +#define CTR_DRBG_LIB_H_ + +/* Blocklen when using CTR DRBG AES-128, AES-192 and + AES-256 algorithm. + + Cf. [6] Figure 4. 'Key-Block-Round Combinations' + Cf. [1] Table 3 'Definitions for the CTR_DRBG' + + Output block length is also called 'outlen'. +*/ +#define CTR_DRBG_AES_BLOCKLEN 128 + +/* Key length when using CTR DRBG AES-256 algorithm. + + Cf. [1] Table 3 'Definitions for the CTR_DRBG' + Cf. [5] s37.5 'Random Number Generator Protocol': + 'Security level must be at least 256 bits' +*/ +#define CTR_DRBG_AES_256_KEYLEN 256 + +/** Seed length when using CTR DRBG AES-256 algorithm. + + Cf. [1] Table 3 'Definitions for the CTR_DRBG' + Seed length (seedlen =3D outlen + keylen) +*/ +#define CTR_DRBG_AES_256_SEEDLEN (CTR_DRBG_AES_BLOCKLEN + \ + CTR_DRBG_AES_256_KEYLEN) + +/** Ctr specific internal state. + + Some fields defined at [1] s10.2.1.1 'CTR_DRBG Internal State' might be + in the DRBG_INTERNAL_STATE structure. +*/ +typedef struct { + // Working state. + /// Value + BIT_STREAM *Val; + /// Key + BIT_STREAM *Key; + /// Counter: Number of requests for pseudorandom bits + /// since instantiation or reseeding + UINTN ReseedCounter; +} CTR_INTERNAL_STATE; + +/** Ctr specific values. + + Cf. [1] Table 3: Definitions for the CTR_DRBG + Some fields might be in the DRBG_VALUE_DEFINITIONS structure. +*/ +typedef struct { + /// Input and output block length + UINTN BlockLen; + /// Counter field length. + UINTN CtrLen; + // Key length. + UINTN KeyLen; + /// Required minimum entropy for instantiate and reseed. + UINTN MinRequiredEntropy; + /// Seed length. + UINTN SeedLen; + /// Maximum number of requests between two reseeds. + UINT64 ReseedInterval; +} CTR_VALUE_DEFINITIONS; + +#endif // CTR_DRBG_LIB_H_ --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90904): https://edk2.groups.io/g/devel/message/90904 Mute This Topic: https://groups.io/mt/92072293/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90905+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90905+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530382; cv=none; d=zohomail.com; s=zohoarc; b=d+/H5sw8bWL5Ro5CvW9dWnInTN2E1g8QwOkHFCpAatkDBvXS7PgILSRaWvAp1Nf7Ae/IJf2FIjyS+oQIa4MMkNxs9u4jOSMIddJBSHZ6GG3w0eNJjrqyCPx2hhcLAhzJSEbRCRiC7g0wGohcPMMq/Gf8obYhnY+9gX4xYkGsHfw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530382; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=UUDEmmJKoUSZFXGbrMxYZvMgupRkLkqSJRuEsZ+nmQQ=; b=BKexnurAG18Aypcy2HJc94qKehwY3POz31Np3PhIJ3/cY36FXF+gaMt5cpy49QitFosJ76NySGGH11RWQv3RxJpBHoMMHHvZRBjwLROp5XQ35w9S0tpDv3BnEQs/eUXBmHIEJJ5m68m0n98Y7rf5D/xZZyovYdwC2cOgzmZIRCo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90905+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530382016308.92804226675673; Wed, 29 Jun 2022 12:19:42 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 07rRYY1788612xyT0tLLMGBT; Wed, 29 Jun 2022 12:19:41 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.15707.1656530381004631752 for ; Wed, 29 Jun 2022 12:19:41 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id ED36B14BF; Wed, 29 Jun 2022 12:19:40 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id C52B93F792; Wed, 29 Jun 2022 12:19:38 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 7/9] MdePkg/DrbgLib: Add Drbg mechanism functions and module Date: Wed, 29 Jun 2022 21:18:44 +0200 Message-Id: <20220629191848.2619317-8-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: bTc9gaMMSXIx4PqRHPG6AscFx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530381; bh=vy/O5Vr8AdIRDH2y/PXStbPLUU2lFdG13eertCoZxCk=; h=Cc:Date:From:Reply-To:Subject:To; b=w82NzCD/ArLN7zcfNsTI2PgLKMGaV82594GUJD8Xiag+oQvwJd/R7l7BcxYXm689Ye0 MjkNWMDNwEE8EIAbxfMDZYBxiOBcD3MIG676HJqKF6SqkkSNzkLeZ+lpEJzxjfHaKmd+m GQEWESKJLxZ3AxnD2fuUNbVJqGw+1xNo2G0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530384237100005 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3971 From the NIST Special Publication 800-90A, the implementation of a Drbg can be split into: 1. DRBG Mechanism Functions (s9 of the spec), describing the operations generic to all the mechanisms. 2. DRBG Algorithm Specifications (s10 of the spec), describing the operations specific to each mechanisms (CTR, HMAC, ...) This patch implements 1., i.e. the operations generic to all the mechanisms. Functions implemented here are also the DrbgLib interface. The .inf file associated to the module is also added here. Signed-off-by: Pierre Gondois Signed-off-by: Sami Mujawar --- MdePkg/Library/DrbgLib/DrbgLib.c | 628 +++++++++++++++++++++++ MdePkg/Library/DrbgLib/DrbgLib.inf | 39 ++ MdePkg/Library/DrbgLib/DrbgLibInternal.h | 310 +++++++++++ MdePkg/MdePkg.dsc | 1 + 4 files changed, 978 insertions(+) create mode 100644 MdePkg/Library/DrbgLib/DrbgLib.c create mode 100644 MdePkg/Library/DrbgLib/DrbgLib.inf create mode 100644 MdePkg/Library/DrbgLib/DrbgLibInternal.h diff --git a/MdePkg/Library/DrbgLib/DrbgLib.c b/MdePkg/Library/DrbgLib/Drbg= Lib.c new file mode 100644 index 000000000000..bfad8fc670be --- /dev/null +++ b/MdePkg/Library/DrbgLib/DrbgLib.c @@ -0,0 +1,628 @@ +/** @file + Drbg library. + Cf. [1] s9 DRBG Mechanism Functions + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation for Key Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + - [5] Unified Extensible Firmware Interface (UEFI) Specification, + Version 2.8 Errata B, May 2020 + (https://www.uefi.org/specifications) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#include +#include +#include +#include + +#include "Common.h" +#include "GetEntropyInput.h" + +/** Check the internal state of the Drbg handle. + + @param [in] DrbgHandle The Drbg handle. + + @retval TRUE The Drbg handle has a valid internal state. + @retval FALSE Otherwise. +**/ +STATIC +BOOLEAN +CheckInternalState ( + IN DRBG_HANDLE DrbgHandle + ) +{ + if ((DrbgHandle =3D=3D NULL) || + EFI_ERROR (DrbgHandle->DrbgCheckInternalState (DrbgHandle))) + { + ASSERT (DrbgHandle !=3D NULL); + ASSERT_EFI_ERROR (DrbgHandle->DrbgCheckInternalState (DrbgHandle)); + return FALSE; + } + + return TRUE; +} + +/** Reseed a DRBG instance. + + Implementation of Reseed_function. + Cf. [1] s9.2 'Reseeding a DRBG Instantiation' + + @param [in] PredResRequest Indicates whether prediction resistance + is to be provided during the request. + Might not be supported by all Drbgs. + @param [in] AddInput An optional additional input. + Might not be supported by all Drbgs. + @param [in] AddInputLen Additional input length (in bits). + Might not be supported by all Drbgs. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgReseedFn ( + IN BOOLEAN PredResRequest, + IN CONST CHAR8 *AddInput, + IN UINTN AddInputLen, + IN OUT VOID *Handle + ) +{ + EFI_STATUS Status; + DRBG_HANDLE DrbgHandle; + BIT_STREAM *AddInputStream; + BIT_STREAM *EntropyBitsStream; + + DrbgHandle =3D (DRBG_HANDLE)Handle; + + // 1. Using state_handle, obtain the current internal state. + // If state_handle indicates an invalid or unused internal state, + // return (ERROR_FLAG). + if (((AddInput =3D=3D NULL) ^ (AddInputLen =3D=3D 0)) || + !CheckInternalState (DrbgHandle)) + { + ASSERT (!((AddInput =3D=3D NULL) ^ (AddInputLen =3D=3D 0))); + ASSERT (CheckInternalState (DrbgHandle)); + return EFI_INVALID_PARAMETER; + } + + AddInputStream =3D NULL; + EntropyBitsStream =3D NULL; + + // 2. If prediction_resistance_request is set, and prediction_resistance= _flag + // is not set, then return (ERROR_FLAG). + if (PredResRequest && !DrbgHandle->IntState.PredResFlag) { + ASSERT (!(PredResRequest && !DrbgHandle->IntState.PredResFlag)); + return EFI_INVALID_PARAMETER; + } + + // 3. If the length of the additional_input > max_additional_input_lengt= h, + // return (ERROR_FLAG). + if (AddInputLen > DrbgHandle->DrbgVal.MaxAddInputLen) { + ASSERT (AddInputLen <=3D DrbgHandle->DrbgVal.MaxAddInputLen); + return EFI_INVALID_PARAMETER; + } + + // 4. (status, entropy_input) =3D Get_entropy_input (security_strength, + // min_length, max_length, prediction_resistance_request). + // 5. If (status !=3D SUCCESS), return (status). + // + // Note: in this implementation, there is no difference between + // ERROR_FLAG and CATASTROPHIC_ERROR_FLAG. + Status =3D DrbgHandle->DrbgGetEntropyInput ( + DrbgHandle, + DrbgHandle->DrbgVal.MinLen, + &EntropyBitsStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Create a BitStream for AddInput, even for a NULL AddInput. AddInput is + // used during instantiation but doesn't persist in the Drbg handle. + Status =3D BitStreamInit ( + (UINT8 *)AddInput, + AddInputLen, + &AddInputStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 6. new_working_state =3D Reseed_algorithm (working_state, entropy_inp= ut, + // additional_input). + // 7. Replace the working_state in the internal state for the DRBG + // instantiation (e.g., as indicated by state_handle) with the values of + // new_working_state obtained in step 6. + Status =3D DrbgHandle->DrbgReseedAlgo ( + EntropyBitsStream, + AddInputStream, + DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall trough + } + +ExitHandler: + if (AddInputStream !=3D NULL) { + BitStreamFree (&AddInputStream); + } + + if (EntropyBitsStream !=3D NULL) { + BitStreamFree (&EntropyBitsStream); + } + + // 8. Return (SUCCESS). + return Status; +} + +/** Create a Drbg instance. + + Implementation of Instantiate_function. + Cf. [1] s9.1 Instantiating a DRBG + + @param [in] DrbgMechanism DRBG mechanism chosen. + @param [in] DrbgEntropySrc Entropy source chosen. + @param [in] ReqSecStrength Requested security strength (in bits). + The security strenght granted can be diffe= rent. + @param [in] PredRes Prediction resistance flag. + If relevant, instantiate a DRBG that suppo= rts + prediction resistance. + Might not be supported by all Drbgs. + @param [in] PersStr Personnalization string. + Might not be supported by all Drbgs. + @param [in] PersStrLen Personnalization string length (in bits). + Might not be supported by all Drbgs. + @param [out] HandlePtr Pointer containting the created Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgInstantiateFn ( + IN DRBG_MECHANISM DrbgMechanism, + IN DRBG_ENTROPY_SRC DrbgEntropySrc, + IN UINTN ReqSecStrength, + IN BOOLEAN PredRes, + IN CONST CHAR8 *PersStr, + IN UINTN PersStrLen, + OUT VOID **HandlePtr + ) +{ + EFI_STATUS Status; + BIT_STREAM *EntropyBitsStream; + BIT_STREAM *PersStrBitStream; + DRBG_HANDLE DrbgHandle; + + if ((ReqSecStrength =3D=3D 0) || + ((PersStr =3D=3D NULL) ^ (PersStrLen =3D=3D 0)) || + (HandlePtr =3D=3D NULL)) + { + ASSERT (ReqSecStrength !=3D 0); + ASSERT (!((PersStr =3D=3D NULL) ^ (PersStrLen =3D=3D 0))); + ASSERT (HandlePtr !=3D NULL); + return EFI_INVALID_PARAMETER; + } + + // Allocate a Drbg. + DrbgHandle =3D AllocateZeroPool (sizeof (DRBG_INFO)); + if (DrbgHandle =3D=3D NULL) { + ASSERT (DrbgHandle !=3D NULL); + return EFI_OUT_OF_RESOURCES; + } + + // Init the handle according to the mechanism. + switch (DrbgMechanism) { + case DrbgMechansimCtr: + Status =3D CtrInitHandle (DrbgHandle); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + break; + + default: + Status =3D EFI_INVALID_PARAMETER; + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // Init the handle according to entropy. + switch (DrbgEntropySrc) { + case DrbgEntropyNoCondFn: + DrbgHandle->DrbgGetEntropyInput =3D GetEntropyInputNoCondFn; + break; + + default: + Status =3D EFI_INVALID_PARAMETER; + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + EntropyBitsStream =3D NULL; + PersStrBitStream =3D NULL; + + // 1. If requested_instantiation_security_strength > + // highest_supported_security_strength, + // then return (ERROR_FLAG, Invalid). + if (ReqSecStrength > DrbgHandle->DrbgVal.HighestSuppSecStrength) { + ASSERT (ReqSecStrength <=3D DrbgHandle->DrbgVal.HighestSuppSecStrength= ); + goto ExitHandler; + } + + // 2. If prediction_resistance_flag is set, and prediction resistance + // is not supported, then return (ERROR_FLAG, Invalid). + if (!DrbgHandle->PredResSupported && PredRes) { + ASSERT (!(!DrbgHandle->PredResSupported && PredRes)); + goto ExitHandler; + } + + if (PersStr !=3D NULL) { + // 3. If the length of the personalization_string > + // max_personalization_string_length, + // return (ERROR_FLAG, Invalid). + if (PersStrLen > DrbgHandle->DrbgVal.MaxPersStrLen) { + ASSERT (PersStrLen <=3D DrbgHandle->DrbgVal.MaxPersStrLen); + goto ExitHandler; + } + } + + // 4. Set security_strength to the lowest security strength greater than= or + // equal to requested_instantiation_security_strength from the set + // {112, 128, 192, 256}. + // + // Note: [5], Section 37.5 Random Number Generator Protocol: + // 'When a Deterministic Random Bit Generator (DRBG) is used on the + // output of a (raw) entropy source, its security level must be at + // least 256 bits.' + // So set the security strength to 256. + // + // Note2: Set it here so CTR_DRBG_Instantiate_algorithm has access to it. + DrbgHandle->IntState.SecStrength =3D SecStrength256bits; + DEBUG (( + DEBUG_INFO, + "Requested security strength =3D %d bits. " \ + "Setting security strength for DRBG to %d bits.\n", + ReqSecStrength, + SecStrength256bits + )); + + // Create a BitStream for PersStr, even for a NULL PersStr. PersStr is + // used during instantiation but doesn't persist in the Drbg handle. + Status =3D BitStreamInit ( + (UINT8 *)PersStr, + PersStrLen, + &PersStrBitStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 5. Null step. + // 6. (status, entropy_input) =3D Get_entropy_input (security_strength, + // min_length, max_length, prediction_resistance_request). + // + // Note: in this implementation, there is no difference between + // ERROR_FLAG and CATASTROPHIC_ERROR_FLAG. + // + // 7. If (status !=3D SUCCESS), return (status, Invalid). + Status =3D DrbgHandle->DrbgGetEntropyInput ( + DrbgHandle, + DrbgHandle->DrbgVal.MinLen, + &EntropyBitsStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 8. Obtain a nonce. + Status =3D DrbgHandle->DrbgGetNonce (DrbgHandle, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 9. initial_working_state =3D Instantiate_algorithm (entropy_input, no= nce, + // personalization_string, security_strength). + Status =3D DrbgHandle->DrbgInstantiateAlgo ( + EntropyBitsStream, + PersStrBitStream, + DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 10. Get a state_handle for a currently empty internal state. If an em= pty + // internal state cannot be found, return (ERROR_FLAG, Invalid). + // 11. Set the internal state for the new instantiation (e.g., as indica= ted + // by state_handle) to the initial values for the internal state (i.e., = set + // the working_state to the values returned as initial_working_state in + // step 9) and any other values required for the working_state (see + // Section 10), and set the administrative information to the appropriate + // values (e.g., the values of security_strength and the + // prediction_resistance_flag). + DrbgHandle->IntState.PredResFlag =3D PredRes; + // DrbgInstantiateAlgo already sets ReseedCounter + +ExitHandler: + if (EntropyBitsStream !=3D NULL) { + BitStreamFree (&EntropyBitsStream); + } + + if (PersStrBitStream !=3D NULL) { + BitStreamFree (&PersStrBitStream); + } + + if (EFI_ERROR (Status)) { + FreePool (DrbgHandle); + DrbgHandle =3D NULL; + } + + // 12. Return (SUCCESS, state_handle). + *HandlePtr =3D (VOID **)DrbgHandle; + return Status; +} + +/** Generate a random number. + + Implementation of Generate_function. + Cf. [1] s9.3.1 The Generate Function + + @param [in] ReqSecStrength Requested security strength (in bits). + If the DrbgHandle cannot satisfy the reque= st, + an error is returned. + @param [in] PredResReq Request prediction resistance. + If the DrbgHandle cannot satisfy the reque= st, + an error is returned. + @param [in] AddInput Additional input. + Might not be supported by all Drbgs. + @param [in] AddInputLen Additional input length (in bits). + Might not be supported by all Drbgs. + @param [in] ReqNbBits Number of random bits requested. + @param [in, out] OutBuffer If success, contains the random bits. + The buffer must be at least ReqNbBits bits + long. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +EFI_STATUS +EFIAPI +DrbgGenerateFn ( + IN UINTN ReqSecStrength, + IN BOOLEAN PredResReq, + IN CONST CHAR8 *AddInput, + IN UINTN AddInputLen, + IN UINTN ReqNbBits, + IN OUT UINT8 *OutBuffer, + IN OUT VOID *Handle + ) +{ + EFI_STATUS Status; + DRBG_HANDLE DrbgHandle; + BOOLEAN ReseedReq; + BIT_STREAM *AddInputStream; + BIT_STREAM *RandomBitsStream; + + DrbgHandle =3D (DRBG_HANDLE)Handle; + + // 1. Using state_handle, obtain the current internal state for the + // instantiation. If state_handle indicates an invalid or unused internal + // state, then return (ERROR_FLAG, Null). + if ((ReqSecStrength =3D=3D 0) || + ((AddInput !=3D NULL) ^ (AddInputLen !=3D 0)) || + (ReqNbBits =3D=3D 0) || + (OutBuffer =3D=3D NULL) || + !CheckInternalState (DrbgHandle)) + { + ASSERT (ReqSecStrength !=3D 0); + ASSERT (!((AddInput !=3D NULL) ^ (AddInputLen !=3D 0))); + ASSERT (ReqNbBits !=3D 0); + ASSERT (OutBuffer !=3D NULL); + ASSERT (CheckInternalState (DrbgHandle)); + return EFI_INVALID_PARAMETER; + } + + AddInputStream =3D NULL; + RandomBitsStream =3D NULL; + + // 2. If requested_number_of_bits > max_number_of_bits_per_request, + // then return (ERROR_FLAG, Null). + if (ReqNbBits > DrbgHandle->DrbgVal.MaxNbBitsPerRequest) { + ASSERT (ReqNbBits <=3D DrbgHandle->DrbgVal.MaxNbBitsPerRequest); + return EFI_INVALID_PARAMETER; + } + + // 3. If requested_security_strength > the security_strength indicated + // in the internal state, then return (ERROR_FLAG, Null). + if (ReqSecStrength > DrbgHandle->IntState.SecStrength) { + ASSERT (ReqSecStrength <=3D DrbgHandle->IntState.SecStrength); + return EFI_INVALID_PARAMETER; + } + + // 4. If the length of the additional_input > max_additional_input_lengt= h, + // then return (ERROR_FLAG, Null). + if (AddInputLen > DrbgHandle->DrbgVal.MaxAddInputLen) { + ASSERT (AddInputLen <=3D DrbgHandle->DrbgVal.MaxAddInputLen); + return EFI_INVALID_PARAMETER; + } + + // 5. If prediction_resistance_request is set, and prediction_resistance= _flag + // is not set, then return (ERROR_FLAG, Null). + if (PredResReq && !DrbgHandle->IntState.PredResFlag) { + ASSERT (!(PredResReq && !DrbgHandle->IntState.PredResFlag)); + return EFI_INVALID_PARAMETER; + } + + // 6. Clear the reseed_required_flag. + ReseedReq =3D FALSE; + + // 7. If reseed_required_flag is set, or if prediction_resistance_reques= t is + // set, then +Step7: + if (ReseedReq || PredResReq) { + // 7.1 status =3D Reseed_function (state_handle, + // prediction_resistance_request, additional_input). + // 7.2 If (status !=3D SUCCESS), then return (status, Null). + // 7.3 Using state_handle, obtain the new internal state. + // + // Note: in this implementation, there is no difference between + // ERROR_FLAG and CATASTROPHIC_ERROR_FLAG. + Status =3D DrbgReseedFn ( + PredResReq, + AddInput, + AddInputLen, + DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 7.4 additional_input =3D the Null string. + AddInput =3D NULL; + AddInputLen =3D 0; + + // 7.5 Clear the reseed_required_flag. + ReseedReq =3D FALSE; + } + + // Create a BitStream for AddInput, even for a NULL AddInput. AddInput is + // used during instantiation but doesn't persist in the Drbg handle. + Status =3D BitStreamInit ( + (UINT8 *)AddInput, + AddInputLen, + &AddInputStream + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // 8. (status, pseudorandom_bits, new_working_state) =3D + // Generate_algorithm (working_state, requested_number_of_bits, + // additional_input). + Status =3D DrbgHandle->DrbgGenerateAlgo ( + AddInputStream, + ReqNbBits, + &RandomBitsStream, + DrbgHandle + ); + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_READY)) { + ASSERT_EFI_ERROR (Status); + goto ExitHandler; + } + + // Free AddInputStream now that it has been used. + if (AddInputStream !=3D NULL) { + BitStreamFree (&AddInputStream); + } + + // 9. If status indicates that a reseed is required before the requested + // bits can be generated, then + if (Status =3D=3D EFI_NOT_READY) { + if (DrbgHandle->ReseedSupported) { + // 9.1 Set the reseed_required_flag. + ReseedReq =3D TRUE; + + // 9.2 If the prediction_resistance_flag is set, then set the + // prediction_resistance request indication. + if (DrbgHandle->IntState.PredResFlag) { + PredResReq =3D TRUE; + } + + // 9.3 Go to step 7. + goto Step7; + } else { + // Implementation notes: + // If a reseed capability is not supported, or a reseed is not desir= ed, + // then generate process steps 6 and 7 are removed; generate process + // step 9 is replaced by: + // 9. If status indicates that a reseed is required before the reque= sted + // bits can be generated, then + // 9.1 status =3D Uninstantiate_function (state_handle). + // + // No need to check the returned status. + DrbgUninstantiateFn (DrbgHandle); + + // 9.2 Return an indication that the DRBG instantiation can no longe= r be used. + goto ExitHandler; + } + } + + // The Drbg succeeded, copy the random bits. + Status =3D BitStreamToBuffer (RandomBitsStream, OutBuffer); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + // Fall through. + } + + // 10. Replace the old working_state in the internal state of the DRBG + // instantiation (e.g., as indicated by state_handle) with the values of + // new_working_state. + // 11. Return (SUCCESS, pseudorandom_bits). +ExitHandler: + if (AddInputStream !=3D NULL) { + BitStreamFree (&AddInputStream); + } + + if (RandomBitsStream !=3D NULL) { + BitStreamFree (&RandomBitsStream); + } + + return Status; +} + +/** Remove a DRBG instance. + + Implementation of Uninstantiate_function. + Cf. [1] s9.4 Removing a DRBG Instantiation + + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +DrbgUninstantiateFn ( + IN OUT VOID *Handle + ) +{ + DRBG_HANDLE DrbgHandle; + + DrbgHandle =3D (DRBG_HANDLE)Handle; + return DrbgHandle->DrbgUninstantiateFn (DrbgHandle); +} diff --git a/MdePkg/Library/DrbgLib/DrbgLib.inf b/MdePkg/Library/DrbgLib/Dr= bgLib.inf new file mode 100644 index 000000000000..34272aa88d85 --- /dev/null +++ b/MdePkg/Library/DrbgLib/DrbgLib.inf @@ -0,0 +1,39 @@ +## @file +# Drbg library +# +# Copyright (c) 2022, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D DrbgLib + FILE_GUID =3D 454B071B-FD44-4055-B689-E06B6FE5D3D7 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + LIBRARY_CLASS =3D DrbgLib + +# +# VALID_ARCHITECTURES =3D AARCH64 ARM +# + +[Sources] + BitStream.c + BitStream.h + Common.c + Common.h + CtrDrbg.c + CtrDrbg.h + DrbgLib.c + DrbgLibInternal.h + GetEntropyInput.c + GetEntropyInput.h + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + AesLib + BaseLib + TrngLib diff --git a/MdePkg/Library/DrbgLib/DrbgLibInternal.h b/MdePkg/Library/Drbg= Lib/DrbgLibInternal.h new file mode 100644 index 000000000000..6cf681951431 --- /dev/null +++ b/MdePkg/Library/DrbgLib/DrbgLibInternal.h @@ -0,0 +1,310 @@ +/** @file + Arm DRBG library internal definitions. + Cf. [1] s9 DRBG Mechanism Functions + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + + - [1] NIST Special Publication 800-90A Revision 1, June 2015, Recommenda= tion + for Random Number Generation Using Deterministic Random Bit Genera= tors. + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final) + - [2] NIST Special Publication 800-90B, Recommendation for the Entropy + Sources Used for Random Bit Generation. + (https://csrc.nist.gov/publications/detail/sp/800-90b/final) + - [3] (Second Draft) NIST Special Publication 800-90C, Recommendation for + Random Bit Generator (RBG) Constructions. + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft) + - [4] NIST Special Publication 800-57 Part 1 Revision 5, May 2020, + Recommendation forKey Management:Part 1 - General. + (https://csrc.nist.gov/publications/detail/sp/800-57-part-1/rev-5/= final) + - [5] Unified Extensible Firmware Interface (UEFI) Specification, + Version 2.8 Errata B, May 2020 + (https://www.uefi.org/specifications) + + @par Glossary: + - TRNG - True Random Number Generator + - Sec - Security + - DRBG - Deterministic Random Bits Generator + - CTR - Counter +**/ + +#ifndef ARM_DRBG_LIB_INTERNAL_H_ +#define ARM_DRBG_LIB_INTERNAL_H_ + +// Forward declarations of DRBG_INFO. +typedef struct DrbgInfo DRBG_INFO; +typedef DRBG_INFO *DRBG_HANDLE; + +#include +#include +#include "BitStream.h" + +/** Security strengths for block cipher algorithms. + + Cf [2] 5.6.1.1, Table 2: Comparable security strengths of symmetric bl= ock + cipher and asymmetric-key algorithms. + + [2]: 'Although 3TDEA is listed as providing 112 bits of security stren= gth, + its use has been deprecated (see SP 800-131A)' +*/ +typedef enum { + SecStrengthMin =3D 128, ///< Min Security strength of = 128 bits. + SecStrength128bits =3D SecStrengthMin, ///< Security strength of 128 = bits. + SecStrength196bits =3D 196, ///< Security strength of 196 = bits. + SecStrength256bits =3D 256, ///< Security strength of 256 = bits. + SecStrengthMax =3D SecStrength256bits ///< Maximum Security strength. +} SECURITY_STRENGTH; + +/** Get a nonce. + + @param [in, out] DrbgHandle The Drbg handle. + @param [out] NonceStream Stream containing the Nonce. + + @retval EFI_SUCCESS Success. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_GET_NONCE) ( + IN OUT DRBG_HANDLE DrbgHandle, + OUT BIT_STREAM *NonceStream + ); + +/** Check the internal state of the Drbg handle. + + @param [in] DrbgHandle The Drbg handle. + + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_SUCCESS Success. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_CHECK_INTERNAL_STATE) ( + IN DRBG_HANDLE DrbgHandle + ); + +/** GetEntropyInput implementation (no conditionning function). + + Cf. [3] 10.3.3 Get_entropy_input Constructions for Accessing Entropy Sou= rces + + @param [in] DrbgHandle The Drbg hanble. + @param [in] MinEntropy Minimum entropy. + @param [out] EntropyBitsStream Stream containing the generated entropy. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_GET_ENTROPY_INTPUT) ( + IN DRBG_HANDLE DrbgHandle, + IN UINTN MinEntropy, + OUT BIT_STREAM **EntropyBitsStream + ); + +/** Update algorithm. + + CTR_DRBG_Update implementation. + + Cf. [1] s10.2.1.2 The Update Function (CTR_DRBG_Update) + + @param [in] ProvidedData The data to be used. This must be exactly + seedlen bits in length. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_UPDATE) ( + IN BIT_STREAM *ProvidedData, + IN OUT DRBG_HANDLE DrbgHandle + ); + +/** Reseed algorithm + + @param [in] EntropyInput The string of bits obtained from the + randomness source. + @param [in] AddInput The additional input string received + from the consuming application. Note + that the length of the additional_input + string may be zero. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_RESEED) ( + IN BIT_STREAM *EntropyInput, + IN BIT_STREAM *AddInput, + IN OUT DRBG_HANDLE DrbgHandle + ); + +/** Instantiate algorithm. + + CTR_DRBG_Instantiate_algorithm implementation. + + Cf. [1] s10.2.1.3.1 Instantiation When a Derivation Function is Not Used + + @param [in] EntropyInput The string of bits obtained from the + randomness source. + @param [in] PersStrBitStream The personalization string received from= the + consuming application. Note that the len= gth + of the personalization_string may be zer= o. + Note: PersStrBitStream must be initializ= ed, + even with a NULL BitStream. + @param [out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_INSTANTIATE) ( + IN BIT_STREAM *EntropyInput, + IN BIT_STREAM *PersStrBitStream, + OUT DRBG_HANDLE DrbgHandle + ); + +/** Generate algorithm. + + @param [in] AddInput The additional input string received= from + the consuming application. Note that= the + length of the additional_input string + may be zero. + @param [in] RequestedNbBits The number of pseudorandom bits to be + returned to the generate function. + @param [out] RndBitStream BitStream containing the random bits. + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval EFI_OUT_OF_RESOURCES Out of resources. + @retval EFI_NOT_READY A reseed is required before the requested + pseudorandom bits can be generated. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_GENERATE_ALGORITHM) ( + IN BIT_STREAM *AddInput, + IN UINTN RequestedNbBits, + OUT BIT_STREAM **RndBitStream, + IN OUT DRBG_HANDLE DrbgHandle + ); + +/** Uninstantiate a DRBG instance. + + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +typedef EFI_STATUS EFIAPI (*DRBG_UNINSTANTIATE_FUNCTION) ( + IN OUT DRBG_HANDLE DrbgHandle + ); + +/** Drbg algo specific value definitions. +*/ +typedef VOID *DRBG_ALGO_VALUE_DEFINITIONS; + +/** Drbg algo internal state values. +*/ +typedef VOID *DRBG_ALGO_INTERNAL_STATE; + +/** Drbg values definitions. + + Values are specific to a Drbg mechanism. + Cf. [1]: + Table 2: Definitions for Hash-Based DRBG Mechanisms + Table 3: Definitions for the CTR_DRBG +*/ +typedef struct { + /// Supported security strengths. + // Not applicable. + /// Highest supported security strength. + SECURITY_STRENGTH HighestSuppSecStrength; + /// Minimum entropy input length. + UINTN MinLen; + /// Maximum entropy input length. + UINTN MaxLen; + /// Maximum personalization string length. + UINTN MaxPersStrLen; + /// Maximum additional_input length. + UINTN MaxAddInputLen; + /// Maximum number of bits per request. + UINTN MaxNbBitsPerRequest; + + /// Drbg algo specific value definitions. + DRBG_ALGO_VALUE_DEFINITIONS DrbgAlgoVal; +} DRBG_VALUE_DEFINITIONS; + +/** Internal state. + + For a Drbg mechanism, values are specific to a Drbg instance. +*/ +typedef struct { + // Administrative information. + /// Security strength + SECURITY_STRENGTH SecStrength; + /// Prediction resistance flag + BOOLEAN PredResFlag; + + /// Drbg algo specific internal state values. + DRBG_ALGO_INTERNAL_STATE DrbgAlgoIntState; +} DRBG_INTERNAL_STATE; + +/** Drbg info structure. + + This structure is a Drbg instance. It contains information specific to t= he + Drbg mechanism chosen (e.g. the block size for Ctr mechanism) and instan= ce + specific information (i.e. the internal state of the instance). +*/ +struct DrbgInfo { + /// Drbg mechanism used. + DRBG_MECHANISM DrbgMechanism; + /// GUID of the algorithm used. + EFI_RNG_ALGORITHM Algo; + + /// Values specifics to the Drbg mechanism used. + DRBG_VALUE_DEFINITIONS DrbgVal; + + /// Internal state of the Drbg instance. + DRBG_INTERNAL_STATE IntState; + + /// Prediction resistance is supported for this Drbg instance. + BOOLEAN PredResSupported; + /// Reseeding is supported for this Drbg instance. + BOOLEAN ReseedSupported; + + /// Callback to get a nonce. + DRBG_GET_NONCE DrbgGetNonce; + /// Callback to check the internal state. + DRBG_CHECK_INTERNAL_STATE DrbgCheckInternalState; + /// Callback to get some entropy. + DRBG_GET_ENTROPY_INTPUT DrbgGetEntropyInput; + + /// Callback to update the instance + /// (according to the mechanism used). + DRBG_UPDATE DrbgUpdate; + /// Callback to reseed the instance + /// (according to the mechanism used). + DRBG_RESEED DrbgReseedAlgo; + /// Callback to instantiate the Drbg instance + /// (according to the mechanism used). + DRBG_INSTANTIATE DrbgInstantiateAlgo; + /// Callback to generate random bits the instance + /// (according to the mechanism used). + DRBG_GENERATE_ALGORITHM DrbgGenerateAlgo; + /// Callback to uninstantiate the Drbg instance + /// (according to the mechanism used). + DRBG_UNINSTANTIATE_FUNCTION DrbgUninstantiateFn; +}; + +/** Drbg mechanism specific instantiation steps. + + @param [in, out] DrbgHandle The Drbg handle. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +CtrInitHandle ( + IN OUT DRBG_HANDLE DrbgHandle + ); + +#endif // ARM_DRBG_LIB_INTERNAL_H_ diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 4820cecd0db8..5926a179d810 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -70,6 +70,7 @@ [Components] MdePkg/Library/BaseTrngLibNull/BaseTrngLibNull.inf MdePkg/Library/AesLibNull/AesLibNull.inf MdePkg/Library/DrbgLibNull/DrbgLibNull.inf + MdePkg/Library/DrbgLib/DrbgLib.inf =20 MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90905): https://edk2.groups.io/g/devel/message/90905 Mute This Topic: https://groups.io/mt/92072294/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90906+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90906+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530384; cv=none; d=zohomail.com; s=zohoarc; b=ErHZjNxJPcNtPPVq3v37A/qU08KIAmIQxbmlXNluXXVTJPpApK6NcN190d8dPGkWgfmHxBbRQr1Kv/ZPBLnyXVT9nKDr/piJ8UEYSvhC3GzY9jn6hAjyqDM5goqh/LqX/virJhd2VICqw1VEH7LRpf3bSfhFR9e0yAm6albfbKw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530384; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=soW87ahBF4bCyMMVU7HuAcqC3bE2Nal7nUQXFzGZw2M=; b=NMJTunKSIs+mhxi1i2EXUlkfcPFrcxfYafq1AMeVxjj2dWheqDkBFhtACCZzt1AdxMlaAhHZ0XyNabtFJXDvb8hFobFOR51BOcEaC1NQOh3wZRUDEg3lG307Md8NZ+2uyuxFx+asE8sMYlvHJeQgBu4ATuvzhGQ5MMDLPlgJlos= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90906+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530384501541.5912665270771; Wed, 29 Jun 2022 12:19:44 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id Rok8YY1788612xghYIfJTqQR; Wed, 29 Jun 2022 12:19:44 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web09.16029.1656530383666236906 for ; Wed, 29 Jun 2022 12:19:43 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8A0911480; Wed, 29 Jun 2022 12:19:43 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 169D73F792; Wed, 29 Jun 2022 12:19:40 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 8/9] ArmVirtPkg: Kvmtool: Add AesLib/DrbgLib for RngDxe Date: Wed, 29 Jun 2022 21:18:45 +0200 Message-Id: <20220629191848.2619317-9-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: A0fCYMIXIVJcKHnUMHoNLxTgx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530384; bh=jxd87uOtdLwBx9MGMEFngVsAcQnLoSW9gX9UlAx1qSw=; h=Cc:Date:From:Reply-To:Subject:To; b=U821PkM0bC4feC1n69clejUlr8Bq4b72DVrRiPt3qlrXaIFYqWuxKi+fVXUDrv5RuJw nh/ZBq/l6V25cNuHxidn0W/g9HecMSj+f+29MrEzcKCInWwhaxW0u7Tl8PHLKmh+YOckr BxrO1JjfseWJZkbsHo4Hchq1Zmco3AvnSgM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530386179100010 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3971 The RngDxe will require both AesLib and DrbgLib for Arm. Thus add the libraries to ArmVirtKvmTool.dsc. Signed-off-by: Pierre Gondois --- ArmVirtPkg/ArmVirtKvmTool.dsc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ArmVirtPkg/ArmVirtKvmTool.dsc b/ArmVirtPkg/ArmVirtKvmTool.dsc index 847dbdd2af2b..f14ec7a72a42 100644 --- a/ArmVirtPkg/ArmVirtKvmTool.dsc +++ b/ArmVirtPkg/ArmVirtKvmTool.dsc @@ -81,7 +81,9 @@ [LibraryClasses.common] HwInfoParserLib|DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoPar= serLib.inf DynamicPlatRepoLib|DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/Dy= namicPlatRepoLib.inf =20 + AesLib|ArmPkg/Library/ArmAesLib/ArmAesLib.inf ArmMonitorLib|ArmPkg/Library/ArmMonitorLib/ArmMonitorLib.inf + DrbgLib|MdePkg/Library/DrbgLib/DrbgLib.inf TrngLib|ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf =20 [LibraryClasses.common.SEC, LibraryClasses.common.PEI_CORE, LibraryClasses= .common.PEIM] --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90906): https://edk2.groups.io/g/devel/message/90906 Mute This Topic: https://groups.io/mt/92072295/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90908+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90908+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530389; cv=none; d=zohomail.com; s=zohoarc; b=lKSV4zvz+0E9eV9T4E5qDisl5SGN+op2A01+1B1fgCmHeSuBHMtIqvT4cPf+BVdSClpGDwHVmSfXAJ2xWUCxa9nvMdmlpwBvpqjinRTwuj4wUtMSV+DLoZ92V/IpWMMsMOWH7iaW9WC4HlYLaQkPIMPWzgGKmGP76WmpL63P3k8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530389; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=C9jSeCZL1HsLenHqdttsVWnFIFFmPwLeN4Kh82H8HBk=; b=GMlvgAFJh9gF8YI232D41HUzgepeRuqQMpxcpEe8bn8GyN15FQsbSS/v7YSuHZpKU6DdaT+acX+fyLmAY+PXnZ3rbYyNOMKfZi+9wULVW2PXxQGQ032Cy764chGmnpnRwKqs5Pxy7JRU2AXSFDjfGbge4NHYe4zaQ9nLymEJEy4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90908+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530389321375.95512670590745; Wed, 29 Jun 2022 12:19:49 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 1VVRYY1788612xDQJOKAril0; Wed, 29 Jun 2022 12:19:49 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.15934.1656530388338470344 for ; Wed, 29 Jun 2022 12:19:48 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4BCA11480; Wed, 29 Jun 2022 12:19:48 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E48873F792; Wed, 29 Jun 2022 12:19:45 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 09/10] SecurityPkg: Update Securitypkg.ci.yaml Date: Wed, 29 Jun 2022 21:18:47 +0200 Message-Id: <20220629191848.2619317-11-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: 3ZyWdNeZfF9z0rzh8EUYH9Jkx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530389; bh=Ilpudz90o4b1iwS+JXYzxP7NSOszpHHD1jkiiQMXNEY=; h=Cc:Date:From:Reply-To:Subject:To; b=lSt8SMCb46Pel91HuqFMfX9kRQnb8972KvoLUA+xqYNcvd9yd91h8FZPYVFbXqM8zzm yY+FnQvZOwdicLqB58jy5P2iii5spDpYKvhuGaK1gP+Po5ltOSezpRGhfMjyTGRw7ZhZx Nt53MxETnint/JDmXC0+sffRYO7YBOAzTHY= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530390189100020 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois Add ArmPkg.dec as a valid dependency for the SecurityPkg. Signed-off-by: Pierre Gondois --- SecurityPkg/SecurityPkg.ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.y= aml index 791214239899..08e98d713224 100644 --- a/SecurityPkg/SecurityPkg.ci.yaml +++ b/SecurityPkg/SecurityPkg.ci.yaml @@ -31,6 +31,7 @@ }, "DependencyCheck": { "AcceptableDependencies": [ + "ArmPkg/ArmPkg.dec", "MdePkg/MdePkg.dec", "MdeModulePkg/MdeModulePkg.dec", "SecurityPkg/SecurityPkg.dec", --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90908): https://edk2.groups.io/g/devel/message/90908 Mute This Topic: https://groups.io/mt/92072297/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90907+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90907+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530386; cv=none; d=zohomail.com; s=zohoarc; b=P89tf1CIoCdyOmXExddqnxHJzK84ylhXe/Q4elQYfoZZUJFSSNaAU0IV5IVCj9yztMf38mQ5nuhpUy2k0VRQvJx83K0V/oSWWSpPupQQW5v+0t6EgqXey3a9MBxQB31yVvPV/dJv4VYrHs6XHvnfMCIH3x/Gp1McjYtoSTNei6k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530386; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=R/vrzoT3eoagMdWITY+fbm1bq555wQCyFMu/5hmmzog=; b=XBXJfhgXw6cScBEcr7khFy0ctiBxjC2gCDI9Dopz62jzfaVGbpKTx6LTFqdFKrlIzR8G8wzc7YggfW7rsBIySdSw1ucJBAlf8S7GvSC4MGSgMJXBfBRwe6XS70cioZZIpqE1X7dZ3MEB48CF6WXoFkjia/UycU4AOwUqcWFB+q0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90907+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530386931989.5364184551919; Wed, 29 Jun 2022 12:19:46 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id lBQVYY1788612xG2u1KWD3cm; Wed, 29 Jun 2022 12:19:46 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.15709.1656530385947618012 for ; Wed, 29 Jun 2022 12:19:46 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D6AC614BF; Wed, 29 Jun 2022 12:19:45 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8FCD03F792; Wed, 29 Jun 2022 12:19:43 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH RESEND v1 9/9] SecurityPkg/RngDxe: Use DrbgLib in RngDxe for Arm Date: Wed, 29 Jun 2022 21:18:46 +0200 Message-Id: <20220629191848.2619317-10-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: RlvRcKT1IySYNy0PXJp958Mtx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530386; bh=LRfhe7Bczj+Qbq8zNOrSzqKY4HzQ7jOmgBzRhklJOHE=; h=Cc:Date:From:Reply-To:Subject:To; b=BzhzXNAA6d1cLViLESB3Kbwx5HMUD+Oy6ViH21ZzgrJpvdofB+K5PYM3qSgNVG4sca7 DivNwORMGJmyorjJ27k8X51BmyyXPekQWoQHPArFdRcXoofUrc3ZCeN1siI4z6leX4Yht JTns7s7Htt2aWrMbqiKMNTCcSkDCoCfwr9w= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530388201100016 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois Make use of the new DrbgLib and advertise support for the SP800-90 Ctr 256 bits Drbg. The algorithm will be used for Arm and AArch64 arch. Signed-off-by: Pierre Gondois --- .../RandomNumberGenerator/RngDxe/ArmRngDxe.c | 75 ++++++++++++++++++- .../RandomNumberGenerator/RngDxe/RngDxe.inf | 1 + SecurityPkg/SecurityPkg.dsc | 2 + 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c b/Securit= yPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c index 4775252d30b6..400b0a5e9a7c 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,7 @@ // populated only once. // The valid entry with the lowest index will be the default algorithm. // -#define RNG_AVAILABLE_ALGO_MAX 2 +#define RNG_AVAILABLE_ALGO_MAX 3 STATIC BOOLEAN mAvailableAlgoArrayInit =3D FALSE; STATIC UINTN mAvailableAlgoArrayCount; STATIC EFI_RNG_ALGORITHM mAvailableAlgoArray[RNG_AVAILABLE_ALGO_MAX]; @@ -87,11 +88,78 @@ RngInitAvailableAlgoArray ( sizeof (EFI_RNG_ALGORITHM) ); mAvailableAlgoArrayCount++; + + // SP800-90 Ctr 256 bits Drbg. + // Arm implementation is based on the Trng. + CopyMem ( + &mAvailableAlgoArray[mAvailableAlgoArrayCount], + &gEfiRngAlgorithmSp80090Ctr256Guid, + sizeof (EFI_RNG_ALGORITHM) + ); + mAvailableAlgoArrayCount++; } =20 mAvailableAlgoArrayInit =3D TRUE; } =20 +/** Produces and returns an RNG value using a specified Drbg algorithm. + + @param[in] DrbgMechanism The Drbg mechanism to use. + @param[in] RNGValueLength The length in bytes of the memory buffer p= ointed to by + RNGValue. The driver shall return exactly = this numbers of bytes. + @param[out] RNGValue A caller-allocated memory buffer filled by= the driver with the + resulting RNG value. +**/ +STATIC +EFI_STATUS +EFIAPI +RngGetDrbgVal ( + IN DRBG_MECHANISM DrbgMechanism, + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ) +{ + EFI_STATUS Status; + STATIC VOID *DrbgHandle =3D NULL; + + // Only instantiate once. + if (DrbgHandle =3D=3D NULL) { + Status =3D DrbgInstantiateFn ( + DrbgMechanism, + DrbgEntropyNoCondFn, + 256, + FALSE, + NULL, + 0, + &DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // Check overflow. + if (RNGValueLength > (MAX_UINTN >> 3)) { + return EFI_INVALID_PARAMETER; + } + + Status =3D DrbgGenerateFn ( + 256, + FALSE, + NULL, + 0, + RNGValueLength << 3, + RNGValue, + DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } + + return Status; +} + /** Produces and returns an RNG value using either the default or specified = RNG algorithm. =20 @@ -163,6 +231,11 @@ FoundAlgo: return GenerateEntropy (RNGValueLength, RNGValue); } =20 + // SP800-90 Ctr 256 bits Drbg + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) { + return RngGetDrbgVal (DrbgMechansimCtr, RNGValueLength, RNGValue); + } + // // Other algorithms are unsupported by this driver. // diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/Security= Pkg/RandomNumberGenerator/RngDxe/RngDxe.inf index 20752e71ac4e..c95e958e7f85 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf @@ -63,6 +63,7 @@ [LibraryClasses] =20 [LibraryClasses.AARCH64, LibraryClasses.ARM] ArmLib + DrbgLib TrngLib =20 [Guids] diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 779aa2a061a0..cc6d6de72cea 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -95,7 +95,9 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf =20 # RngDxe dependencies + AesLib|MdePkg/Library/AesLibNull/AesLibNull.inf ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf + DrbgLib|MdePkg/Library/DrbgLibNull/DrbgLibNull.inf =20 [LibraryClasses.ARM] RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90907): https://edk2.groups.io/g/devel/message/90907 Mute This Topic: https://groups.io/mt/92072296/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri May 17 20:40:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+90909+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90909+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1656530392; cv=none; d=zohomail.com; s=zohoarc; b=WfDTjhRYnlm/ybNQOBUpCNED1zBbQYNq7kYknFGicZfxLtr4LLpi1+m5LoDbVbJH/DiH6D1BXySiMgHIL+WSVWuUNTF6imAOJjK6OONActLT84evEZZPXZAWL1BUi0Cc5/IKUpS3yfsfitnbcssSXhOxWDItv+Y0hM/bpreVwbQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1656530392; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=pttYByayLirZjNsLQ3BbTGKrQQwHdcaHvvT2re2nZr8=; b=htVOyYg1/mDaSDl4jnDWP9jbVovetipvQGv9gH4Mt3U2cLHX/6Dq5FAwbsFo29guJfYRI5K+UlNM/oGBs3ccEZLEMpQAO57ATUfCnatMFo2O189XAgwDRvQpZACxk+3IG5X/0q9QCgxAyhHW2GvsdIzKx8fk11SOL5RXOm2P5oI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+90909+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1656530391947184.9762534254637; Wed, 29 Jun 2022 12:19:51 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ogSHYY1788612x63320PONQQ; Wed, 29 Jun 2022 12:19:51 -0700 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.15711.1656530390968349415 for ; Wed, 29 Jun 2022 12:19:51 -0700 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D387614BF; Wed, 29 Jun 2022 12:19:50 -0700 (PDT) X-Received: from pierre123.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 71AA03F792; Wed, 29 Jun 2022 12:19:48 -0700 (PDT) From: "PierreGondois" To: devel@edk2.groups.io Cc: Sami Mujawar , Leif Lindholm , Ard Biesheuvel , Rebecca Cran , Michael D Kinney , Liming Gao , Jiewen Yao , Jian J Wang Subject: [edk2-devel] [PATCH v1 10/10] SecurityPkg/RngDxe: Use DrbgLib in RngDxe for Arm Date: Wed, 29 Jun 2022 21:18:48 +0200 Message-Id: <20220629191848.2619317-12-Pierre.Gondois@arm.com> In-Reply-To: <20220629191848.2619317-1-Pierre.Gondois@arm.com> References: <20220629191848.2619317-1-Pierre.Gondois@arm.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pierre.gondois@arm.com X-Gm-Message-State: bnuyYDNefOYyu4gIZIZbaWZux1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1656530391; bh=i5KhbicFEKmIt1tG3bAnTLtUK/v/Ay0BTAXYmj4m5mc=; h=Cc:Date:From:Reply-To:Subject:To; b=xBJYFV10zkMUe7xC+/X83LNoS1MRyN/3JlA57197wR97+9z3rVisK7LI2TkBhUik8kq elqxOhLzmhzY2Pw+cqIFzVcNh9+kXLcefslGYgFqSQbaj/AbXAakvrI7UlqDxefWIbrUk QNYxb53L3r48rnhduuNcIPEkd1QjQY3TBb8= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1656530394270100003 Content-Type: text/plain; charset="utf-8" From: Pierre Gondois Make use of the new DrbgLib and advertise support for the SP800-90 Ctr 256 bits Drbg. The algorithm will be used for Arm and AArch64 arch. Signed-off-by: Pierre Gondois --- .../RandomNumberGenerator/RngDxe/ArmRngDxe.c | 75 ++++++++++++++++++- .../RandomNumberGenerator/RngDxe/RngDxe.inf | 2 + SecurityPkg/SecurityPkg.dsc | 5 ++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c b/Securit= yPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c index 4775252d30b6..400b0a5e9a7c 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/ArmRngDxe.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,7 @@ // populated only once. // The valid entry with the lowest index will be the default algorithm. // -#define RNG_AVAILABLE_ALGO_MAX 2 +#define RNG_AVAILABLE_ALGO_MAX 3 STATIC BOOLEAN mAvailableAlgoArrayInit =3D FALSE; STATIC UINTN mAvailableAlgoArrayCount; STATIC EFI_RNG_ALGORITHM mAvailableAlgoArray[RNG_AVAILABLE_ALGO_MAX]; @@ -87,11 +88,78 @@ RngInitAvailableAlgoArray ( sizeof (EFI_RNG_ALGORITHM) ); mAvailableAlgoArrayCount++; + + // SP800-90 Ctr 256 bits Drbg. + // Arm implementation is based on the Trng. + CopyMem ( + &mAvailableAlgoArray[mAvailableAlgoArrayCount], + &gEfiRngAlgorithmSp80090Ctr256Guid, + sizeof (EFI_RNG_ALGORITHM) + ); + mAvailableAlgoArrayCount++; } =20 mAvailableAlgoArrayInit =3D TRUE; } =20 +/** Produces and returns an RNG value using a specified Drbg algorithm. + + @param[in] DrbgMechanism The Drbg mechanism to use. + @param[in] RNGValueLength The length in bytes of the memory buffer p= ointed to by + RNGValue. The driver shall return exactly = this numbers of bytes. + @param[out] RNGValue A caller-allocated memory buffer filled by= the driver with the + resulting RNG value. +**/ +STATIC +EFI_STATUS +EFIAPI +RngGetDrbgVal ( + IN DRBG_MECHANISM DrbgMechanism, + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ) +{ + EFI_STATUS Status; + STATIC VOID *DrbgHandle =3D NULL; + + // Only instantiate once. + if (DrbgHandle =3D=3D NULL) { + Status =3D DrbgInstantiateFn ( + DrbgMechanism, + DrbgEntropyNoCondFn, + 256, + FALSE, + NULL, + 0, + &DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // Check overflow. + if (RNGValueLength > (MAX_UINTN >> 3)) { + return EFI_INVALID_PARAMETER; + } + + Status =3D DrbgGenerateFn ( + 256, + FALSE, + NULL, + 0, + RNGValueLength << 3, + RNGValue, + DrbgHandle + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } + + return Status; +} + /** Produces and returns an RNG value using either the default or specified = RNG algorithm. =20 @@ -163,6 +231,11 @@ FoundAlgo: return GenerateEntropy (RNGValueLength, RNGValue); } =20 + // SP800-90 Ctr 256 bits Drbg + if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) { + return RngGetDrbgVal (DrbgMechansimCtr, RNGValueLength, RNGValue); + } + // // Other algorithms are unsupported by this driver. // diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/Security= Pkg/RandomNumberGenerator/RngDxe/RngDxe.inf index 599a3085102d..c95e958e7f85 100644 --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf @@ -62,6 +62,8 @@ [LibraryClasses] RngLib =20 [LibraryClasses.AARCH64, LibraryClasses.ARM] + ArmLib + DrbgLib TrngLib =20 [Guids] diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index 882d639489ea..cc6d6de72cea 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -94,6 +94,11 @@ [LibraryClasses.ARM, LibraryClasses.AARCH64] ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf =20 + # RngDxe dependencies + AesLib|MdePkg/Library/AesLibNull/AesLibNull.inf + ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf + DrbgLib|MdePkg/Library/DrbgLibNull/DrbgLibNull.inf + [LibraryClasses.ARM] RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf =20 --=20 2.25.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#90909): https://edk2.groups.io/g/devel/message/90909 Mute This Topic: https://groups.io/mt/92072298/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-