comparison ecc.c @ 765:5503e05ab3a4 ecc

- Rename buf_put_ecc_pubkey_string() to buf_put_ecc_raw_pubkey_string() - Reindent ecc.c properly
author Matt Johnston <matt@ucc.asn.au>
date Mon, 08 Apr 2013 23:56:31 +0800
parents f744321ac048
children d1575fdc29a6
comparison
equal deleted inserted replaced
764:2202e854d187 765:5503e05ab3a4
29 .name = "nistp521" 29 .name = "nistp521"
30 }; 30 };
31 #endif 31 #endif
32 32
33 static ecc_key * new_ecc_key(void) { 33 static ecc_key * new_ecc_key(void) {
34 ecc_key *key = m_malloc(sizeof(*key)); 34 ecc_key *key = m_malloc(sizeof(*key));
35 key->pubkey.x = m_malloc(sizeof(mp_int)); 35 key->pubkey.x = m_malloc(sizeof(mp_int));
36 key->pubkey.y = m_malloc(sizeof(mp_int)); 36 key->pubkey.y = m_malloc(sizeof(mp_int));
37 key->pubkey.z = m_malloc(sizeof(mp_int)); 37 key->pubkey.z = m_malloc(sizeof(mp_int));
38 key->k = m_malloc(sizeof(mp_int)); 38 key->k = m_malloc(sizeof(mp_int));
39 m_mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); 39 m_mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
40 return key; 40 return key;
41 } 41 }
42 42
43 void buf_put_ecc_pubkey_string(buffer *buf, ecc_key *key) { 43 // Copied from libtomcrypt ecc_import.c (version there is static), modified
44 // for different mp_int pointer without LTC_SOURCE
45 static int ecc_is_point(ecc_key *key)
46 {
47 mp_int *prime, *b, *t1, *t2;
48 int err;
49
50 prime = m_malloc(sizeof(mp_int));
51 b = m_malloc(sizeof(mp_int));
52 t1 = m_malloc(sizeof(mp_int));
53 t2 = m_malloc(sizeof(mp_int));
54
55 m_mp_init_multi(prime, b, t1, t2, NULL);
56
57 /* load prime and b */
58 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
59 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
60
61 /* compute y^2 */
62 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
63
64 /* compute x^3 */
65 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
66 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
67 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
68
69 /* compute y^2 - x^3 */
70 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
71
72 /* compute y^2 - x^3 + 3x */
73 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
74 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
75 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
76 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
77 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
78 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
79 }
80 while (mp_cmp(t1, prime) != LTC_MP_LT) {
81 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
82 }
83
84 /* compare to b */
85 if (mp_cmp(t1, b) != LTC_MP_EQ) {
86 err = CRYPT_INVALID_PACKET;
87 } else {
88 err = CRYPT_OK;
89 }
90
91 error:
92 mp_clear_multi(prime, b, t1, t2, NULL);
93 m_free(prime);
94 m_free(b);
95 m_free(t1);
96 m_free(t2);
97 return err;
98 }
99
100 /* For the "ephemeral public key octet string" in ECDH (rfc5656 section 4) */
101 void buf_put_ecc_raw_pubkey_string(buffer *buf, ecc_key *key) {
44 unsigned long len = key->dp->size*2 + 1; 102 unsigned long len = key->dp->size*2 + 1;
45 buf_putint(buf, len); 103 buf_putint(buf, len);
46 int err = ecc_ansi_x963_export(key, buf_getwriteptr(buf, len), &len); 104 int err = ecc_ansi_x963_export(key, buf_getwriteptr(buf, len), &len);
47 if (err != CRYPT_OK) { 105 if (err != CRYPT_OK) {
48 dropbear_exit("ECC error"); 106 dropbear_exit("ECC error");
49 } 107 }
50 buf_incrwritepos(buf, len); 108 buf_incrwritepos(buf, len);
51 } 109 }
52 110
53 // Copied from libtomcrypt ecc_import.c (version there is static), modified 111 /* For the "ephemeral public key octet string" in ECDH (rfc5656 section 4) */
54 // for different mp_int pointer without LTC_SOURCE 112 ecc_key * buf_get_ecc_raw_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve) {
55 static int ecc_is_point(ecc_key *key) 113 ecc_key *key = NULL;
56 { 114 int ret = DROPBEAR_FAILURE;
57 mp_int *prime, *b, *t1, *t2; 115 const unsigned int size = curve->dp->size;
58 int err; 116 buf_setpos(buf, 0);
59 117 unsigned int len = buf->len;
60 prime = m_malloc(sizeof(mp_int)); 118 unsigned char first = buf_getbyte(buf);
61 b = m_malloc(sizeof(mp_int)); 119 if (first == 2 || first == 3) {
62 t1 = m_malloc(sizeof(mp_int)); 120 dropbear_log(LOG_WARNING, "Dropbear doesn't support ECC point compression");
63 t2 = m_malloc(sizeof(mp_int)); 121 return NULL;
64 122 }
65 m_mp_init_multi(prime, b, t1, t2, NULL); 123 if (first != 4 || len != 1+2*size) {
66 124 return NULL;
67 /* load prime and b */ 125 }
68 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; } 126
69 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; } 127 key = new_ecc_key();
70 128 key->dp = curve->dp;
71 /* compute y^2 */ 129
72 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; } 130 if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
73 131 goto out;
74 /* compute x^3 */ 132 }
75 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; } 133 buf_incrpos(buf, size);
76 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; } 134
77 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; } 135 if (mp_read_unsigned_bin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
78 136 goto out;
79 /* compute y^2 - x^3 */ 137 }
80 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; } 138 buf_incrpos(buf, size);
81 139
82 /* compute y^2 - x^3 + 3x */ 140 mp_set(key->pubkey.z, 1);
83 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } 141
84 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } 142 if (ecc_is_point(key) != CRYPT_OK) {
85 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } 143 goto out;
86 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; } 144 }
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) {
111 ecc_key *key = NULL;
112 int ret = DROPBEAR_FAILURE;
113 const unsigned int size = curve->dp->size;
114 buf_setpos(buf, 0);
115 unsigned int len = buf->len;
116 unsigned char first = buf_getbyte(buf);
117 if (first == 2 || first == 3) {
118 dropbear_log(LOG_WARNING, "Dropbear doesn't support ECC point compression");
119 return NULL;
120 }
121 if (first != 4 || len != 1+2*size) {
122 return NULL;
123 }
124
125 key = new_ecc_key();
126 key->dp = curve->dp;
127
128 if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
129 goto out;
130 }
131 buf_incrpos(buf, size);
132
133 if (mp_read_unsigned_bin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
134 goto out;
135 }
136 buf_incrpos(buf, size);
137
138 mp_set(key->pubkey.z, 1);
139
140 if (ecc_is_point(key) != CRYPT_OK) {
141 goto out;
142 }
143 145
144 // SEC1 3.2.3.1 Check that Q != 0 146 // SEC1 3.2.3.1 Check that Q != 0
145 if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) { 147 if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) {
146 goto out; 148 goto out;
147 } 149 }
148 if (mp_cmp_d(key->pubkey.y, 0) == LTC_MP_EQ) { 150 if (mp_cmp_d(key->pubkey.y, 0) == LTC_MP_EQ) {
149 goto out; 151 goto out;
150 } 152 }
151 153
152 ret = DROPBEAR_SUCCESS; 154 ret = DROPBEAR_SUCCESS;
153 155
154 out: 156 out:
155 if (ret == DROPBEAR_FAILURE) { 157 if (ret == DROPBEAR_FAILURE) {
156 if (key) { 158 if (key) {
157 ecc_free(key); 159 ecc_free(key);
158 m_free(key); 160 m_free(key);
159 key = NULL; 161 key = NULL;
160 } 162 }
161 } 163 }
162 164
163 return key; 165 return key;
164 166
165 } 167 }
166 168
167 // a modified version of libtomcrypt's "ecc_shared_secret" to output 169 // a modified version of libtomcrypt's "ecc_shared_secret" to output
168 // a mp_int instead. 170 // a mp_int instead.
169 mp_int * dropbear_ecc_shared_secret(ecc_key *public_key, ecc_key *private_key) 171 mp_int * dropbear_ecc_shared_secret(ecc_key *public_key, ecc_key *private_key)
170 { 172 {
171 ecc_point *result = NULL; 173 ecc_point *result = NULL;
172 mp_int *prime = NULL, *shared_secret = NULL; 174 mp_int *prime = NULL, *shared_secret = NULL;
173 int err = DROPBEAR_FAILURE; 175 int err = DROPBEAR_FAILURE;
174 176
175 /* type valid? */ 177 /* type valid? */
176 if (private_key->type != PK_PRIVATE) { 178 if (private_key->type != PK_PRIVATE) {
177 goto done; 179 goto done;
178 } 180 }
179 181
180 if (private_key->dp != public_key->dp) { 182 if (private_key->dp != public_key->dp) {
181 goto done; 183 goto done;
182 } 184 }
183 185
184 /* make new point */ 186 /* make new point */
185 result = ltc_ecc_new_point(); 187 result = ltc_ecc_new_point();
186 if (result == NULL) { 188 if (result == NULL) {
187 goto done; 189 goto done;
188 } 190 }
189 191
190 prime = m_malloc(sizeof(*prime)); 192 prime = m_malloc(sizeof(*prime));
191 m_mp_init(prime); 193 m_mp_init(prime);
192 194
193 if (mp_read_radix(prime, (char *)private_key->dp->prime, 16) != CRYPT_OK) { 195 if (mp_read_radix(prime, (char *)private_key->dp->prime, 16) != CRYPT_OK) {
194 goto done; 196 goto done;
195 } 197 }
196 if (ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1) != CRYPT_OK) { 198 if (ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1) != CRYPT_OK) {
197 goto done; 199 goto done;
198 } 200 }
199 201
200 err = DROPBEAR_SUCCESS; 202 err = DROPBEAR_SUCCESS;
201 done: 203 done:
202 if (err == DROPBEAR_SUCCESS) { 204 if (err == DROPBEAR_SUCCESS) {
203 shared_secret = m_malloc(sizeof(*shared_secret)); 205 shared_secret = m_malloc(sizeof(*shared_secret));
204 m_mp_init(shared_secret); 206 m_mp_init(shared_secret);
205 mp_copy(result->x, shared_secret); 207 mp_copy(result->x, shared_secret);
206 } 208 }
207 209
208 if (prime) { 210 if (prime) {
209 mp_clear(prime); 211 mp_clear(prime);
210 m_free(prime); 212 m_free(prime);
211 } 213 }
212 if (result) 214 if (result)
213 { 215 {
214 ltc_ecc_del_point(result); 216 ltc_ecc_del_point(result);
215 } 217 }
216 218
217 if (err == DROPBEAR_FAILURE) { 219 if (err == DROPBEAR_FAILURE) {
218 dropbear_exit("ECC error"); 220 dropbear_exit("ECC error");
219 } 221 }
220 return shared_secret; 222 return shared_secret;
221 } 223 }
222 224
223 #endif 225 #endif