/* If DhContext is NULL, then return FALSE. If PeerPublicKey is NULL, then return FALSE. If KeySize is NULL, then return FALSE. If Key is NULL, then return FALSE. If KeySize is not large enough, then return FALSE. */
BOOLEAN EFIAPI DhComputeKey(IN OUT VOID *DhContext, IN CONST UINT8 *PeerPublicKey, IN UINTN PeerPublicKeySize, OUT UINT8 *Key, IN OUT UINTN *KeySize)
/* If DhContext is NULL, then return FALSE. If PeerPublicKey is NULL, then return FALSE. If KeySize is NULL, then return FALSE. If Key is NULL, then return FALSE. If KeySize is not large enough, then return FALSE. */
BOOLEAN EFIAPI DhComputeKey(IN OUT VOID *DhContext, IN CONST UINT8 *PeerPublicKey, IN UINTN PeerPublicKeySize, OUT UINT8 *Key, IN OUT UINTN *KeySize)
{
  BIGNUM  *Bn;
  INTN    Size;
  if ((DhContext == NULL) || (PeerPublicKey == NULL) || (KeySize == NULL) || (Key == NULL)) {
    return FALSE;
  }
  if (PeerPublicKeySize > INT_MAX) {
    return FALSE;
  }
  Bn = BN_bin2bn (PeerPublicKey, (UINT32)PeerPublicKeySize, NULL);
  if (Bn == NULL) {
    return FALSE;
  }
  Size = DH_compute_key (Key, Bn, DhContext);
  if (Size < 0) {
    BN_free (Bn);
    return FALSE;
  }
  if (*KeySize < (UINTN)Size) {
    *KeySize = Size;
    BN_free (Bn);
    return FALSE;
  }
  *KeySize = Size;
  BN_free (Bn);
  return TRUE;
}