From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by mx.groups.io with SMTP id smtpd.web09.2897.1663736055782012016 for ; Tue, 20 Sep 2022 21:54:15 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=QBmfD+TA; spf=pass (domain: intel.com, ip: 192.55.52.43, mailfrom: yi1.li@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1663736055; x=1695272055; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nqWdlFH/pRrbqP1K1rnW1cKAFlRuU6X+6N2VDQiEF8Q=; b=QBmfD+TA0hD98VBwCGOxTXShZPPhBdoSpCoKFBihQk6XuYronQPTohXb hG9njJPm9NTbk3mmM98D3dAF4I4cPGYbS5CFcFd4aSZQ7KrfIdjQLpIaT L4QWwp260R0YQDM1PCWH/zLW746umg6nmWV9UJmgD4ZmVkJjnqETZEkaP OB0xHdO8FMKXhUt4j1hZyYsWI38HWrDXFKp69+KPMjCsxOFNXDd7kaAEl MstFfNBZx1QPDqqEATKuGaZmFLR8m1XKUNxlpNqK8zLYTfoLWF44HKpVM RqOLwX78pjkwflTzEpYnPtJegKl4KqBq3eqfXcEjE56QpVKQgxWkLXdhz g==; X-IronPort-AV: E=McAfee;i="6500,9779,10476"; a="386184479" X-IronPort-AV: E=Sophos;i="5.93,332,1654585200"; d="scan'208";a="386184479" Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Sep 2022 21:54:15 -0700 X-IronPort-AV: E=Sophos;i="5.93,332,1654585200"; d="scan'208";a="947982485" Received: from liyi4-desktop.ccr.corp.intel.com ([10.239.153.82]) by fmsmga005-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Sep 2022 21:54:13 -0700 From: "yi1 li" To: devel@edk2.groups.io Cc: Yi Li , Jiewen Yao , Jian J Wang , Xiaoyu Lu , Guomin Jiang Subject: [PATCH V2 2/3] CryptoPkg: Add BigNum API to DXE and protocol Date: Wed, 21 Sep 2022 12:53:46 +0800 Message-Id: <5f6709f235008f6519d81b8ac86b84441c704f98.1663735456.git.yi1.li@intel.com> X-Mailer: git-send-email 2.31.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3828 The implementation provides CryptBn library functions for EFI Driver and EFI BaseCrypt Protocol. Cc: Jiewen Yao Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li --- CryptoPkg/CryptoPkg.dsc | 1 + CryptoPkg/Driver/Crypto.c | 520 +++++++++++++++++- .../Pcd/PcdCryptoServiceFamilyEnable.h | 30 + .../BaseCryptLibOnProtocolPpi/CryptLib.c | 492 +++++++++++++++++ CryptoPkg/Private/Protocol/Crypto.h | 429 ++++++++++++++- 5 files changed, 1470 insertions(+), 2 deletions(-) diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 50e7721f25..a766851728 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -168,6 +168,7 @@ gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Tls.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsSet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.TlsGet.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY + gEfiCryptoPkgTokenSpaceGuid.PcdCryptoServiceFamilyEnable.Bn.Family | PCD_CRYPTO_SERVICE_ENABLE_FAMILY !endif !if $(CRYPTO_SERVICES) == MIN_PEI diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c index 76cb9f4da0..07150ad2f2 100644 --- a/CryptoPkg/Driver/Crypto.c +++ b/CryptoPkg/Driver/Crypto.c @@ -4582,6 +4582,498 @@ CryptoServiceParallelHash256HashAll ( return CALL_BASECRYPTLIB (ParallelHash.Services.HashAll, ParallelHash256HashAll, (Input, InputByteLen, BlockSize, Output, OutputByteLen, Customization, CustomByteLen), FALSE); } +// ===================================================================================== +// Big number primitives +// ===================================================================================== + +/** + Allocate new Big Number. + + @retval New BigNum opaque structure or NULL on failure. +**/ +VOID * +EFIAPI +CryptoServiceBigNumInit ( + VOID + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Init, BigNumInit, (), NULL); +} + +/** + Allocate new Big Number and assign the provided value to it. + + @param[in] Buf Big endian encoded buffer. + @param[in] Len Buffer length. + + @retval New BigNum opaque structure or NULL on failure. +**/ +VOID * +EFIAPI +CryptoServiceBigNumFromBin ( + IN CONST UINT8 *Buf, + IN UINTN Len + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.FromBin, BigNumFromBin, (Buf, Len), NULL); +} + +/** + Convert the absolute value of Bn into big-endian form and store it at Buf. + The Buf array should have at least BigNumBytes() in it. + + @param[in] Bn Big number to convert. + @param[out] Buf Output buffer. + + @retval The length of the big-endian number placed at Buf or -1 on error. +**/ +INTN +EFIAPI +CryptoServiceBigNumToBin ( + IN CONST VOID *Bn, + OUT UINT8 *Buf + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.ToBin, BigNumToBin, (Bn, Buf), -1); +} + +/** + Free the Big Number. + + @param[in] Bn Big number to free. + @param[in] Clear TRUE if the buffer should be cleared. +**/ +VOID +EFIAPI +CryptoServiceBigNumFree ( + IN VOID *Bn, + IN BOOLEAN Clear + ) +{ + CALL_VOID_BASECRYPTLIB (Bn.Services.Free, BigNumFree, (Bn, Clear)); +} + +/** + Calculate the sum of two Big Numbers. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA + BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumAdd ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Add, BigNumAdd, (BnA, BnB, BnRes), FALSE); +} + +/** + Subtract two Big Numbers. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA - BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumSub ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Sub, BigNumSub, (BnA, BnB, BnRes), FALSE); +} + +/** + Calculate remainder: BnRes = BnA % BnB. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA % BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Mod, BigNumMod, (BnA, BnB, BnRes), FALSE); +} + +/** + Compute BnA to the BnP-th power modulo BnM. + Please note, all "out" Big number arguments should be properly initialized. + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnP Big number (power). + @param[in] BnM Big number (modulo). + @param[out] BnRes The result of (BnA ^ BnP) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumExpMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnP, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.ExpMod, BigNumExpMod, (BnA, BnP, BnM, BnRes), FALSE); +} + +/** + Compute BnA inverse modulo BnM. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA * BnRes) % BnM == 1. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumInverseMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.InverseMod, BigNumInverseMod, (BnA, BnM, BnRes), FALSE); +} + +/** + Divide two Big Numbers. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result, such that BnA / BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumDiv ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Div, BigNumDiv, (BnA, BnB, BnRes), FALSE); +} + +/** + Multiply two Big Numbers modulo BnM. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA * BnB) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumMulMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.MulMod, BigNumMulMod, (BnA, BnB, BnM, BnRes), FALSE); +} + +/** + Compare two Big Numbers. + + @param[in] BnA Big number. + @param[in] BnB Big number. + + @retval 0 BnA == BnB. + @retval 1 BnA > BnB. + @retval -1 BnA < BnB. +**/ +INTN +EFIAPI +CryptoServiceBigNumCmp ( + IN CONST VOID *BnA, + IN CONST VOID *BnB + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Cmp, BigNumCmp, (BnA, BnB), 0); +} + +/** + Get number of bits in Bn. + + @param[in] Bn Big number. + + @retval Number of bits. +**/ +UINTN +EFIAPI +CryptoServiceBigNumBits ( + IN CONST VOID *Bn + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Bits, BigNumBits, (Bn), 0); +} + +/** + Get number of bytes in Bn. + + @param[in] Bn Big number. + + @retval Number of bytes. +**/ +UINTN +EFIAPI +CryptoServiceBigNumBytes ( + IN CONST VOID *Bn + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Bytes, BigNumBytes, (Bn), 0); +} + +/** + Checks if Big Number equals to the given Num. + + @param[in] Bn Big number. + @param[in] Num Number. + + @retval TRUE iff Bn == Num. + @retval FALSE otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumIsWord ( + IN CONST VOID *Bn, + IN UINTN Num + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.IsWord, BigNumIsWord, (Bn, Num), FALSE); +} + +/** + Checks if Big Number is odd. + + @param[in] Bn Big number. + + @retval TRUE Bn is odd (Bn % 2 == 1). + @retval FALSE otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumIsOdd ( + IN CONST VOID *Bn + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.IsOdd, BigNumIsOdd, (Bn), FALSE); +} + +/** + Copy Big number. + + @param[out] BnDst Destination. + @param[in] BnSrc Source. + + @retval BnDst on success. + @retval NULL otherwise. +**/ +VOID * +EFIAPI +CryptoServiceBigNumCopy ( + OUT VOID *BnDst, + IN CONST VOID *BnSrc + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.Copy, BigNumCopy, (BnDst, BnSrc), NULL); +} + +/** + Get constant Big number with value of "1". + This may be used to save expensive allocations. + + @retval Big Number with value of 1. +**/ +CONST VOID * +EFIAPI +CryptoServiceBigNumValueOne ( + VOID + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.ValueOne, BigNumValueOne, (), NULL); +} + +/** + Shift right Big Number. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] Bn Big number. + @param[in] N Number of bits to shift. + @param[out] BnRes The result. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumRShift ( + IN CONST VOID *Bn, + IN UINTN N, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.RShift, BigNumRShift, (Bn, N, BnRes), FALSE); +} + +/** + Mark Big Number for constant time computations. + This function should be called before any constant time computations are + performed on the given Big number. + + @param[in] Bn Big number. +**/ +VOID +EFIAPI +CryptoServiceBigNumConstTime ( + IN VOID *Bn + ) +{ + CALL_VOID_BASECRYPTLIB (Bn.Services.ConstTime, BigNumConstTime, (Bn)); +} + +/** + Calculate square modulo. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA ^ 2) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumSqrMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.SqrMod, BigNumSqrMod, (BnA, BnM, BnRes), FALSE); +} + +/** + Create new Big Number computation context. This is an opaque structure + which should be passed to any function that requires it. The BN context is + needed to optimize calculations and expensive allocations. + + @retval Big Number context struct or NULL on failure. +**/ +VOID * +EFIAPI +CryptoServiceBigNumNewContext ( + VOID + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.NewContext, BigNumNewContext, (), NULL); +} + +/** + Free Big Number context that was allocated with BigNumNewContext(). + + @param[in] BnCtx Big number context to free. +**/ +VOID +EFIAPI +CryptoServiceBigNumContextFree ( + IN VOID *BnCtx + ) +{ + CALL_VOID_BASECRYPTLIB (Bn.Services.ContextFree, BigNumContextFree, (BnCtx)); +} + +/** + Set Big Number to a given value. + + @param[in] Bn Big number to set. + @param[in] Val Value to set. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumSetUint ( + IN VOID *Bn, + IN UINTN Val + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.SetUint, BigNumSetUint, (Bn, Val), FALSE); +} + +/** + Add two Big Numbers modulo BnM. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA + BnB) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +CryptoServiceBigNumAddMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + return CALL_BASECRYPTLIB (Bn.Services.AddMod, BigNumAddMod, (BnA, BnB, BnM, BnRes), FALSE); +} + const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { /// Version CryptoServiceGetCryptoVersion, @@ -4787,5 +5279,31 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = { CryptoServiceRsaPssSign, CryptoServiceRsaPssVerify, /// Parallel hash - CryptoServiceParallelHash256HashAll + CryptoServiceParallelHash256HashAll, + /// Big Numbers + CryptoServiceBigNumInit, + CryptoServiceBigNumFromBin, + CryptoServiceBigNumToBin, + CryptoServiceBigNumFree, + CryptoServiceBigNumAdd, + CryptoServiceBigNumSub, + CryptoServiceBigNumMod, + CryptoServiceBigNumExpMod, + CryptoServiceBigNumInverseMod, + CryptoServiceBigNumDiv, + CryptoServiceBigNumMulMod, + CryptoServiceBigNumCmp, + CryptoServiceBigNumBits, + CryptoServiceBigNumBytes, + CryptoServiceBigNumIsWord, + CryptoServiceBigNumIsOdd, + CryptoServiceBigNumCopy, + CryptoServiceBigNumValueOne, + CryptoServiceBigNumRShift, + CryptoServiceBigNumConstTime, + CryptoServiceBigNumSqrMod, + CryptoServiceBigNumNewContext, + CryptoServiceBigNumContextFree, + CryptoServiceBigNumSetUint, + CryptoServiceBigNumAddMod, }; diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h index 3d53c2f105..1b3c9d8f52 100644 --- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h +++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h @@ -301,6 +301,36 @@ typedef struct { } Services; UINT32 Family; } ParallelHash; + union { + struct { + UINT8 Init : 1; + UINT8 FromBin : 1; + UINT8 ToBin : 1; + UINT8 Free : 1; + UINT8 Add : 1; + UINT8 Sub : 1; + UINT8 Mod : 1; + UINT8 ExpMod : 1; + UINT8 InverseMod : 1; + UINT8 Div : 1; + UINT8 MulMod : 1; + UINT8 Cmp : 1; + UINT8 Bits : 1; + UINT8 Bytes : 1; + UINT8 IsWord : 1; + UINT8 IsOdd : 1; + UINT8 Copy : 1; + UINT8 ValueOne : 1; + UINT8 RShift : 1; + UINT8 ConstTime : 1; + UINT8 SqrMod : 1; + UINT8 NewContext : 1; + UINT8 ContextFree : 1; + UINT8 SetUint : 1; + UINT8 AddMod : 1; + } Services; + UINT32 Family; + } Bn; } PCD_CRYPTO_SERVICE_FAMILY_ENABLE; #endif diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c index 8ee1b53cf9..c5d71b5269 100644 --- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c +++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c @@ -3612,3 +3612,495 @@ TlsGetCertRevocationList ( { CALL_CRYPTO_SERVICE (TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED); } + +// ===================================================================================== +// Big number primitive +// ===================================================================================== + +/** + Allocate new Big Number. + + @retval New BigNum opaque structure or NULL on failure. +**/ +VOID * +EFIAPI +BigNumInit ( + VOID + ) +{ + CALL_CRYPTO_SERVICE (BigNumInit, (), NULL); +} + +/** + Allocate new Big Number and assign the provided value to it. + + @param[in] Buf Big endian encoded buffer. + @param[in] Len Buffer length. + + @retval New BigNum opaque structure or NULL on failure. +**/ +VOID * +EFIAPI +BigNumFromBin ( + IN CONST UINT8 *Buf, + IN UINTN Len + ) +{ + CALL_CRYPTO_SERVICE (BigNumFromBin, (Buf, Len), NULL); +} + +/** + Convert the absolute value of Bn into big-endian form and store it at Buf. + The Buf array should have at least BigNumBytes() in it. + + @param[in] Bn Big number to convert. + @param[out] Buf Output buffer. + + @retval The length of the big-endian number placed at Buf or -1 on error. +**/ +INTN +EFIAPI +BigNumToBin ( + IN CONST VOID *Bn, + OUT UINT8 *Buf + ) +{ + CALL_CRYPTO_SERVICE (BigNumToBin, (Bn, Buf), -1); +} + +/** + Free the Big Number. + + @param[in] Bn Big number to free. + @param[in] Clear TRUE if the buffer should be cleared. +**/ +VOID +EFIAPI +BigNumFree ( + IN VOID *Bn, + IN BOOLEAN Clear + ) +{ + CALL_VOID_CRYPTO_SERVICE (BigNumFree, (Bn, Clear)); +} + +/** + Calculate the sum of two Big Numbers. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA + BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumAdd ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumAdd, (BnA, BnB, BnRes), FALSE); +} + +/** + Subtract two Big Numbers. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA - BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumSub ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumSub, (BnA, BnB, BnRes), FALSE); +} + +/** + Calculate remainder: BnRes = BnA % BnB + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA % BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumMod, (BnA, BnB, BnRes), FALSE); +} + +/** + Compute BnA to the BnP-th power modulo BnM. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnP Big number (power). + @param[in] BnM Big number (modulo). + @param[out] BnRes The result of (BnA ^ BnP) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumExpMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnP, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumExpMod, (BnA, BnP, BnM, BnRes), FALSE); +} + +/** + Compute BnA inverse modulo BnM. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA * BnRes) % BnM == 1. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumInverseMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumInverseMod, (BnA, BnM, BnRes), FALSE); +} + +/** + Divide two Big Numbers. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result, such that BnA / BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumDiv ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumDiv, (BnA, BnB, BnRes), FALSE); +} + +/** + Multiply two Big Numbers modulo BnM. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA * BnB) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumMulMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumMulMod, (BnA, BnB, BnM, BnRes), FALSE); +} + +/** + Compare two Big Numbers. + + @param[in] BnA Big number. + @param[in] BnB Big number. + + @retval 0 BnA == BnB. + @retval 1 BnA > BnB. + @retval -1 BnA < BnB. +**/ +INTN +EFIAPI +BigNumCmp ( + IN CONST VOID *BnA, + IN CONST VOID *BnB + ) +{ + CALL_CRYPTO_SERVICE (BigNumCmp, (BnA, BnB), 0); +} + +/** + Get number of bits in Bn. + + @param[in] Bn Big number. + + @retval Number of bits. +**/ +UINTN +EFIAPI +BigNumBits ( + IN CONST VOID *Bn + ) +{ + CALL_CRYPTO_SERVICE (BigNumBits, (Bn), 0); +} + +/** + Get number of bytes in Bn. + + @param[in] Bn Big number. + + @retval Number of bytes. +**/ +UINTN +EFIAPI +BigNumBytes ( + IN CONST VOID *Bn + ) +{ + CALL_CRYPTO_SERVICE (BigNumBytes, (Bn), 0); +} + +/** + Checks if Big Number equals to the given Num. + + @param[in] Bn Big number. + @param[in] Num Number. + + @retval TRUE iff Bn == Num. + @retval FALSE otherwise. +**/ +BOOLEAN +EFIAPI +BigNumIsWord ( + IN CONST VOID *Bn, + IN UINTN Num + ) +{ + CALL_CRYPTO_SERVICE (BigNumIsWord, (Bn, Num), FALSE); +} + +/** + Checks if Big Number is odd. + + @param[in] Bn Big number. + + @retval TRUE Bn is odd (Bn % 2 == 1). + @retval FALSE otherwise. +**/ +BOOLEAN +EFIAPI +BigNumIsOdd ( + IN CONST VOID *Bn + ) +{ + CALL_CRYPTO_SERVICE (BigNumIsOdd, (Bn), FALSE); +} + +/** + Copy Big number. + + @param[out] BnDst Destination. + @param[in] BnSrc Source. + + @retval BnDst on success. + @retval NULL otherwise. +**/ +VOID * +EFIAPI +BigNumCopy ( + OUT VOID *BnDst, + IN CONST VOID *BnSrc + ) +{ + CALL_CRYPTO_SERVICE (BigNumCopy, (BnDst, BnSrc), NULL); +} + +/** + Get constant Big number with value of "1". + This may be used to save expensive allocations. + + @retval Big Number with value of 1. +**/ +CONST VOID * +EFIAPI +BigNumValueOne ( + VOID + ) +{ + CALL_CRYPTO_SERVICE (BigNumValueOne, (), NULL); +} + +/** + Shift right Big Number. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] Bn Big number. + @param[in] N Number of bits to shift. + @param[out] BnRes The result. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumRShift ( + IN CONST VOID *Bn, + IN UINTN N, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumRShift, (Bn, N, BnRes), FALSE); +} + +/** + Mark Big Number for constant time computations. + This function should be called before any constant time computations are + performed on the given Big number. + + @param[in] Bn Big number. +**/ +VOID +EFIAPI +BigNumConstTime ( + IN VOID *Bn + ) +{ + CALL_VOID_CRYPTO_SERVICE (BigNumConstTime, (Bn)); +} + +/** + Calculate square modulo. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] BnA Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA ^ 2) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumSqrMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumSqrMod, (BnA, BnM, BnRes), FALSE); +} + +/** + Create new Big Number computation context. This is an opaque structure + which should be passed to any function that requires it. The BN context is + needed to optimize calculations and expensive allocations. + + @retval Big Number context struct or NULL on failure. +**/ +VOID * +EFIAPI +BigNumNewContext ( + VOID + ) +{ + CALL_CRYPTO_SERVICE (BigNumNewContext, (), NULL); +} + +/** + Free Big Number context that was allocated with BigNumNewContext(). + + @param[in] BnCtx Big number context to free. +**/ +VOID +EFIAPI +BigNumContextFree ( + IN VOID *BnCtx + ) +{ + CALL_VOID_CRYPTO_SERVICE (BigNumContextFree, (BnCtx)); +} + +/** + Set Big Number to a given value. + + @param[in] Bn Big number to set. + @param[in] Val Value to set. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumSetUint ( + IN VOID *Bn, + IN UINTN Val + ) +{ + CALL_CRYPTO_SERVICE (BigNumSetUint, (Bn, Val), FALSE); +} + +/** + Add two Big Numbers modulo BnM. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA + BnB) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +BOOLEAN +EFIAPI +BigNumAddMod ( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + IN CONST VOID *BnM, + OUT VOID *BnRes + ) +{ + CALL_CRYPTO_SERVICE (BigNumAddMod, (BnA, BnB, BnM, BnRes), FALSE); +} diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index c417568e96..9812568cc7 100644 --- a/CryptoPkg/Private/Protocol/Crypto.h +++ b/CryptoPkg/Private/Protocol/Crypto.h @@ -21,7 +21,7 @@ /// the EDK II Crypto Protocol is extended, this version define must be /// increased. /// -#define EDKII_CRYPTO_VERSION 8 +#define EDKII_CRYPTO_VERSION 9 /// /// EDK II Crypto Protocol forward declaration @@ -3486,6 +3486,407 @@ BOOLEAN IN UINTN CustomByteLen ); +// ===================================================================================== +// Big Number Primitive +// ===================================================================================== + +/** + Allocate new Big Number. + + @retval New BigNum opaque structure or NULL on failure. +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_BIGNUM_INIT)( + VOID + ); + +/** + Allocate new Big Number and assign the provided value to it. + + @param[in] Buf Big endian encoded buffer. + @param[in] Len Buffer length. + + @retval New EDKII_CRYPTO_BIGNUM_ opaque structure or NULL on failure. +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_BIGNUM_FROM_BIN)( + IN CONST UINT8 *Buf, + IN UINTN Len + ); + +/** + Convert the absolute value of Bn into big-endian form and store it at Buf. + The Buf array should have at least EDKII_CRYPTO_BIGNUM_Bytes() in it. + + @param[in] Bn Big number to convert. + @param[out] Buf Output buffer. + + @retval The length of the big-endian number placed at Buf or -1 on error. +**/ +typedef +INTN +(EFIAPI *EDKII_CRYPTO_BIGNUM_TO_BIN)( + IN CONST VOID *Bn, + OUT UINT8 *Buf + ); + +/** + Free the Big Number. + + @param[in] Bn Big number to free. + @param[in] Clear TRUE if the buffer should be cleared. +**/ +typedef +VOID +(EFIAPI *EDKII_CRYPTO_BIGNUM_FREE)( + IN VOID *Bn, + IN BOOLEAN Clear + ); + +/** + Calculate the sum of two Big Numbers. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA + BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_ADD)( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ); + +/** + Subtract two Big Numbers. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA - BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_SUB)( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ); + +/** + Calculate remainder: BnRes = BnA % BnB. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result of BnA % BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_MOD)( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ); + +/** + Compute BnA to the BnP-th power modulo BnM. + + @param[in] BnA Big number. + @param[in] BnP Big number (power). + @param[in] BnM Big number (modulo). + @param[out] BnRes The result of BnA ^ BnP % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_EXP_MOD)( + IN CONST VOID *BnA, + IN CONST VOID *BnP, + IN CONST VOID *BnM, + OUT VOID *BnRes + ); + +/** + Compute BnA inverse modulo BnM. + + @param[in] BnA Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA * BnRes) % BnM == 1. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_INVERSE_MOD)( + IN CONST VOID *BnA, + IN CONST VOID *BnM, + OUT VOID *BnRes + ); + +/** + Divide two Big Numbers. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[out] BnRes The result, such that BnA / BnB. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_DIV)( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + OUT VOID *BnRes + ); + +/** + Multiply two Big Numbers modulo BnM. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA * BnB) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_MUL_MOD)( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + IN CONST VOID *BnM, + OUT VOID *BnRes + ); + +/** + Compare two Big Numbers. + + @param[in] BnA Big number. + @param[in] BnB Big number. + + @retval 0 BnA == BnB. + @retval 1 BnA > BnB. + @retval -1 BnA < BnB. +**/ +typedef +INTN +(EFIAPI *EDKII_CRYPTO_BIGNUM_CMP)( + IN CONST VOID *BnA, + IN CONST VOID *BnB + ); + +/** + Get number of bits in Bn. + + @param[in] Bn Big number. + + @retval Number of bits. +**/ +typedef +UINTN +(EFIAPI *EDKII_CRYPTO_BIGNUM_BITS)( + IN CONST VOID *Bn + ); + +/** + Get number of bytes in Bn. + + @param[in] Bn Big number. + + @retval Number of bytes. +**/ +typedef +UINTN +(EFIAPI *EDKII_CRYPTO_BIGNUM_BYTES)( + IN CONST VOID *Bn + ); + +/** + Checks if Big Number equals to the given Num. + + @param[in] Bn Big number. + @param[in] Num Number. + + @retval TRUE iff Bn == Num. + @retval FALSE otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_IS_WORD)( + IN CONST VOID *Bn, + IN UINTN Num + ); + +/** + Checks if Big Number is odd. + + @param[in] Bn Big number. + + @retval TRUE Bn is odd (Bn % 2 == 1). + @retval FALSE otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_IS_ODD)( + IN CONST VOID *Bn + ); + +/** + Copy Big number. + + @param[out] BnDst Destination. + @param[in] BnSrc Source. + + @retval BnDst on success. + @retval NULL otherwise. +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_BIGNUM_COPY)( + OUT VOID *BnDst, + IN CONST VOID *BnSrc + ); + +/** + Get constant Big number with value of "1". + This may be used to save expensive allocations. + + @retval Big Number with value of 1. +**/ +typedef +CONST VOID * +(EFIAPI *EDKII_CRYPTO_BIGNUM_VALUE_ONE)( + VOID + ); + +/** + Shift right Big Number. + Please note, all "out" Big number arguments should be properly initialized + by calling to BigNumInit() or BigNumFromBin() functions. + + @param[in] Bn Big number. + @param[in] N Number of bits to shift. + @param[out] BnRes The result. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_R_SHIFT)( + IN CONST VOID *Bn, + IN UINTN N, + OUT VOID *BnRes + ); + +/** + Mark Big Number for constant time computations. + This function should be called before any constant time computations are + performed on the given Big number. + + @param[in] Bn Big number. +**/ +typedef +VOID +(EFIAPI *EDKII_CRYPTO_BIGNUM_CONST_TIME)( + IN VOID *Bn + ); + +/** + Calculate square modulo. + + @param[in] BnA Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA ^ 2) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_SQR_MOD)( + IN CONST VOID *BnA, + IN CONST VOID *BnM, + OUT VOID *BnRes + ); + +/** + Create new Big Number computation context. This is an opaque structure. + which should be passed to any function that requires it. The BN context is + needed to optimize calculations and expensive allocations. + + @retval Big Number context struct or NULL on failure. +**/ +typedef +VOID * +(EFIAPI *EDKII_CRYPTO_BIGNUM_NEW_CONTEXT)( + VOID + ); + +/** + Free Big Number context that was allocated with EDKII_CRYPTO_BIGNUM_NewContext(). + + @param[in] BnCtx Big number context to free. +**/ +typedef +VOID +(EFIAPI *EDKII_CRYPTO_BIGNUM_CONTEXT_FREE)( + IN VOID *BnCtx + ); + +/** + Set Big Number to a given value. + + @param[in] Bn Big number to set. + @param[in] Val Value to set. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_SET_UINT)( + IN VOID *Bn, + IN UINTN Val + ); + +/** + Add two Big Numbers modulo BnM. + + @param[in] BnA Big number. + @param[in] BnB Big number. + @param[in] BnM Big number (modulo). + @param[out] BnRes The result, such that (BnA + BnB) % BnM. + + @retval TRUE On success. + @retval FALSE Otherwise. +**/ +typedef +BOOLEAN +(EFIAPI *EDKII_CRYPTO_BIGNUM_ADD_MOD)( + IN CONST VOID *BnA, + IN CONST VOID *BnB, + IN CONST VOID *BnM, + OUT VOID *BnRes + ); + /// /// EDK II Crypto Protocol /// @@ -3675,6 +4076,32 @@ struct _EDKII_CRYPTO_PROTOCOL { EDKII_CRYPTO_RSA_PSS_VERIFY RsaPssVerify; /// Parallel hash EDKII_CRYPTO_PARALLEL_HASH_ALL ParallelHash256HashAll; + /// Big Number + EDKII_CRYPTO_BIGNUM_INIT BigNumInit; + EDKII_CRYPTO_BIGNUM_FROM_BIN BigNumFromBin; + EDKII_CRYPTO_BIGNUM_TO_BIN BigNumToBin; + EDKII_CRYPTO_BIGNUM_FREE BigNumFree; + EDKII_CRYPTO_BIGNUM_ADD BigNumAdd; + EDKII_CRYPTO_BIGNUM_SUB BigNumSub; + EDKII_CRYPTO_BIGNUM_MOD BigNumMod; + EDKII_CRYPTO_BIGNUM_EXP_MOD BigNumExpMod; + EDKII_CRYPTO_BIGNUM_INVERSE_MOD BigNumInverseMod; + EDKII_CRYPTO_BIGNUM_DIV BigNumDiv; + EDKII_CRYPTO_BIGNUM_MUL_MOD BigNumMulMod; + EDKII_CRYPTO_BIGNUM_CMP BigNumCmp; + EDKII_CRYPTO_BIGNUM_BITS BigNumBits; + EDKII_CRYPTO_BIGNUM_BYTES BigNumBytes; + EDKII_CRYPTO_BIGNUM_IS_WORD BigNumIsWord; + EDKII_CRYPTO_BIGNUM_IS_ODD BigNumIsOdd; + EDKII_CRYPTO_BIGNUM_COPY BigNumCopy; + EDKII_CRYPTO_BIGNUM_VALUE_ONE BigNumValueOne; + EDKII_CRYPTO_BIGNUM_R_SHIFT BigNumRShift; + EDKII_CRYPTO_BIGNUM_CONST_TIME BigNumConstTime; + EDKII_CRYPTO_BIGNUM_SQR_MOD BigNumSqrMod; + EDKII_CRYPTO_BIGNUM_NEW_CONTEXT BigNumNewContext; + EDKII_CRYPTO_BIGNUM_CONTEXT_FREE BigNumContextFree; + EDKII_CRYPTO_BIGNUM_SET_UINT BigNumSetUint; + EDKII_CRYPTO_BIGNUM_ADD_MOD BigNumAddMod; }; extern GUID gEdkiiCryptoProtocolGuid; -- 2.31.1.windows.1