• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Dropbear - a SSH2 server
3  *
4  * Copyright (c) 2002,2003 Matt Johnston
5  * All rights reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE. */
24 
25 #include "includes.h"
26 #include "packet.h"
27 #include "session.h"
28 #include "dbutil.h"
29 #include "ssh.h"
30 #include "algo.h"
31 #include "buffer.h"
32 #include "kex.h"
33 #include "random.h"
34 #include "service.h"
35 #include "auth.h"
36 #include "channel.h"
37 
38 static void read_packet_init();
39 static void writemac(buffer * outputbuffer, buffer * clearwritebuf);
40 static int checkmac(buffer* hashbuf, buffer* readbuf);
41 
42 #define ZLIB_COMPRESS_INCR 20 /* this is 12 bytes + 0.1% of 8000 bytes */
43 #define ZLIB_DECOMPRESS_INCR 100
44 #ifndef DISABLE_ZLIB
45 static buffer* buf_decompress(buffer* buf, unsigned int len);
46 static void buf_compress(buffer * dest, buffer * src, unsigned int len);
47 #endif
48 
49 /* non-blocking function writing out a current encrypted packet */
write_packet()50 void write_packet() {
51 
52 	int len, written;
53 	buffer * writebuf = NULL;
54 
55 	TRACE(("enter write_packet"))
56 	dropbear_assert(!isempty(&ses.writequeue));
57 
58 	/* Get the next buffer in the queue of encrypted packets to write*/
59 	writebuf = (buffer*)examine(&ses.writequeue);
60 
61 	len = writebuf->len - writebuf->pos;
62 	dropbear_assert(len > 0);
63 	/* Try to write as much as possible */
64 	written = write(ses.sock, buf_getptr(writebuf, len), len);
65 
66 	if (written < 0) {
67 		if (errno == EINTR) {
68 			TRACE(("leave writepacket: EINTR"))
69 			return;
70 		} else {
71 			dropbear_exit("error writing");
72 		}
73 	}
74 
75 	if (written == 0) {
76 		ses.remoteclosed();
77 	}
78 
79 	if (written == len) {
80 		/* We've finished with the packet, free it */
81 		dequeue(&ses.writequeue);
82 		buf_free(writebuf);
83 		writebuf = NULL;
84 	} else {
85 		/* More packet left to write, leave it in the queue for later */
86 		buf_incrpos(writebuf, written);
87 	}
88 
89 	TRACE(("leave write_packet"))
90 }
91 
92 /* Non-blocking function reading available portion of a packet into the
93  * ses's buffer, decrypting the length if encrypted, decrypting the
94  * full portion if possible */
read_packet()95 void read_packet() {
96 
97 	int len;
98 	unsigned int maxlen;
99 	unsigned char blocksize;
100 
101 	TRACE(("enter read_packet"))
102 	blocksize = ses.keys->recv_algo_crypt->blocksize;
103 
104 	if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
105 		/* In the first blocksize of a packet */
106 
107 		/* Read the first blocksize of the packet, so we can decrypt it and
108 		 * find the length of the whole packet */
109 		read_packet_init();
110 
111 		/* If we don't have the length of decryptreadbuf, we didn't read
112 		 * a whole blocksize and should exit */
113 		if (ses.decryptreadbuf->len == 0) {
114 			TRACE(("leave read_packet: packetinit done"))
115 			return;
116 		}
117 	}
118 
119 	/* Attempt to read the remainder of the packet, note that there
120 	 * mightn't be any available (EAGAIN) */
121 	dropbear_assert(ses.readbuf != NULL);
122 	maxlen = ses.readbuf->len - ses.readbuf->pos;
123 	len = read(ses.sock, buf_getptr(ses.readbuf, maxlen), maxlen);
124 
125 	if (len == 0) {
126 		ses.remoteclosed();
127 	}
128 
129 	if (len < 0) {
130 		if (errno == EINTR || errno == EAGAIN) {
131 			TRACE(("leave read_packet: EINTR or EAGAIN"))
132 			return;
133 		} else {
134 			dropbear_exit("error reading: %s", strerror(errno));
135 		}
136 	}
137 
138 	buf_incrpos(ses.readbuf, len);
139 
140 	if ((unsigned int)len == maxlen) {
141 		/* The whole packet has been read */
142 		decrypt_packet();
143 		/* The main select() loop process_packet() to
144 		 * handle the packet contents... */
145 	}
146 	TRACE(("leave read_packet"))
147 }
148 
149 /* Function used to read the initial portion of a packet, and determine the
150  * length. Only called during the first BLOCKSIZE of a packet. */
read_packet_init()151 static void read_packet_init() {
152 
153 	unsigned int maxlen;
154 	int len;
155 	unsigned char blocksize;
156 	unsigned char macsize;
157 
158 
159 	blocksize = ses.keys->recv_algo_crypt->blocksize;
160 	macsize = ses.keys->recv_algo_mac->hashsize;
161 
162 	if (ses.readbuf == NULL) {
163 		/* start of a new packet */
164 		ses.readbuf = buf_new(INIT_READBUF);
165 		dropbear_assert(ses.decryptreadbuf == NULL);
166 		ses.decryptreadbuf = buf_new(blocksize);
167 	}
168 
169 	maxlen = blocksize - ses.readbuf->pos;
170 
171 	/* read the rest of the packet if possible */
172 	len = read(ses.sock, buf_getwriteptr(ses.readbuf, maxlen),
173 			maxlen);
174 	if (len == 0) {
175 		ses.remoteclosed();
176 	}
177 	if (len < 0) {
178 		if (errno == EINTR) {
179 			TRACE(("leave read_packet_init: EINTR"))
180 			return;
181 		}
182 		dropbear_exit("error reading: %s", strerror(errno));
183 	}
184 
185 	buf_incrwritepos(ses.readbuf, len);
186 
187 	if ((unsigned int)len != maxlen) {
188 		/* don't have enough bytes to determine length, get next time */
189 		return;
190 	}
191 
192 	/* now we have the first block, need to get packet length, so we decrypt
193 	 * the first block (only need first 4 bytes) */
194 	buf_setpos(ses.readbuf, 0);
195 	if (ses.keys->recv_algo_crypt->cipherdesc == NULL) {
196 		/* copy it */
197 		memcpy(buf_getwriteptr(ses.decryptreadbuf, blocksize),
198 				buf_getptr(ses.readbuf, blocksize),
199 				blocksize);
200 	} else {
201 		/* decrypt it */
202 		if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize),
203 					buf_getwriteptr(ses.decryptreadbuf,blocksize),
204 					blocksize,
205 					&ses.keys->recv_symmetric_struct) != CRYPT_OK) {
206 			dropbear_exit("error decrypting");
207 		}
208 	}
209 	buf_setlen(ses.decryptreadbuf, blocksize);
210 	len = buf_getint(ses.decryptreadbuf) + 4 + macsize;
211 
212 	buf_setpos(ses.readbuf, blocksize);
213 
214 	/* check packet length */
215 	if ((len > MAX_PACKET_LEN) ||
216 		(len < MIN_PACKET_LEN + macsize) ||
217 		((len - macsize) % blocksize != 0)) {
218 		dropbear_exit("bad packet size %d", len);
219 	}
220 
221 	buf_resize(ses.readbuf, len);
222 	buf_setlen(ses.readbuf, len);
223 
224 }
225 
226 /* handle the received packet */
decrypt_packet()227 void decrypt_packet() {
228 
229 	unsigned char blocksize;
230 	unsigned char macsize;
231 	unsigned int padlen;
232 	unsigned int len;
233 
234 	TRACE(("enter decrypt_packet"))
235 	blocksize = ses.keys->recv_algo_crypt->blocksize;
236 	macsize = ses.keys->recv_algo_mac->hashsize;
237 
238 	ses.kexstate.datarecv += ses.readbuf->len;
239 
240 	/* we've already decrypted the first blocksize in read_packet_init */
241 	buf_setpos(ses.readbuf, blocksize);
242 
243 	buf_resize(ses.decryptreadbuf, ses.readbuf->len - macsize);
244 	buf_setlen(ses.decryptreadbuf, ses.decryptreadbuf->size);
245 	buf_setpos(ses.decryptreadbuf, blocksize);
246 
247 	/* decrypt if encryption is set, memcpy otherwise */
248 	if (ses.keys->recv_algo_crypt->cipherdesc == NULL) {
249 		/* copy it */
250 		len = ses.readbuf->len - macsize - blocksize;
251 		memcpy(buf_getwriteptr(ses.decryptreadbuf, len),
252 				buf_getptr(ses.readbuf, len), len);
253 	} else {
254 		/* decrypt */
255 		while (ses.readbuf->pos < ses.readbuf->len - macsize) {
256 			if (cbc_decrypt(buf_getptr(ses.readbuf, blocksize),
257 						buf_getwriteptr(ses.decryptreadbuf, blocksize),
258 						blocksize,
259 						&ses.keys->recv_symmetric_struct) != CRYPT_OK) {
260 				dropbear_exit("error decrypting");
261 			}
262 			buf_incrpos(ses.readbuf, blocksize);
263 			buf_incrwritepos(ses.decryptreadbuf, blocksize);
264 		}
265 	}
266 
267 	/* check the hmac */
268 	buf_setpos(ses.readbuf, ses.readbuf->len - macsize);
269 	if (checkmac(ses.readbuf, ses.decryptreadbuf) != DROPBEAR_SUCCESS) {
270 		dropbear_exit("Integrity error");
271 	}
272 
273 	/* readbuf no longer required */
274 	buf_free(ses.readbuf);
275 	ses.readbuf = NULL;
276 
277 	/* get padding length */
278 	buf_setpos(ses.decryptreadbuf, PACKET_PADDING_OFF);
279 	padlen = buf_getbyte(ses.decryptreadbuf);
280 
281 	/* payload length */
282 	/* - 4 - 1 is for LEN and PADLEN values */
283 	len = ses.decryptreadbuf->len - padlen - 4 - 1;
284 	if ((len > MAX_PAYLOAD_LEN) || (len < 1)) {
285 		dropbear_exit("bad packet size");
286 	}
287 
288 	buf_setpos(ses.decryptreadbuf, PACKET_PAYLOAD_OFF);
289 
290 #ifndef DISABLE_ZLIB
291 	if (ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB) {
292 		/* decompress */
293 		ses.payload = buf_decompress(ses.decryptreadbuf, len);
294 
295 	} else
296 #endif
297 	{
298 		/* copy payload */
299 		ses.payload = buf_new(len);
300 		memcpy(ses.payload->data, buf_getptr(ses.decryptreadbuf, len), len);
301 		buf_incrlen(ses.payload, len);
302 	}
303 
304 	buf_free(ses.decryptreadbuf);
305 	ses.decryptreadbuf = NULL;
306 	buf_setpos(ses.payload, 0);
307 
308 	ses.recvseq++;
309 
310 	TRACE(("leave decrypt_packet"))
311 }
312 
313 /* Checks the mac in hashbuf, for the data in readbuf.
314  * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
checkmac(buffer * macbuf,buffer * sourcebuf)315 static int checkmac(buffer* macbuf, buffer* sourcebuf) {
316 
317 	unsigned int macsize;
318 	hmac_state hmac;
319 	unsigned char tempbuf[MAX_MAC_LEN];
320 	unsigned long bufsize;
321 	unsigned int len;
322 
323 	macsize = ses.keys->recv_algo_mac->hashsize;
324 	if (macsize == 0) {
325 		return DROPBEAR_SUCCESS;
326 	}
327 
328 	/* calculate the mac */
329 	if (hmac_init(&hmac,
330 				find_hash(ses.keys->recv_algo_mac->hashdesc->name),
331 				ses.keys->recvmackey,
332 				ses.keys->recv_algo_mac->keysize)
333 				!= CRYPT_OK) {
334 		dropbear_exit("HMAC error");
335 	}
336 
337 	/* sequence number */
338 	STORE32H(ses.recvseq, tempbuf);
339 	if (hmac_process(&hmac, tempbuf, 4) != CRYPT_OK) {
340 		dropbear_exit("HMAC error");
341 	}
342 
343 	buf_setpos(sourcebuf, 0);
344 	len = sourcebuf->len;
345 	if (hmac_process(&hmac, buf_getptr(sourcebuf, len), len) != CRYPT_OK) {
346 		dropbear_exit("HMAC error");
347 	}
348 
349 	bufsize = sizeof(tempbuf);
350 	if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) {
351 		dropbear_exit("HMAC error");
352 	}
353 
354 	/* compare the hash */
355 	if (memcmp(tempbuf, buf_getptr(macbuf, macsize), macsize) != 0) {
356 		return DROPBEAR_FAILURE;
357 	} else {
358 		return DROPBEAR_SUCCESS;
359 	}
360 }
361 
362 #ifndef DISABLE_ZLIB
363 /* returns a pointer to a newly created buffer */
buf_decompress(buffer * buf,unsigned int len)364 static buffer* buf_decompress(buffer* buf, unsigned int len) {
365 
366 	int result;
367 	buffer * ret;
368 	z_streamp zstream;
369 
370 	zstream = ses.keys->recv_zstream;
371 	ret = buf_new(len);
372 
373 	zstream->avail_in = len;
374 	zstream->next_in = buf_getptr(buf, len);
375 
376 	/* decompress the payload, incrementally resizing the output buffer */
377 	while (1) {
378 
379 		zstream->avail_out = ret->size - ret->pos;
380 		zstream->next_out = buf_getwriteptr(ret, zstream->avail_out);
381 
382 		result = inflate(zstream, Z_SYNC_FLUSH);
383 
384 		buf_setlen(ret, ret->size - zstream->avail_out);
385 		buf_setpos(ret, ret->len);
386 
387 		if (result != Z_BUF_ERROR && result != Z_OK) {
388 			dropbear_exit("zlib error");
389 		}
390 
391 		if (zstream->avail_in == 0 &&
392 		   		(zstream->avail_out != 0 || result == Z_BUF_ERROR)) {
393 			/* we can only exit if avail_out hasn't all been used,
394 			 * and there's no remaining input */
395 			return ret;
396 		}
397 
398 		if (zstream->avail_out == 0) {
399 			buf_resize(ret, ret->size + ZLIB_DECOMPRESS_INCR);
400 		}
401 	}
402 }
403 #endif
404 
405 
406 
407 
408 /* encrypt the writepayload, putting into writebuf, ready for write_packet()
409  * to put on the wire */
encrypt_packet()410 void encrypt_packet() {
411 
412 	unsigned char padlen;
413 	unsigned char blocksize, macsize;
414 	buffer * writebuf; /* the packet which will go on the wire */
415 	buffer * clearwritebuf; /* unencrypted, possibly compressed */
416 
417 	TRACE(("enter encrypt_packet()"))
418 	TRACE(("encrypt_packet type is %d", ses.writepayload->data[0]))
419 	blocksize = ses.keys->trans_algo_crypt->blocksize;
420 	macsize = ses.keys->trans_algo_mac->hashsize;
421 
422 	/* Encrypted packet len is payload+5, then worst case is if we are 3 away
423 	 * from a blocksize multiple. In which case we need to pad to the
424 	 * multiple, then add another blocksize (or MIN_PACKET_LEN) */
425 	clearwritebuf = buf_new((ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3
426 #ifndef DISABLE_ZLIB
427 			+ ZLIB_COMPRESS_INCR /* bit of a kludge, but we can't know len*/
428 #endif
429 			);
430 	buf_setlen(clearwritebuf, PACKET_PAYLOAD_OFF);
431 	buf_setpos(clearwritebuf, PACKET_PAYLOAD_OFF);
432 
433 	buf_setpos(ses.writepayload, 0);
434 
435 #ifndef DISABLE_ZLIB
436 	/* compression */
437 	if (ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB) {
438 		buf_compress(clearwritebuf, ses.writepayload, ses.writepayload->len);
439 	} else
440 #endif
441 	{
442 		memcpy(buf_getwriteptr(clearwritebuf, ses.writepayload->len),
443 				buf_getptr(ses.writepayload, ses.writepayload->len),
444 				ses.writepayload->len);
445 		buf_incrwritepos(clearwritebuf, ses.writepayload->len);
446 	}
447 
448 	/* finished with payload */
449 	buf_setpos(ses.writepayload, 0);
450 	buf_setlen(ses.writepayload, 0);
451 
452 	/* length of padding - packet length must be a multiple of blocksize,
453 	 * with a minimum of 4 bytes of padding */
454 	padlen = blocksize - (clearwritebuf->len) % blocksize;
455 	if (padlen < 4) {
456 		padlen += blocksize;
457 	}
458 	/* check for min packet length */
459 	if (clearwritebuf->len + padlen < MIN_PACKET_LEN) {
460 		padlen += blocksize;
461 	}
462 
463 	buf_setpos(clearwritebuf, 0);
464 	/* packet length excluding the packetlength uint32 */
465 	buf_putint(clearwritebuf, clearwritebuf->len + padlen - 4);
466 
467 	/* padding len */
468 	buf_putbyte(clearwritebuf, padlen);
469 	/* actual padding */
470 	buf_setpos(clearwritebuf, clearwritebuf->len);
471 	buf_incrlen(clearwritebuf, padlen);
472 	genrandom(buf_getptr(clearwritebuf, padlen), padlen);
473 
474 	/* do the actual encryption */
475 	buf_setpos(clearwritebuf, 0);
476 	/* create a new writebuffer, this is freed when it has been put on the
477 	 * wire by writepacket() */
478 	writebuf = buf_new(clearwritebuf->len + macsize);
479 
480 	if (ses.keys->trans_algo_crypt->cipherdesc == NULL) {
481 		/* copy it */
482 		memcpy(buf_getwriteptr(writebuf, clearwritebuf->len),
483 				buf_getptr(clearwritebuf, clearwritebuf->len),
484 				clearwritebuf->len);
485 		buf_incrwritepos(writebuf, clearwritebuf->len);
486 	} else {
487 		/* encrypt it */
488 		while (clearwritebuf->pos < clearwritebuf->len) {
489 			if (cbc_encrypt(buf_getptr(clearwritebuf, blocksize),
490 						buf_getwriteptr(writebuf, blocksize),
491 						blocksize,
492 						&ses.keys->trans_symmetric_struct) != CRYPT_OK) {
493 				dropbear_exit("error encrypting");
494 			}
495 			buf_incrpos(clearwritebuf, blocksize);
496 			buf_incrwritepos(writebuf, blocksize);
497 		}
498 	}
499 
500 	/* now add a hmac and we're done */
501 	writemac(writebuf, clearwritebuf);
502 
503 	/* clearwritebuf is finished with */
504 	buf_free(clearwritebuf);
505 	clearwritebuf = NULL;
506 
507 	/* enqueue the packet for sending */
508 	buf_setpos(writebuf, 0);
509 	enqueue(&ses.writequeue, (void*)writebuf);
510 
511 	/* Update counts */
512 	ses.kexstate.datatrans += writebuf->len;
513 	ses.transseq++;
514 
515 	TRACE(("leave encrypt_packet()"))
516 }
517 
518 
519 /* Create the packet mac, and append H(seqno|clearbuf) to the output */
writemac(buffer * outputbuffer,buffer * clearwritebuf)520 static void writemac(buffer * outputbuffer, buffer * clearwritebuf) {
521 
522 	unsigned int macsize;
523 	unsigned char seqbuf[4];
524 	unsigned char tempbuf[MAX_MAC_LEN];
525 	unsigned long bufsize;
526 	hmac_state hmac;
527 
528 	TRACE(("enter writemac"))
529 
530 	macsize = ses.keys->trans_algo_mac->hashsize;
531 	if (macsize > 0) {
532 		/* calculate the mac */
533 		if (hmac_init(&hmac,
534 					find_hash(ses.keys->trans_algo_mac->hashdesc->name),
535 					ses.keys->transmackey,
536 					ses.keys->trans_algo_mac->keysize) != CRYPT_OK) {
537 			dropbear_exit("HMAC error");
538 		}
539 
540 		/* sequence number */
541 		STORE32H(ses.transseq, seqbuf);
542 		if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
543 			dropbear_exit("HMAC error");
544 		}
545 
546 		/* the actual contents */
547 		buf_setpos(clearwritebuf, 0);
548 		if (hmac_process(&hmac,
549 					buf_getptr(clearwritebuf,
550 						clearwritebuf->len),
551 					clearwritebuf->len) != CRYPT_OK) {
552 			dropbear_exit("HMAC error");
553 		}
554 
555 		bufsize = sizeof(tempbuf);
556 		if (hmac_done(&hmac, tempbuf, &bufsize)
557 				!= CRYPT_OK) {
558 			dropbear_exit("HMAC error");
559 		}
560 		buf_putbytes(outputbuffer, tempbuf, macsize);
561 	}
562 	TRACE(("leave writemac"))
563 }
564 
565 #ifndef DISABLE_ZLIB
566 /* compresses len bytes from src, outputting to dest (starting from the
567  * respective current positions. */
buf_compress(buffer * dest,buffer * src,unsigned int len)568 static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
569 
570 	unsigned int endpos = src->pos + len;
571 	int result;
572 
573 	TRACE(("enter buf_compress"))
574 
575 	while (1) {
576 
577 		ses.keys->trans_zstream->avail_in = endpos - src->pos;
578 		ses.keys->trans_zstream->next_in =
579 			buf_getptr(src, ses.keys->trans_zstream->avail_in);
580 
581 		ses.keys->trans_zstream->avail_out = dest->size - dest->pos;
582 		ses.keys->trans_zstream->next_out =
583 			buf_getwriteptr(dest, ses.keys->trans_zstream->avail_out);
584 
585 		result = deflate(ses.keys->trans_zstream, Z_SYNC_FLUSH);
586 
587 		buf_setpos(src, endpos - ses.keys->trans_zstream->avail_in);
588 		buf_setlen(dest, dest->size - ses.keys->trans_zstream->avail_out);
589 		buf_setpos(dest, dest->len);
590 
591 		if (result != Z_OK) {
592 			dropbear_exit("zlib error");
593 		}
594 
595 		if (ses.keys->trans_zstream->avail_in == 0) {
596 			break;
597 		}
598 
599 		dropbear_assert(ses.keys->trans_zstream->avail_out == 0);
600 
601 		/* the buffer has been filled, we must extend. This only happens in
602 		 * unusual circumstances where the data grows in size after deflate(),
603 		 * but it is possible */
604 		buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR);
605 
606 	}
607 	TRACE(("leave buf_compress"))
608 }
609 #endif
610