4 #include "crypto_desc.h"
11 int signkey_is_ecdsa(enum signkey_type type
)
13 return type
== DROPBEAR_SIGNKEY_ECDSA_NISTP256
14 || type
== DROPBEAR_SIGNKEY_ECDSA_NISTP384
15 || type
== DROPBEAR_SIGNKEY_ECDSA_NISTP521
;
18 enum signkey_type
ecdsa_signkey_type(ecc_key
* key
) {
19 #ifdef DROPBEAR_ECC_256
20 if (key
->dp
== ecc_curve_nistp256
.dp
) {
21 return DROPBEAR_SIGNKEY_ECDSA_NISTP256
;
24 #ifdef DROPBEAR_ECC_384
25 if (key
->dp
== ecc_curve_nistp384
.dp
) {
26 return DROPBEAR_SIGNKEY_ECDSA_NISTP384
;
29 #ifdef DROPBEAR_ECC_521
30 if (key
->dp
== ecc_curve_nistp521
.dp
) {
31 return DROPBEAR_SIGNKEY_ECDSA_NISTP521
;
34 return DROPBEAR_SIGNKEY_NONE
;
37 ecc_key
*gen_ecdsa_priv_key(unsigned int bit_size
) {
38 const ltc_ecc_set_type
*dp
= NULL
; /* curve domain parameters */
39 ecc_key
*new_key
= NULL
;
41 #ifdef DROPBEAR_ECC_256
43 dp
= ecc_curve_nistp256
.dp
;
46 #ifdef DROPBEAR_ECC_384
48 dp
= ecc_curve_nistp384
.dp
;
51 #ifdef DROPBEAR_ECC_521
53 dp
= ecc_curve_nistp521
.dp
;
58 dropbear_exit("Key size %d isn't valid. Try "
59 #ifdef DROPBEAR_ECC_256
62 #ifdef DROPBEAR_ECC_384
65 #ifdef DROPBEAR_ECC_521
71 new_key
= m_malloc(sizeof(*new_key
));
72 if (ecc_make_key_ex(NULL
, dropbear_ltc_prng
, new_key
, dp
) != CRYPT_OK
) {
73 dropbear_exit("ECC error");
78 ecc_key
*buf_get_ecdsa_pub_key(buffer
* buf
) {
79 unsigned char *key_ident
= NULL
, *identifier
= NULL
;
80 unsigned int key_ident_len
, identifier_len
;
82 struct dropbear_ecc_curve
**curve
;
83 ecc_key
*new_key
= NULL
;
85 /* string "ecdsa-sha2-[identifier]" */
86 key_ident
= (unsigned char*)buf_getstring(buf
, &key_ident_len
);
87 /* string "[identifier]" */
88 identifier
= (unsigned char*)buf_getstring(buf
, &identifier_len
);
90 if (key_ident_len
!= identifier_len
+ strlen("ecdsa-sha2-")) {
91 TRACE(("Bad identifier lengths"))
94 if (memcmp(&key_ident
[strlen("ecdsa-sha2-")], identifier
, identifier_len
) != 0) {
95 TRACE(("mismatching identifiers"))
99 for (curve
= dropbear_ecc_curves
; *curve
; curve
++) {
100 if (memcmp(identifier
, (char*)(*curve
)->name
, strlen((char*)(*curve
)->name
)) == 0) {
105 TRACE(("couldn't match ecc curve"))
110 q_buf
= buf_getstringbuf(buf
);
111 new_key
= buf_get_ecc_raw_pubkey(q_buf
, *curve
);
120 TRACE(("leave buf_get_ecdsa_pub_key"))
124 ecc_key
*buf_get_ecdsa_priv_key(buffer
*buf
) {
125 ecc_key
*new_key
= NULL
;
126 TRACE(("enter buf_get_ecdsa_priv_key"))
127 new_key
= buf_get_ecdsa_pub_key(buf
);
132 if (buf_getmpint(buf
, new_key
->k
) != DROPBEAR_SUCCESS
) {
141 void buf_put_ecdsa_pub_key(buffer
*buf
, ecc_key
*key
) {
142 struct dropbear_ecc_curve
*curve
= NULL
;
145 curve
= curve_for_dp(key
->dp
);
146 snprintf(key_ident
, sizeof(key_ident
), "ecdsa-sha2-%s", curve
->name
);
147 buf_putstring(buf
, key_ident
, strlen(key_ident
));
148 buf_putstring(buf
, curve
->name
, strlen(curve
->name
));
149 buf_put_ecc_raw_pubkey_string(buf
, key
);
152 void buf_put_ecdsa_priv_key(buffer
*buf
, ecc_key
*key
) {
153 buf_put_ecdsa_pub_key(buf
, key
);
154 buf_putmpint(buf
, key
->k
);
157 void buf_put_ecdsa_sign(buffer
*buf
, ecc_key
*key
, buffer
*data_buf
) {
158 /* Based on libtomcrypt's ecc_sign_hash but without the asn1 */
159 int err
= DROPBEAR_FAILURE
;
160 struct dropbear_ecc_curve
*curve
= NULL
;
162 unsigned char hash
[64];
163 void *e
= NULL
, *p
= NULL
, *s
= NULL
, *r
;
165 buffer
*sigbuf
= NULL
;
167 TRACE(("buf_put_ecdsa_sign"))
168 curve
= curve_for_dp(key
->dp
);
170 if (ltc_init_multi(&r
, &s
, &p
, &e
, NULL
) != CRYPT_OK
) {
174 curve
->hash_desc
->init(&hs
);
175 curve
->hash_desc
->process(&hs
, data_buf
->data
, data_buf
->len
);
176 curve
->hash_desc
->done(&hs
, hash
);
178 if (ltc_mp
.unsigned_read(e
, hash
, curve
->hash_desc
->hashsize
) != CRYPT_OK
) {
182 if (ltc_mp
.read_radix(p
, (char *)key
->dp
->order
, 16) != CRYPT_OK
) {
187 ecc_key R_key
; /* ephemeral key */
188 if (ecc_make_key_ex(NULL
, dropbear_ltc_prng
, &R_key
, key
->dp
) != CRYPT_OK
) {
191 if (ltc_mp
.mpdiv(R_key
.pubkey
.x
, p
, NULL
, r
) != CRYPT_OK
) {
194 if (ltc_mp
.compare_d(r
, 0) == LTC_MP_EQ
) {
200 if (ltc_mp
.invmod(R_key
.k
, p
, R_key
.k
) != CRYPT_OK
) {
204 if (ltc_mp
.mulmod(key
->k
, r
, p
, s
) != CRYPT_OK
) {
208 if (ltc_mp
.add(e
, s
, s
) != CRYPT_OK
) {
211 if (ltc_mp
.mpdiv(s
, p
, NULL
, s
) != CRYPT_OK
) {
215 if (ltc_mp
.mulmod(s
, R_key
.k
, p
, s
) != CRYPT_OK
) {
220 if (ltc_mp
.compare_d(s
, 0) != LTC_MP_EQ
) {
225 snprintf(key_ident
, sizeof(key_ident
), "ecdsa-sha2-%s", curve
->name
);
226 buf_putstring(buf
, key_ident
, strlen(key_ident
));
227 /* enough for nistp521 */
228 sigbuf
= buf_new(200);
229 buf_putmpint(sigbuf
, (mp_int
*)r
);
230 buf_putmpint(sigbuf
, (mp_int
*)s
);
231 buf_putbufstring(buf
, sigbuf
);
233 err
= DROPBEAR_SUCCESS
;
236 if (r
&& s
&& p
&& e
) {
237 ltc_deinit_multi(r
, s
, p
, e
, NULL
);
244 if (err
== DROPBEAR_FAILURE
) {
245 dropbear_exit("ECC error");
249 /* returns values in s and r
250 returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
251 static int buf_get_ecdsa_verify_params(buffer
*buf
,
253 int ret
= DROPBEAR_FAILURE
;
254 unsigned int sig_len
;
255 unsigned int sig_pos
;
257 sig_len
= buf_getint(buf
);
259 if (buf_getmpint(buf
, r
) != DROPBEAR_SUCCESS
) {
262 if (buf_getmpint(buf
, s
) != DROPBEAR_SUCCESS
) {
265 if (buf
->pos
- sig_pos
!= sig_len
) {
268 ret
= DROPBEAR_SUCCESS
;
275 int buf_ecdsa_verify(buffer
*buf
, ecc_key
*key
, buffer
*data_buf
) {
276 /* Based on libtomcrypt's ecc_verify_hash but without the asn1 */
277 int ret
= DROPBEAR_FAILURE
;
279 struct dropbear_ecc_curve
*curve
= NULL
;
280 unsigned char hash
[64];
281 ecc_point
*mG
= NULL
, *mQ
= NULL
;
282 void *r
= NULL
, *s
= NULL
, *v
= NULL
, *w
= NULL
, *u1
= NULL
, *u2
= NULL
,
283 *e
= NULL
, *p
= NULL
, *m
= NULL
;
296 TRACE(("buf_ecdsa_verify"))
297 curve
= curve_for_dp(key
->dp
);
299 mG
= ltc_ecc_new_point();
300 mQ
= ltc_ecc_new_point();
301 if (ltc_init_multi(&r
, &s
, &v
, &w
, &u1
, &u2
, &p
, &e
, &m
, NULL
) != CRYPT_OK
304 dropbear_exit("ECC error");
307 if (buf_get_ecdsa_verify_params(buf
, r
, s
) != DROPBEAR_SUCCESS
) {
311 curve
->hash_desc
->init(&hs
);
312 curve
->hash_desc
->process(&hs
, data_buf
->data
, data_buf
->len
);
313 curve
->hash_desc
->done(&hs
, hash
);
315 if (ltc_mp
.unsigned_read(e
, hash
, curve
->hash_desc
->hashsize
) != CRYPT_OK
) {
320 if (ltc_mp
.read_radix(p
, (char *)key
->dp
->order
, 16) != CRYPT_OK
) {
324 /* get the modulus */
325 if (ltc_mp
.read_radix(m
, (char *)key
->dp
->prime
, 16) != CRYPT_OK
) {
330 if (ltc_mp
.compare_d(r
, 0) == LTC_MP_EQ
331 || ltc_mp
.compare_d(s
, 0) == LTC_MP_EQ
332 || ltc_mp
.compare(r
, p
) != LTC_MP_LT
333 || ltc_mp
.compare(s
, p
) != LTC_MP_LT
) {
338 if (ltc_mp
.invmod(s
, p
, w
) != CRYPT_OK
) {
343 if (ltc_mp
.mulmod(e
, w
, p
, u1
) != CRYPT_OK
) {
348 if (ltc_mp
.mulmod(r
, w
, p
, u2
) != CRYPT_OK
) {
353 if (ltc_mp
.read_radix(mG
->x
, (char *)key
->dp
->Gx
, 16) != CRYPT_OK
) {
356 if (ltc_mp
.read_radix(mG
->y
, (char *)key
->dp
->Gy
, 16) != CRYPT_OK
) {
359 if (ltc_mp
.set_int(mG
->z
, 1) != CRYPT_OK
) {
363 if (ltc_mp
.copy(key
->pubkey
.x
, mQ
->x
) != CRYPT_OK
364 || ltc_mp
.copy(key
->pubkey
.y
, mQ
->y
) != CRYPT_OK
365 || ltc_mp
.copy(key
->pubkey
.z
, mQ
->z
) != CRYPT_OK
) {
369 /* compute u1*mG + u2*mQ = mG */
370 if (ltc_mp
.ecc_mul2add
== NULL
) {
371 if (ltc_mp
.ecc_ptmul(u1
, mG
, mG
, m
, 0) != CRYPT_OK
) {
374 if (ltc_mp
.ecc_ptmul(u2
, mQ
, mQ
, m
, 0) != CRYPT_OK
) {
378 /* find the montgomery mp */
379 if (ltc_mp
.montgomery_setup(m
, &mp
) != CRYPT_OK
) {
384 if (ltc_mp
.ecc_ptadd(mQ
, mG
, mG
, m
, mp
) != CRYPT_OK
) {
389 if (ltc_mp
.ecc_map(mG
, m
, mp
) != CRYPT_OK
) {
393 /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
394 if (ltc_mp
.ecc_mul2add(mG
, u1
, mQ
, u2
, mG
, m
) != CRYPT_OK
) {
400 if (ltc_mp
.mpdiv(mG
->x
, p
, NULL
, v
) != CRYPT_OK
) {
405 if (ltc_mp
.compare(v
, r
) == LTC_MP_EQ
) {
406 ret
= DROPBEAR_SUCCESS
;
410 ltc_ecc_del_point(mG
);
411 ltc_ecc_del_point(mQ
);
412 ltc_deinit_multi(r
, s
, v
, w
, u1
, u2
, p
, e
, m
, NULL
);
414 ltc_mp
.montgomery_deinit(mp
);
421 #endif /* DROPBEAR_ECDSA */