/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/dh.h>

#include <openssl/bn.h>
#include <openssl/err.h>

#include "internal.h"

#define OPENSSL_DH_MAX_MODULUS_BITS 10000

static int generate_parameters(DH *ret, int prime_bits, int generator, BN_GENCB *cb) {
  /* We generate DH parameters as follows
   * find a prime q which is prime_bits/2 bits long.
   * p=(2*q)+1 or (p-1)/2 = q
   * For this case, g is a generator if
   * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
   * Since the factors of p-1 are q and 2, we just need to check
   * g^2 mod p != 1 and g^q mod p != 1.
   *
   * Having said all that,
   * there is another special case method for the generators 2, 3 and 5.
   * for 2, p mod 24 == 11
   * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
   * for 5, p mod 10 == 3 or 7
   *
   * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
   * special generators and for answering some of my questions.
   *
   * I've implemented the second simple method :-).
   * Since DH should be using a safe prime (both p and q are prime),
   * this generator function can take a very very long time to run.
   */

  /* Actually there is no reason to insist that 'generator' be a generator.
   * It's just as OK (and in some sense better) to use a generator of the
   * order-q subgroup.
   */

  BIGNUM *t1, *t2;
  int g, ok = 0;
  BN_CTX *ctx = NULL;

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  t1 = BN_CTX_get(ctx);
  t2 = BN_CTX_get(ctx);
  if (t1 == NULL || t2 == NULL) {
    goto err;
  }

  /* Make sure 'ret' has the necessary elements */
  if (!ret->p && ((ret->p = BN_new()) == NULL)) {
    goto err;
  }
  if (!ret->g && ((ret->g = BN_new()) == NULL)) {
    goto err;
  }

  if (generator <= 1) {
    OPENSSL_PUT_ERROR(DH, generate_parameters, DH_R_BAD_GENERATOR);
    goto err;
  }
  if (generator == DH_GENERATOR_2) {
    if (!BN_set_word(t1, 24)) {
      goto err;
    }
    if (!BN_set_word(t2, 11)) {
      goto err;
    }
    g = 2;
  } else if (generator == DH_GENERATOR_5) {
    if (!BN_set_word(t1, 10)) {
      goto err;
    }
    if (!BN_set_word(t2, 3)) {
      goto err;
    }
    /* BN_set_word(t3,7); just have to miss
     * out on these ones :-( */
    g = 5;
  } else {
    /* in the general case, don't worry if 'generator' is a
     * generator or not: since we are using safe primes,
     * it will generate either an order-q or an order-2q group,
     * which both is OK */
    if (!BN_set_word(t1, 2)) {
      goto err;
    }
    if (!BN_set_word(t2, 1)) {
      goto err;
    }
    g = generator;
  }

  if (!BN_generate_prime_ex(ret->p, prime_bits, 1, t1, t2, cb)) {
    goto err;
  }
  if (!BN_GENCB_call(cb, 3, 0)) {
    goto err;
  }
  if (!BN_set_word(ret->g, g)) {
    goto err;
  }
  ok = 1;

err:
  if (!ok) {
    OPENSSL_PUT_ERROR(DH, generate_parameters, ERR_R_BN_LIB);
  }

  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  return ok;
}

static int generate_key(DH *dh) {
  int ok = 0;
  int generate_new_key = 0;
  unsigned l;
  BN_CTX *ctx;
  BN_MONT_CTX *mont = NULL;
  BIGNUM *pub_key = NULL, *priv_key = NULL;
  BIGNUM local_priv;

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }

  if (dh->priv_key == NULL) {
    priv_key = BN_new();
    if (priv_key == NULL) {
      goto err;
    }
    generate_new_key = 1;
  } else {
    priv_key = dh->priv_key;
  }

  if (dh->pub_key == NULL) {
    pub_key = BN_new();
    if (pub_key == NULL) {
      goto err;
    }
  } else {
    pub_key = dh->pub_key;
  }

  mont =
      BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx);
  if (!mont) {
    goto err;
  }

  if (generate_new_key) {
    if (dh->q) {
      do {
        if (!BN_rand_range(priv_key, dh->q)) {
          goto err;
        }
      } while (BN_is_zero(priv_key) || BN_is_one(priv_key));
    } else {
      /* secret exponent length */
      DH_check_standard_parameters(dh);
      l = dh->priv_length ? dh->priv_length : BN_num_bits(dh->p) - 1;
      if (!BN_rand(priv_key, l, 0, 0)) {
        goto err;
      }
    }
  }

  BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME);
  if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) {
    goto err;
  }

  dh->pub_key = pub_key;
  dh->priv_key = priv_key;
  ok = 1;

err:
  if (ok != 1) {
    OPENSSL_PUT_ERROR(DH, generate_key, ERR_R_BN_LIB);
  }

  if (pub_key != NULL && dh->pub_key == NULL) {
    BN_free(pub_key);
  }
  if (priv_key != NULL && dh->priv_key == NULL) {
    BN_free(priv_key);
  }
  BN_CTX_free(ctx);
  return ok;
}

static int compute_key(DH *dh, unsigned char *out, const BIGNUM *pub_key) {
  BN_CTX *ctx = NULL;
  BN_MONT_CTX *mont = NULL;
  BIGNUM *shared_key;
  int ret = -1;
  int check_result;
  BIGNUM local_priv;

  if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
    OPENSSL_PUT_ERROR(DH, compute_key, DH_R_MODULUS_TOO_LARGE);
    goto err;
  }

  ctx = BN_CTX_new();
  if (ctx == NULL) {
    goto err;
  }
  BN_CTX_start(ctx);
  shared_key = BN_CTX_get(ctx);
  if (shared_key == NULL) {
    goto err;
  }

  if (dh->priv_key == NULL) {
    OPENSSL_PUT_ERROR(DH, compute_key, DH_R_NO_PRIVATE_VALUE);
    goto err;
  }

  mont =
      BN_MONT_CTX_set_locked(&dh->method_mont_p, CRYPTO_LOCK_DH, dh->p, ctx);
  if (!mont) {
    goto err;
  }

  if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
    OPENSSL_PUT_ERROR(DH, compute_key, DH_R_INVALID_PUBKEY);
    goto err;
  }

  BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
  if (!BN_mod_exp_mont(shared_key, pub_key, &local_priv, dh->p, ctx,
                       mont)) {
    OPENSSL_PUT_ERROR(DH, compute_key, ERR_R_BN_LIB);
    goto err;
  }

  ret = BN_bn2bin(shared_key, out);

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }

  return ret;
}

const struct dh_method DH_default_method = {
  {
    0 /* references */,
    1 /* is_static */,
  },
  NULL /* app_data */,
  NULL /* init */,
  NULL /* finish */,
  generate_parameters,
  generate_key,
  compute_key,
};
