#include "includes.h"
#include "options.h"
#include "ecc.h"
#include "dbutil.h"
#include "bignum.h"

#if DROPBEAR_ECC

/* .dp members are filled out by dropbear_ecc_fill_dp() at startup */
#if DROPBEAR_ECC_256
struct dropbear_ecc_curve ecc_curve_nistp256 = {
	32,		/* .ltc_size	*/
	NULL,		/* .dp		*/
	&sha256_desc,	/* .hash_desc	*/
	"nistp256"	/* .name	*/
};
#endif
#if DROPBEAR_ECC_384
struct dropbear_ecc_curve ecc_curve_nistp384 = {
	48,		/* .ltc_size	*/
	NULL,		/* .dp		*/
	&sha384_desc,	/* .hash_desc	*/
	"nistp384"	/* .name	*/
};
#endif
#if DROPBEAR_ECC_521
struct dropbear_ecc_curve ecc_curve_nistp521 = {
	66,		/* .ltc_size	*/
	NULL,		/* .dp		*/
	&sha512_desc,	/* .hash_desc	*/
	"nistp521"	/* .name	*/
};
#endif

struct dropbear_ecc_curve *dropbear_ecc_curves[] = {
#if DROPBEAR_ECC_256
	&ecc_curve_nistp256,
#endif
#if DROPBEAR_ECC_384
	&ecc_curve_nistp384,
#endif
#if DROPBEAR_ECC_521
	&ecc_curve_nistp521,
#endif
	NULL
};

void dropbear_ecc_fill_dp() {
	struct dropbear_ecc_curve **curve;
	/* libtomcrypt guarantees they're ordered by size */
	const ltc_ecc_set_type *dp = ltc_ecc_sets;
	for (curve = dropbear_ecc_curves; *curve; curve++) {
		for (;dp->size > 0; dp++) {
			if (dp->size == (*curve)->ltc_size) {
				(*curve)->dp = dp;
				break;
			}
		}
		if (!(*curve)->dp) {
			dropbear_exit("Missing ECC params %s", (*curve)->name);
		}
	}
}

struct dropbear_ecc_curve* curve_for_dp(const ltc_ecc_set_type *dp) {
	struct dropbear_ecc_curve **curve = NULL;
	for (curve = dropbear_ecc_curves; *curve; curve++) {
		if ((*curve)->dp == dp) {
			break;
		}
	}
	assert(*curve);
	return *curve;
}

ecc_key * new_ecc_key(void) {
	ecc_key *key = m_malloc(sizeof(*key));
	m_mp_alloc_init_multi((mp_int**)&key->pubkey.x, (mp_int**)&key->pubkey.y, 
		(mp_int**)&key->pubkey.z, (mp_int**)&key->k, NULL);
	return key;
}

/* Copied from libtomcrypt ecc_import.c (version there is static), modified
   for different mp_int pointer without LTC_SOURCE */
static int ecc_is_point(ecc_key *key)
{
	mp_int *prime, *b, *t1, *t2;
	int err;
	
	m_mp_alloc_init_multi(&prime, &b, &t1, &t2, NULL);
	
   /* load prime and b */
	if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK)                          { goto error; }
	if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK)                                  { goto error; }
	
   /* compute y^2 */
	if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK)                                         { goto error; }
	
   /* compute x^3 */
	if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK)                                         { goto error; }
	if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK)                                             { goto error; }
	if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK)                                     { goto error; }
	
   /* compute y^2 - x^3 */
	if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK)                                                { goto error; }
	
   /* compute y^2 - x^3 + 3x */
	if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
	if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
	if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
	if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK)                                             { goto error; }
	while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
		if ((err = mp_add(t1, prime, t1)) != CRYPT_OK)                                          { goto error; }
	}
	while (mp_cmp(t1, prime) != LTC_MP_LT) {
		if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK)                                          { goto error; }
	}
	
   /* compare to b */
	if (mp_cmp(t1, b) != LTC_MP_EQ) {
		err = CRYPT_INVALID_PACKET;
	} else {
		err = CRYPT_OK;
	}
	
	error:
	mp_clear_multi(prime, b, t1, t2, NULL);
	m_free(prime);
	m_free(b);
	m_free(t1);
	m_free(t2);
	return err;
}

