#include "options.h"
#include "includes.h"
#include "dbutil.h"
#include "crypto_desc.h"
#include "ecc.h"
#include "ecdsa.h"
#include "signkey.h"

#ifdef DROPBEAR_ECDSA

int signkey_is_ecdsa(enum signkey_type type)
{
	return type == DROPBEAR_SIGNKEY_ECDSA_NISTP256
		|| type == DROPBEAR_SIGNKEY_ECDSA_NISTP384
		|| type == DROPBEAR_SIGNKEY_ECDSA_NISTP521;
}

enum signkey_type ecdsa_signkey_type(ecc_key * key) {
#ifdef DROPBEAR_ECC_256
	if (key->dp == ecc_curve_nistp256.dp) {
		return DROPBEAR_SIGNKEY_ECDSA_NISTP256;
	}
#endif
#ifdef DROPBEAR_ECC_384
	if (key->dp == ecc_curve_nistp384.dp) {
		return DROPBEAR_SIGNKEY_ECDSA_NISTP384;
	}
#endif
#ifdef DROPBEAR_ECC_521
	if (key->dp == ecc_curve_nistp521.dp) {
		return DROPBEAR_SIGNKEY_ECDSA_NISTP521;
	}
#endif
	return DROPBEAR_SIGNKEY_NONE;
}

ecc_key *gen_ecdsa_priv_key(unsigned int bit_size) {
	const ltc_ecc_set_type *dp = NULL; /* curve domain parameters */
	ecc_key *new_key = NULL;
	switch (bit_size) {
#ifdef DROPBEAR_ECC_256
		case 256:
			dp = ecc_curve_nistp256.dp;
			break;
#endif
#ifdef DROPBEAR_ECC_384
		case 384:
			dp = ecc_curve_nistp384.dp;
			break;
#endif
#ifdef DROPBEAR_ECC_521
		case 521:
			dp = ecc_curve_nistp521.dp;
			break;
#endif
	}
	if (!dp) {
		dropbear_exit("Key size %d isn't valid. Try "
#ifdef DROPBEAR_ECC_256
			"256 "
#endif
#ifdef DROPBEAR_ECC_384
			"384 "
#endif
#ifdef DROPBEAR_ECC_521
			"521 "
#endif
			, bit_size);
	}

	new_key = m_malloc(sizeof(*new_key));
	if (ecc_make_key_ex(NULL, dropbear_ltc_prng, new_key, dp) != CRYPT_OK) {
		dropbear_exit("ECC error");
	}
	return new_key;
}

ecc_key *buf_get_ecdsa_pub_key(buffer* buf) {
	unsigned char *key_ident = NULL, *identifier = NULL;
	unsigned int key_ident_len, identifier_len;
	buffer *q_buf = NULL;
	struct dropbear_ecc_curve **curve;
	ecc_key *new_key = NULL;

	/* string   "ecdsa-sha2-[identifier]" */
	key_ident = buf_getstring(buf, &key_ident_len);
	/* string   "[identifier]" */
	identifier = buf_getstring(buf, &identifier_len);

	if (key_ident_len != identifier_len + strlen("ecdsa-sha2-")) {
		TRACE(("Bad identifier lengths"))
		goto out;
	}
	if (memcmp(&key_ident[strlen("ecdsa-sha2-")], identifier, identifier_len) != 0) {
		TRACE(("mismatching identifiers"))
		goto out;
	}

	for (curve = dropbear_ecc_curves; *curve; curve++) {
		if (memcmp(identifier, (char*)(*curve)->name, strlen((char*)(*curve)->name)) == 0) {
			break;
		}
	}
	if (!*curve) {
		TRACE(("couldn't match ecc curve"))
		goto out;
	}

	/* string Q */
	q_buf = buf_getstringbuf(buf);
	new_key = buf_get_ecc_raw_pubkey(q_buf, *curve);

out:
	m_free(key_ident);
	m_free(identifier);
	if (q_buf) {
		buf_free(q_buf);
		q_buf = NULL;
	}
	TRACE(("leave buf_get_ecdsa_pub_key"))	
	return new_key;
}

ecc_key *buf_get_ecdsa_priv_key(buffer *buf) {
	ecc_key *new_key = NULL;
	TRACE(("enter buf_get_ecdsa_priv_key"))
	new_key = buf_get_ecdsa_pub_key(buf);
	if (!new_key) {
		return NULL;
	}

	if (buf_getmpint(buf, new_key->k) != DROPBEAR_SUCCESS) {
		ecc_free(new_key);
		return NULL;
	}

	return new_key;
}

