* [PATCH V2 1/3] CryptoPkg: Add BigNum support
[not found] <cover.1663735456.git.yi1.li@intel.com>
@ 2022-09-21 4:53 ` yi1 li
2022-09-21 4:53 ` [PATCH V2 2/3] CryptoPkg: Add BigNum API to DXE and protocol yi1 li
2022-09-21 4:53 ` [PATCH V2 3/3] CryptoPkg/Test: Add unit test for CryptoBn yi1 li
2 siblings, 0 replies; 3+ messages in thread
From: yi1 li @ 2022-09-21 4:53 UTC (permalink / raw)
To: devel; +Cc: Yi Li, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3828
This patch is used to add CryptBn library, which is wrapped
over OpenSSL.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Yi Li <yi1.li@intel.com>
---
CryptoPkg/Include/Library/BaseCryptLib.h | 418 +++++++++++++
.../Library/BaseCryptLib/BaseCryptLib.inf | 1 +
CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c | 581 ++++++++++++++++++
.../Library/BaseCryptLib/Bn/CryptBnNull.c | 520 ++++++++++++++++
.../Library/BaseCryptLib/PeiCryptLib.inf | 1 +
.../Library/BaseCryptLib/SmmCryptLib.inf | 1 +
.../BaseCryptLibNull/BaseCryptLibNull.inf | 1 +
.../Library/BaseCryptLibNull/Bn/CryptBnNull.c | 520 ++++++++++++++++
8 files changed, 2043 insertions(+)
create mode 100644 CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c
create mode 100644 CryptoPkg/Library/BaseCryptLib/Bn/CryptBnNull.c
create mode 100644 CryptoPkg/Library/BaseCryptLibNull/Bn/CryptBnNull.c
diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index 7d1499350a..b253923dd8 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -2432,4 +2432,422 @@ 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 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.
+**/
+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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+BigNumExpMod (
+ IN CONST VOID *BnA,
+ IN CONST VOID *BnP,
+ IN CONST 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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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] 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
+ );
+
+/**
+ 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
+ );
+
+/**
+ 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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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.
+
+ @retval TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+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/Library/BaseCryptLib/BaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
index 3d7b917103..9e4be2fb0d 100644
--- a/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
@@ -53,6 +53,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 0000000000..282926ddcc
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Bn/CryptBn.c
@@ -0,0 +1,581 @@
+/** @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 "InternalCryptLib.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, (INT32)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
+ )
+{
+ 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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+BigNumAdd (
+ IN CONST VOID *BnA,
+ IN CONST VOID *BnB,
+ OUT VOID *BnRes
+ )
+{
+ return (BOOLEAN)BN_add (BnRes, BnA, BnB);
+}
+
+/**
+ 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
+ )
+{
+ return (BOOLEAN)BN_sub (BnRes, BnA, BnB);
+}
+
+/**
+ 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
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = (BOOLEAN)BN_mod (BnRes, BnA, BnB, Ctx);
+ BN_CTX_free (Ctx);
+
+ return RetVal;
+}
+
+/**
+ 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
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = (BOOLEAN)BN_mod_exp (BnRes, BnA, BnP, BnM, Ctx);
+
+ BN_CTX_free (Ctx);
+ return RetVal;
+}
+
+/**
+ 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
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = FALSE;
+ if (BN_mod_inverse (BnRes, BnA, BnM, Ctx) != NULL) {
+ RetVal = TRUE;
+ }
+
+ BN_CTX_free (Ctx);
+ return RetVal;
+}
+
+/**
+ 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
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = (BOOLEAN)BN_div (BnRes, NULL, BnA, BnB, Ctx);
+ BN_CTX_free (Ctx);
+
+ return RetVal;
+}
+
+/**
+ 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
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = (BOOLEAN)BN_mod_mul (BnRes, BnA, BnB, BnM, Ctx);
+ BN_CTX_free (Ctx);
+
+ return RetVal;
+}
+
+/**
+ 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 (BOOLEAN)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 (BOOLEAN)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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+BigNumRShift (
+ IN CONST VOID *Bn,
+ IN UINTN N,
+ OUT VOID *BnRes
+ )
+{
+ return (BOOLEAN)BN_rshift (BnRes, Bn, (INT32)N);
+}
+
+/**
+ 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 TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+BigNumSqrMod (
+ IN CONST VOID *BnA,
+ IN CONST VOID *BnM,
+ OUT VOID *BnRes
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = (BOOLEAN)BN_mod_sqr (BnRes, BnA, BnM, Ctx);
+ BN_CTX_free (Ctx);
+
+ return RetVal;
+}
+
+/**
+ 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.
+
+ @retval TRUE On success.
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+BigNumSetUint (
+ IN VOID *Bn,
+ IN UINTN Val
+ )
+{
+ return (BOOLEAN)BN_set_word (Bn, 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.
+**/
+BOOLEAN
+EFIAPI
+BigNumAddMod (
+ IN CONST VOID *BnA,
+ IN CONST VOID *BnB,
+ IN CONST VOID *BnM,
+ OUT VOID *BnRes
+ )
+{
+ BOOLEAN RetVal;
+ BN_CTX *Ctx;
+
+ Ctx = BN_CTX_new ();
+ if (Ctx == NULL) {
+ return FALSE;
+ }
+
+ RetVal = (BOOLEAN)BN_mod_add (BnRes, BnA, BnB, BnM, Ctx);
+ BN_CTX_free (Ctx);
+
+ return RetVal;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Bn/CryptBnNull.c b/CryptoPkg/Library/BaseCryptLib/Bn/CryptBnNull.c
new file mode 100644
index 0000000000..547401fa12
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLib/Bn/CryptBnNull.c
@@ -0,0 +1,520 @@
+/** @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 <Library/BaseCryptLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Allocate new Big Number.
+
+ @retval New BigNum opaque structure or NULL on failure.
+**/
+VOID *
+EFIAPI
+BigNumInit (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return -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
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+/**
+ Get number of bits in Bn.
+
+ @param[in] Bn Big number.
+
+ @retval Number of bits.
+**/
+UINTN
+EFIAPI
+BigNumBits (
+ IN CONST VOID *Bn
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+/**
+ Get number of bytes in Bn.
+
+ @param[in] Bn Big number.
+
+ @retval Number of bytes.
+**/
+UINTN
+EFIAPI
+BigNumBytes (
+ IN CONST VOID *Bn
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return NULL;
+}
+
+/**
+ Free Big Number context that was allocated with BigNumNewContext().
+
+ @param[in] BnCtx Big number context to free.
+**/
+VOID
+EFIAPI
+BigNumContextFree (
+ IN VOID *BnCtx
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
index 01de27e037..65ad23fb81 100644
--- a/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
@@ -60,6 +60,7 @@
Pk/CryptRsaPssSignNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
+ Bn/CryptBnNull.c
SysCall/CrtWrapper.c
SysCall/ConstantTimeClock.c
diff --git a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
index 91a1715095..ce6a789dfd 100644
--- a/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
@@ -60,6 +60,7 @@
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Pem/CryptPem.c
+ Bn/CryptBnNull.c
SysCall/CrtWrapper.c
SysCall/ConstantTimeClock.c
diff --git a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
index 63d1d82d19..354f3d80aa 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+++ b/CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
@@ -53,6 +53,7 @@
Rand/CryptRandNull.c
Pk/CryptRsaPssNull.c
Pk/CryptRsaPssSignNull.c
+ Bn/CryptBnNull.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Bn/CryptBnNull.c b/CryptoPkg/Library/BaseCryptLibNull/Bn/CryptBnNull.c
new file mode 100644
index 0000000000..547401fa12
--- /dev/null
+++ b/CryptoPkg/Library/BaseCryptLibNull/Bn/CryptBnNull.c
@@ -0,0 +1,520 @@
+/** @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 <Library/BaseCryptLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Allocate new Big Number.
+
+ @retval New BigNum opaque structure or NULL on failure.
+**/
+VOID *
+EFIAPI
+BigNumInit (
+ VOID
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return -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
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+/**
+ Get number of bits in Bn.
+
+ @param[in] Bn Big number.
+
+ @retval Number of bits.
+**/
+UINTN
+EFIAPI
+BigNumBits (
+ IN CONST VOID *Bn
+ )
+{
+ ASSERT (FALSE);
+ return 0;
+}
+
+/**
+ Get number of bytes in Bn.
+
+ @param[in] Bn Big number.
+
+ @retval Number of bytes.
+**/
+UINTN
+EFIAPI
+BigNumBytes (
+ IN CONST VOID *Bn
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return NULL;
+}
+
+/**
+ Free Big Number context that was allocated with BigNumNewContext().
+
+ @param[in] BnCtx Big number context to free.
+**/
+VOID
+EFIAPI
+BigNumContextFree (
+ IN VOID *BnCtx
+ )
+{
+ ASSERT (FALSE);
+}
+
+/**
+ 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
+ )
+{
+ ASSERT (FALSE);
+ return 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
+ )
+{
+ ASSERT (FALSE);
+ return FALSE;
+}
--
2.31.1.windows.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH V2 2/3] CryptoPkg: Add BigNum API to DXE and protocol
[not found] <cover.1663735456.git.yi1.li@intel.com>
2022-09-21 4:53 ` [PATCH V2 1/3] CryptoPkg: Add BigNum support yi1 li
@ 2022-09-21 4:53 ` yi1 li
2022-09-21 4:53 ` [PATCH V2 3/3] CryptoPkg/Test: Add unit test for CryptoBn yi1 li
2 siblings, 0 replies; 3+ messages in thread
From: yi1 li @ 2022-09-21 4:53 UTC (permalink / raw)
To: devel; +Cc: Yi Li, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang
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 <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Yi Li <yi1.li@intel.com>
---
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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH V2 3/3] CryptoPkg/Test: Add unit test for CryptoBn
[not found] <cover.1663735456.git.yi1.li@intel.com>
2022-09-21 4:53 ` [PATCH V2 1/3] CryptoPkg: Add BigNum support yi1 li
2022-09-21 4:53 ` [PATCH V2 2/3] CryptoPkg: Add BigNum API to DXE and protocol yi1 li
@ 2022-09-21 4:53 ` yi1 li
2 siblings, 0 replies; 3+ messages in thread
From: yi1 li @ 2022-09-21 4:53 UTC (permalink / raw)
To: devel; +Cc: Yi Li, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang
Add unit test for CryptoBn.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Yi Li <yi1.li@intel.com>
---
.../BaseCryptLib/UnitTestHostBaseCryptLib.inf | 1 +
.../BaseCryptLib/BaseCryptLibUnitTests.c | 1 +
.../UnitTest/Library/BaseCryptLib/BnTests.c | 266 ++++++++++++++++++
.../Library/BaseCryptLib/TestBaseCryptLib.h | 3 +
.../BaseCryptLib/TestBaseCryptLibHost.inf | 1 +
.../BaseCryptLib/TestBaseCryptLibShell.inf | 1 +
6 files changed, 273 insertions(+)
create mode 100644 CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BnTests.c
diff --git a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
index 11ff1c6931..cf8810e598 100644
--- a/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
+++ b/CryptoPkg/Library/BaseCryptLib/UnitTestHostBaseCryptLib.inf
@@ -46,6 +46,7 @@
Pem/CryptPem.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSign.c
+ Bn/CryptBn.c
SysCall/UnitTestHostCrtWrapper.c
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
index 3c57aead1e..792006a194 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
@@ -25,6 +25,7 @@ SUITE_DESC mSuiteDesc[] = {
{ "DH verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mDhTestNum, mDhTest },
{ "PRNG verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mPrngTestNum, mPrngTest },
{ "OAEP encrypt verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mOaepTestNum, mOaepTest },
+ { "Bn verify tests", "CryptoPkg.BaseCryptLib", NULL, NULL, &mBnTestNum, mBnTest },
};
EFI_STATUS
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BnTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BnTests.c
new file mode 100644
index 0000000000..2636bb6318
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BnTests.c
@@ -0,0 +1,266 @@
+/** @file
+ Application for BigNumber Primitives Validation.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+//
+// Debug data
+//
+#define MAX_TEST_DATA_SIZE 512
+#define BYTES_OF_OPERATION_A 60
+#define BITS_OF_OPERATION_A 480// (8 * 60)
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnOperationA[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+ 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+ 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+ 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnOperationB[] = {
+ 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
+ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
+ 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
+ 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnOperationC[] = {
+ 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnOperationExp[] = {
+ 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnOperationMod[] = {
+ 0x48, 0xbe, 0xcb, 0xd5, 0x36, 0x2e, 0x93, 0x0b, 0x51, 0x45, 0x9c, 0x7d, 0xe7, 0xfe, 0x47, 0xaa,
+ 0xc5, 0xd3, 0x4b, 0x4f, 0x06, 0x24, 0xb4, 0x31, 0x83, 0x55, 0xb5, 0xf0, 0xda, 0x14, 0xca, 0x46
+};
+
+// BnOperationA + BnOperationB
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultSum[] = {
+ 0xb0, 0x03, 0x61, 0xa4, 0x29, 0x78, 0xf5, 0x57, 0x80, 0x52, 0x72, 0xab, 0xa0, 0x20, 0x56, 0xde,
+ 0xdd, 0xe7, 0x6f, 0x8d, 0xcf, 0x4c, 0xdd, 0x2d, 0xc0, 0x3f, 0x2c, 0x4f, 0xe6, 0x1c, 0x23, 0xa1,
+ 0x48, 0xbe, 0xcb, 0xd5, 0x36, 0x2e, 0x93, 0x0b, 0x51, 0x45, 0x9c, 0x7d, 0xe7, 0xfe, 0x47, 0xaa,
+ 0xc5, 0xd3, 0x4b, 0x4f, 0x06, 0x24, 0xb4, 0x31, 0x83, 0x55, 0xb5, 0xf0, 0xda, 0x14, 0xca, 0x46
+};
+
+// (BnOperationA + BnOperationC) % BnOperationMod
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultSumMod[] = {
+ 0x16, 0x0a, 0xcf, 0x78, 0x20, 0xac, 0x31, 0x53, 0xd9, 0x0f, 0x22, 0xfc, 0x08, 0x8d, 0xde, 0x0d,
+ 0x29, 0xf4, 0x07, 0xdd, 0xfa, 0xf5, 0x61, 0xd4, 0x1a, 0xe5, 0xa1, 0xef, 0x4a, 0x37, 0xfe, 0xec
+};
+
+// (BnOperationA * BnOperationC) % BnOperationMod
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultMulMod[] = {
+ 0x01, 0xDB, 0xD2, 0x82, 0xC9, 0x24, 0x66, 0x2A, 0x96, 0x05, 0x11, 0xF2, 0x31, 0xF0, 0xCB, 0x28,
+ 0xBA, 0x5C, 0xBE, 0x7D, 0xEE, 0x37, 0x25, 0xB1, 0x24, 0x7E, 0x15, 0xAB, 0xCD, 0x86, 0x8E, 0x39
+};
+
+// BnOperationA / BnOperationMod
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultDiv[] = {
+ 0x02, 0x06, 0xA6, 0xDC, 0x2E, 0x97, 0x05, 0xEA, 0xCD, 0xF7, 0xAB, 0xCD, 0xE5, 0x9C, 0x33, 0x03,
+ 0xCE, 0x3D, 0x7E, 0x63, 0x23, 0xB2, 0xEC, 0xED, 0x96, 0x9D, 0xC9, 0xBB, 0x78
+};
+
+// BnOperationA % BnOperationMod
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultMod[] = {
+ 0x06, 0x2A, 0x8D, 0x06, 0x9D, 0x14, 0x53, 0x3B, 0x05, 0xD9, 0x86, 0x00, 0xA5, 0xB9, 0x05, 0x7F,
+ 0xC1, 0x82, 0xEC, 0x23, 0x44, 0x23, 0xC8, 0xA2, 0x42, 0xB3, 0x43, 0xB8, 0x7C, 0xD6, 0xB1, 0xCF
+};
+
+// BnOperationA % BnOperationMod
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultInverseMod[] = {
+ 0x3a, 0xeb, 0xc5, 0x98, 0x9c, 0x22, 0xd6, 0x76, 0x7d, 0x1c, 0xc6, 0xd6, 0xbb, 0x1b, 0xed, 0xfd,
+ 0x0f, 0x34, 0xbf, 0xe0, 0x2b, 0x4a, 0x26, 0xc3, 0xc0, 0xd9, 0x57, 0xc7, 0x11, 0xc0, 0xd6, 0x35
+};
+
+// BnOperationA % BnOperationMod
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultExpMod[] = {
+ 0x39, 0xf8, 0x74, 0xa0, 0xe8, 0x02, 0x8b, 0xf2, 0x22, 0x62, 0x82, 0x4c, 0xe0, 0xed, 0x63, 0x48,
+ 0xb9, 0xa2, 0xaa, 0xbc, 0xba, 0xb1, 0xd3, 0x6a, 0x02, 0xfd, 0xf3, 0x0e, 0x3a, 0x19, 0x39, 0x37
+};
+
+// BnOperationA >> 128
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultRShift[] = {
+ 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+ 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6,0x4b, 0x55, 0xd3, 0x9a,
+ 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23,0xa3, 0xfe, 0xeb, 0xbd
+};
+
+// 0x12345678
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 BnResultUIntSet[] = { 0x12, 0x34, 0x56, 0x78 };
+
+typedef struct {
+ VOID *BnA;
+ VOID *BnB;
+ VOID *BnC;
+ VOID *BnD;
+ VOID *BnCTX;
+} BN_TEST_CONTEXT;
+
+GLOBAL_REMOVE_IF_UNREFERENCED STATIC BN_TEST_CONTEXT mBnContext = { NULL, NULL, NULL, NULL, NULL };
+
+//
+// Debug function
+//
+STATIC
+BOOLEAN
+EqualBn2Bn (
+ CONST VOID *Expected,
+ CONST VOID *Actual
+ )
+{
+ if (BigNumCmp (Expected, Actual) == 0) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+STATIC
+BOOLEAN
+EqualBn2Bin (
+ CONST VOID *Bn,
+ CONST UINT8 *Buffer,
+ CONST UINTN BufferSize
+ )
+{
+ UINTN BnTestBufferSize;
+ UINT8 BnTestBuffer[MAX_TEST_DATA_SIZE];
+
+ BnTestBufferSize = BigNumToBin (Bn, BnTestBuffer);
+ if (BnTestBufferSize == BufferSize) {
+ if (CompareMem (Buffer, BnTestBuffer, BnTestBufferSize) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyBnPreReq (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ BN_TEST_CONTEXT *BnContext;
+
+ BnContext = Context;
+ BnContext->BnCTX = BigNumNewContext ();
+ BnContext->BnA = BigNumInit ();
+ BnContext->BnB = BigNumInit ();
+ BnContext->BnC = BigNumInit ();
+ BnContext->BnD = BigNumInit ();
+ if ( (BnContext->BnCTX == NULL)
+ || (BnContext->BnA == NULL)
+ || (BnContext->BnB == NULL)
+ || (BnContext->BnC == NULL)
+ || (BnContext->BnD == NULL)
+ )
+ {
+ return UNIT_TEST_ERROR_TEST_FAILED;
+ }
+
+ return UNIT_TEST_PASSED;
+}
+
+VOID
+EFIAPI
+TestVerifyBnCleanUp (
+ UNIT_TEST_CONTEXT Context
+ )
+{
+ BN_TEST_CONTEXT *BnContext;
+
+ BnContext = Context;
+ BigNumContextFree (BnContext->BnCTX);
+ BigNumFree (BnContext->BnA, TRUE);
+ BigNumFree (BnContext->BnB, TRUE);
+ BigNumFree (BnContext->BnC, TRUE);
+ BigNumFree (BnContext->BnD, TRUE);
+}
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyBn (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ BN_TEST_CONTEXT *BnContext;
+ UINTN Num;
+ CONST VOID *BnOne;
+
+ BnContext = Context;
+
+ // Calculation tests
+ BnContext->BnA = BigNumFromBin (BnOperationA, sizeof (BnOperationA));
+ BnContext->BnB = BigNumFromBin (BnOperationB, sizeof (BnOperationB));
+ // C=A+B
+ BigNumAdd (BnContext->BnA, BnContext->BnB, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultSum, sizeof (BnResultSum)));
+ // D=C-A=B
+ BigNumSub (BnContext->BnC, BnContext->BnA, BnContext->BnD);
+ UT_ASSERT_TRUE (EqualBn2Bn (BnContext->BnB, BnContext->BnD));
+ // C=(A+B)%D
+ BnContext->BnD = BigNumFromBin (BnOperationMod, sizeof (BnOperationMod));
+ BigNumAddMod (BnContext->BnA, BnContext->BnB, BnContext->BnD, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultSumMod, sizeof (BnResultSumMod)));
+ // C=(A*B)%D
+ BigNumMulMod (BnContext->BnA, BnContext->BnB, BnContext->BnD, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultMulMod, sizeof (BnResultMulMod)));
+ // C=A/D
+ BigNumDiv (BnContext->BnA, BnContext->BnD, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultDiv, sizeof (BnResultDiv)));
+ // C=A%D
+ BigNumMod (BnContext->BnA, BnContext->BnD, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultMod, sizeof (BnResultMod)));
+ // 1=(A*C)%D
+ BigNumInverseMod (BnContext->BnA, BnContext->BnD, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultInverseMod, sizeof (BnResultInverseMod)));
+ // C=(A^B)%D
+ BnContext->BnB = BigNumFromBin (BnOperationExp, sizeof (BnOperationExp));
+ BigNumExpMod (BnContext->BnA, BnContext->BnB, BnContext->BnD, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultExpMod, sizeof (BnResultExpMod)));
+ // C=A>>128
+ BigNumRShift (BnContext->BnA, 128, BnContext->BnC);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultRShift, sizeof (BnResultRShift)));
+ // C=0x12345678
+ BigNumSetUint (BnContext->BnC, 0x12345678);
+ UT_ASSERT_TRUE (EqualBn2Bin (BnContext->BnC, BnResultUIntSet, sizeof (BnResultUIntSet)));
+ // Bn compare
+ UT_ASSERT_TRUE (BigNumIsWord (BnContext->BnC, 0x12345678));
+ UT_ASSERT_FALSE (BigNumIsWord (BnContext->BnC, 0x12345600));
+ UT_ASSERT_FALSE (BigNumIsOdd (BnContext->BnC));
+ UT_ASSERT_TRUE (BigNumIsOdd (BnContext->BnA));
+
+ // Other tests
+ BigNumConstTime (BnContext->BnA);
+ Num = BigNumBytes (BnContext->BnA);
+ UT_ASSERT_EQUAL (Num, BYTES_OF_OPERATION_A);
+ Num = BigNumBits (BnContext->BnA);
+ UT_ASSERT_EQUAL (Num, BITS_OF_OPERATION_A);
+ BnOne = BigNumValueOne ();
+ if (BnOne == NULL) {
+ return UNIT_TEST_ERROR_TEST_FAILED;
+ }
+
+ UT_ASSERT_TRUE (BigNumIsWord (BnOne, 0x1));
+
+ return UNIT_TEST_PASSED;
+}
+
+TEST_DESC mBnTest[] = {
+ //
+ // -----Description----------------Class---------------------Function-----------Pre----------------Post---------Context
+ //
+ { "TestVerifyBn()", "CryptoPkg.BaseCryptLib.BigNumber", TestVerifyBn, TestVerifyBnPreReq, TestVerifyBnCleanUp, &mBnContext },
+};
+
+UINTN mBnTestNum = ARRAY_SIZE (mBnTest);
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index a6b3482742..b8f0fdfd89 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -86,6 +86,9 @@ extern TEST_DESC mOaepTest[];
extern UINTN mRsaPssTestNum;
extern TEST_DESC mRsaPssTest[];
+extern UINTN mBnTestNum;
+extern TEST_DESC mBnTest[];
+
/** Creates a framework you can use */
EFI_STATUS
EFIAPI
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 399db596c2..1301345a13 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -37,6 +37,7 @@
OaepEncryptTests.c
RsaPssTests.c
ParallelhashTests.c
+ BnTests.c
[Packages]
MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index ca789aa6ad..9a41dbc317 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -36,6 +36,7 @@
Pkcs7EkuTests.c
OaepEncryptTests.c
RsaPssTests.c
+ BnTests.c
[Packages]
MdePkg/MdePkg.dec
--
2.31.1.windows.1
^ permalink raw reply related [flat|nested] 3+ messages in thread