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(&param->pub, &param->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, &param->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(&param->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, &param->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, &param->priv, &dh_p, &param->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(&param->pub, &param->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, &param->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 = &param->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 = &param->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 &param->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(&param->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, &param->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 = &param->key;
697 Q_S = Q_them;
698 } else {
699 Q_C = Q_them;
700 Q_S = &param->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) {