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;