void buf_put_ecdsa_pub_key(buffer *buf, ecc_key *key) {
	struct dropbear_ecc_curve *curve = NULL;
	unsigned char key_ident[30];

	curve = curve_for_dp(key->dp);
	snprintf((char*)key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name);
	buf_putstring(buf, key_ident, strlen(key_ident));
	buf_putstring(buf, curve->name, strlen(curve->name));
	buf_put_ecc_raw_pubkey_string(buf, key);
}

void buf_put_ecdsa_priv_key(buffer *buf, ecc_key *key) {
	buf_put_ecdsa_pub_key(buf, key);
	buf_putmpint(buf, key->k);
}

void buf_put_ecdsa_sign(buffer *buf, ecc_key *key, buffer *data_buf) {
	/* Based on libtomcrypt's ecc_sign_hash but without the asn1 */
	int err = DROPBEAR_FAILURE;
	struct dropbear_ecc_curve *curve = NULL;
	hash_state hs;
	unsigned char hash[64];
	void *e = NULL, *p = NULL, *s = NULL, *r;
	unsigned char key_ident[30];
	buffer *sigbuf = NULL;

	TRACE(("buf_put_ecdsa_sign"))
	curve = curve_for_dp(key->dp);

	if (ltc_init_multi(&r, &s, &p, &e, NULL) != CRYPT_OK) { 
		goto out;
	}

	curve->hash_desc->init(&hs);
	curve->hash_desc->process(&hs, data_buf->data, data_buf->len);
	curve->hash_desc->done(&hs, hash);

	if (ltc_mp.unsigned_read(e, hash, curve->hash_desc->hashsize) != CRYPT_OK) {
		goto out;
	}

	if (ltc_mp.read_radix(p, (char *)key->dp->order, 16) != CRYPT_OK) { 
		goto out; 
	}

	for (;;) {
		ecc_key R_key; /* ephemeral key */
		if (ecc_make_key_ex(NULL, dropbear_ltc_prng, &R_key, key->dp) != CRYPT_OK) {
			goto out;
		}
		if (ltc_mp.mpdiv(R_key.pubkey.x, p, NULL, r) != CRYPT_OK) {
			goto out;
		}
		if (ltc_mp.compare_d(r, 0) == LTC_MP_EQ) {
			/* try again */
			ecc_free(&R_key);
			continue;
		}
		/* k = 1/k */
		if (ltc_mp.invmod(R_key.k, p, R_key.k) != CRYPT_OK) {
			goto out;
		}
		/* s = xr */
		if (ltc_mp.mulmod(key->k, r, p, s) != CRYPT_OK) {
			goto out;
		}
		/* s = e +  xr */
		if (ltc_mp.add(e, s, s) != CRYPT_OK) {
			goto out;
		}
		if (ltc_mp.mpdiv(s, p, NULL, s) != CRYPT_OK) {
			goto out;
		}
		/* s = (e + xr)/k */
		if (ltc_mp.mulmod(s, R_key.k, p, s) != CRYPT_OK) {
			goto out;
		}
		ecc_free(&R_key);

		if (ltc_mp.compare_d(s, 0) != LTC_MP_EQ) {
			break;
		}
	}

	snprintf((char*)key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name);
	buf_putstring(buf, key_ident, strlen(key_ident));
	/* enough for nistp521 */
	sigbuf = buf_new(200);
	buf_putmpint(sigbuf, (mp_int*)r);
	buf_putmpint(sigbuf, (mp_int*)s);
	buf_putbufstring(buf, sigbuf);

	err = DROPBEAR_SUCCESS;

out:
	if (r && s && p && e) {
		ltc_deinit_multi(r, s, p, e, NULL);
	}

	if (sigbuf) {
		buf_free(sigbuf);
	}

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

/* returns values in s and r
   returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
static int buf_get_ecdsa_verify_params(buffer *buf,
			void *r, void* s) {
	int ret = DROPBEAR_FAILURE;
	unsigned int sig_len;
	unsigned int sig_pos;

	sig_len = buf_getint(buf);
	sig_pos = buf->pos;
	if (buf_getmpint(buf, r) != DROPBEAR_SUCCESS) {
		goto out;
	}
	if (buf_getmpint(buf, s) != DROPBEAR_SUCCESS) {
		goto out;
	}
	if (buf->pos - sig_pos != sig_len) {
		goto out;
	}
	ret = DROPBEAR_SUCCESS;

out:
	return ret;
}


int buf_ecdsa_verify(buffer *buf, ecc_key *key, buffer *data_buf) {
	/* Based on libtomcrypt's ecc_verify_hash but without the asn1 */
	int ret = DROPBEAR_FAILURE;
	hash_state hs;
	struct dropbear_ecc_curve *curve = NULL;
	unsigned char hash[64];
	ecc_point *mG = NULL, *mQ = NULL;
	void *r = NULL, *s = NULL, *v = NULL, *w = NULL, *u1 = NULL, *u2 = NULL, 
		*e = NULL, *p = NULL, *m = NULL;
	void *mp = NULL;

	/* verify 
	 *
	 * w  = s^-1 mod n
	 * u1 = xw 
	 * u2 = rw
	 * X = u1*G + u2*Q
	 * v = X_x1 mod n
	 * accept if v == r
	 */

	TRACE(("buf_ecdsa_verify"))
	curve = curve_for_dp(key->dp);

	mG = ltc_ecc_new_point();
	mQ = ltc_ecc_new_point();
	if (ltc_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL) != CRYPT_OK
		|| !mG
		|| !mQ) {
		dropbear_exit("ECC error");
	}

	if (buf_get_ecdsa_verify_params(buf, r, s) != DROPBEAR_SUCCESS) {
		goto out;
	}

	curve->hash_desc->init(&hs);
	curve->hash_desc->process(&hs, data_buf->data, data_buf->len);
	curve->hash_desc->done(&hs, hash);

	if (ltc_mp.unsigned_read(e, hash, curve->hash_desc->hashsize) != CRYPT_OK) {
		goto out;
	}

   /* get the order */
	if (ltc_mp.read_radix(p, (char *)key->dp->order, 16) != CRYPT_OK) { 
		goto out; 
	}

   /* get the modulus */
	if (ltc_mp.read_radix(m, (char *)key->dp->prime, 16) != CRYPT_OK) { 
		goto out; 
	}

   /* check for zero */
	if (ltc_mp.compare_d(r, 0) == LTC_MP_EQ 
		|| ltc_mp.compare_d(s, 0) == LTC_MP_EQ 
		|| ltc_mp.compare(r, p) != LTC_MP_LT 
		|| ltc_mp.compare(s, p) != LTC_MP_LT) {
		goto out;
	}

   /*  w  = s^-1 mod n */
	if (ltc_mp.invmod(s, p, w) != CRYPT_OK) { 
		goto out; 
	}

   /* u1 = ew */
	if (ltc_mp.mulmod(e, w, p, u1) != CRYPT_OK) { 
		goto out; 
	}

   /* u2 = rw */
	if (ltc_mp.mulmod(r, w, p, u2) != CRYPT_OK) { 
		goto out; 
	}

   /* find mG and mQ */
	if (ltc_mp.read_radix(mG->x, (char *)key->dp->Gx, 16) != CRYPT_OK) { 
		goto out; 
	}
	if (ltc_mp.read_radix(mG->y, (char *)key->dp->Gy, 16) != CRYPT_OK) { 
		goto out; 
	}
	if (ltc_mp.set_int(mG->z, 1) != CRYPT_OK) { 
		goto out; 
	}

	if (ltc_mp.copy(key->pubkey.x, mQ->x) != CRYPT_OK
		|| ltc_mp.copy(key->pubkey.y, mQ->y) != CRYPT_OK
		|| ltc_mp.copy(key->pubkey.z, mQ->z) != CRYPT_OK) { 
		goto out; 
	}

   /* compute u1*mG + u2*mQ = mG */
	if (ltc_mp.ecc_mul2add == NULL) {
		if (ltc_mp.ecc_ptmul(u1, mG, mG, m, 0) != CRYPT_OK) { 
			goto out; 
		}
		if (ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0) != CRYPT_OK) {
			goto out; 
		}

		/* find the montgomery mp */
		if (ltc_mp.montgomery_setup(m, &mp) != CRYPT_OK) { 
			goto out; 
		}

		/* add them */
		if (ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp) != CRYPT_OK) { 
			goto out; 
		}

    	/* reduce */
		if (ltc_mp.ecc_map(mG, m, mp) != CRYPT_OK) { 
			goto out; 
		}
	} else {
      /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
		if (ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m) != CRYPT_OK) { 
			goto out; 
		}
	}

   /* v = X_x1 mod n */
	if (ltc_mp.mpdiv(mG->x, p, NULL, v) != CRYPT_OK) { 
		goto out; 
	}

   /* does v == r */
	if (ltc_mp.compare(v, r) == LTC_MP_EQ) {
		ret = DROPBEAR_SUCCESS;
	}

out:
	ltc_ecc_del_point(mG);
	ltc_ecc_del_point(mQ);
	mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
	if (mp != NULL) { 
		ltc_mp.montgomery_deinit(mp);
	}
	return ret;
}



#endif /* DROPBEAR_ECDSA */
