public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "yi1 li" <yi1.li@intel.com>
To: devel@edk2.groups.io
Cc: yi1 li <yi1.li@intel.com>, Jiewen Yao <jiewen.yao@intel.com>,
	Jian J Wang <jian.j.wang@intel.com>,
	Xiaoyu Lu <xiaoyux.lu@intel.com>,
	Guomin Jiang <guomin.jiang@intel.com>
Subject: [PATCH 1/2] CryptoPkg: Add BigNum support
Date: Sun, 30 Jan 2022 06:09:15 +0800	[thread overview]
Message-ID: <19a83075cadeea3805d4c30d4924be26fff66e14.1643494016.git.yi1.li@intel.com> (raw)
In-Reply-To: <cover.1643494016.git.yi1.li@intel.com>

This patch is used to add CryptBn library, which is wrapped
over OpenSSL. The implementation provides CryptBn library functions
for EFI BaseCrypt protocol and EFI BaseCrypt Configuration Protocol.

Signed-off-by: yi1 li <yi1.li@intel.com>

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
---
 CryptoPkg/CryptoPkg.dsc                       |   1 +
 CryptoPkg/Driver/Crypto.c                     | 522 ++++++++++++++-
 CryptoPkg/Include/Library/BaseCryptLib.h      | 423 +++++++++++++
 .../Pcd/PcdCryptoServiceFamilyEnable.h        |  30 +
 .../Library/BaseCryptLib/BaseCryptLib.inf     |   1 +
 CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c   | 594 ++++++++++++++++++
 .../Library/BaseCryptLib/PeiCryptLib.inf      |   1 +
 .../Library/BaseCryptLib/SmmCryptLib.inf      |   2 +-
 .../BaseCryptLibOnProtocolPpi/CryptLib.c      | 497 +++++++++++++++
 CryptoPkg/Private/Protocol/Crypto.h           | 434 +++++++++++++
 10 files changed, 2503 insertions(+), 2 deletions(-)
 create mode 100644 CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c

diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 0aa72ed87846..4b14db884078 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -165,6 +165,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 d5d6aa8e5820..a5b3a2f46fbb 100644
--- a/CryptoPkg/Driver/Crypto.c
+++ b/CryptoPkg/Driver/Crypto.c
@@ -4470,6 +4470,499 @@ CryptoServiceTlsGetCertRevocationList (
   return CALL_BASECRYPTLIB (TlsGet.Services.CertRevocationList, TlsGetCertRevocationList, (Data, DataSize), EFI_UNSUPPORTED);
 }
 
+/**
+  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 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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumAdd (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.Add, BigNumAdd, (BnA, BnB, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumSub (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.Sub, BigNumSub, (BnA, BnB, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.Mod, BigNumMod, (BnA, BnB, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumExpMod (
+  IN VOID   *BnA,
+  IN VOID   *BnP,
+  IN VOID   *BnM,
+  OUT VOID  *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.ExpMod, BigNumExpMod, (BnA, BnP, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumInverseMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.InverseMod, BigNumInverseMod, (BnA, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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]   BnM     Big number (modulo).
+  @param[out]  BnRes   The result, such that BnA / BnB.
+
+  @retval EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumDiv (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.Div, BigNumDiv, (BnA, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+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), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumRShift (
+  IN CONST VOID  *Bn,
+  IN UINTN       n,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.RShift, BigNumRShift, (Bn, n, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumSqrMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.SqrMod, BigNumSqrMod, (BnA, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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.
+**/
+EFI_STATUS
+EFIAPI
+CryptoServiceBigNumSetUint (
+  IN VOID   *Bn,
+  IN UINTN  Val
+  )
+{
+  return CALL_BASECRYPTLIB (Bn.Services.SetUint, BigNumSetUint, (Bn, Val), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+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), EFI_UNSUPPORTED);
+}
+
 const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   /// Version
   CryptoServiceGetCryptoVersion,
@@ -4670,5 +5163,32 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   CryptoServiceTlsGetCaCertificate,
   CryptoServiceTlsGetHostPublicCert,
   CryptoServiceTlsGetHostPrivateKey,
-  CryptoServiceTlsGetCertRevocationList
+  CryptoServiceTlsGetCertRevocationList,
+
+  // 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/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index f4bc7c0d73d9..d64ea5b3dd94 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -2403,4 +2403,427 @@ HkdfSha256ExtractAndExpand (
   IN   UINTN        OutSize
   );
 
