summaryrefslogtreecommitdiff
path: root/ecc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ecc.c')
-rw-r--r--ecc.c79
1 files changed, 68 insertions, 11 deletions
diff --git a/ecc.c b/ecc.c
index 873a92a..0172516 100644
--- a/ecc.c
+++ b/ecc.c
@@ -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 = &ltc_ecc_sets[0],
+const struct dropbear_ecc_curve ecc_curve_secp256r1 {
+ .dp = &ltc_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 = &ltc_ecc_sets[1],
+const struct dropbear_ecc_curve ecc_curve_secp384r1 {
+ .dp = &ltc_ecc_sets[1],
.hash_desc = sha384_desc,
.name = "secp384r1"
};
#endif
-#ifdef DROPBEAR_ECC_256
-const struct ecc_curve_secp256r1 {
- .ltc_set = &ltc_ecc_sets[0],
- .hash_desc = sha256_desc,
- .name = "secp256r1"
+#ifdef DROPBEAR_ECC_521
+const struct dropbear_ecc_curve ecc_curve_secp521r1 {
+ .dp = &ltc_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