Mercurial > dropbear
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")) |