/* For the "ephemeral public key octet string" in ECDH (rfc5656 section 4) */
void buf_put_ecc_raw_pubkey_string(buffer *buf, ecc_key *key) {
	unsigned long len = key->dp->size*2 + 1;
	int err;
	buf_putint(buf, len);
	err = ecc_ansi_x963_export(key, buf_getwriteptr(buf, len), &len);
	if (err != CRYPT_OK) {
		dropbear_exit("ECC error");
	}
	buf_incrwritepos(buf, len);
}

/* For the "ephemeral public key octet string" in ECDH (rfc5656 section 4) */
ecc_key * buf_get_ecc_raw_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve) {
	ecc_key *key = NULL;
	int ret = DROPBEAR_FAILURE;
	const unsigned int size = curve->dp->size;
	unsigned char first;

	TRACE(("enter buf_get_ecc_raw_pubkey"))

	buf_setpos(buf, 0);
	first = buf_getbyte(buf);
	if (first == 2 || first == 3) {
		dropbear_log(LOG_WARNING, "Dropbear doesn't support ECC point compression");
		return NULL;
	}
	if (first != 4 || buf->len != 1+2*size) {
		TRACE(("leave, wrong size"))
		return NULL;
	}

	key = new_ecc_key();
	key->dp = curve->dp;

	if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
		TRACE(("failed to read x"))
		goto out;
	}
	buf_incrpos(buf, size);

	if (mp_read_unsigned_bin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
		TRACE(("failed to read y"))
		goto out;
	}
	buf_incrpos(buf, size);

	mp_set(key->pubkey.z, 1);

	if (ecc_is_point(key) != CRYPT_OK) {
		TRACE(("failed, not a point"))
		goto out;
	}

   /* SEC1 3.2.3.1 Check that Q != 0 */
	if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) {
		TRACE(("failed, x == 0"))
		goto out;
	}
	if (mp_cmp_d(key->pubkey.y, 0) == LTC_MP_EQ) {
		TRACE(("failed, y == 0"))
		goto out;
	}

	ret = DROPBEAR_SUCCESS;

	out:
	if (ret == DROPBEAR_FAILURE) {
		if (key) {
			ecc_free(key);
			m_free(key);
			key = NULL;
		}
	}

	return key;

}

/* a modified version of libtomcrypt's "ecc_shared_secret" to output
   a mp_int instead. */
mp_int * dropbear_ecc_shared_secret(ecc_key *public_key, ecc_key *private_key)
{
	ecc_point *result = NULL;
	mp_int *prime = NULL, *shared_secret = NULL;
	int err = DROPBEAR_FAILURE;

   /* type valid? */
	if (private_key->type != PK_PRIVATE) {
		goto done;
	}

	if (private_key->dp != public_key->dp) {
		goto done;
	}

   /* make new point */
	result = ltc_ecc_new_point();
	if (result == NULL) {
		goto done;
	}

	prime = m_malloc(sizeof(*prime));
	m_mp_init(prime);

	if (mp_read_radix(prime, (char *)private_key->dp->prime, 16) != CRYPT_OK) { 
		goto done; 
	}
	if (ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1) != CRYPT_OK) { 
		goto done; 
	}

	err = DROPBEAR_SUCCESS;
	done:
	if (err == DROPBEAR_SUCCESS) {
		shared_secret = m_malloc(sizeof(*shared_secret));
		m_mp_init(shared_secret);
		mp_copy(result->x, shared_secret);
	}

	if (prime) {
		mp_clear(prime);
		m_free(prime);
	}
	if (result)
	{
		ltc_ecc_del_point(result);
	}

	if (err == DROPBEAR_FAILURE) {
		dropbear_exit("ECC error");
	}
	return shared_secret;
}

#endif
