Mercurial > dropbear
comparison common-kex.c @ 640:76097ec1a29a dropbear-tfm
- Bring in original tomsfastmath patch against 0.52 from Peter Turczak
in 2008
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 21 Nov 2011 19:19:57 +0800 |
parents | 43bbe17d6ba0 |
children | 2b1bb792cd4d |
comparison
equal
deleted
inserted
replaced
518:ce104c8b0be1 | 640:76097ec1a29a |
---|---|
259 | 259 |
260 TRACE(("enter gen_new_keys")) | 260 TRACE(("enter gen_new_keys")) |
261 /* the dh_K and hash are the start of all hashes, we make use of that */ | 261 /* the dh_K and hash are the start of all hashes, we make use of that */ |
262 | 262 |
263 sha1_init(&hs); | 263 sha1_init(&hs); |
264 sha1_process_mp(&hs, ses.dh_K); | 264 sha1_process_fp(&hs, ses.dh_K); |
265 mp_clear(ses.dh_K); | 265 fp_zero(ses.dh_K); |
266 m_free(ses.dh_K); | 266 m_free(ses.dh_K); |
267 sha1_process(&hs, ses.hash, SHA1_HASH_SIZE); | 267 sha1_process(&hs, ses.hash, SHA1_HASH_SIZE); |
268 m_burn(ses.hash, SHA1_HASH_SIZE); | 268 m_burn(ses.hash, SHA1_HASH_SIZE); |
269 | 269 |
270 if (IS_DROPBEAR_CLIENT) { | 270 if (IS_DROPBEAR_CLIENT) { |
480 } | 480 } |
481 | 481 |
482 /* Initialises and generate one side of the diffie-hellman key exchange values. | 482 /* Initialises and generate one side of the diffie-hellman key exchange values. |
483 * See the ietf-secsh-transport draft, section 6, for details */ | 483 * See the ietf-secsh-transport draft, section 6, for details */ |
484 /* dh_pub and dh_priv MUST be already initialised */ | 484 /* dh_pub and dh_priv MUST be already initialised */ |
485 void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { | 485 void gen_kexdh_vals(fp_int *dh_pub, fp_int *dh_priv) { |
486 | 486 |
487 DEF_MP_INT(dh_p); | 487 DEF_FP_INT(dh_p); |
488 DEF_MP_INT(dh_q); | 488 DEF_FP_INT(dh_q); |
489 DEF_MP_INT(dh_g); | 489 DEF_FP_INT(dh_g); |
490 | 490 |
491 TRACE(("enter send_msg_kexdh_reply")) | 491 TRACE(("enter send_msg_kexdh_reply")) |
492 | 492 |
493 m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); | 493 m_fp_init_multi(&dh_g, &dh_p, &dh_q, NULL); |
494 | 494 |
495 /* read the prime and generator*/ | 495 /* read the prime and generator*/ |
496 bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN); | 496 bytes_to_fp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN); |
497 | 497 |
498 if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { | 498 fp_set(&dh_g, DH_G_VAL); |
499 dropbear_exit("Diffie-Hellman error"); | |
500 } | |
501 | 499 |
502 /* calculate q = (p-1)/2 */ | 500 /* calculate q = (p-1)/2 */ |
503 /* dh_priv is just a temp var here */ | 501 /* dh_priv is just a temp var here */ |
504 if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) { | 502 fp_sub_d(&dh_p, 1, dh_priv); |
503 | |
504 fp_div_2(dh_priv, &dh_q); | |
505 | |
506 /* Generate a private portion 0 < dh_priv < dh_q */ | |
507 gen_random_fpint(&dh_q, dh_priv); | |
508 | |
509 /* f = g^y mod p */ | |
510 if (fp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != FP_OKAY) { | |
505 dropbear_exit("Diffie-Hellman error"); | 511 dropbear_exit("Diffie-Hellman error"); |
506 } | 512 } |
507 if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) { | 513 m_fp_zero_multi(&dh_g, &dh_p, &dh_q, NULL); |
508 dropbear_exit("Diffie-Hellman error"); | |
509 } | |
510 | |
511 /* Generate a private portion 0 < dh_priv < dh_q */ | |
512 gen_random_mpint(&dh_q, dh_priv); | |
513 | |
514 /* f = g^y mod p */ | |
515 if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { | |
516 dropbear_exit("Diffie-Hellman error"); | |
517 } | |
518 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); | |
519 } | 514 } |
520 | 515 |
521 /* This function is fairly common between client/server, with some substitution | 516 /* This function is fairly common between client/server, with some substitution |
522 * of dh_e/dh_f etc. Hence these arguments: | 517 * of dh_e/dh_f etc. Hence these arguments: |
523 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is | 518 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is |
524 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ | 519 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ |
525 void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, | 520 void kexdh_comb_key(fp_int *dh_pub_us, fp_int *dh_priv, fp_int *dh_pub_them, |
526 sign_key *hostkey) { | 521 sign_key *hostkey) { |
527 | 522 |
528 mp_int dh_p; | 523 fp_int dh_p; |
529 mp_int *dh_e = NULL, *dh_f = NULL; | 524 fp_int *dh_e = NULL, *dh_f = NULL; |
530 hash_state hs; | 525 hash_state hs; |
531 | 526 |
532 /* read the prime and generator*/ | 527 /* read the prime and generator*/ |
533 m_mp_init(&dh_p); | 528 m_fp_init(&dh_p); |
534 bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); | 529 bytes_to_fp(&dh_p, dh_p_val, DH_P_LEN); |
535 | 530 |
536 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ | 531 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ |
537 if (mp_cmp(dh_pub_them, &dh_p) != MP_LT | 532 if (fp_cmp(dh_pub_them, &dh_p) != FP_LT |
538 || mp_cmp_d(dh_pub_them, 0) != MP_GT) { | 533 || fp_cmp_d(dh_pub_them, 0) != FP_GT) { |
539 dropbear_exit("Diffie-Hellman error"); | 534 dropbear_exit("Diffie-Hellman error"); |
540 } | 535 } |
541 | 536 |
542 /* K = e^y mod p = f^x mod p */ | 537 /* K = e^y mod p = f^x mod p */ |
543 ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); | 538 ses.dh_K = (fp_int*)m_malloc(sizeof(fp_int)); |
544 m_mp_init(ses.dh_K); | 539 m_fp_init(ses.dh_K); |
545 if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) { | 540 if (fp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != FP_OKAY) { |
546 dropbear_exit("Diffie-Hellman error"); | 541 dropbear_exit("Diffie-Hellman error"); |
547 } | 542 } |
548 | 543 |
549 /* clear no longer needed vars */ | 544 /* clear no longer needed vars */ |
550 mp_clear_multi(&dh_p, NULL); | 545 m_fp_zero_multi(&dh_p, NULL); |
551 | 546 |
552 /* From here on, the code needs to work with the _same_ vars on each side, | 547 /* From here on, the code needs to work with the _same_ vars on each side, |
553 * not vice-versaing for client/server */ | 548 * not vice-versaing for client/server */ |
554 if (IS_DROPBEAR_CLIENT) { | 549 if (IS_DROPBEAR_CLIENT) { |
555 dh_e = dh_pub_us; | 550 dh_e = dh_pub_us; |
561 | 556 |
562 /* Create the remainder of the hash buffer, to generate the exchange hash */ | 557 /* Create the remainder of the hash buffer, to generate the exchange hash */ |
563 /* K_S, the host key */ | 558 /* K_S, the host key */ |
564 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); | 559 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); |
565 /* e, exchange value sent by the client */ | 560 /* e, exchange value sent by the client */ |
566 buf_putmpint(ses.kexhashbuf, dh_e); | 561 buf_putfpint(ses.kexhashbuf, dh_e); |
567 /* f, exchange value sent by the server */ | 562 /* f, exchange value sent by the server */ |
568 buf_putmpint(ses.kexhashbuf, dh_f); | 563 buf_putfpint(ses.kexhashbuf, dh_f); |
569 /* K, the shared secret */ | 564 /* K, the shared secret */ |
570 buf_putmpint(ses.kexhashbuf, ses.dh_K); | 565 buf_putfpint(ses.kexhashbuf, ses.dh_K); |
571 | 566 |
572 /* calculate the hash H to sign */ | 567 /* calculate the hash H to sign */ |
573 sha1_init(&hs); | 568 sha1_init(&hs); |
574 buf_setpos(ses.kexhashbuf, 0); | 569 buf_setpos(ses.kexhashbuf, 0); |
575 sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), | 570 sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), |
595 /* for asymmetry */ | 590 /* for asymmetry */ |
596 algo_type * c2s_hash_algo = NULL; | 591 algo_type * c2s_hash_algo = NULL; |
597 algo_type * s2c_hash_algo = NULL; | 592 algo_type * s2c_hash_algo = NULL; |
598 algo_type * c2s_cipher_algo = NULL; | 593 algo_type * c2s_cipher_algo = NULL; |
599 algo_type * s2c_cipher_algo = NULL; | 594 algo_type * s2c_cipher_algo = NULL; |
600 algo_type * c2s_comp_algo = NULL; | 595 algo_type * c2s_cofp_algo = NULL; |
601 algo_type * s2c_comp_algo = NULL; | 596 algo_type * s2c_cofp_algo = NULL; |
602 /* the generic one */ | 597 /* the generic one */ |
603 algo_type * algo = NULL; | 598 algo_type * algo = NULL; |
604 | 599 |
605 /* which algo couldn't match */ | 600 /* which algo couldn't match */ |
606 char * erralgo = NULL; | 601 char * erralgo = NULL; |
664 goto error; | 659 goto error; |
665 } | 660 } |
666 TRACE(("hash s2c is %s", s2c_hash_algo->name)) | 661 TRACE(("hash s2c is %s", s2c_hash_algo->name)) |
667 | 662 |
668 /* compression_algorithms_client_to_server */ | 663 /* compression_algorithms_client_to_server */ |
669 c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); | 664 c2s_cofp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); |
670 if (c2s_comp_algo == NULL) { | 665 if (c2s_cofp_algo == NULL) { |
671 erralgo = "comp c->s"; | 666 erralgo = "comp c->s"; |
672 goto error; | 667 goto error; |
673 } | 668 } |
674 TRACE(("hash c2s is %s", c2s_comp_algo->name)) | 669 TRACE(("hash c2s is %s", c2s_cofp_algo->name)) |
675 | 670 |
676 /* compression_algorithms_server_to_client */ | 671 /* compression_algorithms_server_to_client */ |
677 s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); | 672 s2c_cofp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); |
678 if (s2c_comp_algo == NULL) { | 673 if (s2c_cofp_algo == NULL) { |
679 erralgo = "comp s->c"; | 674 erralgo = "comp s->c"; |
680 goto error; | 675 goto error; |
681 } | 676 } |
682 TRACE(("hash s2c is %s", s2c_comp_algo->name)) | 677 TRACE(("hash s2c is %s", s2c_cofp_algo->name)) |
683 | 678 |
684 /* languages_client_to_server */ | 679 /* languages_client_to_server */ |
685 buf_eatstring(ses.payload); | 680 buf_eatstring(ses.payload); |
686 | 681 |
687 /* languages_server_to_client */ | 682 /* languages_server_to_client */ |
708 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; | 703 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; |
709 ses.newkeys->recv_algo_mac = | 704 ses.newkeys->recv_algo_mac = |
710 (struct dropbear_hash*)s2c_hash_algo->data; | 705 (struct dropbear_hash*)s2c_hash_algo->data; |
711 ses.newkeys->trans_algo_mac = | 706 ses.newkeys->trans_algo_mac = |
712 (struct dropbear_hash*)c2s_hash_algo->data; | 707 (struct dropbear_hash*)c2s_hash_algo->data; |
713 ses.newkeys->recv_algo_comp = s2c_comp_algo->val; | 708 ses.newkeys->recv_algo_comp = s2c_cofp_algo->val; |
714 ses.newkeys->trans_algo_comp = c2s_comp_algo->val; | 709 ses.newkeys->trans_algo_comp = c2s_cofp_algo->val; |
715 } else { | 710 } else { |
716 /* SERVER */ | 711 /* SERVER */ |
717 ses.newkeys->recv_algo_crypt = | 712 ses.newkeys->recv_algo_crypt = |
718 (struct dropbear_cipher*)c2s_cipher_algo->data; | 713 (struct dropbear_cipher*)c2s_cipher_algo->data; |
719 ses.newkeys->trans_algo_crypt = | 714 ses.newkeys->trans_algo_crypt = |
724 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; | 719 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; |
725 ses.newkeys->recv_algo_mac = | 720 ses.newkeys->recv_algo_mac = |
726 (struct dropbear_hash*)c2s_hash_algo->data; | 721 (struct dropbear_hash*)c2s_hash_algo->data; |
727 ses.newkeys->trans_algo_mac = | 722 ses.newkeys->trans_algo_mac = |
728 (struct dropbear_hash*)s2c_hash_algo->data; | 723 (struct dropbear_hash*)s2c_hash_algo->data; |
729 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; | 724 ses.newkeys->recv_algo_comp = c2s_cofp_algo->val; |
730 ses.newkeys->trans_algo_comp = s2c_comp_algo->val; | 725 ses.newkeys->trans_algo_comp = s2c_cofp_algo->val; |
731 } | 726 } |
732 | 727 |
733 /* reserved for future extensions */ | 728 /* reserved for future extensions */ |
734 buf_getint(ses.payload); | 729 buf_getint(ses.payload); |
735 return; | 730 return; |