summaryrefslogtreecommitdiffhomepage
path: root/common-kex.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2013-11-08 23:11:43 +0800
committerMatt Johnston <matt@ucc.asn.au>2013-11-08 23:11:43 +0800
commit0162c116da2ce2d546cb6b6523b659d10f460d33 (patch)
tree3689163e79d631171074c9bc0b85660d7e903b4b /common-kex.c
parentcfac8435a73cddbc54a70ab07418b0bdb900fc10 (diff)
curve25519
--HG-- branch : ecc
Diffstat (limited to 'common-kex.c')
-rw-r--r--common-kex.c72
1 files changed, 68 insertions, 4 deletions
diff --git a/common-kex.c b/common-kex.c
index a32ca6d..8e3d1fc 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -690,8 +690,8 @@ void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them,
ses.dh_K = dropbear_ecc_shared_secret(Q_them, &param->key);
- /* From here on, the code needs to work with the _same_ vars on each side,
- * not vice-versaing for client/server */
+ /* Create the remainder of the hash buffer, to generate the exchange hash
+ See RFC5656 section 4 page 7 */
if (IS_DROPBEAR_CLIENT) {
Q_C = &param->key;
Q_S = Q_them;
@@ -700,7 +700,6 @@ void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them,
Q_S = &param->key;
}
- /* Create the remainder of the hash buffer, to generate the exchange hash */
/* K_S, the host key */
buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
/* Q_C, client's ephemeral public key octet string */
@@ -713,7 +712,72 @@ void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them,
/* calculate the hash H to sign */
finish_kexhashbuf();
}
-#endif
+#endif /* DROPBEAR_ECDH */
+
+#ifdef DROPBEAR_CURVE25519
+struct kex_curve25519_param *gen_kexcurve25519_param () {
+ /* Per http://cr.yp.to/ecdh.html */
+ struct kex_curve25519_param *param = m_malloc(sizeof(*param));
+ const unsigned char basepoint[32] = {9};
+
+ genrandom(param->priv, CURVE25519_LEN);
+ param->priv[0] &= 248;
+ param->priv[31] &= 127;
+ param->priv[31] |= 64;
+
+ curve25519_donna(param->pub, param->priv, basepoint);
+
+ return param;
+}
+
+void free_kexcurve25519_param(struct kex_curve25519_param *param)
+{
+ m_burn(param->priv, CURVE25519_LEN);
+ m_free(param);
+}
+
+void kexcurve25519_comb_key(struct kex_curve25519_param *param, buffer *buf_pub_them,
+ sign_key *hostkey) {
+ unsigned char* out = m_malloc(CURVE25519_LEN);
+ const unsigned char* Q_C = NULL;
+ const unsigned char* Q_S = NULL;
+
+ if (buf_pub_them->len != CURVE25519_LEN)
+ {
+ dropbear_exit("Bad curve25519");
+ }
+
+ curve25519_donna(out, param->priv, buf_pub_them->data);
+ ses.dh_K = m_malloc(sizeof(*ses.dh_K));
+ m_mp_init(ses.dh_K);
+ bytes_to_mp(ses.dh_K, out, CURVE25519_LEN);
+ m_free(out);
+
+ /* Create the remainder of the hash buffer, to generate the exchange hash.
+ See RFC5656 section 4 page 7 */
+ if (IS_DROPBEAR_CLIENT) {
+ Q_C = param->pub;
+ Q_S = buf_pub_them->data;
+ } else {
+ Q_S = param->pub;
+ Q_C = buf_pub_them->data;
+ }
+
+ /* K_S, the host key */
+ buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
+ /* Q_C, client's ephemeral public key octet string */
+ buf_putstring(ses.kexhashbuf, Q_C, CURVE25519_LEN);
+ /* Q_S, server's ephemeral public key octet string */
+ buf_putstring(ses.kexhashbuf, Q_S, CURVE25519_LEN);
+ /* K, the shared secret */
+ buf_putmpint(ses.kexhashbuf, ses.dh_K);
+
+ /* calculate the hash H to sign */
+ finish_kexhashbuf();
+}
+#endif /* DROPBEAR_CURVE25519 */
+
+
static void finish_kexhashbuf(void) {
hash_state hs;