comparison svr-kex.c @ 839:33207ed1174b

Merge in ECC
author Matt Johnston <matt@ucc.asn.au>
date Mon, 21 Oct 2013 22:57:21 +0800
parents 7dcb46da72d9
children b298bb438625 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"
37 38
38 39 static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs);
39 static void send_msg_kexdh_reply(mp_int *dh_e);
40 40
41 /* Handle a diffie-hellman key exchange initialisation. This involves 41 /* Handle a diffie-hellman key exchange initialisation. This involves
42 * calculating a session key reply value, and corresponding hash. These 42 * calculating a session key reply value, and corresponding hash. These
43 * are carried out by send_msg_kexdh_reply(). recv_msg_kexdh_init() calls 43 * are carried out by send_msg_kexdh_reply(). recv_msg_kexdh_init() calls
44 * that function, then brings the new keys into use */ 44 * that function, then brings the new keys into use */
45 void recv_msg_kexdh_init() { 45 void recv_msg_kexdh_init() {
46 46
47 DEF_MP_INT(dh_e); 47 DEF_MP_INT(dh_e);
48 buffer *ecdh_qs = NULL;
48 49
49 TRACE(("enter recv_msg_kexdh_init")) 50 TRACE(("enter recv_msg_kexdh_init"))
50 if (!ses.kexstate.recvkexinit) { 51 if (!ses.kexstate.recvkexinit) {
51 dropbear_exit("Premature kexdh_init message received"); 52 dropbear_exit("Premature kexdh_init message received");
52 } 53 }
53 54
54 m_mp_init(&dh_e); 55 if (IS_NORMAL_DH(ses.newkeys->algo_kex)) {
55 if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) { 56 m_mp_init(&dh_e);
56 dropbear_exit("Failed to get kex value"); 57 if (buf_getmpint(ses.payload, &dh_e) != DROPBEAR_SUCCESS) {
58 dropbear_exit("Failed to get kex value");
59 }
60 } else {
61 #ifdef DROPBEAR_ECDH
62 ecdh_qs = buf_getstringbuf(ses.payload);
63 #endif
57 } 64 }
58 65
59 send_msg_kexdh_reply(&dh_e); 66 send_msg_kexdh_reply(&dh_e, ecdh_qs);
60 67
61 mp_clear(&dh_e); 68 mp_clear(&dh_e);
69 if (ecdh_qs) {
70 buf_free(ecdh_qs);
71 }
62 72
63 send_msg_newkeys(); 73 send_msg_newkeys();
64 ses.requirenext[0] = SSH_MSG_NEWKEYS; 74 ses.requirenext[0] = SSH_MSG_NEWKEYS;
65 ses.requirenext[1] = 0; 75 ses.requirenext[1] = 0;
66 TRACE(("leave recv_msg_kexdh_init")) 76 TRACE(("leave recv_msg_kexdh_init"))
69 /* Generate our side of the diffie-hellman key exchange value (dh_f), and 79 /* Generate our side of the diffie-hellman key exchange value (dh_f), and
70 * calculate the session key using the diffie-hellman algorithm. Following 80 * calculate the session key using the diffie-hellman algorithm. Following
71 * that, the session hash is calculated, and signed with RSA or DSS. The 81 * that, the session hash is calculated, and signed with RSA or DSS. The
72 * result is sent to the client. 82 * result is sent to the client.
73 * 83 *
74 * See the transport rfc 4253 section 8 for details */ 84 * See the transport RFC4253 section 8 for details
75 static void send_msg_kexdh_reply(mp_int *dh_e) { 85 * or RFC5656 section 4 for elliptic curve variant. */
76 86 static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs) {
77 DEF_MP_INT(dh_y);
78 DEF_MP_INT(dh_f);
79
80 TRACE(("enter send_msg_kexdh_reply")) 87 TRACE(("enter send_msg_kexdh_reply"))
81 m_mp_init_multi(&dh_y, &dh_f, NULL);
82
83 gen_kexdh_vals(&dh_f, &dh_y);
84
85 kexdh_comb_key(&dh_f, &dh_y, dh_e, svr_opts.hostkey);
86 mp_clear(&dh_y);
87 88
88 /* we can start creating the kexdh_reply packet */ 89 /* we can start creating the kexdh_reply packet */
89 CHECKCLEARTOWRITE(); 90 CHECKCLEARTOWRITE();
90 buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY); 91 buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_REPLY);
91 buf_put_pub_key(ses.writepayload, svr_opts.hostkey, 92 buf_put_pub_key(ses.writepayload, svr_opts.hostkey,
92 ses.newkeys->algo_hostkey); 93 ses.newkeys->algo_hostkey);
93 94
94 /* put f */ 95 if (IS_NORMAL_DH(ses.newkeys->algo_kex)) {
95 buf_putmpint(ses.writepayload, &dh_f); 96 // Normal diffie-hellman
96 mp_clear(&dh_f); 97 struct kex_dh_param * dh_param = gen_kexdh_param();
98 kexdh_comb_key(dh_param, dh_e, svr_opts.hostkey);
99
100 /* put f */
101 buf_putmpint(ses.writepayload, &dh_param->pub);
102 free_kexdh_param(dh_param);
103 } else {
104 #ifdef DROPBEAR_ECDH
105 struct kex_ecdh_param *ecdh_param = gen_kexecdh_param();
106 kexecdh_comb_key(ecdh_param, ecdh_qs, svr_opts.hostkey);
107
108 buf_put_ecc_raw_pubkey_string(ses.writepayload, &ecdh_param->key);
109 free_kexecdh_param(ecdh_param);
110 #endif
111 }
97 112
98 /* calc the signature */ 113 /* calc the signature */
99 buf_put_sign(ses.writepayload, svr_opts.hostkey, 114 buf_put_sign(ses.writepayload, svr_opts.hostkey,
100 ses.newkeys->algo_hostkey, ses.hash, SHA1_HASH_SIZE); 115 ses.newkeys->algo_hostkey, ses.hash);
101 116
102 /* the SSH_MSG_KEXDH_REPLY is done */ 117 /* the SSH_MSG_KEXDH_REPLY is done */
103 encrypt_packet(); 118 encrypt_packet();
104 119
105 TRACE(("leave send_msg_kexdh_reply")) 120 TRACE(("leave send_msg_kexdh_reply"))