// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2001-2007, Tom St Denis
 * Copyright (c) 2014, STMicroelectronics International N.V.
 * All rights reserved.
 *
 * 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 above 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER 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.
 */

#include "tomcrypt_private.h"
#include <stdint.h>

/*
 * Make a DH key [private key pair]
 * @param prng     An active PRNG state
 * @param wprng    The index for the PRNG you desire to use
 * @param keysize  The key size (octets) desired of the private key
 * @param q        If not null, then the private key is in the range
 *                 [2, q-2] where q is called the subprime
 * @param xbits    If not 0, then the private key has 'xbits' bits
 * @note           The private key must always be less than p-1
 * @param key      [in/out] Where the newly created DH key will be stored
 *                  g and p are provided as input in the key
 *                  type, x and y are output of this function
 * @return CRYPT_OK if successful, note: on error all allocated memory will be
 *         freed automatically.
*/

int dh_make_key(prng_state *prng, int wprng, void *q, int xbits, dh_key *key)
{
	const int limit = 500;	/* number of tries */
	int err, i;
	int key_size = 0;	/* max key size, in bytes */
	int key_size_p = 0;	/* key size of p */
	int key_size_q = 0;	/* key size of p */
	void *arg_mod;
	uint8_t *buf = 0;	/* intermediate buffer to have a raw random  */
	int found = 0;

	/*
	 * Check the arguments
	 */
	LTC_ARGCHK(key != NULL);
	LTC_ARGCHK(key->base != NULL);
	LTC_ARGCHK(key->prime != NULL);
	err = prng_is_valid(wprng);
	if (err != CRYPT_OK)
		return err;

	/*
	 * Set the key size and check constraints
	 */
	if (xbits) {
		LTC_ARGCHK((xbits % 8) == 0);
		key_size = xbits / 8;
	}
	key_size_p = mp_unsigned_bin_size(key->prime);
	if (q)
		key_size_q = mp_unsigned_bin_size(q);
	if (key_size) {
		/* check the constraints */
		LTC_ARGCHK(key_size <= key_size_p);
		LTC_ARGCHK((q == NULL) || (key_size <= key_size_q));
	} else {
		if (q)
			key_size = MIN(key_size_p, key_size_q);
		else
			key_size =key_size_p;
	}

	/* Set the argument we will make the modulo against to */
	if ((q != NULL) && (key_size_q < key_size_p))
		arg_mod = q;
	else
		arg_mod = key->prime;

	/* initialize the key */
	key->x = NULL;
	key->y = NULL;
	err = mp_init_multi(&key->x, &key->y, NULL);
	if (err != CRYPT_OK)
		goto error;

	/* Initialize the buffer used to store the random number */
	buf = XMALLOC(key_size);
	if (buf == NULL) {
		err = CRYPT_MEM;
		goto error;
	}

	for (i = 0; (i < limit) && (!found); i++) {
		/* generate the private key in a raw-buffer */
		if (prng_descriptor[wprng]->read(buf, key_size, prng) !=
		    (unsigned long)key_size) {
			err = CRYPT_ERROR_READPRNG;
			goto error;
		}

		/* make sure it is on the right number of bits */
		if (xbits)
		      buf[0] |= 0x80;

		/* transform it as a Big Number */
		err = mp_read_unsigned_bin(key->x, buf, key_size);
		if (err != CRYPT_OK)
			goto error;

		/*
		 * Transform it as a Big Number compatible with p and q
		 */
		err = mp_read_unsigned_bin(key->y, buf, key_size);
		if (err != CRYPT_OK)
			goto error;
		err = mp_mod(key->y, arg_mod, key->x);
		if (err != CRYPT_OK)
			goto error;

		/*
		 * Check the constraints
		 * - x < p  is ok by construction
		 * - x < q-1:
		 * - x contains xbits
		 */
		if (xbits) {
			if (mp_count_bits(key->x) != xbits)
				continue;
		}

		/* we found a suitable private key key->x */
		found = 1;
	}

	if (!found) {
		/* key is not found */
		err = CRYPT_ERROR;
		goto error;
	}

	/* generate the public key key->y */
	err = mp_exptmod(key->base, key->x, key->prime, key->y);
	if (err != CRYPT_OK)
		goto error;

	/* no error */
	err = CRYPT_OK;

error:
	if (err != CRYPT_OK)
		mp_clear_multi(key->x, key->y, NULL);
	if (buf)
		XFREE(buf);

	return err;
}