+// =====================================================================================
+//    Big number primitives
+// =====================================================================================
+
+/**
+  Allocate new Big Number.
+
+  @retval New BigNum opaque structure or NULL on failure.
+**/
+VOID *
+EFIAPI
+BigNumInit (
+  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 BigNum opaque structure or NULL on failure.
+**/
+VOID *
+EFIAPI
+BigNumFromBin (
+  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 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 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.
+**/
+VOID
+EFIAPI
+BigNumFree (
+  IN VOID     *Bn,
+  IN BOOLEAN  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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumAdd (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  );
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSub (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  );
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  );
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumExpMod (
+  IN VOID   *BnA,
+  IN VOID   *BnP,
+  IN VOID   *BnM,
+  OUT VOID  *BnRes
+  );
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumInverseMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  );
+
+/**
+  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]   BnM     Big number (modulo).
+  @param[out]  BnRes   The result, such that BnA / BnB.
+
+  @retval EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumDiv (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  );
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumMulMod (
+  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.
+**/
+INTN
+EFIAPI
+BigNumCmp (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB
+  );
+
+/**
+  Get number of bits in Bn.
+
+  @param[in]   Bn     Big number.
+
+  @retval Number of bits.
+**/
+
+UINTN
+EFIAPI
+BigNumBits (
+  IN CONST VOID  *Bn
+  );
+
+/**
+  Get number of bytes in Bn.
+
+  @param[in]   Bn     Big number.
+
+  @retval Number of bytes.
+**/
+UINTN
+EFIAPI
+BigNumBytes (
+  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.
+**/
+BOOLEAN
+EFIAPI
+BigNumIsWord (
+  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.
+**/
+BOOLEAN
+EFIAPI
+BigNumIsOdd (
+  IN CONST VOID  *Bn
+  );
+
+/**
+  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
+  );
+
+/**
+  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
+  );
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumRShift (
+  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.
+**/
+VOID
+EFIAPI
+BigNumConsttime (
+  IN VOID  *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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSqrMod (
+  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.
+**/
+VOID *
+EFIAPI
+BigNumNewContext (
+  VOID
+  );
+
+/**
+  Free Big Number context that was allocated with BigNumNewContext().
+
+  @param[in]   BnCtx     Big number context to free.
+**/
+VOID
+EFIAPI
+BigNumContextFree (
+  IN VOID  *BnCtx
+  );
+
+/**
+  Set Big Number to a given value.
+
+  @param[in]   Bn     Big number to set.
+  @param[in]   Val    Value to set.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSetUint (
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumAddMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  );
+
 #endif // __BASE_CRYPT_LIB_H__
diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
index 5186a54759ae..31b4728167de 100644
--- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
+++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
@@ -288,6 +288,36 @@ typedef struct {
     } Services;
     UINT32    Family;
   } TlsGet;
+  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/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 49703fa4c963..3c3564197ee7 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -52,6 +52,7 @@
   Pk/CryptRsaPss.c
   Pk/CryptRsaPssSign.c
   Pem/CryptPem.c
+  Bn/CryptBn.c
 
   SysCall/CrtWrapper.c
   SysCall/TimerWrapper.c
diff --git a/CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c b/CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c
new file mode 100644
index 000000000000..2e9f1cbea67f
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c
@@ -0,0 +1,594 @@
+/** @file  Big number API implementation based on OpenSSL
+
+  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <openssl/bn.h>
+
+/**
+  Allocate new Big Number.
+
+  @retval New BigNum opaque structure or NULL on failure.
+**/
+VOID *
+EFIAPI
+BigNumInit (
+  VOID
+  )
+{
+  return BN_new ();
+}
+
+/**
+  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
+  )
+{
+  return BN_bin2bn (Buf, (int)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 VOID    *Bn,
+  OUT UINT8  *Buf
+  )
+{
+  return BN_bn2bin (Bn, Buf);
+}
+
+/**
+  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
+  )
+{
+  if (Clear) {
+    BN_clear_free (Bn);
+  } else {
+    BN_free (Bn);
+  }
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumAdd (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  return BN_add (BnRes, BnA, BnB) ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSub (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  return BN_sub (BnRes, BnA, BnB) ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  int     Res;
+  BN_CTX  *Bnctx;
+
+  Bnctx = BN_CTX_new ();
+  if (!Bnctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_mod (BnRes, BnA, BnB, Bnctx);
+  BN_CTX_free (Bnctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumExpMod (
+  IN VOID   *BnA,
+  IN VOID   *BnP,
+  IN VOID   *BnM,
+  OUT VOID  *BnRes
+  )
+{
+  int     Res;
+  BN_CTX  *Bnctx;
+
+  Bnctx = BN_CTX_new ();
+  if (!Bnctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_mod_exp (BnRes, BnA, BnP, BnM, Bnctx);
+  BN_CTX_free (Bnctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumInverseMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  BIGNUM  *Res;
+  BN_CTX  *Bnctx;
+
+  Bnctx = BN_CTX_new ();
+  if (!Bnctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_mod_inverse (BnRes, BnA, BnM, Bnctx);
+  BN_CTX_free (Bnctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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]   BnM     Big number (modulo).
+  @param[out]  BnRes   The result, such that BnA / BnB.
+
+  @retval EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumDiv (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  int     Res;
+  BN_CTX  *Bnctx;
+
+  Bnctx = BN_CTX_new ();
+  if (!Bnctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_div (BnRes, NULL, BnA, BnM, Bnctx);
+  BN_CTX_free (Bnctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumMulMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  int     Res;
+  BN_CTX  *Bnctx;
+
+  Bnctx = BN_CTX_new ();
+  if (!Bnctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_mod_mul (BnRes, BnA, BnB, BnM, Bnctx);
+  BN_CTX_free (Bnctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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
+  )
+{
+  return BN_cmp (BnA, BnB);
+}
+
+/**
+  Get number of bits in Bn.
+
+  @param[in]   Bn     Big number.
+
+  @retval Number of bits.
+**/
+UINTN
+EFIAPI
+BigNumBits (
+  IN CONST VOID  *Bn
+  )
+{
+  return BN_num_bits (Bn);
+}
+
+/**
+  Get number of bytes in Bn.
+
+  @param[in]   Bn     Big number.
+
+  @retval Number of bytes.
+**/
+UINTN
+EFIAPI
+BigNumBytes (
+  IN CONST VOID  *Bn
+  )
+{
+  return BN_num_bytes (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.
+**/
+BOOLEAN
+EFIAPI
+BigNumIsWord (
+  IN CONST VOID  *Bn,
+  IN UINTN       Num
+  )
+{
+  return !!BN_is_word (Bn, Num);
+}
+
+/**
+  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
+  )
+{
+  return !!BN_is_odd (Bn);
+}
+
+/**
+  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
+  )
+{
+  return BN_copy (BnDst, BnSrc);
+}
+
+/**
+  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
+  )
+{
+  return BN_value_one ();
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumRShift (
+  IN CONST VOID  *Bn,
+  IN UINTN       n,
+  OUT VOID       *BnRes
+  )
+{
+  // BN_rshift() does not modify the first argument, so we remove const.
+  if (BN_rshift ((BIGNUM *)Bn, BnRes, (int)n) == 1) {
+    return EFI_SUCCESS;
+  } else {
+    return EFI_PROTOCOL_ERROR;
+  }
+}
+
+/**
+  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
+  )
+{
+  BN_set_flags (Bn, BN_FLG_CONSTTIME);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSqrMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  int     Res;
+  BN_CTX  *Ctx;
+
+  Ctx = BN_CTX_new ();
+  if (!Ctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_mod_sqr (BnRes, BnA, BnM, Ctx);
+  BN_CTX_free (Ctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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
+  )
+{
+  return BN_CTX_new ();
+}
+
+/**
+  Free Big Number context that was allocated with BigNumNewContext().
+
+  @param[in]   BnCtx     Big number context to free.
+**/
+VOID
+EFIAPI
+BigNumContextFree (
+  IN VOID  *BnCtx
+  )
+{
+  BN_CTX_free (BnCtx);
+}
+
+/**
+  Set Big Number to a given value.
+
+  @param[in]   Bn     Big number to set.
+  @param[in]   Val    Value to set.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSetUint (
+  IN VOID   *Bn,
+  IN UINTN  Val
+  )
+{
+  return BN_set_word (Bn, Val) == 1 ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumAddMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  int     Res;
+  BN_CTX  *Bnctx;
+
+  Bnctx = BN_CTX_new ();
+  if (!Bnctx) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Res = BN_mod_add (BnRes, BnA, BnB, BnM, Bnctx);
+  BN_CTX_free (Bnctx);
+
+  return Res ? EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index 0cab5f3ce36c..75d87afbdc03 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -59,6 +59,7 @@
   Pk/CryptRsaPssSignNull.c
   Pem/CryptPemNull.c
   Rand/CryptRandNull.c
+  Bn/CryptBn.c
 
   SysCall/CrtWrapper.c
   SysCall/ConstantTimeClock.c
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index e6470d7a2127..420cef88efb1 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -56,7 +56,7 @@
   Pk/CryptRsaPss.c
   Pk/CryptRsaPssSignNull.c
   Pem/CryptPem.c
-
+  Bn/CryptBn.c
   SysCall/CrtWrapper.c
   SysCall/ConstantTimeClock.c
   SysCall/BaseMemAllocation.c
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index c8df259ea963..6c5025ff6a6a 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -3580,3 +3580,500 @@ 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 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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumAdd (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumAdd, (BnA, BnB, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSub (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumSub, (BnA, BnB, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnB,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumMod, (BnA, BnB, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumExpMod (
+  IN VOID   *BnA,
+  IN VOID   *BnP,
+  IN VOID   *BnM,
+  OUT VOID  *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumExpMod, (BnA, BnP, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumInverseMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumInverseMod, (BnA, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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]   BnM     Big number (modulo).
+  @param[out]  BnRes   The result, such that BnA / BnB.
+
+  @retval EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumDiv (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumDiv, (BnA, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+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), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumRShift (
+  IN CONST VOID  *Bn,
+  IN UINTN       n,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumRShift, (Bn, n, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSqrMod (
+  IN CONST VOID  *BnA,
+  IN CONST VOID  *BnM,
+  OUT VOID       *BnRes
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumSqrMod, (BnA, BnM, BnRes), EFI_UNSUPPORTED);
+}
+
+/**
+  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.
+**/
+EFI_STATUS
+EFIAPI
+BigNumSetUint (
+  IN VOID   *Bn,
+  IN UINTN  Val
+  )
+{
+  CALL_CRYPTO_SERVICE (BigNumSetUint, (Bn, Val), EFI_UNSUPPORTED);
+}
+
+/**
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+EFI_STATUS
+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), EFI_UNSUPPORTED);
+}
diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
index e378a8a8c60e..1be21b7ff690 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -3457,6 +3457,412 @@ BOOLEAN
   IN  UINT16       SaltLen
   );
 
+// =====================================================================================
+//   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 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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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 EFI_SUCCESS          On success.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_CRYPTO_BIGNUM_EXP_MOD)(
+  IN VOID *BnA,
+  IN VOID *BnP,
+  IN 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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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]   BnM     Big number (modulo).
+  @param[out]  BnRes   The result, such that BnA / BnB.
+
+  @retval EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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.
+
+  @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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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_CONSTTIME)(
+  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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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.
+**/
+typedef
+EFI_STATUS
+(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 EFI_SUCCESS          On success.
+  @retval EFI_OUT_OF_RESOURCES In case of internal allocation failures.
+  @retval EFI_PROTOCOL_ERROR   Otherwise.
+**/
+typedef
+EFI_STATUS
+(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
 ///
@@ -3641,6 +4047,34 @@ struct _EDKII_CRYPTO_PROTOCOL {
   EDKII_CRYPTO_TLS_GET_HOST_PUBLIC_CERT              TlsGetHostPublicCert;
   EDKII_CRYPTO_TLS_GET_HOST_PRIVATE_KEY              TlsGetHostPrivateKey;
   EDKII_CRYPTO_TLS_GET_CERT_REVOCATION_LIST          TlsGetCertRevocationList;
+
+  /// 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_CONSTTIME                      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;
+
   /// RSA PSS
   EDKII_CRYPTO_RSA_PSS_SIGN                          RsaPssSign;
   EDKII_CRYPTO_RSA_PSS_VERIFY                        RsaPssVerify;
-- 
2.33.0.windows.2


  reply	other threads:[~2022-01-29 22:09 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-29 22:09 [PATCH 0/2] CryptoPkg: Add BigNum support yi1 li
2022-01-29 22:09 ` yi1 li [this message]
2022-01-29 22:09 ` [PATCH 2/2] CryptoPkg: Add BigNum NullLib yi1 li
2022-01-30  0:04   ` Yao, Jiewen
2022-01-30 17:08     ` yi1 li
2022-01-31  1:10       ` Yao, Jiewen
2022-02-08  8:30         ` yi1 li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19a83075cadeea3805d4c30d4924be26fff66e14.1643494016.git.yi1.li@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox