# HG changeset patch # User Matt Johnston # Date 1364399452 -28800 # Node ID 23066608671112d81ea92a40324dd6c651ec449a # Parent bf9dc2d9c2b1f644f4e29c32e84e62efcb7339c9 ecc key import function diff -r bf9dc2d9c2b1 -r 230666086711 common-kex.c --- a/common-kex.c Wed Mar 27 00:38:03 2013 +0800 +++ b/common-kex.c Wed Mar 27 23:50:52 2013 +0800 @@ -678,10 +678,11 @@ // public keys from client and server ecc_key *Q_C, *Q_S, *Q_them; - // XXX load Q_them +oj // XXX load Q_them + Q_them = buf_get_ecc_key_string() - ses.dh_K = dropbear_ecc_shared_secret() - + ses.dh_K = dropbear_ecc_shared_secret(); + /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ if (mp_cmp(dh_pub_them, &dh_p) != MP_LT || mp_cmp_d(dh_pub_them, 0) != MP_GT) { diff -r bf9dc2d9c2b1 -r 230666086711 ecc.c --- a/ecc.c Wed Mar 27 00:38:03 2013 +0800 +++ b/ecc.c Wed Mar 27 23:50:52 2013 +0800 @@ -4,9 +4,11 @@ #ifdef DROPBEAR_ECC +// TODO: use raw bytes for the dp rather than the hex strings in libtomcrypt's ecc.c + #ifdef DROPBEAR_ECC_256 -const struct ecc_curve_secp256r1 { - .ltc_set = <c_ecc_sets[0], +const struct dropbear_ecc_curve ecc_curve_secp256r1 { + .dp = <c_ecc_sets[0], .hash_desc = sha256_desc, .name = "secp256r1" }; @@ -14,23 +16,23 @@ #ifdef DROPBEAR_ECC_384 -const struct ecc_curve_secp384r1 { - .ltc_set = <c_ecc_sets[1], +const struct dropbear_ecc_curve ecc_curve_secp384r1 { + .dp = <c_ecc_sets[1], .hash_desc = sha384_desc, .name = "secp384r1" }; #endif -#ifdef DROPBEAR_ECC_256 -const struct ecc_curve_secp256r1 { - .ltc_set = <c_ecc_sets[0], - .hash_desc = sha256_desc, - .name = "secp256r1" +#ifdef DROPBEAR_ECC_521 +const struct dropbear_ecc_curve ecc_curve_secp521r1 { + .dp = <c_ecc_sets[2], + .hash_desc = sha521_desc, + .name = "secp521r1" }; #endif -void buf_put_ecc_key_string(buffer *buf, ecc_key *key) { +void buf_put_ecc_pubkey_string(buffer *buf, ecc_key *key) { // XXX point compression int len = key->dp->size*2 + 1; buf_putint(len); @@ -41,7 +43,62 @@ buf_incrwritepos(buf, len); } -int buf_get_ecc_key_string(buffer *buf, ecc_key *key) { +ecc_key * buf_get_ecc_key_string(buffer *buf, const struct dropbear_ecc_curve *curve) { + ecc_key *key = NULL; + int ret = DROPBEAR_FAILURE; + const int size = curve->dp->size; + unsigned int len = buf_get_string(buf); + unsigned char first = buf_get_char(buf); + if (first == 2 || first == 3) { + dropbear_log("Dropbear doesn't support ECC point compression"); + return NULL; + } + if (first != 4 || len != 1+2*size) { + return NULL; + } + + key = m_malloc(sizeof(*key)); + m_mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); + + if (mp_read_unsigned_bin(&key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) { + goto out; + } + buf_incrpos(buf, size); + + if (mp_read_unsigned_bin(&key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) { + goto out; + } + buf_incrpos(buf, size); + + if (mp_set(key->pubkey.z, 1) != MP_OKAY) { + goto out; + } + + if (is_point(key) != CRYPT_OK) { + goto out; + } + + // SEC1 3.2.3.1 Check that Q != 0 + if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) { + goto out; + } + if (mp_cmp_d(key->pubkey.y, 0) == LTC_MP_EQ) { + goto out; + } + + ret = DROPBEAR_SUCCESS; + +out: + if (ret == DROPBEAR_FAILURE) { + if (key) { + mp_free_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); + m_free(key); + key = NULL; + } + } + + return key; + } // a modified version of libtomcrypt's "ecc_shared_secret" to output diff -r bf9dc2d9c2b1 -r 230666086711 ecc.h --- a/ecc.h Wed Mar 27 00:38:03 2013 +0800 +++ b/ecc.h Wed Mar 27 23:50:52 2013 +0800 @@ -9,7 +9,7 @@ #ifdef DROPBEAR_ECC struct dropbear_ecc_curve { - const ltc_ecc_set_type* ltc_set; + const ltc_ecc_set_type *dp; // curve domain parameters const struct ltc_hash_descriptor *hash_desc; const char *name; };