]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c
Update CryptoPkg for new ciphers (HMAC, Block Cipher, etc) supports.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptDh.c
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptDh.c
new file mode 100644 (file)
index 0000000..b7e164c
--- /dev/null
@@ -0,0 +1,238 @@
+/** @file\r
+  Diffie-Hellman Wrapper Implementation over OpenSSL.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalCryptLib.h"\r
+#include <openssl/dh.h>\r
+\r
+\r
+/**\r
+  Allocates and Initializes one Diffie-Hellman Context for subsequent use.\r
+\r
+  @return  Pointer to the Diffie-Hellman Context that has been initialized.\r
+           If the allocations fails, DhNew() returns NULL.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+DhNew (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Allocates & Initializes DH Context by OpenSSL DH_new()\r
+  //\r
+  return (VOID *)DH_new ();\r
+}\r
+\r
+/**\r
+  Release the specified DH context.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+\r
+  @param[in]  DhContext  Pointer to the DH context to be released.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DhFree (\r
+  IN  VOID  *DhContext\r
+  )\r
+{\r
+  //\r
+  // Free OpenSSL DH Context\r
+  //\r
+  DH_free ((DH *)DhContext);\r
+}\r
+\r
+/**\r
+  Generates DH parameter.\r
+\r
+  Given generator g, and length of prime number p in bits, this function generates p,\r
+  and sets DH context according to value of g and p.\r
+  \r
+  Before this function can be invoked, pseudorandom number generator must be correctly\r
+  initialized by RandomSeed().\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If Prime is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.\r
+\r
+  @retval TRUE   DH pamameter generation succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateParameter (\r
+  IN OUT  VOID   *DhContext,\r
+  IN      UINTN  Generator,\r
+  IN      UINTN  PrimeLength,\r
+  OUT     UINT8  *Prime\r
+  )\r
+{\r
+  BOOLEAN RetVal;\r
+\r
+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
+    return FALSE;\r
+  }\r
+\r
+  RetVal = (BOOLEAN) DH_generate_parameters_ex (DhContext, (UINT32) PrimeLength, (UINT32) Generator, NULL);\r
+  if (!RetVal) {\r
+    return FALSE;\r
+  }\r
+\r
+  BN_bn2bin (((DH *) DhContext)->p, Prime);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Sets generator and prime parameters for DH.\r
+\r
+  Given generator g, and prime number p, this function and sets DH\r
+  context accordingly.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If Prime is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext    Pointer to the DH context.\r
+  @param[in]       Generator    Value of generator.\r
+  @param[in]       PrimeLength  Length in bits of prime to be generated.\r
+  @param[in]       Prime        Pointer to the prime number.\r
+\r
+  @retval TRUE   DH pamameter setting succeeded.\r
+  @retval FALSE  Value of Generator is not supported.\r
+  @retval FALSE  Value of Generator is not suitable for the Prime.\r
+  @retval FALSE  Value of Prime is not a prime number.\r
+  @retval FALSE  Value of Prime is not a safe prime number.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhSetParameter (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      UINTN        Generator,\r
+  IN      UINTN        PrimeLength,\r
+  IN      CONST UINT8  *Prime\r
+  )\r
+{\r
+  DH  *Dh;\r
+\r
+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
+    return FALSE;\r
+  }\r
+\r
+  Dh = (DH *) DhContext;\r
+  Dh->p = BN_new();\r
+  Dh->g = BN_new();\r
+\r
+  BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p);\r
+  BN_set_word (Dh->g, (UINT32) Generator);\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Generates DH public key.\r
+\r
+  This function generates random secret exponent, and computes the public key, which is \r
+  returned via parameter PublicKey and PublicKeySize. DH context is updated accordingly.\r
+  If the PublicKey buffer is too small to hold the public key, FALSE is returned and\r
+  PublicKeySize is set to the required buffer size to obtain the public key.\r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If PublicKeySize is NULL, then ASSERT().\r
+  If PublicKeySize is large enough but PublicKey is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext      Pointer to the DH context.\r
+  @param[out]      PublicKey      Pointer to the buffer to receive generated public key.\r
+  @param[in, out]  PublicKeySize  On input, the size of PublicKey buffer in bytes.\r
+                                  On output, the size of data returned in PublicKey buffer in bytes.\r
+\r
+  @retval TRUE   DH public key generation succeeded.\r
+  @retval FALSE  DH public key generation failed.\r
+  @retval FALSE  PublicKeySize is not large enough.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhGenerateKey (\r
+  IN OUT  VOID   *DhContext,\r
+  OUT     UINT8  *PublicKey,\r
+  IN OUT  UINTN  *PublicKeySize\r
+  )\r
+{\r
+  BOOLEAN RetVal;\r
+  DH      *Dh;\r
+\r
+  Dh = (DH *) DhContext;\r
+  *PublicKeySize = 0;\r
+\r
+  RetVal = (BOOLEAN) DH_generate_key (DhContext);\r
+  if (RetVal) {\r
+    BN_bn2bin (Dh->pub_key, PublicKey);\r
+    *PublicKeySize  = BN_num_bytes (Dh->pub_key);\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  Computes exchanged common key.\r
+\r
+  Given peer's public key, this function computes the exchanged common key, based on its own\r
+  context including value of prime modulus and random secret exponent. \r
+\r
+  If DhContext is NULL, then ASSERT().\r
+  If PeerPublicKey is NULL, then ASSERT().\r
+  If KeySize is NULL, then ASSERT().\r
+  If KeySize is large enough but Key is NULL, then ASSERT().\r
+\r
+  @param[in, out]  DhContext          Pointer to the DH context.\r
+  @param[in]       PeerPublicKey      Pointer to the peer's public key.\r
+  @param[in]       PeerPublicKeySize  Size of peer's public key in bytes.\r
+  @param[out]      Key                Pointer to the buffer to receive generated key.\r
+  @param[in, out]  KeySize            On input, the size of Key buffer in bytes.\r
+                                      On output, the size of data returned in Key buffer in bytes.\r
+\r
+  @retval TRUE   DH exchanged key generation succeeded.\r
+  @retval FALSE  DH exchanged key generation failed.\r
+  @retval FALSE  KeySize is not large enough.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+DhComputeKey (\r
+  IN OUT  VOID         *DhContext,\r
+  IN      CONST UINT8  *PeerPublicKey,\r
+  IN      UINTN        PeerPublicKeySize,\r
+  OUT     UINT8        *Key,\r
+  IN OUT  UINTN        *KeySize\r
+  )\r
+{\r
+  BIGNUM  *Bn;\r
+\r
+  Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL);\r
+\r
+  *KeySize = (BOOLEAN) DH_compute_key (Key, Bn, DhContext);\r
+\r
+  BN_free (Bn);\r
+\r
+  return TRUE;\r
+}\r