CryptoPkg: Add BigNum API to DXE and protocol

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>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
Yi Li
2022-09-07 16:14:35 +08:00
committed by mergify[bot]
parent fd0ad0c346
commit 42951543dd
5 changed files with 1470 additions and 2 deletions

View File

@@ -5027,6 +5027,498 @@ CryptoServiceAeadAesGcmDecrypt (
return CALL_BASECRYPTLIB (AeadAesGcm.Services.Decrypt, AeadAesGcmDecrypt, (Key, KeySize, Iv, IvSize, AData, ADataSize, DataIn, DataInSize, Tag, TagSize, DataOut, DataOutSize), 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,
@@ -5251,5 +5743,31 @@ const EDKII_CRYPTO_PROTOCOL mEdkiiCrypto = {
CryptoServiceHkdfSha384Expand,
/// Aead Aes GCM
CryptoServiceAeadAesGcmEncrypt,
CryptoServiceAeadAesGcmDecrypt
CryptoServiceAeadAesGcmDecrypt,
/// 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,
};