diff options
author | Matt Johnston <matt@ucc.asn.au> | 2013-03-27 23:50:52 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2013-03-27 23:50:52 +0800 |
commit | cf7a271f90c2cc6970a02264a6dca9799984d3c6 (patch) | |
tree | 03f3d234bfe1d28d7fce63ccdd13ac9511ab0ae6 /ecc.c | |
parent | 74cad1612f577fd067ca900ab06517c2a260bbe8 (diff) |
ecc key import function
--HG--
branch : ecc
Diffstat (limited to 'ecc.c')
-rw-r--r-- | ecc.c | 79 |
1 files changed, 68 insertions, 11 deletions
@@ -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 @@ const struct ecc_curve_secp256r1 { #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 @@ void buf_put_ecc_key_string(buffer *buf, ecc_key *key) { 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 |