comparison ecc.c @ 759:76fba0856749 ecc

More changes for KEX and ECDH. Set up hash descriptors, make ECC code work, ses.hash and ses.session_id are now buffers (doesn't compile)
author Matt Johnston <matt@ucc.asn.au>
date Fri, 29 Mar 2013 00:28:09 +0800
parents 230666086711
children ac2158e3e403
comparison
equal deleted inserted replaced
758:1c607a62d235 759:76fba0856749
1 #include "includes.h" 1 #include "includes.h"
2 #include "options.h" 2 #include "options.h"
3 #include "ecc.h" 3 #include "ecc.h"
4 #include "dbutil.h"
5 #include "bignum.h"
4 6
5 #ifdef DROPBEAR_ECC 7 #ifdef DROPBEAR_ECC
6 8
7 // TODO: use raw bytes for the dp rather than the hex strings in libtomcrypt's ecc.c 9 // TODO: use raw bytes for the dp rather than the hex strings in libtomcrypt's ecc.c
8 10
9 #ifdef DROPBEAR_ECC_256 11 #ifdef DROPBEAR_ECC_256
10 const struct dropbear_ecc_curve ecc_curve_secp256r1 { 12 const struct dropbear_ecc_curve ecc_curve_secp256r1 = {
11 .dp = &ltc_ecc_sets[0], 13 .dp = &ltc_ecc_sets[0],
12 .hash_desc = sha256_desc, 14 .hash_desc = &sha256_desc,
13 .name = "secp256r1" 15 .name = "secp256r1"
14 }; 16 };
15 #endif 17 #endif
16
17
18 #ifdef DROPBEAR_ECC_384 18 #ifdef DROPBEAR_ECC_384
19 const struct dropbear_ecc_curve ecc_curve_secp384r1 { 19 const struct dropbear_ecc_curve ecc_curve_secp384r1 = {
20 .dp = &ltc_ecc_sets[1], 20 .dp = &ltc_ecc_sets[1],
21 .hash_desc = sha384_desc, 21 .hash_desc = &sha384_desc,
22 .name = "secp384r1" 22 .name = "secp384r1"
23 }; 23 };
24 #endif 24 #endif
25
26 #ifdef DROPBEAR_ECC_521 25 #ifdef DROPBEAR_ECC_521
27 const struct dropbear_ecc_curve ecc_curve_secp521r1 { 26 const struct dropbear_ecc_curve ecc_curve_secp521r1 = {
28 .dp = &ltc_ecc_sets[2], 27 .dp = &ltc_ecc_sets[2],
29 .hash_desc = sha521_desc, 28 .hash_desc = &sha512_desc,
30 .name = "secp521r1" 29 .name = "secp521r1"
31 }; 30 };
32 #endif 31 #endif
33 32
33 static ecc_key * new_ecc_key(void) {
34 ecc_key *key = m_malloc(sizeof(*key));
35 key->pubkey.x = m_malloc(sizeof(mp_int));
36 key->pubkey.y = m_malloc(sizeof(mp_int));
37 key->pubkey.z = m_malloc(sizeof(mp_int));
38 key->k = m_malloc(sizeof(mp_init));
39 m_mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
40 return key;
41 }
34 42
35 void buf_put_ecc_pubkey_string(buffer *buf, ecc_key *key) { 43 void buf_put_ecc_pubkey_string(buffer *buf, ecc_key *key) {
36 // XXX point compression 44 unsigned long len = key->dp->size*2 + 1;
37 int len = key->dp->size*2 + 1; 45 buf_putint(buf, len);
38 buf_putint(len);
39 int err = ecc_ansi_x963_export(key, buf_getwriteptr(buf, len), &len); 46 int err = ecc_ansi_x963_export(key, buf_getwriteptr(buf, len), &len);
40 if (err != CRYPT_OK) { 47 if (err != CRYPT_OK) {
41 dropbear_exit("ECC error"); 48 dropbear_exit("ECC error");
42 } 49 }
43 buf_incrwritepos(buf, len); 50 buf_incrwritepos(buf, len);
44 } 51 }
45 52
46 ecc_key * buf_get_ecc_key_string(buffer *buf, const struct dropbear_ecc_curve *curve) { 53 // Copied from libtomcrypt ecc_import.c (version there is static), modified
54 // for different mp_int pointer without LTC_SOURCE
55 static int ecc_is_point(ecc_key *key)
56 {
57 mp_int *prime, *b, *t1, *t2;
58 int err;
59
60 prime = m_malloc(sizeof(mp_int));
61 b = m_malloc(sizeof(mp_int));
62 t1 = m_malloc(sizeof(mp_int));
63 t2 = m_malloc(sizeof(mp_int));
64
65 m_mp_init_multi(prime, b, t1, t2, NULL);
66
67 /* load prime and b */
68 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
69 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
70
71 /* compute y^2 */
72 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
73
74 /* compute x^3 */
75 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
76 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
77 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
78
79 /* compute y^2 - x^3 */
80 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
81
82 /* compute y^2 - x^3 + 3x */
83 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
84 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
85 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
86 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
87 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
88 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
89 }
90 while (mp_cmp(t1, prime) != LTC_MP_LT) {
91 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
92 }
93
94 /* compare to b */
95 if (mp_cmp(t1, b) != LTC_MP_EQ) {
96 err = CRYPT_INVALID_PACKET;
97 } else {
98 err = CRYPT_OK;
99 }
100
101 error:
102 mp_clear_multi(prime, b, t1, t2, NULL);
103 m_free(prime);
104 m_free(b);
105 m_free(t1);
106 m_free(t2);
107 return err;
108 }
109
110 ecc_key * buf_get_ecc_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve) {
47 ecc_key *key = NULL; 111 ecc_key *key = NULL;
48 int ret = DROPBEAR_FAILURE; 112 int ret = DROPBEAR_FAILURE;
49 const int size = curve->dp->size; 113 const int size = curve->dp->size;
50 unsigned int len = buf_get_string(buf); 114 buf_setpos(buf, 0);
51 unsigned char first = buf_get_char(buf); 115 unsigned int len = buf->len;
116 unsigned char first = buf_getbyte(buf);
52 if (first == 2 || first == 3) { 117 if (first == 2 || first == 3) {
53 dropbear_log("Dropbear doesn't support ECC point compression"); 118 dropbear_log(LOG_WARNING, "Dropbear doesn't support ECC point compression");
54 return NULL; 119 return NULL;
55 } 120 }
56 if (first != 4 || len != 1+2*size) { 121 if (first != 4 || len != 1+2*size) {
57 return NULL; 122 return NULL;
58 } 123 }
59 124
60 key = m_malloc(sizeof(*key)); 125 key = new_ecc_key();
61 m_mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); 126
62 127 if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
63 if (mp_read_unsigned_bin(&key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
64 goto out; 128 goto out;
65 } 129 }
66 buf_incrpos(buf, size); 130 buf_incrpos(buf, size);
67 131
68 if (mp_read_unsigned_bin(&key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) { 132 if (mp_read_unsigned_bin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
69 goto out; 133 goto out;
70 } 134 }
71 buf_incrpos(buf, size); 135 buf_incrpos(buf, size);
72 136
73 if (mp_set(key->pubkey.z, 1) != MP_OKAY) { 137 mp_set(key->pubkey.z, 1);
74 goto out; 138
75 } 139 if (ecc_is_point(key) != CRYPT_OK) {
76
77 if (is_point(key) != CRYPT_OK) {
78 goto out; 140 goto out;
79 } 141 }
80 142
81 // SEC1 3.2.3.1 Check that Q != 0 143 // SEC1 3.2.3.1 Check that Q != 0
82 if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) { 144 if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) {
89 ret = DROPBEAR_SUCCESS; 151 ret = DROPBEAR_SUCCESS;
90 152
91 out: 153 out:
92 if (ret == DROPBEAR_FAILURE) { 154 if (ret == DROPBEAR_FAILURE) {
93 if (key) { 155 if (key) {
94 mp_free_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); 156 ecc_free(key);
95 m_free(key); 157 m_free(key);
96 key = NULL; 158 key = NULL;
97 } 159 }
98 } 160 }
99 161
103 165
104 // a modified version of libtomcrypt's "ecc_shared_secret" to output 166 // a modified version of libtomcrypt's "ecc_shared_secret" to output
105 // a mp_int instead. 167 // a mp_int instead.
106 mp_int * dropbear_ecc_shared_secret(ecc_key *public_key, ecc_key *private_key) 168 mp_int * dropbear_ecc_shared_secret(ecc_key *public_key, ecc_key *private_key)
107 { 169 {
108 ecc_point *result = NULL 170 ecc_point *result = NULL;
109 mp_int *prime = NULL, *shared_secret = NULL; 171 mp_int *prime = NULL, *shared_secret = NULL;
110 int ret = DROPBEAR_FAILURE; 172 int err = DROPBEAR_FAILURE;
111 173
112 /* type valid? */ 174 /* type valid? */
113 if (private_key->type != PK_PRIVATE) { 175 if (private_key->type != PK_PRIVATE) {
114 goto done; 176 goto done;
115 } 177 }
161 if (err == DROPBEAR_FAILURE) { 223 if (err == DROPBEAR_FAILURE) {
162 dropbear_exit("ECC error"); 224 dropbear_exit("ECC error");
163 } 225 }
164 226
165 return shared_secret; 227 return shared_secret;
166 return err; 228 }
167 } 229
168 230 #endif
169 }
170
171 #endif