From 42951543ddc56e98d413a73ecb57618f01ef20ec Mon Sep 17 00:00:00 2001 From: Yi Li Date: Wed, 7 Sep 2022 16:14:35 +0800 Subject: 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 Cc: Jian J Wang Cc: Xiaoyu Lu Cc: Guomin Jiang Signed-off-by: Yi Li Reviewed-by: Jiewen Yao --- CryptoPkg/Private/Protocol/Crypto.h | 429 +++++++++++++++++++++++++++++++++++- 1 file changed, 428 insertions(+), 1 deletion(-) (limited to 'CryptoPkg/Private') diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h index a66be2c388..3bf37575e9 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 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; -- cgit v1.2.3