]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Driver/Crypto.c
CryptoPkg: Add BigNum API to DXE and protocol
[mirror_edk2.git] / CryptoPkg / Driver / Crypto.c
index 9562dfeec58c3cbb5ae99c1e9d76c8550fd7cf96..9872b5bf7064a104e7474cdd6222d4e12df653ae 100644 (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);\r
 }\r
 \r
+// =====================================================================================\r
+//    Big number primitives\r
+// =====================================================================================\r
+\r
+/**\r
+  Allocate new Big Number.\r
+\r
+  @retval New BigNum opaque structure or NULL on failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+CryptoServiceBigNumInit (\r
+  VOID\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Init, BigNumInit, (), NULL);\r
+}\r
+\r
+/**\r
+  Allocate new Big Number and assign the provided value to it.\r
+\r
+  @param[in]   Buf    Big endian encoded buffer.\r
+  @param[in]   Len    Buffer length.\r
+\r
+  @retval New BigNum opaque structure or NULL on failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+CryptoServiceBigNumFromBin (\r
+  IN CONST UINT8  *Buf,\r
+  IN UINTN        Len\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.FromBin, BigNumFromBin, (Buf, Len), NULL);\r
+}\r
+\r
+/**\r
+  Convert the absolute value of Bn into big-endian form and store it at Buf.\r
+  The Buf array should have at least BigNumBytes() in it.\r
+\r
+  @param[in]   Bn     Big number to convert.\r
+  @param[out]  Buf    Output buffer.\r
+\r
+  @retval The length of the big-endian number placed at Buf or -1 on error.\r
+**/\r
+INTN\r
+EFIAPI\r
+CryptoServiceBigNumToBin (\r
+  IN CONST VOID  *Bn,\r
+  OUT UINT8      *Buf\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.ToBin, BigNumToBin, (Bn, Buf), -1);\r
+}\r
+\r
+/**\r
+  Free the Big Number.\r
+\r
+  @param[in]   Bn      Big number to free.\r
+  @param[in]   Clear   TRUE if the buffer should be cleared.\r
+**/\r
+VOID\r
+EFIAPI\r
+CryptoServiceBigNumFree (\r
+  IN VOID     *Bn,\r
+  IN BOOLEAN  Clear\r
+  )\r
+{\r
+  CALL_VOID_BASECRYPTLIB (Bn.Services.Free, BigNumFree, (Bn, Clear));\r
+}\r
+\r
+/**\r
+  Calculate the sum of two Big Numbers.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnB     Big number.\r
+  @param[out]  BnRes   The result of BnA + BnB.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumAdd (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Add, BigNumAdd, (BnA, BnB, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Subtract two Big Numbers.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnB     Big number.\r
+  @param[out]  BnRes   The result of BnA - BnB.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumSub (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Sub, BigNumSub, (BnA, BnB, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Calculate remainder: BnRes = BnA % BnB.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnB     Big number.\r
+  @param[out]  BnRes   The result of BnA % BnB.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumMod (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Mod, BigNumMod, (BnA, BnB, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Compute BnA to the BnP-th power modulo BnM.\r
+  Please note, all "out" Big number arguments should be properly initialized.\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnP     Big number (power).\r
+  @param[in]   BnM     Big number (modulo).\r
+  @param[out]  BnRes   The result of (BnA ^ BnP) % BnM.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumExpMod (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnP,\r
+  IN CONST VOID  *BnM,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.ExpMod, BigNumExpMod, (BnA, BnP, BnM, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Compute BnA inverse modulo BnM.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnM     Big number (modulo).\r
+  @param[out]  BnRes   The result, such that (BnA * BnRes) % BnM == 1.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumInverseMod (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnM,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.InverseMod, BigNumInverseMod, (BnA, BnM, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Divide two Big Numbers.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnB     Big number.\r
+  @param[out]  BnRes   The result, such that BnA / BnB.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumDiv (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Div, BigNumDiv, (BnA, BnB, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Multiply two Big Numbers modulo BnM.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnB     Big number.\r
+  @param[in]   BnM     Big number (modulo).\r
+  @param[out]  BnRes   The result, such that (BnA * BnB) % BnM.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumMulMod (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB,\r
+  IN CONST VOID  *BnM,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.MulMod, BigNumMulMod, (BnA, BnB, BnM, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Compare two Big Numbers.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnB     Big number.\r
+\r
+  @retval 0          BnA == BnB.\r
+  @retval 1          BnA > BnB.\r
+  @retval -1         BnA < BnB.\r
+**/\r
+INTN\r
+EFIAPI\r
+CryptoServiceBigNumCmp (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Cmp, BigNumCmp, (BnA, BnB), 0);\r
+}\r
+\r
+/**\r
+  Get number of bits in Bn.\r
+\r
+  @param[in]   Bn     Big number.\r
+\r
+  @retval Number of bits.\r
+**/\r
+UINTN\r
+EFIAPI\r
+CryptoServiceBigNumBits (\r
+  IN CONST VOID  *Bn\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Bits, BigNumBits, (Bn), 0);\r
+}\r
+\r
+/**\r
+  Get number of bytes in Bn.\r
+\r
+  @param[in]   Bn     Big number.\r
+\r
+  @retval Number of bytes.\r
+**/\r
+UINTN\r
+EFIAPI\r
+CryptoServiceBigNumBytes (\r
+  IN CONST VOID  *Bn\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Bytes, BigNumBytes, (Bn), 0);\r
+}\r
+\r
+/**\r
+  Checks if Big Number equals to the given Num.\r
+\r
+  @param[in]   Bn     Big number.\r
+  @param[in]   Num    Number.\r
+\r
+  @retval TRUE   iff Bn == Num.\r
+  @retval FALSE  otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumIsWord (\r
+  IN CONST VOID  *Bn,\r
+  IN UINTN       Num\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.IsWord, BigNumIsWord, (Bn, Num), FALSE);\r
+}\r
+\r
+/**\r
+  Checks if Big Number is odd.\r
+\r
+  @param[in]   Bn     Big number.\r
+\r
+  @retval TRUE   Bn is odd (Bn % 2 == 1).\r
+  @retval FALSE  otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumIsOdd (\r
+  IN CONST VOID  *Bn\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.IsOdd, BigNumIsOdd, (Bn), FALSE);\r
+}\r
+\r
+/**\r
+  Copy Big number.\r
+\r
+  @param[out]  BnDst     Destination.\r
+  @param[in]   BnSrc     Source.\r
+\r
+  @retval BnDst on success.\r
+  @retval NULL otherwise.\r
+**/\r
+VOID *\r
+EFIAPI\r
+CryptoServiceBigNumCopy (\r
+  OUT VOID       *BnDst,\r
+  IN CONST VOID  *BnSrc\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.Copy, BigNumCopy, (BnDst, BnSrc), NULL);\r
+}\r
+\r
+/**\r
+  Get constant Big number with value of "1".\r
+  This may be used to save expensive allocations.\r
+\r
+  @retval Big Number with value of 1.\r
+**/\r
+CONST VOID *\r
+EFIAPI\r
+CryptoServiceBigNumValueOne (\r
+  VOID\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.ValueOne, BigNumValueOne, (), NULL);\r
+}\r
+\r
+/**\r
+  Shift right Big Number.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   Bn      Big number.\r
+  @param[in]   N       Number of bits to shift.\r
+  @param[out]  BnRes   The result.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumRShift (\r
+  IN CONST VOID  *Bn,\r
+  IN UINTN       N,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.RShift, BigNumRShift, (Bn, N, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Mark Big Number for constant time computations.\r
+  This function should be called before any constant time computations are\r
+  performed on the given Big number.\r
+\r
+  @param[in]   Bn     Big number.\r
+**/\r
+VOID\r
+EFIAPI\r
+CryptoServiceBigNumConstTime (\r
+  IN VOID  *Bn\r
+  )\r
+{\r
+  CALL_VOID_BASECRYPTLIB (Bn.Services.ConstTime, BigNumConstTime, (Bn));\r
+}\r
+\r
+/**\r
+  Calculate square modulo.\r
+  Please note, all "out" Big number arguments should be properly initialized\r
+  by calling to BigNumInit() or BigNumFromBin() functions.\r
+\r
+  @param[in]   BnA     Big number.\r
+  @param[in]   BnM     Big number (modulo).\r
+  @param[out]  BnRes   The result, such that (BnA ^ 2) % BnM.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumSqrMod (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnM,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.SqrMod, BigNumSqrMod, (BnA, BnM, BnRes), FALSE);\r
+}\r
+\r
+/**\r
+  Create new Big Number computation context. This is an opaque structure\r
+  which should be passed to any function that requires it. The BN context is\r
+  needed to optimize calculations and expensive allocations.\r
+\r
+  @retval Big Number context struct or NULL on failure.\r
+**/\r
+VOID *\r
+EFIAPI\r
+CryptoServiceBigNumNewContext (\r
+  VOID\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.NewContext, BigNumNewContext, (), NULL);\r
+}\r
+\r
+/**\r
+  Free Big Number context that was allocated with BigNumNewContext().\r
+\r
+  @param[in]   BnCtx     Big number context to free.\r
+**/\r
+VOID\r
+EFIAPI\r
+CryptoServiceBigNumContextFree (\r
+  IN VOID  *BnCtx\r
+  )\r
+{\r
+  CALL_VOID_BASECRYPTLIB (Bn.Services.ContextFree, BigNumContextFree, (BnCtx));\r
+}\r
+\r
+/**\r
+  Set Big Number to a given value.\r
+\r
+  @param[in]   Bn     Big number to set.\r
+  @param[in]   Val    Value to set.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumSetUint (\r
+  IN VOID   *Bn,\r
+  IN UINTN  Val\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.SetUint, BigNumSetUint, (Bn, Val), FALSE);\r
+}\r
+\r
+/**\r
+  Add two Big Numbers modulo BnM.\r
+\r
+  @param[in]   BnA       Big number.\r
+  @param[in]   BnB       Big number.\r
+  @param[in]   BnM       Big number (modulo).\r
+  @param[out]  BnRes     The result, such that (BnA + BnB) % BnM.\r
+\r
+  @retval TRUE          On success.\r
+  @retval FALSE         Otherwise.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CryptoServiceBigNumAddMod (\r
+  IN CONST VOID  *BnA,\r
+  IN CONST VOID  *BnB,\r
+  IN CONST VOID  *BnM,\r
+  OUT VOID       *BnRes\r
+  )\r
+{\r
+  return CALL_BASECRYPTLIB (Bn.Services.AddMod, BigNumAddMod, (BnA, BnB, BnM, BnRes), FALSE);\r
+}\r
+\r
 const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {\r
   /// Version\r
   CryptoServiceGetCryptoVersion,\r
@@ -5251,5 +5743,31 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   CryptoServiceHkdfSha384Expand,\r
   /// Aead Aes GCM\r
   CryptoServiceAeadAesGcmEncrypt,\r
-  CryptoServiceAeadAesGcmDecrypt\r
+  CryptoServiceAeadAesGcmDecrypt,\r
+  /// Big Numbers\r
+  CryptoServiceBigNumInit,\r
+  CryptoServiceBigNumFromBin,\r
+  CryptoServiceBigNumToBin,\r
+  CryptoServiceBigNumFree,\r
+  CryptoServiceBigNumAdd,\r
+  CryptoServiceBigNumSub,\r
+  CryptoServiceBigNumMod,\r
+  CryptoServiceBigNumExpMod,\r
+  CryptoServiceBigNumInverseMod,\r
+  CryptoServiceBigNumDiv,\r
+  CryptoServiceBigNumMulMod,\r
+  CryptoServiceBigNumCmp,\r
+  CryptoServiceBigNumBits,\r
+  CryptoServiceBigNumBytes,\r
+  CryptoServiceBigNumIsWord,\r
+  CryptoServiceBigNumIsOdd,\r
+  CryptoServiceBigNumCopy,\r
+  CryptoServiceBigNumValueOne,\r
+  CryptoServiceBigNumRShift,\r
+  CryptoServiceBigNumConstTime,\r
+  CryptoServiceBigNumSqrMod,\r
+  CryptoServiceBigNumNewContext,\r
+  CryptoServiceBigNumContextFree,\r
+  CryptoServiceBigNumSetUint,\r
+  CryptoServiceBigNumAddMod,\r
 };\r