Mercurial > dropbear
comparison common-kex.c @ 755:b07eb3dc23ec ecc
refactor kexdh code a bit, start working on ecdh etc
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 26 Mar 2013 01:35:22 +0800 |
parents | bf0ac0512ef7 |
children | bf9dc2d9c2b1 |
comparison
equal
deleted
inserted
replaced
725:49f68a7b7a55 | 755:b07eb3dc23ec |
---|---|
547 } | 547 } |
548 | 548 |
549 /* Initialises and generate one side of the diffie-hellman key exchange values. | 549 /* Initialises and generate one side of the diffie-hellman key exchange values. |
550 * See the transport rfc 4253 section 8 for details */ | 550 * See the transport rfc 4253 section 8 for details */ |
551 /* dh_pub and dh_priv MUST be already initialised */ | 551 /* dh_pub and dh_priv MUST be already initialised */ |
552 void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { | 552 struct kex_dh_param *gen_kexdh_param() { |
553 | 553 |
554 DEF_MP_INT(dh_p); | 554 DEF_MP_INT(dh_p); |
555 DEF_MP_INT(dh_q); | 555 DEF_MP_INT(dh_q); |
556 DEF_MP_INT(dh_g); | 556 DEF_MP_INT(dh_g); |
557 | 557 |
558 TRACE(("enter send_msg_kexdh_reply")) | 558 TRACE(("enter send_msg_kexdh_reply")) |
559 | 559 |
560 m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); | 560 struct kex_dh_param *param = m_malloc(sizeof(*param)); |
561 m_mp_init_multi(¶m->pub, ¶m->priv, NULL); | |
561 | 562 |
562 /* read the prime and generator*/ | 563 /* read the prime and generator*/ |
563 load_dh_p(&dh_p); | 564 load_dh_p(&dh_p); |
564 | 565 |
565 if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { | 566 if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { |
566 dropbear_exit("Diffie-Hellman error"); | 567 dropbear_exit("Diffie-Hellman error"); |
567 } | 568 } |
568 | 569 |
569 /* calculate q = (p-1)/2 */ | 570 /* calculate q = (p-1)/2 */ |
570 /* dh_priv is just a temp var here */ | 571 /* dh_priv is just a temp var here */ |
571 if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) { | 572 if (mp_sub_d(&dh_p, 1, ¶m->priv) != MP_OKAY) { |
572 dropbear_exit("Diffie-Hellman error"); | 573 dropbear_exit("Diffie-Hellman error"); |
573 } | 574 } |
574 if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) { | 575 if (mp_div_2(¶m->priv, &dh_q) != MP_OKAY) { |
575 dropbear_exit("Diffie-Hellman error"); | 576 dropbear_exit("Diffie-Hellman error"); |
576 } | 577 } |
577 | 578 |
578 /* Generate a private portion 0 < dh_priv < dh_q */ | 579 /* Generate a private portion 0 < dh_priv < dh_q */ |
579 gen_random_mpint(&dh_q, dh_priv); | 580 gen_random_mpint(&dh_q, ¶m->priv); |
580 | 581 |
581 /* f = g^y mod p */ | 582 /* f = g^y mod p */ |
582 if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { | 583 if (mp_exptmod(&dh_g, ¶m->priv, &dh_p, ¶m->pub) != MP_OKAY) { |
583 dropbear_exit("Diffie-Hellman error"); | 584 dropbear_exit("Diffie-Hellman error"); |
584 } | 585 } |
585 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); | 586 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); |
587 return param; | |
588 } | |
589 | |
590 void free_kexdh_param(struct kex_dh_param *param) | |
591 { | |
592 mp_clear_multi(¶m->pub, ¶m->priv, NULL); | |
593 m_free(param); | |
586 } | 594 } |
587 | 595 |
588 /* This function is fairly common between client/server, with some substitution | 596 /* This function is fairly common between client/server, with some substitution |
589 * of dh_e/dh_f etc. Hence these arguments: | 597 * of dh_e/dh_f etc. Hence these arguments: |
590 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is | 598 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is |
591 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ | 599 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ |
592 void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, | 600 void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them, |
593 sign_key *hostkey) { | 601 sign_key *hostkey) { |
594 | 602 |
595 mp_int dh_p; | 603 mp_int dh_p; |
596 mp_int *dh_e = NULL, *dh_f = NULL; | 604 mp_int *dh_e = NULL, *dh_f = NULL; |
605 | |
597 hash_state hs; | 606 hash_state hs; |
598 | 607 |
599 /* read the prime and generator*/ | 608 /* read the prime and generator*/ |
600 m_mp_init(&dh_p); | 609 m_mp_init(&dh_p); |
601 load_dh_p(&dh_p); | 610 load_dh_p(&dh_p); |
607 } | 616 } |
608 | 617 |
609 /* K = e^y mod p = f^x mod p */ | 618 /* K = e^y mod p = f^x mod p */ |
610 ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); | 619 ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); |
611 m_mp_init(ses.dh_K); | 620 m_mp_init(ses.dh_K); |
612 if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) { | 621 if (mp_exptmod(dh_pub_them, ¶m->priv, &dh_p, ses.dh_K) != MP_OKAY) { |
613 dropbear_exit("Diffie-Hellman error"); | 622 dropbear_exit("Diffie-Hellman error"); |
614 } | 623 } |
615 | 624 |
616 /* clear no longer needed vars */ | 625 /* clear no longer needed vars */ |
617 mp_clear_multi(&dh_p, NULL); | 626 mp_clear_multi(&dh_p, NULL); |
618 | 627 |
619 /* From here on, the code needs to work with the _same_ vars on each side, | 628 /* From here on, the code needs to work with the _same_ vars on each side, |
620 * not vice-versaing for client/server */ | 629 * not vice-versaing for client/server */ |
621 if (IS_DROPBEAR_CLIENT) { | 630 if (IS_DROPBEAR_CLIENT) { |
622 dh_e = dh_pub_us; | 631 dh_e = ¶m->pub; |
623 dh_f = dh_pub_them; | 632 dh_f = dh_pub_them; |
624 } else { | 633 } else { |
625 dh_e = dh_pub_them; | 634 dh_e = dh_pub_them; |
626 dh_f = dh_pub_us; | 635 dh_f = ¶m->pub; |
627 } | 636 } |
628 | 637 |
629 /* Create the remainder of the hash buffer, to generate the exchange hash */ | 638 /* Create the remainder of the hash buffer, to generate the exchange hash */ |
630 /* K_S, the host key */ | 639 /* K_S, the host key */ |
631 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); | 640 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); |
652 /* create the session_id, this never needs freeing */ | 661 /* create the session_id, this never needs freeing */ |
653 ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); | 662 ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); |
654 memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); | 663 memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); |
655 } | 664 } |
656 } | 665 } |
666 | |
667 #ifdef DROPBEAR_ECDH | |
668 struct kex_ecdh_param *gen_kexecdh_param() { | |
669 struct kex_ecdh_param *param = m_malloc(sizeof(*param)); | |
670 if (ecc_make_key_ex(NULL, dropbear_ltc_prng, ¶m->key | |
671 } | |
672 void free_kexecdh_param(struct kex_ecdh_param *param); | |
673 void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them, | |
674 sign_key *hostkey); | |
675 #endif | |
657 | 676 |
658 /* read the other side's algo list. buf_match_algo is a callback to match | 677 /* read the other side's algo list. buf_match_algo is a callback to match |
659 * algos for the client or server. */ | 678 * algos for the client or server. */ |
660 static void read_kex_algos() { | 679 static void read_kex_algos() { |
661 | 680 |