/* If DhContext is NULL, then return FALSE. If PublicKeySize is NULL, then return FALSE. If PublicKeySize is large enough but PublicKey is NULL, then return FALSE. */
BOOLEAN EFIAPI DhGenerateKey(IN OUT VOID *DhContext, OUT UINT8 *PublicKey, IN OUT UINTN *PublicKeySize)
/* If DhContext is NULL, then return FALSE. If PublicKeySize is NULL, then return FALSE. If PublicKeySize is large enough but PublicKey is NULL, then return FALSE. */
BOOLEAN EFIAPI DhGenerateKey(IN OUT VOID *DhContext, OUT UINT8 *PublicKey, IN OUT UINTN *PublicKeySize)
{
  BOOLEAN  RetVal;
  DH       *Dh;
  BIGNUM   *DhPubKey;
  INTN     Size;
  if ((DhContext == NULL) || (PublicKeySize == NULL)) {
    return FALSE;
  }
  if ((PublicKey == NULL) && (*PublicKeySize != 0)) {
    return FALSE;
  }
  Dh = (DH *)DhContext;
  RetVal = (BOOLEAN)DH_generate_key (DhContext);
  if (RetVal) {
    DH_get0_key (Dh, (const BIGNUM **)&DhPubKey, NULL);
    Size = BN_num_bytes (DhPubKey);
    if ((Size > 0) && (*PublicKeySize < (UINTN)Size)) {
      *PublicKeySize = Size;
      return FALSE;
    }
    if (PublicKey != NULL) {
      BN_bn2bin (DhPubKey, PublicKey);
    }
    *PublicKeySize = Size;
  }
  return RetVal;
}