1 /*
2  * Dropbear SSH
3  *
4  * Copyright (c) 2002-2004 Matt Johnston
5  * Portions Copyright (c) 2004 by Mihnea Stoenescu
6  * All rights reserved.
7  *
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:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
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
24  * SOFTWARE. */
25 
26 #include "includes.h"
27 #include "dbutil.h"
28 #include "algo.h"
29 #include "buffer.h"
30 #include "session.h"
31 #include "kex.h"
32 #include "dh_groups.h"
33 #include "ssh.h"
34 #include "packet.h"
35 #include "bignum.h"
36 #include "dbrandom.h"
37 #include "runopts.h"
38 #include "ecc.h"
39 #include "curve25519.h"
40 #include "crypto_desc.h"
41 
42 static void kexinitialise(void);
43 static void gen_new_keys(void);
44 #ifndef DISABLE_ZLIB
45 static void gen_new_zstream_recv(void);
46 static void gen_new_zstream_trans(void);
47 #endif
48 static void read_kex_algos(void);
49 /* helper function for gen_new_keys */
50 static void hashkeys(unsigned char *out, unsigned int outlen,
51 		const hash_state * hs, const unsigned char X);
52 
53 
54 /* Send our list of algorithms we can use */
send_msg_kexinit()55 void send_msg_kexinit() {
56 
57 	CHECKCLEARTOWRITE();
58 	buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);
59 
60 	/* cookie */
61 	genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
62 	buf_incrwritepos(ses.writepayload, 16);
63 
64 	/* kex algos */
65 	buf_put_algolist(ses.writepayload, sshkex);
66 
67 	/* server_host_key_algorithms */
68 	buf_put_algolist(ses.writepayload, sigalgs);
69 
70 	/* encryption_algorithms_client_to_server */
71 	buf_put_algolist(ses.writepayload, sshciphers);
72 
73 	/* encryption_algorithms_server_to_client */
74 	buf_put_algolist(ses.writepayload, sshciphers);
75 
76 	/* mac_algorithms_client_to_server */
77 	buf_put_algolist(ses.writepayload, sshhashes);
78 
79 	/* mac_algorithms_server_to_client */
80 	buf_put_algolist(ses.writepayload, sshhashes);
81 
82 
83 	/* compression_algorithms_client_to_server */
84 	buf_put_algolist(ses.writepayload, ses.compress_algos);
85 
86 	/* compression_algorithms_server_to_client */
87 	buf_put_algolist(ses.writepayload, ses.compress_algos);
88 
89 	/* languages_client_to_server */
90 	buf_putstring(ses.writepayload, "", 0);
91 
92 	/* languages_server_to_client */
93 	buf_putstring(ses.writepayload, "", 0);
94 
95 	/* first_kex_packet_follows */
96 	buf_putbyte(ses.writepayload, (ses.send_kex_first_guess != NULL));
97 
98 	/* reserved unit32 */
99 	buf_putint(ses.writepayload, 0);
100 
101 	/* set up transmitted kex packet buffer for hashing.
102 	 * This is freed after the end of the kex */
103 	ses.transkexinit = buf_newcopy(ses.writepayload);
104 
105 	encrypt_packet();
106 	ses.dataallowed = 0; /* don't send other packets during kex */
107 
108 	ses.kexstate.sentkexinit = 1;
109 
110 	ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
111 
112 	if (ses.send_kex_first_guess) {
113 		ses.newkeys->algo_kex = first_usable_algo(sshkex)->data;
114 		ses.newkeys->algo_signature = first_usable_algo(sigalgs)->val;
115 		ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
116 		ses.send_kex_first_guess();
117 	}
118 
119 	TRACE(("DATAALLOWED=0"))
120 	TRACE(("-> KEXINIT"))
121 
122 }
123 
switch_keys()124 static void switch_keys() {
125 	TRACE2(("enter switch_keys"))
126 	if (!(ses.kexstate.sentkexinit && ses.kexstate.recvkexinit)) {
127 		dropbear_exit("Unexpected newkeys message");
128 	}
129 
130 	if (!ses.keys) {
131 		ses.keys = m_malloc(sizeof(*ses.newkeys));
132 	}
133 	if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) {
134 		TRACE(("switch_keys recv"))
135 #ifndef DISABLE_ZLIB
136 		gen_new_zstream_recv();
137 #endif
138 		ses.keys->recv = ses.newkeys->recv;
139 		m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv));
140 		ses.newkeys->recv.valid = 0;
141 	}
142 	if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) {
143 		TRACE(("switch_keys trans"))
144 #ifndef DISABLE_ZLIB
145 		gen_new_zstream_trans();
146 #endif
147 		ses.keys->trans = ses.newkeys->trans;
148 		m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans));
149 		ses.newkeys->trans.valid = 0;
150 	}
151 	if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys)
152 	{
153 		TRACE(("switch_keys done"))
154 		ses.keys->algo_kex = ses.newkeys->algo_kex;
155 		ses.keys->algo_hostkey = ses.newkeys->algo_hostkey;
156 		ses.keys->algo_signature = ses.newkeys->algo_signature;
157 		ses.keys->allow_compress = 0;
158 		m_free(ses.newkeys);
159 		ses.newkeys = NULL;
160 		kexinitialise();
161 	}
162 	TRACE2(("leave switch_keys"))
163 }
164 
165 /* Bring new keys into use after a key exchange, and let the client know*/
send_msg_newkeys()166 void send_msg_newkeys() {
167 
168 	TRACE(("enter send_msg_newkeys"))
169 
170 	/* generate the kexinit request */
171 	CHECKCLEARTOWRITE();
172 	buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
173 	encrypt_packet();
174 
175 
176 	/* set up our state */
177 	ses.kexstate.sentnewkeys = 1;
178 	if (ses.kexstate.donefirstkex) {
179 		ses.kexstate.donesecondkex = 1;
180 	}
181 	ses.kexstate.donefirstkex = 1;
182 	ses.dataallowed = 1; /* we can send other packets again now */
183 	gen_new_keys();
184 	switch_keys();
185 
186 	TRACE(("leave send_msg_newkeys"))
187 }
188 
189 /* Bring the new keys into use after a key exchange */
recv_msg_newkeys()190 void recv_msg_newkeys() {
191 
192 	TRACE(("enter recv_msg_newkeys"))
193 
194 	ses.kexstate.recvnewkeys = 1;
195 	switch_keys();
196 
197 	TRACE(("leave recv_msg_newkeys"))
198 }
199 
200 
201 /* Set up the kex for the first time */
kexfirstinitialise()202 void kexfirstinitialise() {
203 #ifdef DISABLE_ZLIB
204 	ses.compress_algos = ssh_nocompress;
205 #else
206 	switch (opts.compress_mode)
207 	{
208 		case DROPBEAR_COMPRESS_DELAYED:
209 			ses.compress_algos = ssh_delaycompress;
210 			break;
211 
212 		case DROPBEAR_COMPRESS_ON:
213 			ses.compress_algos = ssh_compress;
214 			break;
215 
216 		case DROPBEAR_COMPRESS_OFF:
217 			ses.compress_algos = ssh_nocompress;
218 			break;
219 	}
220 #endif
221 	kexinitialise();
222 }
223 
224 /* Reset the kex state, ready for a new negotiation */
kexinitialise()225 static void kexinitialise() {
226 
227 	TRACE(("kexinitialise()"))
228 
229 	/* sent/recv'd MSG_KEXINIT */
230 	ses.kexstate.sentkexinit = 0;
231 	ses.kexstate.recvkexinit = 0;
232 
233 	/* sent/recv'd MSG_NEWKEYS */
234 	ses.kexstate.recvnewkeys = 0;
235 	ses.kexstate.sentnewkeys = 0;
236 
237 	/* first_packet_follows */
238 	ses.kexstate.them_firstfollows = 0;
239 
240 	ses.kexstate.datatrans = 0;
241 	ses.kexstate.datarecv = 0;
242 
243 	ses.kexstate.our_first_follows_matches = 0;
244 
245 	ses.kexstate.lastkextime = monotonic_now();
246 
247 }
248 
249 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the
250  * already initialised hash_state hs, which should already have processed
251  * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
252  * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
253  *
254  * See Section 7.2 of rfc4253 (ssh transport) for details */
hashkeys(unsigned char * out,unsigned int outlen,const hash_state * hs,const unsigned char X)255 static void hashkeys(unsigned char *out, unsigned int outlen,
256 		const hash_state * hs, const unsigned char X) {
257 
258 	const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
259 	hash_state hs2;
260 	unsigned int offset;
261 	unsigned char tmpout[MAX_HASH_SIZE];
262 
263 	memcpy(&hs2, hs, sizeof(hash_state));
264 	hash_desc->process(&hs2, &X, 1);
265 	hash_desc->process(&hs2, ses.session_id->data, ses.session_id->len);
266 	hash_desc->done(&hs2, tmpout);
267 	memcpy(out, tmpout, MIN(hash_desc->hashsize, outlen));
268 	for (offset = hash_desc->hashsize;
269 			offset < outlen;
270 			offset += hash_desc->hashsize)
271 	{
272 		/* need to extend */
273 		memcpy(&hs2, hs, sizeof(hash_state));
274 		hash_desc->process(&hs2, out, offset);
275 		hash_desc->done(&hs2, tmpout);
276 		memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize));
277 	}
278 	m_burn(&hs2, sizeof(hash_state));
279 }
280 
281 /* Generate the actual encryption/integrity keys, using the results of the
282  * key exchange, as specified in section 7.2 of the transport rfc 4253.
283  * This occurs after the DH key-exchange.
284  *
285  * ses.newkeys is the new set of keys which are generated, these are only
286  * taken into use after both sides have sent a newkeys message */
287 
gen_new_keys()288 static void gen_new_keys() {
289 
290 	unsigned char C2S_IV[MAX_IV_LEN];
291 	unsigned char C2S_key[MAX_KEY_LEN];
292 	unsigned char S2C_IV[MAX_IV_LEN];
293 	unsigned char S2C_key[MAX_KEY_LEN];
294 	/* unsigned char key[MAX_KEY_LEN]; */
295 	unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
296 
297 	hash_state hs;
298 	const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
299 	char mactransletter, macrecvletter; /* Client or server specific */
300 
301 	TRACE(("enter gen_new_keys"))
302 	/* the dh_K and hash are the start of all hashes, we make use of that */
303 
304 	hash_desc->init(&hs);
305 	hash_process_mp(hash_desc, &hs, ses.dh_K);
306 	mp_clear(ses.dh_K);
307 	m_free(ses.dh_K);
308 	hash_desc->process(&hs, ses.hash->data, ses.hash->len);
309 	buf_burn(ses.hash);
310 	buf_free(ses.hash);
311 	ses.hash = NULL;
312 
313 	if (IS_DROPBEAR_CLIENT) {
314 		trans_IV	= C2S_IV;
315 		recv_IV		= S2C_IV;
316 		trans_key	= C2S_key;
317 		recv_key	= S2C_key;
318 		mactransletter = 'E';
319 		macrecvletter = 'F';
320 	} else {
321 		trans_IV	= S2C_IV;
322 		recv_IV		= C2S_IV;
323 		trans_key	= S2C_key;
324 		recv_key	= C2S_key;
325 		mactransletter = 'F';
326 		macrecvletter = 'E';
327 	}
328 
329 	hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A');
330 	hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B');
331 	hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C');
332 	hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
333 
334 	if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
335 		int recv_cipher = -1;
336 		if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) {
337 			recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
338 			if (recv_cipher < 0) {
339 				dropbear_exit("Crypto error");
340 			}
341 		}
342 		if (ses.newkeys->recv.crypt_mode->start(recv_cipher,
343 				recv_IV, recv_key,
344 				ses.newkeys->recv.algo_crypt->keysize, 0,
345 				&ses.newkeys->recv.cipher_state) != CRYPT_OK) {
346 			dropbear_exit("Crypto error");
347 		}
348 	}
349 
350 	if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) {
351 		int trans_cipher = -1;
352 		if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) {
353 			trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
354 			if (trans_cipher < 0) {
355 				dropbear_exit("Crypto error");
356 			}
357 		}
358 		if (ses.newkeys->trans.crypt_mode->start(trans_cipher,
359 				trans_IV, trans_key,
360 				ses.newkeys->trans.algo_crypt->keysize, 0,
361 				&ses.newkeys->trans.cipher_state) != CRYPT_OK) {
362 			dropbear_exit("Crypto error");
363 		}
364 	}
365 
366 	if (ses.newkeys->trans.algo_mac->hash_desc != NULL) {
367 		hashkeys(ses.newkeys->trans.mackey,
368 				ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
369 		ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hash_desc->name);
370 	}
371 
372 	if (ses.newkeys->recv.algo_mac->hash_desc != NULL) {
373 		hashkeys(ses.newkeys->recv.mackey,
374 				ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
375 		ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hash_desc->name);
376 	}
377 
378 	/* Ready to switch over */
379 	ses.newkeys->trans.valid = 1;
380 	ses.newkeys->recv.valid = 1;
381 
382 	m_burn(C2S_IV, sizeof(C2S_IV));
383 	m_burn(C2S_key, sizeof(C2S_key));
384 	m_burn(S2C_IV, sizeof(S2C_IV));
385 	m_burn(S2C_key, sizeof(S2C_key));
386 	m_burn(&hs, sizeof(hash_state));
387 
388 	TRACE(("leave gen_new_keys"))
389 }
390 
391 #ifndef DISABLE_ZLIB
392 
is_compress_trans()393 int is_compress_trans() {
394 	return ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB
395 		|| (ses.authstate.authdone
396 			&& ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
397 }
398 
is_compress_recv()399 int is_compress_recv() {
400 	return ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB
401 		|| (ses.authstate.authdone
402 			&& ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
403 }
404 
dropbear_zalloc(void * UNUSED (opaque),uInt items,uInt size)405 static void* dropbear_zalloc(void* UNUSED(opaque), uInt items, uInt size) {
406 	return m_calloc(items, size);
407 }
408 
dropbear_zfree(void * UNUSED (opaque),void * ptr)409 static void dropbear_zfree(void* UNUSED(opaque), void* ptr) {
410 	m_free(ptr);
411 }
412 
413 /* Set up new zlib compression streams, close the old ones. Only
414  * called from gen_new_keys() */
gen_new_zstream_recv()415 static void gen_new_zstream_recv() {
416 
417 	/* create new zstreams */
418 	if (ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB
419 			|| ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
420 		ses.newkeys->recv.zstream = (z_streamp)m_malloc(sizeof(z_stream));
421 		ses.newkeys->recv.zstream->zalloc = dropbear_zalloc;
422 		ses.newkeys->recv.zstream->zfree = dropbear_zfree;
423 
424 		if (inflateInit(ses.newkeys->recv.zstream) != Z_OK) {
425 			dropbear_exit("zlib error");
426 		}
427 	} else {
428 		ses.newkeys->recv.zstream = NULL;
429 	}
430 	/* clean up old keys */
431 	if (ses.keys->recv.zstream != NULL) {
432 		if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
433 			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
434 			dropbear_exit("Crypto error");
435 		}
436 		m_free(ses.keys->recv.zstream);
437 	}
438 }
439 
gen_new_zstream_trans()440 static void gen_new_zstream_trans() {
441 
442 	if (ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB
443 			|| ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
444 		ses.newkeys->trans.zstream = (z_streamp)m_malloc(sizeof(z_stream));
445 		ses.newkeys->trans.zstream->zalloc = dropbear_zalloc;
446 		ses.newkeys->trans.zstream->zfree = dropbear_zfree;
447 
448 		if (deflateInit2(ses.newkeys->trans.zstream, Z_DEFAULT_COMPRESSION,
449 					Z_DEFLATED, DROPBEAR_ZLIB_WINDOW_BITS,
450 					DROPBEAR_ZLIB_MEM_LEVEL, Z_DEFAULT_STRATEGY)
451 				!= Z_OK) {
452 			dropbear_exit("zlib error");
453 		}
454 	} else {
455 		ses.newkeys->trans.zstream = NULL;
456 	}
457 
458 	if (ses.keys->trans.zstream != NULL) {
459 		if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) {
460 			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
461 			dropbear_exit("Crypto error");
462 		}
463 		m_free(ses.keys->trans.zstream);
464 	}
465 }
466 #endif /* DISABLE_ZLIB */
467 
468 
469 /* Executed upon receiving a kexinit message from the client to initiate
470  * key exchange. If we haven't already done so, we send the list of our
471  * preferred algorithms. The client's requested algorithms are processed,
472  * and we calculate the first portion of the key-exchange-hash for used
473  * later in the key exchange. No response is sent, as the client should
474  * initiate the diffie-hellman key exchange */
recv_msg_kexinit()475 void recv_msg_kexinit() {
476 
477 	unsigned int kexhashbuf_len = 0;
478 	unsigned int remote_ident_len = 0;
479 	unsigned int local_ident_len = 0;
480 
481 	TRACE(("<- KEXINIT"))
482 	TRACE(("enter recv_msg_kexinit"))
483 
484 	if (!ses.kexstate.sentkexinit) {
485 		/* we need to send a kex packet */
486 		send_msg_kexinit();
487 		TRACE(("continue recv_msg_kexinit: sent kexinit"))
488 	}
489 
490 	/* "Once a party has sent a SSH_MSG_KEXINIT message ...
491 	further SSH_MSG_KEXINIT messages MUST NOT be sent" */
492 	if (ses.kexstate.recvkexinit) {
493 		dropbear_exit("Unexpected KEXINIT");
494 	}
495 
496 	/* start the kex hash */
497 	local_ident_len = strlen(LOCAL_IDENT);
498 	remote_ident_len = strlen(ses.remoteident);
499 
500 	kexhashbuf_len = local_ident_len + remote_ident_len
501 		+ ses.transkexinit->len + ses.payload->len
502 		+ KEXHASHBUF_MAX_INTS;
503 
504 	ses.kexhashbuf = buf_new(kexhashbuf_len);
505 
506 	if (IS_DROPBEAR_CLIENT) {
507 
508 		/* read the peer's choice of algos */
509 		read_kex_algos();
510 
511 		/* V_C, the client's version string (CR and NL excluded) */
512 		buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
513 		/* V_S, the server's version string (CR and NL excluded) */
514 		buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
515 
516 		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
517 		buf_putstring(ses.kexhashbuf,
518 			(const char*)ses.transkexinit->data, ses.transkexinit->len);
519 		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
520 		buf_setpos(ses.payload, ses.payload_beginning);
521 		buf_putstring(ses.kexhashbuf,
522 			(const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
523 			ses.payload->len-ses.payload->pos);
524 		ses.requirenext = SSH_MSG_KEXDH_REPLY;
525 	} else {
526 		/* SERVER */
527 
528 		/* read the peer's choice of algos */
529 		read_kex_algos();
530 		/* V_C, the client's version string (CR and NL excluded) */
531 		buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
532 		/* V_S, the server's version string (CR and NL excluded) */
533 		buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
534 
535 		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
536 		buf_setpos(ses.payload, ses.payload_beginning);
537 		buf_putstring(ses.kexhashbuf,
538 			(const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
539 			ses.payload->len-ses.payload->pos);
540 
541 		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
542 		buf_putstring(ses.kexhashbuf,
543 			(const char*)ses.transkexinit->data, ses.transkexinit->len);
544 
545 		ses.requirenext = SSH_MSG_KEXDH_INIT;
546 	}
547 
548 	buf_free(ses.transkexinit);
549 	ses.transkexinit = NULL;
550 	/* the rest of ses.kexhashbuf will be done after DH exchange */
551 
552 	ses.kexstate.recvkexinit = 1;
553 
554 	TRACE(("leave recv_msg_kexinit"))
555 }
556 
557 #if DROPBEAR_NORMAL_DH
load_dh_p(mp_int * dh_p)558 static void load_dh_p(mp_int * dh_p)
559 {
560 	bytes_to_mp(dh_p, ses.newkeys->algo_kex->dh_p_bytes,
561 		ses.newkeys->algo_kex->dh_p_len);
562 }
563 
564 /* Initialises and generate one side of the diffie-hellman key exchange values.
565  * See the transport rfc 4253 section 8 for details */
566 /* dh_pub and dh_priv MUST be already initialised */
gen_kexdh_param()567 struct kex_dh_param *gen_kexdh_param() {
568 	struct kex_dh_param *param = NULL;
569 
570 	DEF_MP_INT(dh_p);
571 	DEF_MP_INT(dh_q);
572 	DEF_MP_INT(dh_g);
573 
574 	TRACE(("enter gen_kexdh_vals"))
575 
576 	param = m_malloc(sizeof(*param));
577 	m_mp_init_multi(&param->pub, &param->priv, &dh_g, &dh_p, &dh_q, NULL);
578 
579 	/* read the prime and generator*/
580 	load_dh_p(&dh_p);
581 
582 	mp_set_ul(&dh_g, DH_G_VAL);
583 
584 	/* calculate q = (p-1)/2 */
585 	/* dh_priv is just a temp var here */
586 	if (mp_sub_d(&dh_p, 1, &param->priv) != MP_OKAY) {
587 		dropbear_exit("Diffie-Hellman error");
588 	}
589 	if (mp_div_2(&param->priv, &dh_q) != MP_OKAY) {
590 		dropbear_exit("Diffie-Hellman error");
591 	}
592 
593 	/* Generate a private portion 0 < dh_priv < dh_q */
594 	gen_random_mpint(&dh_q, &param->priv);
595 
596 	/* f = g^y mod p */
597 	if (mp_exptmod(&dh_g, &param->priv, &dh_p, &param->pub) != MP_OKAY) {
598 		dropbear_exit("Diffie-Hellman error");
599 	}
600 	mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL);
601 	return param;
602 }
603 
free_kexdh_param(struct kex_dh_param * param)604 void free_kexdh_param(struct kex_dh_param *param)
605 {
606 	mp_clear_multi(&param->pub, &param->priv, NULL);
607 	m_free(param);
608 }
609 
610 /* This function is fairly common between client/server, with some substitution
611  * of dh_e/dh_f etc. Hence these arguments:
612  * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is
613  * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
kexdh_comb_key(struct kex_dh_param * param,mp_int * dh_pub_them,sign_key * hostkey)614 void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them,
615 		sign_key *hostkey) {
616 
617 	DEF_MP_INT(dh_p);
618 	DEF_MP_INT(dh_p_min1);
619 	mp_int *dh_e = NULL, *dh_f = NULL;
620 
621 	m_mp_init_multi(&dh_p, &dh_p_min1, NULL);
622 	load_dh_p(&dh_p);
623 
624 	if (mp_sub_d(&dh_p, 1, &dh_p_min1) != MP_OKAY) {
625 		dropbear_exit("Diffie-Hellman error");
626 	}
627 
628 	/* Check that dh_pub_them (dh_e or dh_f) is in the range [2, p-2] */
629 	if (mp_cmp(dh_pub_them, &dh_p_min1) != MP_LT
630 			|| mp_cmp_d(dh_pub_them, 1) != MP_GT) {
631 		dropbear_exit("Diffie-Hellman error");
632 	}
633 
634 	/* K = e^y mod p = f^x mod p */
635 	m_mp_alloc_init_multi(&ses.dh_K, NULL);
636 	if (mp_exptmod(dh_pub_them, &param->priv, &dh_p, ses.dh_K) != MP_OKAY) {
637 		dropbear_exit("Diffie-Hellman error");
638 	}
639 
640 	/* clear no longer needed vars */
641 	mp_clear_multi(&dh_p, &dh_p_min1, NULL);
642 
643 	/* From here on, the code needs to work with the _same_ vars on each side,
644 	 * not vice-versaing for client/server */
645 	if (IS_DROPBEAR_CLIENT) {
646 		dh_e = &param->pub;
647 		dh_f = dh_pub_them;
648 	} else {
649 		dh_e = dh_pub_them;
650 		dh_f = &param->pub;
651 	}
652 
653 	/* Create the remainder of the hash buffer, to generate the exchange hash */
654 	/* K_S, the host key */
655 	buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
656 	/* e, exchange value sent by the client */
657 	buf_putmpint(ses.kexhashbuf, dh_e);
658 	/* f, exchange value sent by the server */
659 	buf_putmpint(ses.kexhashbuf, dh_f);
660 	/* K, the shared secret */
661 	buf_putmpint(ses.kexhashbuf, ses.dh_K);
662 
663 	/* calculate the hash H to sign */
664 	finish_kexhashbuf();
665 }
666 #endif
667 
668 #if DROPBEAR_ECDH
gen_kexecdh_param()669 struct kex_ecdh_param *gen_kexecdh_param() {
670 	struct kex_ecdh_param *param = m_malloc(sizeof(*param));
671 	if (ecc_make_key_ex(NULL, dropbear_ltc_prng,
672 		&param->key, ses.newkeys->algo_kex->ecc_curve->dp) != CRYPT_OK) {
673 		dropbear_exit("ECC error");
674 	}
675 	return param;
676 }
677 
free_kexecdh_param(struct kex_ecdh_param * param)678 void free_kexecdh_param(struct kex_ecdh_param *param) {
679 	ecc_free(&param->key);
680 	m_free(param);
681 
682 }
kexecdh_comb_key(struct kex_ecdh_param * param,buffer * pub_them,sign_key * hostkey)683 void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them,
684 		sign_key *hostkey) {
685 	const struct dropbear_kex *algo_kex = ses.newkeys->algo_kex;
686 	/* public keys from client and server */
687 	ecc_key *Q_C, *Q_S, *Q_them;
688 
689 	Q_them = buf_get_ecc_raw_pubkey(pub_them, algo_kex->ecc_curve);
690 	if (Q_them == NULL) {
691 		dropbear_exit("ECC error");
692 	}
693 
694 	ses.dh_K = dropbear_ecc_shared_secret(Q_them, &param->key);
695 
696 	/* Create the remainder of the hash buffer, to generate the exchange hash
697 	   See RFC5656 section 4 page 7 */
698 	if (IS_DROPBEAR_CLIENT) {
699 		Q_C = &param->key;
700 		Q_S = Q_them;
701 	} else {
702 		Q_C = Q_them;
703 		Q_S = &param->key;
704 	}
705 
706 	/* K_S, the host key */
707 	buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
708 	/* Q_C, client's ephemeral public key octet string */
709 	buf_put_ecc_raw_pubkey_string(ses.kexhashbuf, Q_C);
710 	/* Q_S, server's ephemeral public key octet string */
711 	buf_put_ecc_raw_pubkey_string(ses.kexhashbuf, Q_S);
712 	/* K, the shared secret */
713 	buf_putmpint(ses.kexhashbuf, ses.dh_K);
714 
715 	ecc_free(Q_them);
716 	m_free(Q_them);
717 
718 	/* calculate the hash H to sign */
719 	finish_kexhashbuf();
720 }
721 #endif /* DROPBEAR_ECDH */
722 
723 #if DROPBEAR_CURVE25519
gen_kexcurve25519_param()724 struct kex_curve25519_param *gen_kexcurve25519_param() {
725 	/* Per http://cr.yp.to/ecdh.html */
726 	struct kex_curve25519_param *param = m_malloc(sizeof(*param));
727 	const unsigned char basepoint[32] = {9};
728 
729 	genrandom(param->priv, CURVE25519_LEN);
730 	dropbear_curve25519_scalarmult(param->pub, param->priv, basepoint);
731 
732 	return param;
733 }
734 
free_kexcurve25519_param(struct kex_curve25519_param * param)735 void free_kexcurve25519_param(struct kex_curve25519_param *param) {
736 	m_burn(param->priv, CURVE25519_LEN);
737 	m_free(param);
738 }
739 
kexcurve25519_comb_key(const struct kex_curve25519_param * param,const buffer * buf_pub_them,sign_key * hostkey)740 void kexcurve25519_comb_key(const struct kex_curve25519_param *param, const buffer *buf_pub_them,
741 	sign_key *hostkey) {
742 	unsigned char out[CURVE25519_LEN];
743 	const unsigned char* Q_C = NULL;
744 	const unsigned char* Q_S = NULL;
745 	char zeroes[CURVE25519_LEN] = {0};
746 
747 	if (buf_pub_them->len != CURVE25519_LEN)
748 	{
749 		dropbear_exit("Bad curve25519");
750 	}
751 
752 	dropbear_curve25519_scalarmult(out, param->priv, buf_pub_them->data);
753 
754 	if (constant_time_memcmp(zeroes, out, CURVE25519_LEN) == 0) {
755 		dropbear_exit("Bad curve25519");
756 	}
757 
758 	m_mp_alloc_init_multi(&ses.dh_K, NULL);
759 	bytes_to_mp(ses.dh_K, out, CURVE25519_LEN);
760 	m_burn(out, sizeof(out));
761 
762 	/* Create the remainder of the hash buffer, to generate the exchange hash.
763 	   See RFC5656 section 4 page 7 */
764 	if (IS_DROPBEAR_CLIENT) {
765 		Q_C = param->pub;
766 		Q_S = buf_pub_them->data;
767 	} else {
768 		Q_S = param->pub;
769 		Q_C = buf_pub_them->data;
770 	}
771 
772 	/* K_S, the host key */
773 	buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
774 	/* Q_C, client's ephemeral public key octet string */
775 	buf_putstring(ses.kexhashbuf, (const char*)Q_C, CURVE25519_LEN);
776 	/* Q_S, server's ephemeral public key octet string */
777 	buf_putstring(ses.kexhashbuf, (const char*)Q_S, CURVE25519_LEN);
778 	/* K, the shared secret */
779 	buf_putmpint(ses.kexhashbuf, ses.dh_K);
780 
781 	/* calculate the hash H to sign */
782 	finish_kexhashbuf();
783 }
784 #endif /* DROPBEAR_CURVE25519 */
785 
786 
finish_kexhashbuf(void)787 void finish_kexhashbuf(void) {
788 	hash_state hs;
789 	const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
790 
791 	hash_desc->init(&hs);
792 	buf_setpos(ses.kexhashbuf, 0);
793 	hash_desc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
794 			ses.kexhashbuf->len);
795 	ses.hash = buf_new(hash_desc->hashsize);
796 	hash_desc->done(&hs, buf_getwriteptr(ses.hash, hash_desc->hashsize));
797 	buf_setlen(ses.hash, hash_desc->hashsize);
798 
799 #if defined(DEBUG_KEXHASH) && DEBUG_TRACE
800 	if (!debug_trace) {
801 		printhex("kexhashbuf", ses.kexhashbuf->data, ses.kexhashbuf->len);
802 		printhex("kexhash", ses.hash->data, ses.hash->len);
803 	}
804 #endif
805 
806 	buf_burn(ses.kexhashbuf);
807 	buf_free(ses.kexhashbuf);
808 	m_burn(&hs, sizeof(hash_state));
809 	ses.kexhashbuf = NULL;
810 
811 	/* first time around, we set the session_id to H */
812 	if (ses.session_id == NULL) {
813 		/* create the session_id, this never needs freeing */
814 		ses.session_id = buf_newcopy(ses.hash);
815 	}
816 }
817 
818 /* read the other side's algo list. buf_match_algo is a callback to match
819  * algos for the client or server. */
read_kex_algos()820 static void read_kex_algos() {
821 
822 	/* for asymmetry */
823 	algo_type * c2s_hash_algo = NULL;
824 	algo_type * s2c_hash_algo = NULL;
825 	algo_type * c2s_cipher_algo = NULL;
826 	algo_type * s2c_cipher_algo = NULL;
827 	algo_type * c2s_comp_algo = NULL;
828 	algo_type * s2c_comp_algo = NULL;
829 	/* the generic one */
830 	algo_type * algo = NULL;
831 
832 	/* which algo couldn't match */
833 	char * erralgo = NULL;
834 
835 	int goodguess = 0;
836 	int allgood = 1; /* we AND this with each goodguess and see if its still
837 						true after */
838 	int kexguess2 = 0;
839 
840 	buf_incrpos(ses.payload, 16); /* start after the cookie */
841 
842 	memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
843 
844 	/* kex_algorithms */
845 #if DROPBEAR_KEXGUESS2
846 	if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) {
847 		kexguess2 = 1;
848 	}
849 #endif
850 
851 #if DROPBEAR_EXT_INFO
852 	/* Determine if SSH_MSG_EXT_INFO messages should be sent.
853 	Should be done for the first key exchange. Only required on server side
854     for server-sig-algs */
855 	if (IS_DROPBEAR_SERVER) {
856 		if (!ses.kexstate.donefirstkex) {
857 			if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) {
858 				ses.allow_ext_info = 1;
859 			}
860 		}
861 	}
862 #endif
863 
864 	algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
865 	allgood &= goodguess;
866 	if (algo == NULL || algo->data == NULL) {
867 		/* kexguess2, ext-info-c, ext-info-s should not match negotiation */
868 		erralgo = "kex";
869 		goto error;
870 	}
871 	TRACE(("kexguess2 %d", kexguess2))
872 	TRACE(("kex algo %s", algo->name))
873 	ses.newkeys->algo_kex = algo->data;
874 
875 	/* server_host_key_algorithms */
876 	algo = buf_match_algo(ses.payload, sigalgs, kexguess2, &goodguess);
877 	allgood &= goodguess;
878 	if (algo == NULL) {
879 		erralgo = "hostkey";
880 		goto error;
881 	}
882 	TRACE(("signature algo %s", algo->name))
883 	ses.newkeys->algo_signature = algo->val;
884 	ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
885 
886 	/* encryption_algorithms_client_to_server */
887 	c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
888 	if (c2s_cipher_algo == NULL) {
889 		erralgo = "enc c->s";
890 		goto error;
891 	}
892 	TRACE(("enc c2s is  %s", c2s_cipher_algo->name))
893 
894 	/* encryption_algorithms_server_to_client */
895 	s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
896 	if (s2c_cipher_algo == NULL) {
897 		erralgo = "enc s->c";
898 		goto error;
899 	}
900 	TRACE(("enc s2c is  %s", s2c_cipher_algo->name))
901 
902 	/* mac_algorithms_client_to_server */
903 	c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
904 #if DROPBEAR_AEAD_MODE
905 	if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) {
906 		c2s_hash_algo = NULL;
907 	} else
908 #endif
909 	if (c2s_hash_algo == NULL) {
910 		erralgo = "mac c->s";
911 		goto error;
912 	}
913 	TRACE(("hash c2s is  %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>"))
914 
915 	/* mac_algorithms_server_to_client */
916 	s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
917 #if DROPBEAR_AEAD_MODE
918 	if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) {
919 		s2c_hash_algo = NULL;
920 	} else
921 #endif
922 	if (s2c_hash_algo == NULL) {
923 		erralgo = "mac s->c";
924 		goto error;
925 	}
926 	TRACE(("hash s2c is  %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>"))
927 
928 	/* compression_algorithms_client_to_server */
929 	c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL);
930 	if (c2s_comp_algo == NULL) {
931 		erralgo = "comp c->s";
932 		goto error;
933 	}
934 	TRACE(("hash c2s is  %s", c2s_comp_algo->name))
935 
936 	/* compression_algorithms_server_to_client */
937 	s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL);
938 	if (s2c_comp_algo == NULL) {
939 		erralgo = "comp s->c";
940 		goto error;
941 	}
942 	TRACE(("hash s2c is  %s", s2c_comp_algo->name))
943 
944 	/* languages_client_to_server */
945 	buf_eatstring(ses.payload);
946 
947 	/* languages_server_to_client */
948 	buf_eatstring(ses.payload);
949 
950 	/* their first_kex_packet_follows */
951 	if (buf_getbool(ses.payload)) {
952 		TRACE(("them kex firstfollows. allgood %d", allgood))
953 		ses.kexstate.them_firstfollows = 1;
954 		/* if the guess wasn't good, we ignore the packet sent */
955 		if (!allgood) {
956 			ses.ignorenext = 1;
957 		}
958 	}
959 
960 	/* Handle the asymmetry */
961 	if (IS_DROPBEAR_CLIENT) {
962 		ses.newkeys->recv.algo_crypt =
963 			(struct dropbear_cipher*)s2c_cipher_algo->data;
964 		ses.newkeys->trans.algo_crypt =
965 			(struct dropbear_cipher*)c2s_cipher_algo->data;
966 		ses.newkeys->recv.crypt_mode =
967 			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
968 		ses.newkeys->trans.crypt_mode =
969 			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
970 		ses.newkeys->recv.algo_mac =
971 #if DROPBEAR_AEAD_MODE
972 			s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
973 #endif
974 			(struct dropbear_hash*)s2c_hash_algo->data;
975 		ses.newkeys->trans.algo_mac =
976 #if DROPBEAR_AEAD_MODE
977 			c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
978 #endif
979 			(struct dropbear_hash*)c2s_hash_algo->data;
980 		ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
981 		ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
982 	} else {
983 		/* SERVER */
984 		ses.newkeys->recv.algo_crypt =
985 			(struct dropbear_cipher*)c2s_cipher_algo->data;
986 		ses.newkeys->trans.algo_crypt =
987 			(struct dropbear_cipher*)s2c_cipher_algo->data;
988 		ses.newkeys->recv.crypt_mode =
989 			(struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
990 		ses.newkeys->trans.crypt_mode =
991 			(struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
992 		ses.newkeys->recv.algo_mac =
993 #if DROPBEAR_AEAD_MODE
994 			c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
995 #endif
996 			(struct dropbear_hash*)c2s_hash_algo->data;
997 		ses.newkeys->trans.algo_mac =
998 #if DROPBEAR_AEAD_MODE
999 			s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
1000 #endif
1001 			(struct dropbear_hash*)s2c_hash_algo->data;
1002 		ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
1003 		ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
1004 	}
1005 
1006 #if DROPBEAR_FUZZ
1007 	if (fuzz.fuzzing) {
1008 		fuzz_kex_fakealgos();
1009 	}
1010 #endif
1011 
1012 	/* reserved for future extensions */
1013 	buf_getint(ses.payload);
1014 
1015 	if (ses.send_kex_first_guess && allgood) {
1016 		TRACE(("our_first_follows_matches 1"))
1017 		ses.kexstate.our_first_follows_matches = 1;
1018 	}
1019 	return;
1020 
1021 error:
1022 	dropbear_exit("No matching algo %s", erralgo);
1023 }
1024