4 * Copyright (c) 2002-2004 Matt Johnston
5 * Portions Copyright (c) 2004 by Mihnea Stoenescu
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 #include "crypto_desc.h"
40 /* diffie-hellman-group1-sha1 value for p */
41 const unsigned char dh_p_1
[DH_P_1_LEN
] = {
42 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
43 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
44 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
45 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
46 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
47 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
48 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
49 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
50 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
51 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
52 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
54 /* diffie-hellman-group14-sha1 value for p */
55 const unsigned char dh_p_14
[DH_P_14_LEN
] = {
56 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
57 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
58 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
59 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
60 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
61 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
62 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
63 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
64 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
65 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
66 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
67 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
68 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
69 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
70 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
71 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
72 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
73 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
74 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
75 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
76 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
77 0xFF, 0xFF, 0xFF, 0xFF};
79 /* Same for group1 and group14 */
80 static const int DH_G_VAL
= 2;
82 static void kexinitialise();
83 static void gen_new_keys();
85 static void gen_new_zstream_recv();
86 static void gen_new_zstream_trans();
88 static void read_kex_algos();
89 /* helper function for gen_new_keys */
90 static void hashkeys(unsigned char *out
, unsigned int outlen
,
91 const hash_state
* hs
, const unsigned char X
);
92 static void finish_kexhashbuf(void);
95 /* Send our list of algorithms we can use */
96 void send_msg_kexinit() {
99 buf_putbyte(ses
.writepayload
, SSH_MSG_KEXINIT
);
102 genrandom(buf_getwriteptr(ses
.writepayload
, 16), 16);
103 buf_incrwritepos(ses
.writepayload
, 16);
106 buf_put_algolist(ses
.writepayload
, sshkex
);
108 /* server_host_key_algorithms */
109 buf_put_algolist(ses
.writepayload
, sshhostkey
);
111 /* encryption_algorithms_client_to_server */
112 buf_put_algolist(ses
.writepayload
, sshciphers
);
114 /* encryption_algorithms_server_to_client */
115 buf_put_algolist(ses
.writepayload
, sshciphers
);
117 /* mac_algorithms_client_to_server */
118 buf_put_algolist(ses
.writepayload
, sshhashes
);
120 /* mac_algorithms_server_to_client */
121 buf_put_algolist(ses
.writepayload
, sshhashes
);
124 /* compression_algorithms_client_to_server */
125 buf_put_algolist(ses
.writepayload
, ses
.compress_algos
);
127 /* compression_algorithms_server_to_client */
128 buf_put_algolist(ses
.writepayload
, ses
.compress_algos
);
130 /* languages_client_to_server */
131 buf_putstring(ses
.writepayload
, "", 0);
133 /* languages_server_to_client */
134 buf_putstring(ses
.writepayload
, "", 0);
136 /* first_kex_packet_follows */
137 buf_putbyte(ses
.writepayload
, (ses
.send_kex_first_guess
!= NULL
));
139 /* reserved unit32 */
140 buf_putint(ses
.writepayload
, 0);
142 /* set up transmitted kex packet buffer for hashing.
143 * This is freed after the end of the kex */
144 ses
.transkexinit
= buf_newcopy(ses
.writepayload
);
147 ses
.dataallowed
= 0; /* don't send other packets during kex */
149 ses
.kexstate
.sentkexinit
= 1;
151 ses
.newkeys
= (struct key_context
*)m_malloc(sizeof(struct key_context
));
153 if (ses
.send_kex_first_guess
) {
154 ses
.newkeys
->algo_kex
= sshkex
[0].data
;
155 ses
.newkeys
->algo_hostkey
= sshhostkey
[0].val
;
156 ses
.send_kex_first_guess();
159 TRACE(("DATAALLOWED=0"))
160 TRACE(("-> KEXINIT"))
164 static void switch_keys() {
165 TRACE2(("enter switch_keys"))
166 if (!(ses
.kexstate
.sentkexinit
&& ses
.kexstate
.recvkexinit
)) {
167 dropbear_exit("Unexpected newkeys message");
171 ses
.keys
= m_malloc(sizeof(*ses
.newkeys
));
173 if (ses
.kexstate
.recvnewkeys
&& ses
.newkeys
->recv
.valid
) {
174 TRACE(("switch_keys recv"))
176 gen_new_zstream_recv();
178 ses
.keys
->recv
= ses
.newkeys
->recv
;
179 m_burn(&ses
.newkeys
->recv
, sizeof(ses
.newkeys
->recv
));
180 ses
.newkeys
->recv
.valid
= 0;
182 if (ses
.kexstate
.sentnewkeys
&& ses
.newkeys
->trans
.valid
) {
183 TRACE(("switch_keys trans"))
185 gen_new_zstream_trans();
187 ses
.keys
->trans
= ses
.newkeys
->trans
;
188 m_burn(&ses
.newkeys
->trans
, sizeof(ses
.newkeys
->trans
));
189 ses
.newkeys
->trans
.valid
= 0;
191 if (ses
.kexstate
.sentnewkeys
&& ses
.kexstate
.recvnewkeys
)
193 TRACE(("switch_keys done"))
194 ses
.keys
->algo_kex
= ses
.newkeys
->algo_kex
;
195 ses
.keys
->algo_hostkey
= ses
.newkeys
->algo_hostkey
;
196 ses
.keys
->allow_compress
= 0;
201 TRACE2(("leave switch_keys"))
204 /* Bring new keys into use after a key exchange, and let the client know*/
205 void send_msg_newkeys() {
207 TRACE(("enter send_msg_newkeys"))
209 /* generate the kexinit request */
211 buf_putbyte(ses
.writepayload
, SSH_MSG_NEWKEYS
);
215 /* set up our state */
216 ses
.kexstate
.sentnewkeys
= 1;
217 ses
.kexstate
.donefirstkex
= 1;
218 ses
.dataallowed
= 1; /* we can send other packets again now */
222 TRACE(("leave send_msg_newkeys"))
225 /* Bring the new keys into use after a key exchange */
226 void recv_msg_newkeys() {
228 TRACE(("enter recv_msg_newkeys"))
230 ses
.kexstate
.recvnewkeys
= 1;
233 TRACE(("leave recv_msg_newkeys"))
237 /* Set up the kex for the first time */
238 void kexfirstinitialise() {
239 ses
.kexstate
.donefirstkex
= 0;
242 ses
.compress_algos
= ssh_nocompress
;
244 switch (opts
.compress_mode
)
246 case DROPBEAR_COMPRESS_DELAYED
:
247 ses
.compress_algos
= ssh_delaycompress
;
250 case DROPBEAR_COMPRESS_ON
:
251 ses
.compress_algos
= ssh_compress
;
254 case DROPBEAR_COMPRESS_OFF
:
255 ses
.compress_algos
= ssh_nocompress
;
262 /* Reset the kex state, ready for a new negotiation */
263 static void kexinitialise() {
265 TRACE(("kexinitialise()"))
267 /* sent/recv'd MSG_KEXINIT */
268 ses
.kexstate
.sentkexinit
= 0;
269 ses
.kexstate
.recvkexinit
= 0;
271 /* sent/recv'd MSG_NEWKEYS */
272 ses
.kexstate
.recvnewkeys
= 0;
273 ses
.kexstate
.sentnewkeys
= 0;
275 /* first_packet_follows */
276 ses
.kexstate
.them_firstfollows
= 0;
278 ses
.kexstate
.datatrans
= 0;
279 ses
.kexstate
.datarecv
= 0;
281 ses
.kexstate
.our_first_follows_matches
= 0;
283 ses
.kexstate
.lastkextime
= monotonic_now();
287 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the
288 * already initialised hash_state hs, which should already have processed
289 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
290 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
292 * See Section 7.2 of rfc4253 (ssh transport) for details */
293 static void hashkeys(unsigned char *out
, unsigned int outlen
,
294 const hash_state
* hs
, const unsigned char X
) {
296 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
299 unsigned char tmpout
[MAX_HASH_SIZE
];
301 memcpy(&hs2
, hs
, sizeof(hash_state
));
302 hash_desc
->process(&hs2
, &X
, 1);
303 hash_desc
->process(&hs2
, ses
.session_id
->data
, ses
.session_id
->len
);
304 hash_desc
->done(&hs2
, tmpout
);
305 memcpy(out
, tmpout
, MIN(hash_desc
->hashsize
, outlen
));
306 for (offset
= hash_desc
->hashsize
;
308 offset
+= hash_desc
->hashsize
)
311 memcpy(&hs2
, hs
, sizeof(hash_state
));
312 hash_desc
->process(&hs2
, out
, offset
);
313 hash_desc
->done(&hs2
, tmpout
);
314 memcpy(&out
[offset
], tmpout
, MIN(outlen
- offset
, hash_desc
->hashsize
));
316 m_burn(&hs2
, sizeof(hash_state
));
319 /* Generate the actual encryption/integrity keys, using the results of the
320 * key exchange, as specified in section 7.2 of the transport rfc 4253.
321 * This occurs after the DH key-exchange.
323 * ses.newkeys is the new set of keys which are generated, these are only
324 * taken into use after both sides have sent a newkeys message */
326 static void gen_new_keys() {
328 unsigned char C2S_IV
[MAX_IV_LEN
];
329 unsigned char C2S_key
[MAX_KEY_LEN
];
330 unsigned char S2C_IV
[MAX_IV_LEN
];
331 unsigned char S2C_key
[MAX_KEY_LEN
];
332 /* unsigned char key[MAX_KEY_LEN]; */
333 unsigned char *trans_IV
, *trans_key
, *recv_IV
, *recv_key
;
336 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
337 char mactransletter
, macrecvletter
; /* Client or server specific */
339 TRACE(("enter gen_new_keys"))
340 /* the dh_K and hash are the start of all hashes, we make use of that */
342 hash_desc
->init(&hs
);
343 hash_process_mp(hash_desc
, &hs
, ses
.dh_K
);
346 hash_desc
->process(&hs
, ses
.hash
->data
, ses
.hash
->len
);
351 if (IS_DROPBEAR_CLIENT
) {
356 mactransletter
= 'E';
363 mactransletter
= 'F';
367 hashkeys(C2S_IV
, sizeof(C2S_IV
), &hs
, 'A');
368 hashkeys(S2C_IV
, sizeof(S2C_IV
), &hs
, 'B');
369 hashkeys(C2S_key
, sizeof(C2S_key
), &hs
, 'C');
370 hashkeys(S2C_key
, sizeof(S2C_key
), &hs
, 'D');
372 if (ses
.newkeys
->recv
.algo_crypt
->cipherdesc
!= NULL
) {
373 int recv_cipher
= find_cipher(ses
.newkeys
->recv
.algo_crypt
->cipherdesc
->name
);
375 dropbear_exit("Crypto error");
376 if (ses
.newkeys
->recv
.crypt_mode
->start(recv_cipher
,
378 ses
.newkeys
->recv
.algo_crypt
->keysize
, 0,
379 &ses
.newkeys
->recv
.cipher_state
) != CRYPT_OK
) {
380 dropbear_exit("Crypto error");
384 if (ses
.newkeys
->trans
.algo_crypt
->cipherdesc
!= NULL
) {
385 int trans_cipher
= find_cipher(ses
.newkeys
->trans
.algo_crypt
->cipherdesc
->name
);
386 if (trans_cipher
< 0)
387 dropbear_exit("Crypto error");
388 if (ses
.newkeys
->trans
.crypt_mode
->start(trans_cipher
,
390 ses
.newkeys
->trans
.algo_crypt
->keysize
, 0,
391 &ses
.newkeys
->trans
.cipher_state
) != CRYPT_OK
) {
392 dropbear_exit("Crypto error");
396 if (ses
.newkeys
->trans
.algo_mac
->hash_desc
!= NULL
) {
397 hashkeys(ses
.newkeys
->trans
.mackey
,
398 ses
.newkeys
->trans
.algo_mac
->keysize
, &hs
, mactransletter
);
399 ses
.newkeys
->trans
.hash_index
= find_hash(ses
.newkeys
->trans
.algo_mac
->hash_desc
->name
);
402 if (ses
.newkeys
->recv
.algo_mac
->hash_desc
!= NULL
) {
403 hashkeys(ses
.newkeys
->recv
.mackey
,
404 ses
.newkeys
->recv
.algo_mac
->keysize
, &hs
, macrecvletter
);
405 ses
.newkeys
->recv
.hash_index
= find_hash(ses
.newkeys
->recv
.algo_mac
->hash_desc
->name
);
408 /* Ready to switch over */
409 ses
.newkeys
->trans
.valid
= 1;
410 ses
.newkeys
->recv
.valid
= 1;
412 m_burn(C2S_IV
, sizeof(C2S_IV
));
413 m_burn(C2S_key
, sizeof(C2S_key
));
414 m_burn(S2C_IV
, sizeof(S2C_IV
));
415 m_burn(S2C_key
, sizeof(S2C_key
));
416 m_burn(&hs
, sizeof(hash_state
));
418 TRACE(("leave gen_new_keys"))
423 int is_compress_trans() {
424 return ses
.keys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB
425 || (ses
.authstate
.authdone
426 && ses
.keys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
);
429 int is_compress_recv() {
430 return ses
.keys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB
431 || (ses
.authstate
.authdone
432 && ses
.keys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
);
435 /* Set up new zlib compression streams, close the old ones. Only
436 * called from gen_new_keys() */
437 static void gen_new_zstream_recv() {
439 /* create new zstreams */
440 if (ses
.newkeys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB
441 || ses
.newkeys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
) {
442 ses
.newkeys
->recv
.zstream
= (z_streamp
)m_malloc(sizeof(z_stream
));
443 ses
.newkeys
->recv
.zstream
->zalloc
= Z_NULL
;
444 ses
.newkeys
->recv
.zstream
->zfree
= Z_NULL
;
446 if (inflateInit(ses
.newkeys
->recv
.zstream
) != Z_OK
) {
447 dropbear_exit("zlib error");
450 ses
.newkeys
->recv
.zstream
= NULL
;
452 /* clean up old keys */
453 if (ses
.keys
->recv
.zstream
!= NULL
) {
454 if (inflateEnd(ses
.keys
->recv
.zstream
) == Z_STREAM_ERROR
) {
455 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
456 dropbear_exit("Crypto error");
458 m_free(ses
.keys
->recv
.zstream
);
462 static void gen_new_zstream_trans() {
464 if (ses
.newkeys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB
465 || ses
.newkeys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
) {
466 ses
.newkeys
->trans
.zstream
= (z_streamp
)m_malloc(sizeof(z_stream
));
467 ses
.newkeys
->trans
.zstream
->zalloc
= Z_NULL
;
468 ses
.newkeys
->trans
.zstream
->zfree
= Z_NULL
;
470 if (deflateInit2(ses
.newkeys
->trans
.zstream
, Z_DEFAULT_COMPRESSION
,
471 Z_DEFLATED
, DROPBEAR_ZLIB_WINDOW_BITS
,
472 DROPBEAR_ZLIB_MEM_LEVEL
, Z_DEFAULT_STRATEGY
)
474 dropbear_exit("zlib error");
477 ses
.newkeys
->trans
.zstream
= NULL
;
480 if (ses
.keys
->trans
.zstream
!= NULL
) {
481 if (deflateEnd(ses
.keys
->trans
.zstream
) == Z_STREAM_ERROR
) {
482 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
483 dropbear_exit("Crypto error");
485 m_free(ses
.keys
->trans
.zstream
);
488 #endif /* DISABLE_ZLIB */
491 /* Executed upon receiving a kexinit message from the client to initiate
492 * key exchange. If we haven't already done so, we send the list of our
493 * preferred algorithms. The client's requested algorithms are processed,
494 * and we calculate the first portion of the key-exchange-hash for used
495 * later in the key exchange. No response is sent, as the client should
496 * initiate the diffie-hellman key exchange */
497 void recv_msg_kexinit() {
499 unsigned int kexhashbuf_len
= 0;
500 unsigned int remote_ident_len
= 0;
501 unsigned int local_ident_len
= 0;
503 TRACE(("<- KEXINIT"))
504 TRACE(("enter recv_msg_kexinit"))
506 if (!ses
.kexstate
.sentkexinit
) {
507 /* we need to send a kex packet */
509 TRACE(("continue recv_msg_kexinit: sent kexinit"))
512 /* start the kex hash */
513 local_ident_len
= strlen(LOCAL_IDENT
);
514 remote_ident_len
= strlen((char*)ses
.remoteident
);
516 kexhashbuf_len
= local_ident_len
+ remote_ident_len
517 + ses
.transkexinit
->len
+ ses
.payload
->len
518 + KEXHASHBUF_MAX_INTS
;
520 ses
.kexhashbuf
= buf_new(kexhashbuf_len
);
522 if (IS_DROPBEAR_CLIENT
) {
524 /* read the peer's choice of algos */
527 /* V_C, the client's version string (CR and NL excluded) */
528 buf_putstring(ses
.kexhashbuf
,
529 (unsigned char*)LOCAL_IDENT
, local_ident_len
);
530 /* V_S, the server's version string (CR and NL excluded) */
531 buf_putstring(ses
.kexhashbuf
, ses
.remoteident
, remote_ident_len
);
533 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
534 buf_putstring(ses
.kexhashbuf
,
535 ses
.transkexinit
->data
, ses
.transkexinit
->len
);
536 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
537 buf_setpos(ses
.payload
, 0);
538 buf_putstring(ses
.kexhashbuf
, ses
.payload
->data
, ses
.payload
->len
);
539 ses
.requirenext
= SSH_MSG_KEXDH_REPLY
;
543 /* read the peer's choice of algos */
545 /* V_C, the client's version string (CR and NL excluded) */
546 buf_putstring(ses
.kexhashbuf
, ses
.remoteident
, remote_ident_len
);
547 /* V_S, the server's version string (CR and NL excluded) */
548 buf_putstring(ses
.kexhashbuf
,
549 (unsigned char*)LOCAL_IDENT
, local_ident_len
);
551 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
552 buf_setpos(ses
.payload
, 0);
553 buf_putstring(ses
.kexhashbuf
, ses
.payload
->data
, ses
.payload
->len
);
555 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
556 buf_putstring(ses
.kexhashbuf
,
557 ses
.transkexinit
->data
, ses
.transkexinit
->len
);
559 ses
.requirenext
= SSH_MSG_KEXDH_INIT
;
562 buf_free(ses
.transkexinit
);
563 ses
.transkexinit
= NULL
;
564 /* the rest of ses.kexhashbuf will be done after DH exchange */
566 ses
.kexstate
.recvkexinit
= 1;
568 TRACE(("leave recv_msg_kexinit"))
571 static void load_dh_p(mp_int
* dh_p
)
573 bytes_to_mp(dh_p
, ses
.newkeys
->algo_kex
->dh_p_bytes
,
574 ses
.newkeys
->algo_kex
->dh_p_len
);
577 /* Initialises and generate one side of the diffie-hellman key exchange values.
578 * See the transport rfc 4253 section 8 for details */
579 /* dh_pub and dh_priv MUST be already initialised */
580 struct kex_dh_param
*gen_kexdh_param() {
581 struct kex_dh_param
*param
= NULL
;
587 TRACE(("enter gen_kexdh_vals"))
589 param
= m_malloc(sizeof(*param
));
590 m_mp_init_multi(¶m
->pub
, ¶m
->priv
, &dh_g
, &dh_p
, &dh_q
, NULL
);
592 /* read the prime and generator*/
595 if (mp_set_int(&dh_g
, DH_G_VAL
) != MP_OKAY
) {
596 dropbear_exit("Diffie-Hellman error");
599 /* calculate q = (p-1)/2 */
600 /* dh_priv is just a temp var here */
601 if (mp_sub_d(&dh_p
, 1, ¶m
->priv
) != MP_OKAY
) {
602 dropbear_exit("Diffie-Hellman error");
604 if (mp_div_2(¶m
->priv
, &dh_q
) != MP_OKAY
) {
605 dropbear_exit("Diffie-Hellman error");
608 /* Generate a private portion 0 < dh_priv < dh_q */
609 gen_random_mpint(&dh_q
, ¶m
->priv
);
612 if (mp_exptmod(&dh_g
, ¶m
->priv
, &dh_p
, ¶m
->pub
) != MP_OKAY
) {
613 dropbear_exit("Diffie-Hellman error");
615 mp_clear_multi(&dh_g
, &dh_p
, &dh_q
, NULL
);
619 void free_kexdh_param(struct kex_dh_param
*param
)
621 mp_clear_multi(¶m
->pub
, ¶m
->priv
, NULL
);
625 /* This function is fairly common between client/server, with some substitution
626 * of dh_e/dh_f etc. Hence these arguments:
627 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is
628 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
629 void kexdh_comb_key(struct kex_dh_param
*param
, mp_int
*dh_pub_them
,
633 mp_int
*dh_e
= NULL
, *dh_f
= NULL
;
635 /* read the prime and generator*/
639 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
640 if (mp_cmp(dh_pub_them
, &dh_p
) != MP_LT
641 || mp_cmp_d(dh_pub_them
, 0) != MP_GT
) {
642 dropbear_exit("Diffie-Hellman error");
645 /* K = e^y mod p = f^x mod p */
646 m_mp_alloc_init_multi(&ses
.dh_K
, NULL
);
647 if (mp_exptmod(dh_pub_them
, ¶m
->priv
, &dh_p
, ses
.dh_K
) != MP_OKAY
) {
648 dropbear_exit("Diffie-Hellman error");
651 /* clear no longer needed vars */
652 mp_clear_multi(&dh_p
, NULL
);
654 /* From here on, the code needs to work with the _same_ vars on each side,
655 * not vice-versaing for client/server */
656 if (IS_DROPBEAR_CLIENT
) {
664 /* Create the remainder of the hash buffer, to generate the exchange hash */
665 /* K_S, the host key */
666 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
667 /* e, exchange value sent by the client */
668 buf_putmpint(ses
.kexhashbuf
, dh_e
);
669 /* f, exchange value sent by the server */
670 buf_putmpint(ses
.kexhashbuf
, dh_f
);
671 /* K, the shared secret */
672 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
674 /* calculate the hash H to sign */
679 struct kex_ecdh_param
*gen_kexecdh_param() {
680 struct kex_ecdh_param
*param
= m_malloc(sizeof(*param
));
681 if (ecc_make_key_ex(NULL
, dropbear_ltc_prng
,
682 ¶m
->key
, ses
.newkeys
->algo_kex
->ecc_curve
->dp
) != CRYPT_OK
) {
683 dropbear_exit("ECC error");
688 void free_kexecdh_param(struct kex_ecdh_param
*param
) {
689 ecc_free(¶m
->key
);
693 void kexecdh_comb_key(struct kex_ecdh_param
*param
, buffer
*pub_them
,
695 const struct dropbear_kex
*algo_kex
= ses
.newkeys
->algo_kex
;
696 /* public keys from client and server */
697 ecc_key
*Q_C
, *Q_S
, *Q_them
;
699 Q_them
= buf_get_ecc_raw_pubkey(pub_them
, algo_kex
->ecc_curve
);
701 ses
.dh_K
= dropbear_ecc_shared_secret(Q_them
, ¶m
->key
);
703 /* Create the remainder of the hash buffer, to generate the exchange hash
704 See RFC5656 section 4 page 7 */
705 if (IS_DROPBEAR_CLIENT
) {
713 /* K_S, the host key */
714 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
715 /* Q_C, client's ephemeral public key octet string */
716 buf_put_ecc_raw_pubkey_string(ses
.kexhashbuf
, Q_C
);
717 /* Q_S, server's ephemeral public key octet string */
718 buf_put_ecc_raw_pubkey_string(ses
.kexhashbuf
, Q_S
);
719 /* K, the shared secret */
720 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
722 /* calculate the hash H to sign */
725 #endif /* DROPBEAR_ECDH */
727 #ifdef DROPBEAR_CURVE25519
728 struct kex_curve25519_param
*gen_kexcurve25519_param () {
729 /* Per http://cr.yp.to/ecdh.html */
730 struct kex_curve25519_param
*param
= m_malloc(sizeof(*param
));
731 const unsigned char basepoint
[32] = {9};
733 genrandom(param
->priv
, CURVE25519_LEN
);
734 param
->priv
[0] &= 248;
735 param
->priv
[31] &= 127;
736 param
->priv
[31] |= 64;
738 curve25519_donna(param
->pub
, param
->priv
, basepoint
);
743 void free_kexcurve25519_param(struct kex_curve25519_param
*param
)
745 m_burn(param
->priv
, CURVE25519_LEN
);
749 void kexcurve25519_comb_key(struct kex_curve25519_param
*param
, buffer
*buf_pub_them
,
751 unsigned char out
[CURVE25519_LEN
];
752 const unsigned char* Q_C
= NULL
;
753 const unsigned char* Q_S
= NULL
;
755 if (buf_pub_them
->len
!= CURVE25519_LEN
)
757 dropbear_exit("Bad curve25519");
760 curve25519_donna(out
, param
->priv
, buf_pub_them
->data
);
761 m_mp_alloc_init_multi(&ses
.dh_K
, NULL
);
762 bytes_to_mp(ses
.dh_K
, out
, CURVE25519_LEN
);
763 m_burn(out
, sizeof(out
));
765 /* Create the remainder of the hash buffer, to generate the exchange hash.
766 See RFC5656 section 4 page 7 */
767 if (IS_DROPBEAR_CLIENT
) {
769 Q_S
= buf_pub_them
->data
;
772 Q_C
= buf_pub_them
->data
;
775 /* K_S, the host key */
776 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
777 /* Q_C, client's ephemeral public key octet string */
778 buf_putstring(ses
.kexhashbuf
, Q_C
, CURVE25519_LEN
);
779 /* Q_S, server's ephemeral public key octet string */
780 buf_putstring(ses
.kexhashbuf
, Q_S
, CURVE25519_LEN
);
781 /* K, the shared secret */
782 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
784 /* calculate the hash H to sign */
787 #endif /* DROPBEAR_CURVE25519 */
791 static void finish_kexhashbuf(void) {
793 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
795 hash_desc
->init(&hs
);
796 buf_setpos(ses
.kexhashbuf
, 0);
797 hash_desc
->process(&hs
, buf_getptr(ses
.kexhashbuf
, ses
.kexhashbuf
->len
),
798 ses
.kexhashbuf
->len
);
799 ses
.hash
= buf_new(hash_desc
->hashsize
);
800 hash_desc
->done(&hs
, buf_getwriteptr(ses
.hash
, hash_desc
->hashsize
));
801 buf_setlen(ses
.hash
, hash_desc
->hashsize
);
803 #if defined(DEBUG_KEXHASH) && defined(DEBUG_TRACE)
805 printhex("kexhashbuf", ses
.kexhashbuf
->data
, ses
.kexhashbuf
->len
);
806 printhex("kexhash", ses
.hash
->data
, ses
.hash
->len
);
810 buf_burn(ses
.kexhashbuf
);
811 buf_free(ses
.kexhashbuf
);
812 m_burn(&hs
, sizeof(hash_state
));
813 ses
.kexhashbuf
= NULL
;
815 /* first time around, we set the session_id to H */
816 if (ses
.session_id
== NULL
) {
817 /* create the session_id, this never needs freeing */
818 ses
.session_id
= buf_newcopy(ses
.hash
);
822 /* read the other side's algo list. buf_match_algo is a callback to match
823 * algos for the client or server. */
824 static void read_kex_algos() {
827 algo_type
* c2s_hash_algo
= NULL
;
828 algo_type
* s2c_hash_algo
= NULL
;
829 algo_type
* c2s_cipher_algo
= NULL
;
830 algo_type
* s2c_cipher_algo
= NULL
;
831 algo_type
* c2s_comp_algo
= NULL
;
832 algo_type
* s2c_comp_algo
= NULL
;
833 /* the generic one */
834 algo_type
* algo
= NULL
;
836 /* which algo couldn't match */
837 char * erralgo
= NULL
;
840 int allgood
= 1; /* we AND this with each goodguess and see if its still
844 enum kexguess2_used kexguess2
= KEXGUESS2_LOOK
;
846 enum kexguess2_used kexguess2
= KEXGUESS2_NO
;
849 buf_incrpos(ses
.payload
, 16); /* start after the cookie */
851 memset(ses
.newkeys
, 0x0, sizeof(*ses
.newkeys
));
854 algo
= buf_match_algo(ses
.payload
, sshkex
, &kexguess2
, &goodguess
);
855 allgood
&= goodguess
;
856 if (algo
== NULL
|| algo
->val
== KEXGUESS2_ALGO_ID
) {
860 TRACE(("kexguess2 %d", kexguess2
))
861 TRACE(("kex algo %s", algo
->name
))
862 ses
.newkeys
->algo_kex
= algo
->data
;
864 /* server_host_key_algorithms */
865 algo
= buf_match_algo(ses
.payload
, sshhostkey
, &kexguess2
, &goodguess
);
866 allgood
&= goodguess
;
871 TRACE(("hostkey algo %s", algo
->name
))
872 ses
.newkeys
->algo_hostkey
= algo
->val
;
874 /* encryption_algorithms_client_to_server */
875 c2s_cipher_algo
= buf_match_algo(ses
.payload
, sshciphers
, NULL
, NULL
);
876 if (c2s_cipher_algo
== NULL
) {
877 erralgo
= "enc c->s";
880 TRACE(("enc c2s is %s", c2s_cipher_algo
->name
))
882 /* encryption_algorithms_server_to_client */
883 s2c_cipher_algo
= buf_match_algo(ses
.payload
, sshciphers
, NULL
, NULL
);
884 if (s2c_cipher_algo
== NULL
) {
885 erralgo
= "enc s->c";
888 TRACE(("enc s2c is %s", s2c_cipher_algo
->name
))
890 /* mac_algorithms_client_to_server */
891 c2s_hash_algo
= buf_match_algo(ses
.payload
, sshhashes
, NULL
, NULL
);
892 if (c2s_hash_algo
== NULL
) {
893 erralgo
= "mac c->s";
896 TRACE(("hash c2s is %s", c2s_hash_algo
->name
))
898 /* mac_algorithms_server_to_client */
899 s2c_hash_algo
= buf_match_algo(ses
.payload
, sshhashes
, NULL
, NULL
);
900 if (s2c_hash_algo
== NULL
) {
901 erralgo
= "mac s->c";
904 TRACE(("hash s2c is %s", s2c_hash_algo
->name
))
906 /* compression_algorithms_client_to_server */
907 c2s_comp_algo
= buf_match_algo(ses
.payload
, ses
.compress_algos
, NULL
, NULL
);
908 if (c2s_comp_algo
== NULL
) {
909 erralgo
= "comp c->s";
912 TRACE(("hash c2s is %s", c2s_comp_algo
->name
))
914 /* compression_algorithms_server_to_client */
915 s2c_comp_algo
= buf_match_algo(ses
.payload
, ses
.compress_algos
, NULL
, NULL
);
916 if (s2c_comp_algo
== NULL
) {
917 erralgo
= "comp s->c";
920 TRACE(("hash s2c is %s", s2c_comp_algo
->name
))
922 /* languages_client_to_server */
923 buf_eatstring(ses
.payload
);
925 /* languages_server_to_client */
926 buf_eatstring(ses
.payload
);
928 /* their first_kex_packet_follows */
929 if (buf_getbool(ses
.payload
)) {
930 TRACE(("them kex firstfollows. allgood %d", allgood
))
931 ses
.kexstate
.them_firstfollows
= 1;
932 /* if the guess wasn't good, we ignore the packet sent */
938 /* Handle the asymmetry */
939 if (IS_DROPBEAR_CLIENT
) {
940 ses
.newkeys
->recv
.algo_crypt
=
941 (struct dropbear_cipher
*)s2c_cipher_algo
->data
;
942 ses
.newkeys
->trans
.algo_crypt
=
943 (struct dropbear_cipher
*)c2s_cipher_algo
->data
;
944 ses
.newkeys
->recv
.crypt_mode
=
945 (struct dropbear_cipher_mode
*)s2c_cipher_algo
->mode
;
946 ses
.newkeys
->trans
.crypt_mode
=
947 (struct dropbear_cipher_mode
*)c2s_cipher_algo
->mode
;
948 ses
.newkeys
->recv
.algo_mac
=
949 (struct dropbear_hash
*)s2c_hash_algo
->data
;
950 ses
.newkeys
->trans
.algo_mac
=
951 (struct dropbear_hash
*)c2s_hash_algo
->data
;
952 ses
.newkeys
->recv
.algo_comp
= s2c_comp_algo
->val
;
953 ses
.newkeys
->trans
.algo_comp
= c2s_comp_algo
->val
;
956 ses
.newkeys
->recv
.algo_crypt
=
957 (struct dropbear_cipher
*)c2s_cipher_algo
->data
;
958 ses
.newkeys
->trans
.algo_crypt
=
959 (struct dropbear_cipher
*)s2c_cipher_algo
->data
;
960 ses
.newkeys
->recv
.crypt_mode
=
961 (struct dropbear_cipher_mode
*)c2s_cipher_algo
->mode
;
962 ses
.newkeys
->trans
.crypt_mode
=
963 (struct dropbear_cipher_mode
*)s2c_cipher_algo
->mode
;
964 ses
.newkeys
->recv
.algo_mac
=
965 (struct dropbear_hash
*)c2s_hash_algo
->data
;
966 ses
.newkeys
->trans
.algo_mac
=
967 (struct dropbear_hash
*)s2c_hash_algo
->data
;
968 ses
.newkeys
->recv
.algo_comp
= c2s_comp_algo
->val
;
969 ses
.newkeys
->trans
.algo_comp
= s2c_comp_algo
->val
;
972 /* reserved for future extensions */
973 buf_getint(ses
.payload
);
975 if (ses
.send_kex_first_guess
&& allgood
) {
976 TRACE(("our_first_follows_matches 1"))
977 ses
.kexstate
.our_first_follows_matches
= 1;
982 dropbear_exit("No matching algo %s", erralgo
);