Mercurial > dropbear
comparison common-kex.c @ 839:33207ed1174b
Merge in ECC
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 21 Oct 2013 22:57:21 +0800 |
parents | 724c3e0c8734 |
children | 6c69e7df3621 |
comparison
equal
deleted
inserted
replaced
834:e378da7eae5d | 839:33207ed1174b |
---|---|
32 #include "ssh.h" | 32 #include "ssh.h" |
33 #include "packet.h" | 33 #include "packet.h" |
34 #include "bignum.h" | 34 #include "bignum.h" |
35 #include "random.h" | 35 #include "random.h" |
36 #include "runopts.h" | 36 #include "runopts.h" |
37 #include "ecc.h" | |
38 #include "crypto_desc.h" | |
37 | 39 |
38 /* diffie-hellman-group1-sha1 value for p */ | 40 /* diffie-hellman-group1-sha1 value for p */ |
39 #define DH_P_1_LEN 128 | 41 const unsigned char dh_p_1[DH_P_1_LEN] = { |
40 static const unsigned char dh_p_1[DH_P_1_LEN] = { | |
41 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, | 42 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, |
42 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, | 43 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, |
43 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, | 44 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, |
44 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, | 45 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, |
45 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, | 46 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, |
49 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, | 50 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, |
50 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, | 51 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, |
51 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 52 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
52 | 53 |
53 /* diffie-hellman-group14-sha1 value for p */ | 54 /* diffie-hellman-group14-sha1 value for p */ |
54 #define DH_P_14_LEN 256 | 55 const unsigned char dh_p_14[DH_P_14_LEN] = { |
55 static const unsigned char dh_p_14[DH_P_14_LEN] = { | |
56 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, | 56 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, |
57 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, | 57 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, |
58 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, | 58 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, |
59 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, | 59 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, |
60 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, | 60 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, |
85 static void gen_new_zstream_recv(); | 85 static void gen_new_zstream_recv(); |
86 static void gen_new_zstream_trans(); | 86 static void gen_new_zstream_trans(); |
87 #endif | 87 #endif |
88 static void read_kex_algos(); | 88 static void read_kex_algos(); |
89 /* helper function for gen_new_keys */ | 89 /* helper function for gen_new_keys */ |
90 static void hashkeys(unsigned char *out, int outlen, | 90 static void hashkeys(unsigned char *out, unsigned int outlen, |
91 const hash_state * hs, unsigned const char X); | 91 const hash_state * hs, const unsigned char X); |
92 static void finish_kexhashbuf(void); | |
92 | 93 |
93 | 94 |
94 /* Send our list of algorithms we can use */ | 95 /* Send our list of algorithms we can use */ |
95 void send_msg_kexinit() { | 96 void send_msg_kexinit() { |
96 | 97 |
148 ses.kexstate.sentkexinit = 1; | 149 ses.kexstate.sentkexinit = 1; |
149 | 150 |
150 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); | 151 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); |
151 | 152 |
152 if (ses.send_kex_first_guess) { | 153 if (ses.send_kex_first_guess) { |
153 ses.newkeys->algo_kex = sshkex[0].val; | 154 ses.newkeys->algo_kex = sshkex[0].data; |
154 ses.newkeys->algo_hostkey = sshhostkey[0].val; | 155 ses.newkeys->algo_hostkey = sshhostkey[0].val; |
155 ses.send_kex_first_guess(); | 156 ses.send_kex_first_guess(); |
156 } | 157 } |
157 | 158 |
158 TRACE(("DATAALLOWED=0")) | 159 TRACE(("DATAALLOWED=0")) |
277 * already initialised hash_state hs, which should already have processed | 278 * already initialised hash_state hs, which should already have processed |
278 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. | 279 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. |
279 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. | 280 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. |
280 * | 281 * |
281 * See Section 7.2 of rfc4253 (ssh transport) for details */ | 282 * See Section 7.2 of rfc4253 (ssh transport) for details */ |
282 static void hashkeys(unsigned char *out, int outlen, | 283 static void hashkeys(unsigned char *out, unsigned int outlen, |
283 const hash_state * hs, const unsigned char X) { | 284 const hash_state * hs, const unsigned char X) { |
284 | 285 |
286 const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc; | |
285 hash_state hs2; | 287 hash_state hs2; |
286 int offset; | 288 unsigned int offset; |
289 unsigned char tmpout[hash_desc->hashsize]; | |
287 | 290 |
288 memcpy(&hs2, hs, sizeof(hash_state)); | 291 memcpy(&hs2, hs, sizeof(hash_state)); |
289 sha1_process(&hs2, &X, 1); | 292 hash_desc->process(&hs2, &X, 1); |
290 sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE); | 293 hash_desc->process(&hs2, ses.session_id->data, ses.session_id->len); |
291 sha1_done(&hs2, out); | 294 hash_desc->done(&hs2, tmpout); |
292 for (offset = SHA1_HASH_SIZE; | 295 memcpy(out, tmpout, MIN(hash_desc->hashsize, outlen)); |
296 for (offset = hash_desc->hashsize; | |
293 offset < outlen; | 297 offset < outlen; |
294 offset += SHA1_HASH_SIZE) | 298 offset += hash_desc->hashsize) |
295 { | 299 { |
296 /* need to extend */ | 300 /* need to extend */ |
297 unsigned char k2[SHA1_HASH_SIZE]; | |
298 memcpy(&hs2, hs, sizeof(hash_state)); | 301 memcpy(&hs2, hs, sizeof(hash_state)); |
299 sha1_process(&hs2, out, offset); | 302 hash_desc->process(&hs2, out, offset); |
300 sha1_done(&hs2, k2); | 303 hash_desc->done(&hs2, tmpout); |
301 memcpy(&out[offset], k2, MIN(outlen - offset, SHA1_HASH_SIZE)); | 304 memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize)); |
302 } | 305 } |
303 } | 306 } |
304 | 307 |
305 /* Generate the actual encryption/integrity keys, using the results of the | 308 /* Generate the actual encryption/integrity keys, using the results of the |
306 * key exchange, as specified in section 7.2 of the transport rfc 4253. | 309 * key exchange, as specified in section 7.2 of the transport rfc 4253. |
317 unsigned char S2C_key[MAX_KEY_LEN]; | 320 unsigned char S2C_key[MAX_KEY_LEN]; |
318 /* unsigned char key[MAX_KEY_LEN]; */ | 321 /* unsigned char key[MAX_KEY_LEN]; */ |
319 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; | 322 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; |
320 | 323 |
321 hash_state hs; | 324 hash_state hs; |
322 unsigned int C2S_keysize, S2C_keysize; | 325 const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc; |
323 char mactransletter, macrecvletter; /* Client or server specific */ | 326 char mactransletter, macrecvletter; /* Client or server specific */ |
324 | 327 |
325 TRACE(("enter gen_new_keys")) | 328 TRACE(("enter gen_new_keys")) |
326 /* the dh_K and hash are the start of all hashes, we make use of that */ | 329 /* the dh_K and hash are the start of all hashes, we make use of that */ |
327 | 330 |
328 sha1_init(&hs); | 331 hash_desc->init(&hs); |
329 sha1_process_mp(&hs, ses.dh_K); | 332 hash_process_mp(hash_desc, &hs, ses.dh_K); |
330 mp_clear(ses.dh_K); | 333 mp_clear(ses.dh_K); |
331 m_free(ses.dh_K); | 334 m_free(ses.dh_K); |
332 sha1_process(&hs, ses.hash, SHA1_HASH_SIZE); | 335 hash_desc->process(&hs, ses.hash->data, ses.hash->len); |
333 m_burn(ses.hash, SHA1_HASH_SIZE); | 336 buf_burn(ses.hash); |
337 buf_free(ses.hash); | |
338 ses.hash = NULL; | |
334 | 339 |
335 if (IS_DROPBEAR_CLIENT) { | 340 if (IS_DROPBEAR_CLIENT) { |
336 trans_IV = C2S_IV; | 341 trans_IV = C2S_IV; |
337 recv_IV = S2C_IV; | 342 recv_IV = S2C_IV; |
338 trans_key = C2S_key; | 343 trans_key = C2S_key; |
339 recv_key = S2C_key; | 344 recv_key = S2C_key; |
340 C2S_keysize = ses.newkeys->trans.algo_crypt->keysize; | |
341 S2C_keysize = ses.newkeys->recv.algo_crypt->keysize; | |
342 mactransletter = 'E'; | 345 mactransletter = 'E'; |
343 macrecvletter = 'F'; | 346 macrecvletter = 'F'; |
344 } else { | 347 } else { |
345 trans_IV = S2C_IV; | 348 trans_IV = S2C_IV; |
346 recv_IV = C2S_IV; | 349 recv_IV = C2S_IV; |
347 trans_key = S2C_key; | 350 trans_key = S2C_key; |
348 recv_key = C2S_key; | 351 recv_key = C2S_key; |
349 C2S_keysize = ses.newkeys->recv.algo_crypt->keysize; | |
350 S2C_keysize = ses.newkeys->trans.algo_crypt->keysize; | |
351 mactransletter = 'F'; | 352 mactransletter = 'F'; |
352 macrecvletter = 'E'; | 353 macrecvletter = 'E'; |
353 } | 354 } |
354 | 355 |
355 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); | 356 hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A'); |
356 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); | 357 hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B'); |
357 hashkeys(C2S_key, C2S_keysize, &hs, 'C'); | 358 hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C'); |
358 hashkeys(S2C_key, S2C_keysize, &hs, 'D'); | 359 hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D'); |
359 | 360 |
360 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { | 361 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) { |
361 int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); | 362 int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name); |
362 if (recv_cipher < 0) | 363 if (recv_cipher < 0) |
363 dropbear_exit("Crypto error"); | 364 dropbear_exit("Crypto error"); |
379 &ses.newkeys->trans.cipher_state) != CRYPT_OK) { | 380 &ses.newkeys->trans.cipher_state) != CRYPT_OK) { |
380 dropbear_exit("Crypto error"); | 381 dropbear_exit("Crypto error"); |
381 } | 382 } |
382 } | 383 } |
383 | 384 |
384 if (ses.newkeys->trans.algo_mac->hashdesc != NULL) { | 385 if (ses.newkeys->trans.algo_mac->hash_desc != NULL) { |
385 hashkeys(ses.newkeys->trans.mackey, | 386 hashkeys(ses.newkeys->trans.mackey, |
386 ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter); | 387 ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter); |
387 ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hashdesc->name); | 388 ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hash_desc->name); |
388 } | 389 } |
389 | 390 |
390 if (ses.newkeys->recv.algo_mac->hashdesc != NULL) { | 391 if (ses.newkeys->recv.algo_mac->hash_desc != NULL) { |
391 hashkeys(ses.newkeys->recv.mackey, | 392 hashkeys(ses.newkeys->recv.mackey, |
392 ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter); | 393 ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter); |
393 ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hashdesc->name); | 394 ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hash_desc->name); |
394 } | 395 } |
395 | 396 |
396 /* Ready to switch over */ | 397 /* Ready to switch over */ |
397 ses.newkeys->trans.valid = 1; | 398 ses.newkeys->trans.valid = 1; |
398 ses.newkeys->recv.valid = 1; | 399 ses.newkeys->recv.valid = 1; |
558 TRACE(("leave recv_msg_kexinit")) | 559 TRACE(("leave recv_msg_kexinit")) |
559 } | 560 } |
560 | 561 |
561 static void load_dh_p(mp_int * dh_p) | 562 static void load_dh_p(mp_int * dh_p) |
562 { | 563 { |
563 switch (ses.newkeys->algo_kex) { | 564 bytes_to_mp(dh_p, ses.newkeys->algo_kex->dh_p_bytes, |
564 case DROPBEAR_KEX_DH_GROUP1: | 565 ses.newkeys->algo_kex->dh_p_len); |
565 bytes_to_mp(dh_p, dh_p_1, DH_P_1_LEN); | |
566 break; | |
567 case DROPBEAR_KEX_DH_GROUP14: | |
568 bytes_to_mp(dh_p, dh_p_14, DH_P_14_LEN); | |
569 break; | |
570 } | |
571 } | 566 } |
572 | 567 |
573 /* Initialises and generate one side of the diffie-hellman key exchange values. | 568 /* Initialises and generate one side of the diffie-hellman key exchange values. |
574 * See the transport rfc 4253 section 8 for details */ | 569 * See the transport rfc 4253 section 8 for details */ |
575 /* dh_pub and dh_priv MUST be already initialised */ | 570 /* dh_pub and dh_priv MUST be already initialised */ |
576 void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { | 571 struct kex_dh_param *gen_kexdh_param() { |
577 | 572 |
578 DEF_MP_INT(dh_p); | 573 DEF_MP_INT(dh_p); |
579 DEF_MP_INT(dh_q); | 574 DEF_MP_INT(dh_q); |
580 DEF_MP_INT(dh_g); | 575 DEF_MP_INT(dh_g); |
581 | 576 |
582 TRACE(("enter gen_kexdh_vals")) | 577 TRACE(("enter gen_kexdh_vals")) |
583 | 578 |
584 m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); | 579 struct kex_dh_param *param = m_malloc(sizeof(*param)); |
580 m_mp_init_multi(¶m->pub, ¶m->priv, NULL); | |
585 | 581 |
586 /* read the prime and generator*/ | 582 /* read the prime and generator*/ |
587 load_dh_p(&dh_p); | 583 load_dh_p(&dh_p); |
588 | 584 |
589 if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { | 585 if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { |
590 dropbear_exit("Diffie-Hellman error"); | 586 dropbear_exit("Diffie-Hellman error"); |
591 } | 587 } |
592 | 588 |
593 /* calculate q = (p-1)/2 */ | 589 /* calculate q = (p-1)/2 */ |
594 /* dh_priv is just a temp var here */ | 590 /* dh_priv is just a temp var here */ |
595 if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) { | 591 if (mp_sub_d(&dh_p, 1, ¶m->priv) != MP_OKAY) { |
596 dropbear_exit("Diffie-Hellman error"); | 592 dropbear_exit("Diffie-Hellman error"); |
597 } | 593 } |
598 if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) { | 594 if (mp_div_2(¶m->priv, &dh_q) != MP_OKAY) { |
599 dropbear_exit("Diffie-Hellman error"); | 595 dropbear_exit("Diffie-Hellman error"); |
600 } | 596 } |
601 | 597 |
602 /* Generate a private portion 0 < dh_priv < dh_q */ | 598 /* Generate a private portion 0 < dh_priv < dh_q */ |
603 gen_random_mpint(&dh_q, dh_priv); | 599 gen_random_mpint(&dh_q, ¶m->priv); |
604 | 600 |
605 /* f = g^y mod p */ | 601 /* f = g^y mod p */ |
606 if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { | 602 if (mp_exptmod(&dh_g, ¶m->priv, &dh_p, ¶m->pub) != MP_OKAY) { |
607 dropbear_exit("Diffie-Hellman error"); | 603 dropbear_exit("Diffie-Hellman error"); |
608 } | 604 } |
609 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); | 605 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); |
606 return param; | |
607 } | |
608 | |
609 void free_kexdh_param(struct kex_dh_param *param) | |
610 { | |
611 mp_clear_multi(¶m->pub, ¶m->priv, NULL); | |
612 m_free(param); | |
610 } | 613 } |
611 | 614 |
612 /* This function is fairly common between client/server, with some substitution | 615 /* This function is fairly common between client/server, with some substitution |
613 * of dh_e/dh_f etc. Hence these arguments: | 616 * of dh_e/dh_f etc. Hence these arguments: |
614 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is | 617 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is |
615 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ | 618 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ |
616 void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, | 619 void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them, |
617 sign_key *hostkey) { | 620 sign_key *hostkey) { |
618 | 621 |
619 mp_int dh_p; | 622 mp_int dh_p; |
620 mp_int *dh_e = NULL, *dh_f = NULL; | 623 mp_int *dh_e = NULL, *dh_f = NULL; |
621 hash_state hs; | |
622 | 624 |
623 /* read the prime and generator*/ | 625 /* read the prime and generator*/ |
624 m_mp_init(&dh_p); | 626 m_mp_init(&dh_p); |
625 load_dh_p(&dh_p); | 627 load_dh_p(&dh_p); |
626 | 628 |
629 || mp_cmp_d(dh_pub_them, 0) != MP_GT) { | 631 || mp_cmp_d(dh_pub_them, 0) != MP_GT) { |
630 dropbear_exit("Diffie-Hellman error"); | 632 dropbear_exit("Diffie-Hellman error"); |
631 } | 633 } |
632 | 634 |
633 /* K = e^y mod p = f^x mod p */ | 635 /* K = e^y mod p = f^x mod p */ |
634 ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); | 636 m_mp_alloc_init_multi(&ses.dh_K, NULL); |
635 m_mp_init(ses.dh_K); | 637 if (mp_exptmod(dh_pub_them, ¶m->priv, &dh_p, ses.dh_K) != MP_OKAY) { |
636 if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) { | |
637 dropbear_exit("Diffie-Hellman error"); | 638 dropbear_exit("Diffie-Hellman error"); |
638 } | 639 } |
639 | 640 |
640 /* clear no longer needed vars */ | 641 /* clear no longer needed vars */ |
641 mp_clear_multi(&dh_p, NULL); | 642 mp_clear_multi(&dh_p, NULL); |
642 | 643 |
643 /* From here on, the code needs to work with the _same_ vars on each side, | 644 /* From here on, the code needs to work with the _same_ vars on each side, |
644 * not vice-versaing for client/server */ | 645 * not vice-versaing for client/server */ |
645 if (IS_DROPBEAR_CLIENT) { | 646 if (IS_DROPBEAR_CLIENT) { |
646 dh_e = dh_pub_us; | 647 dh_e = ¶m->pub; |
647 dh_f = dh_pub_them; | 648 dh_f = dh_pub_them; |
648 } else { | 649 } else { |
649 dh_e = dh_pub_them; | 650 dh_e = dh_pub_them; |
650 dh_f = dh_pub_us; | 651 dh_f = ¶m->pub; |
651 } | 652 } |
652 | 653 |
653 /* Create the remainder of the hash buffer, to generate the exchange hash */ | 654 /* Create the remainder of the hash buffer, to generate the exchange hash */ |
654 /* K_S, the host key */ | 655 /* K_S, the host key */ |
655 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); | 656 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); |
659 buf_putmpint(ses.kexhashbuf, dh_f); | 660 buf_putmpint(ses.kexhashbuf, dh_f); |
660 /* K, the shared secret */ | 661 /* K, the shared secret */ |
661 buf_putmpint(ses.kexhashbuf, ses.dh_K); | 662 buf_putmpint(ses.kexhashbuf, ses.dh_K); |
662 | 663 |
663 /* calculate the hash H to sign */ | 664 /* calculate the hash H to sign */ |
664 sha1_init(&hs); | 665 finish_kexhashbuf(); |
666 } | |
667 | |
668 #ifdef DROPBEAR_ECDH | |
669 struct kex_ecdh_param *gen_kexecdh_param() { | |
670 struct kex_ecdh_param *param = m_malloc(sizeof(*param)); | |
671 if (ecc_make_key_ex(NULL, dropbear_ltc_prng, | |
672 ¶m->key, ses.newkeys->algo_kex->ecc_curve->dp) != CRYPT_OK) { | |
673 dropbear_exit("ECC error"); | |
674 } | |
675 return param; | |
676 } | |
677 | |
678 void free_kexecdh_param(struct kex_ecdh_param *param) { | |
679 ecc_free(¶m->key); | |
680 m_free(param); | |
681 | |
682 } | |
683 void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them, | |
684 sign_key *hostkey) { | |
685 const struct dropbear_kex *algo_kex = ses.newkeys->algo_kex; | |
686 // public keys from client and server | |
687 ecc_key *Q_C, *Q_S, *Q_them; | |
688 | |
689 Q_them = buf_get_ecc_raw_pubkey(pub_them, algo_kex->ecc_curve); | |
690 | |
691 ses.dh_K = dropbear_ecc_shared_secret(Q_them, ¶m->key); | |
692 | |
693 /* From here on, the code needs to work with the _same_ vars on each side, | |
694 * not vice-versaing for client/server */ | |
695 if (IS_DROPBEAR_CLIENT) { | |
696 Q_C = ¶m->key; | |
697 Q_S = Q_them; | |
698 } else { | |
699 Q_C = Q_them; | |
700 Q_S = ¶m->key; | |
701 } | |
702 | |
703 /* Create the remainder of the hash buffer, to generate the exchange hash */ | |
704 /* K_S, the host key */ | |
705 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); | |
706 /* Q_C, client's ephemeral public key octet string */ | |
707 buf_put_ecc_raw_pubkey_string(ses.kexhashbuf, Q_C); | |
708 /* Q_S, server's ephemeral public key octet string */ | |
709 buf_put_ecc_raw_pubkey_string(ses.kexhashbuf, Q_S); | |
710 /* K, the shared secret */ | |
711 buf_putmpint(ses.kexhashbuf, ses.dh_K); | |
712 | |
713 /* calculate the hash H to sign */ | |
714 finish_kexhashbuf(); | |
715 } | |
716 #endif | |
717 | |
718 static void finish_kexhashbuf(void) { | |
719 hash_state hs; | |
720 const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc; | |
721 | |
722 hash_desc->init(&hs); | |
665 buf_setpos(ses.kexhashbuf, 0); | 723 buf_setpos(ses.kexhashbuf, 0); |
666 sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), | 724 hash_desc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), |
667 ses.kexhashbuf->len); | 725 ses.kexhashbuf->len); |
668 sha1_done(&hs, ses.hash); | 726 ses.hash = buf_new(hash_desc->hashsize); |
727 hash_desc->done(&hs, buf_getwriteptr(ses.hash, hash_desc->hashsize)); | |
728 buf_setlen(ses.hash, hash_desc->hashsize); | |
669 | 729 |
670 buf_burn(ses.kexhashbuf); | 730 buf_burn(ses.kexhashbuf); |
671 buf_free(ses.kexhashbuf); | 731 buf_free(ses.kexhashbuf); |
672 ses.kexhashbuf = NULL; | 732 ses.kexhashbuf = NULL; |
673 | 733 |
674 /* first time around, we set the session_id to H */ | 734 /* first time around, we set the session_id to H */ |
675 if (ses.session_id == NULL) { | 735 if (ses.session_id == NULL) { |
676 /* create the session_id, this never needs freeing */ | 736 /* create the session_id, this never needs freeing */ |
677 ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); | 737 ses.session_id = buf_newcopy(ses.hash); |
678 memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); | 738 } |
679 } | 739 |
680 } | 740 } |
681 | 741 |
682 /* read the other side's algo list. buf_match_algo is a callback to match | 742 /* read the other side's algo list. buf_match_algo is a callback to match |
683 * algos for the client or server. */ | 743 * algos for the client or server. */ |
684 static void read_kex_algos() { | 744 static void read_kex_algos() { |
717 erralgo = "kex"; | 777 erralgo = "kex"; |
718 goto error; | 778 goto error; |
719 } | 779 } |
720 TRACE(("kexguess2 %d", kexguess2)) | 780 TRACE(("kexguess2 %d", kexguess2)) |
721 TRACE(("kex algo %s", algo->name)) | 781 TRACE(("kex algo %s", algo->name)) |
722 ses.newkeys->algo_kex = algo->val; | 782 ses.newkeys->algo_kex = algo->data; |
723 | 783 |
724 /* server_host_key_algorithms */ | 784 /* server_host_key_algorithms */ |
725 algo = buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess); | 785 algo = buf_match_algo(ses.payload, sshhostkey, &kexguess2, &goodguess); |
726 allgood &= goodguess; | 786 allgood &= goodguess; |
727 if (algo == NULL) { | 787 if (algo == NULL) { |