Mercurial > dropbear
diff ecc.c @ 757:230666086711 ecc
ecc key import function
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 27 Mar 2013 23:50:52 +0800 |
parents | bf9dc2d9c2b1 |
children | 76fba0856749 |
line wrap: on
line diff
--- 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