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

@ -169,6 +169,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

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,
};

View File

@ -326,6 +326,36 @@ typedef struct {
} Services;
UINT32 Family;
} AeadAesGcm;
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

View File

@ -4061,3 +4061,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);
}

View File

@ -21,7 +21,7 @@
/// the EDK II Crypto Protocol is extended, this version define must be
/// increased.
///
#define EDKII_CRYPTO_VERSION 11
#define EDKII_CRYPTO_VERSION 12
///
/// EDK II Crypto Protocol forward declaration
@ -3888,6 +3888,407 @@ BOOLEAN
OUT UINTN *DataOutSize
);
// =====================================================================================
// 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
///
@ -4096,6 +4497,32 @@ struct _EDKII_CRYPTO_PROTOCOL {
/// AEAD AES-GCM
EDKII_AEAD_AES_GCM_ENCRYPT AeadAesGcmEncrypt;
EDKII_AEAD_AES_GCM_DECRYPT AeadAesGcmDecrypt;
/// BIGNUM
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;