CryptoPkg/BaseCryptLib: Add NULL pointer checks in DH and P7Verify
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Pk / CryptDh.c
index b7e164c..391efd5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Diffie-Hellman Wrapper Implementation over OpenSSL.\r
 \r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2017, 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
@@ -13,9 +13,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "InternalCryptLib.h"\r
+#include <openssl/bn.h>\r
 #include <openssl/dh.h>\r
 \r
-\r
 /**\r
   Allocates and Initializes one Diffie-Hellman Context for subsequent use.\r
 \r
@@ -32,13 +32,13 @@ DhNew (
   //\r
   // Allocates & Initializes DH Context by OpenSSL DH_new()\r
   //\r
-  return (VOID *)DH_new ();\r
+  return (VOID *) DH_new ();\r
 }\r
 \r
 /**\r
   Release the specified DH context.\r
 \r
-  If DhContext is NULL, then ASSERT().\r
+  If DhContext is NULL, then return FALSE.\r
 \r
   @param[in]  DhContext  Pointer to the DH context to be released.\r
 \r
@@ -52,7 +52,7 @@ DhFree (
   //\r
   // Free OpenSSL DH Context\r
   //\r
-  DH_free ((DH *)DhContext);\r
+  DH_free ((DH *) DhContext);\r
 }\r
 \r
 /**\r
@@ -64,15 +64,15 @@ DhFree (
   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
+  If DhContext is NULL, then return FALSE.\r
+  If Prime is NULL, then return FALSE.\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 TRUE   DH parameter 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
@@ -87,6 +87,14 @@ DhGenerateParameter (
   )\r
 {\r
   BOOLEAN RetVal;\r
+  BIGNUM  *BnP;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {\r
+    return FALSE;\r
+  }\r
 \r
   if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
     return FALSE;\r
@@ -97,7 +105,8 @@ DhGenerateParameter (
     return FALSE;\r
   }\r
 \r
-  BN_bn2bin (((DH *) DhContext)->p, Prime);\r
+  DH_get0_pqg (DhContext, (const BIGNUM **)&BnP, NULL, NULL);\r
+  BN_bn2bin (BnP, Prime);\r
 \r
   return TRUE;\r
 }\r
@@ -108,15 +117,15 @@ DhGenerateParameter (
   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
+  If DhContext is NULL, then return FALSE.\r
+  If Prime is NULL, then return FALSE.\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 TRUE   DH parameter 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
@@ -132,20 +141,38 @@ DhSetParameter (
   IN      CONST UINT8  *Prime\r
   )\r
 {\r
-  DH  *Dh;\r
+  DH      *Dh;\r
+  BIGNUM  *BnP;\r
+  BIGNUM  *BnG;\r
 \r
-  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {\r
     return FALSE;\r
   }\r
 \r
-  Dh = (DH *) DhContext;\r
-  Dh->p = BN_new();\r
-  Dh->g = BN_new();\r
+  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {\r
+    return FALSE;\r
+  }\r
 \r
-  BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p);\r
-  BN_set_word (Dh->g, (UINT32) Generator);\r
+  //\r
+  // Set the generator and prime parameters for DH object.\r
+  //\r
+  Dh  = (DH *)DhContext;\r
+  BnP = BN_bin2bn ((const unsigned char *)Prime, (int)(PrimeLength / 8), NULL);\r
+  BnG = BN_bin2bn ((const unsigned char *)&Generator, 1, NULL);\r
+  if ((BnP == NULL) || (BnG == NULL) || !DH_set0_pqg (Dh, BnP, NULL, BnG)) {\r
+    goto Error;\r
+  }\r
 \r
   return TRUE;\r
+\r
+Error:\r
+  BN_free (BnP);\r
+  BN_free (BnG);\r
+\r
+  return FALSE;\r
 }\r
 \r
 /**\r
@@ -156,9 +183,9 @@ DhSetParameter (
   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
+  If DhContext is NULL, then return FALSE.\r
+  If PublicKeySize is NULL, then return FALSE.\r
+  If PublicKeySize is large enough but PublicKey is NULL, then return FALSE.\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
@@ -180,14 +207,35 @@ DhGenerateKey (
 {\r
   BOOLEAN RetVal;\r
   DH      *Dh;\r
+  BIGNUM  *DhPubKey;\r
+  INTN    Size;\r
+\r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (DhContext == NULL || PublicKeySize == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (PublicKey == NULL && *PublicKeySize != 0) {\r
+    return FALSE;\r
+  }\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
+    DH_get0_key (Dh, (const BIGNUM **)&DhPubKey, NULL);\r
+    Size = BN_num_bytes (DhPubKey);\r
+    if ((Size > 0) && (*PublicKeySize < (UINTN) Size)) {\r
+      *PublicKeySize = Size;\r
+      return FALSE;\r
+    }\r
+\r
+    if (PublicKey != NULL) {\r
+      BN_bn2bin (DhPubKey, PublicKey);\r
+    }\r
+    *PublicKeySize = Size;\r
   }\r
 \r
   return RetVal;\r
@@ -199,10 +247,11 @@ DhGenerateKey (
   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
+  If DhContext is NULL, then return FALSE.\r
+  If PeerPublicKey is NULL, then return FALSE.\r
+  If KeySize is NULL, then return FALSE.\r
+  If Key is NULL, then return FALSE.\r
+  If KeySize is not large enough, then return FALSE.\r
 \r
   @param[in, out]  DhContext          Pointer to the DH context.\r
   @param[in]       PeerPublicKey      Pointer to the peer's public key.\r
@@ -227,12 +276,37 @@ DhComputeKey (
   )\r
 {\r
   BIGNUM  *Bn;\r
+  INTN    Size;\r
 \r
+  //\r
+  // Check input parameters.\r
+  //\r
+  if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL || Key == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (PeerPublicKeySize > INT_MAX) {\r
+    return FALSE;\r
+  }\r
+  \r
   Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL);\r
+  if (Bn == NULL) {\r
+    return FALSE;\r
+  }\r
+\r
+  Size = DH_compute_key (Key, Bn, DhContext);\r
+  if (Size < 0) {\r
+    BN_free (Bn);\r
+    return FALSE;\r
+  }\r
 \r
-  *KeySize = (BOOLEAN) DH_compute_key (Key, Bn, DhContext);\r
+  if (*KeySize < (UINTN) Size) {\r
+    *KeySize = Size;\r
+    BN_free (Bn);\r
+    return FALSE;\r
+  }\r
 \r
+  *KeySize = Size;\r
   BN_free (Bn);\r
-\r
   return TRUE;\r
 }\r