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 "dbrandom.h"
34 #include "service.h"
35 #include "auth.h"
36 #include "channel.h"
37 #include "netio.h"
38 #include "runopts.h"
39
40 static int read_packet_init(void);
41 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
42 buffer * clear_buf, unsigned int clear_len,
43 unsigned char *output_mac);
44 static int checkmac(void);
45
46 /* For exact details see http://www.zlib.net/zlib_tech.html
47 * 5 bytes per 16kB block, plus 6 bytes for the stream.
48 * We might allocate 5 unnecessary bytes here if it's an
49 * exact multiple. */
50 #define ZLIB_COMPRESS_EXPANSION (((RECV_MAX_PAYLOAD_LEN/16384)+1)*5 + 6)
51 #define ZLIB_DECOMPRESS_INCR 1024
52 #ifndef DISABLE_ZLIB
53 static buffer* buf_decompress(const buffer* buf, unsigned int len);
54 static void buf_compress(buffer * dest, buffer * src, unsigned int len);
55 #endif
56
57 /* non-blocking function writing out a current encrypted packet */
write_packet()58 void write_packet() {
59
60 ssize_t written;
61 #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))
62 /* 50 is somewhat arbitrary */
63 unsigned int iov_count = 50;
64 struct iovec iov[50];
65 #else
66 int len;
67 buffer* writebuf;
68 #endif
69
70 TRACE2(("enter write_packet"))
71 dropbear_assert(!isempty(&ses.writequeue));
72
73 #if defined(HAVE_WRITEV) && (defined(IOV_MAX) || defined(UIO_MAXIOV))
74
75 packet_queue_to_iovec(&ses.writequeue, iov, &iov_count);
76 /* This may return EAGAIN. The main loop sometimes
77 calls write_packet() without bothering to test with select() since
78 it's likely to be necessary */
79 #if DROPBEAR_FUZZ
80 if (fuzz.fuzzing) {
81 /* pretend to write one packet at a time */
82 /* TODO(fuzz): randomise amount written based on the fuzz input */
83 written = iov[0].iov_len;
84 }
85 else
86 #endif
87 {
88 written = writev(ses.sock_out, iov, iov_count);
89 if (written < 0) {
90 if (errno == EINTR || errno == EAGAIN) {
91 TRACE2(("leave write_packet: EINTR"))
92 return;
93 } else {
94 dropbear_exit("Error writing: %s", strerror(errno));
95 }
96 }
97 }
98
99 packet_queue_consume(&ses.writequeue, written);
100 ses.writequeue_len -= written;
101
102 if (written == 0) {
103 ses.remoteclosed();
104 }
105
106 #else /* No writev () */
107 #if DROPBEAR_FUZZ
108 _Static_assert(0, "No fuzzing code for no-writev writes");
109 #endif
110 /* Get the next buffer in the queue of encrypted packets to write*/
111 writebuf = (buffer*)examine(&ses.writequeue);
112
113 len = writebuf->len - writebuf->pos;
114 dropbear_assert(len > 0);
115 /* Try to write as much as possible */
116 written = write(ses.sock_out, buf_getptr(writebuf, len), len);
117
118 if (written < 0) {
119 if (errno == EINTR || errno == EAGAIN) {
120 TRACE2(("leave writepacket: EINTR"))
121 return;
122 } else {
123 dropbear_exit("Error writing: %s", strerror(errno));
124 }
125 }
126
127 if (written == 0) {
128 ses.remoteclosed();
129 }
130
131 ses.writequeue_len -= written;
132
133 if (written == len) {
134 /* We've finished with the packet, free it */
135 dequeue(&ses.writequeue);
136 buf_free(writebuf);
137 writebuf = NULL;
138 } else {
139 /* More packet left to write, leave it in the queue for later */
140 buf_incrpos(writebuf, written);
141 }
142 #endif /* writev */
143
144 TRACE2(("leave write_packet"))
145 }
146
147 /* Non-blocking function reading available portion of a packet into the
148 * ses's buffer, decrypting the length if encrypted, decrypting the
149 * full portion if possible */
read_packet()150 void read_packet() {
151
152 int len;
153 unsigned int maxlen;
154 unsigned char blocksize;
155
156 TRACE2(("enter read_packet"))
157 blocksize = ses.keys->recv.algo_crypt->blocksize;
158
159 if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
160 int ret;
161 /* In the first blocksize of a packet */
162
163 /* Read the first blocksize of the packet, so we can decrypt it and
164 * find the length of the whole packet */
165 ret = read_packet_init();
166
167 if (ret == DROPBEAR_FAILURE) {
168 /* didn't read enough to determine the length */
169 TRACE2(("leave read_packet: packetinit done"))
170 return;
171 }
172 }
173
174 /* Attempt to read the remainder of the packet, note that there
175 * mightn't be any available (EAGAIN) */
176 maxlen = ses.readbuf->len - ses.readbuf->pos;
177 if (maxlen == 0) {
178 /* Occurs when the packet is only a single block long and has all
179 * been read in read_packet_init(). Usually means that MAC is disabled
180 */
181 len = 0;
182 } else {
183 len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen);
184
185 if (len == 0) {
186 ses.remoteclosed();
187 }
188
189 if (len < 0) {
190 if (errno == EINTR || errno == EAGAIN) {
191 TRACE2(("leave read_packet: EINTR or EAGAIN"))
192 return;
193 } else {
194 dropbear_exit("Error reading: %s", strerror(errno));
195 }
196 }
197
198 buf_incrpos(ses.readbuf, len);
199 }
200
201 if ((unsigned int)len == maxlen) {
202 /* The whole packet has been read */
203 decrypt_packet();
204 /* The main select() loop process_packet() to
205 * handle the packet contents... */
206 }
207 TRACE2(("leave read_packet"))
208 }
209
210 /* Function used to read the initial portion of a packet, and determine the
211 * length. Only called during the first BLOCKSIZE of a packet. */
212 /* Returns DROPBEAR_SUCCESS if the length is determined,
213 * DROPBEAR_FAILURE otherwise */
read_packet_init()214 static int read_packet_init() {
215
216 unsigned int maxlen;
217 int slen;
218 unsigned int len, plen;
219 unsigned int blocksize;
220 unsigned int macsize;
221
222
223 blocksize = ses.keys->recv.algo_crypt->blocksize;
224 macsize = ses.keys->recv.algo_mac->hashsize;
225
226 if (ses.readbuf == NULL) {
227 /* start of a new packet */
228 ses.readbuf = buf_new(INIT_READBUF);
229 }
230
231 maxlen = blocksize - ses.readbuf->pos;
232
233 /* read the rest of the packet if possible */
234 slen = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
235 maxlen);
236 if (slen == 0) {
237 ses.remoteclosed();
238 }
239 if (slen < 0) {
240 if (errno == EINTR || errno == EAGAIN) {
241 TRACE2(("leave read_packet_init: EINTR"))
242 return DROPBEAR_FAILURE;
243 }
244 dropbear_exit("Error reading: %s", strerror(errno));
245 }
246
247 buf_incrwritepos(ses.readbuf, slen);
248
249 if ((unsigned int)slen != maxlen) {
250 /* don't have enough bytes to determine length, get next time */
251 return DROPBEAR_FAILURE;
252 }
253
254 /* now we have the first block, need to get packet length, so we decrypt
255 * the first block (only need first 4 bytes) */
256 buf_setpos(ses.readbuf, 0);
257 #if DROPBEAR_AEAD_MODE
258 if (ses.keys->recv.crypt_mode->aead_crypt) {
259 if (ses.keys->recv.crypt_mode->aead_getlength(ses.recvseq,
260 buf_getptr(ses.readbuf, blocksize), &plen,
261 blocksize,
262 &ses.keys->recv.cipher_state) != CRYPT_OK) {
263 dropbear_exit("Error decrypting");
264 }
265 len = plen + 4 + macsize;
266 } else
267 #endif
268 {
269 if (ses.keys->recv.crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize),
270 buf_getwriteptr(ses.readbuf, blocksize),
271 blocksize,
272 &ses.keys->recv.cipher_state) != CRYPT_OK) {
273 dropbear_exit("Error decrypting");
274 }
275 plen = buf_getint(ses.readbuf) + 4;
276 len = plen + macsize;
277 }
278
279 TRACE2(("packet size is %u, block %u mac %u", len, blocksize, macsize))
280
281
282 /* check packet length */
283 if ((len > RECV_MAX_PACKET_LEN) ||
284 (plen < blocksize) ||
285 (plen % blocksize != 0)) {
286 dropbear_exit("Integrity error (bad packet size %u)", len);
287 }
288
289 if (len > ses.readbuf->size) {
290 ses.readbuf = buf_resize(ses.readbuf, len);
291 }
292 buf_setlen(ses.readbuf, len);
293 buf_setpos(ses.readbuf, blocksize);
294 return DROPBEAR_SUCCESS;
295 }
296
297 /* handle the received packet */
decrypt_packet()298 void decrypt_packet() {
299
300 unsigned char blocksize;
301 unsigned char macsize;
302 unsigned int padlen;
303 unsigned int len;
304
305 TRACE2(("enter decrypt_packet"))
306 blocksize = ses.keys->recv.algo_crypt->blocksize;
307 macsize = ses.keys->recv.algo_mac->hashsize;
308
309 ses.kexstate.datarecv += ses.readbuf->len;
310
311 #if DROPBEAR_AEAD_MODE
312 if (ses.keys->recv.crypt_mode->aead_crypt) {
313 /* first blocksize is not decrypted yet */
314 buf_setpos(ses.readbuf, 0);
315
316 /* decrypt it in-place */
317 len = ses.readbuf->len - macsize - ses.readbuf->pos;
318 if (ses.keys->recv.crypt_mode->aead_crypt(ses.recvseq,
319 buf_getptr(ses.readbuf, len + macsize),
320 buf_getwriteptr(ses.readbuf, len),
321 len, macsize,
322 &ses.keys->recv.cipher_state, LTC_DECRYPT) != CRYPT_OK) {
323 dropbear_exit("Error decrypting");
324 }
325 buf_incrpos(ses.readbuf, len);
326 } else
327 #endif
328 {
329 /* we've already decrypted the first blocksize in read_packet_init */
330 buf_setpos(ses.readbuf, blocksize);
331
332 /* decrypt it in-place */
333 len = ses.readbuf->len - macsize - ses.readbuf->pos;
334 if (ses.keys->recv.crypt_mode->decrypt(
335 buf_getptr(ses.readbuf, len),
336 buf_getwriteptr(ses.readbuf, len),
337 len,
338 &ses.keys->recv.cipher_state) != CRYPT_OK) {
339 dropbear_exit("Error decrypting");
340 }
341 buf_incrpos(ses.readbuf, len);
342
343 /* check the hmac */
344 if (checkmac() != DROPBEAR_SUCCESS) {
345 dropbear_exit("Integrity error");
346 }
347
348 }
349
350 #if DROPBEAR_FUZZ
351 fuzz_dump(ses.readbuf->data, ses.readbuf->len);
352 #endif
353
354 /* get padding length */
355 buf_setpos(ses.readbuf, PACKET_PADDING_OFF);
356 padlen = buf_getbyte(ses.readbuf);
357
358 /* payload length */
359 /* - 4 - 1 is for LEN and PADLEN values */
360 len = ses.readbuf->len - padlen - 4 - 1 - macsize;
361 if ((len > RECV_MAX_PAYLOAD_LEN+ZLIB_COMPRESS_EXPANSION) || (len < 1)) {
362 dropbear_exit("Bad packet size %u", len);
363 }
364
365 buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF);
366
367 #ifndef DISABLE_ZLIB
368 if (is_compress_recv()) {
369 /* decompress */
370 ses.payload = buf_decompress(ses.readbuf, len);
371 buf_setpos(ses.payload, 0);
372 ses.payload_beginning = 0;
373 buf_free(ses.readbuf);
374 } else
375 #endif
376 {
377 ses.payload = ses.readbuf;
378 ses.payload_beginning = ses.payload->pos;
379 buf_setlen(ses.payload, ses.payload->pos + len);
380 }
381 ses.readbuf = NULL;
382
383 ses.recvseq++;
384
385 TRACE2(("leave decrypt_packet"))
386 }
387
388 /* Checks the mac at the end of a decrypted readbuf.
389 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
checkmac()390 static int checkmac() {
391
392 unsigned char mac_bytes[MAX_MAC_LEN];
393 unsigned int mac_size, contents_len;
394
395 mac_size = ses.keys->recv.algo_mac->hashsize;
396 contents_len = ses.readbuf->len - mac_size;
397
398 buf_setpos(ses.readbuf, 0);
399 make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes);
400
401 #if DROPBEAR_FUZZ
402 if (fuzz.fuzzing) {
403 /* fail 1 in 2000 times to test error path. */
404 unsigned int value = 0;
405 if (mac_size > sizeof(value)) {
406 memcpy(&value, mac_bytes, sizeof(value));
407 }
408 if (value % 2000 == 99) {
409 return DROPBEAR_FAILURE;
410 }
411 return DROPBEAR_SUCCESS;
412 }
413 #endif
414
415 /* compare the hash */
416 buf_setpos(ses.readbuf, contents_len);
417 if (constant_time_memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
418 return DROPBEAR_FAILURE;
419 } else {
420 return DROPBEAR_SUCCESS;
421 }
422 }
423
424 #ifndef DISABLE_ZLIB
425 /* returns a pointer to a newly created buffer */
buf_decompress(const buffer * buf,unsigned int len)426 static buffer* buf_decompress(const buffer* buf, unsigned int len) {
427
428 int result;
429 buffer * ret;
430 z_streamp zstream;
431
432 zstream = ses.keys->recv.zstream;
433 ret = buf_new(len);
434
435 zstream->avail_in = len;
436 zstream->next_in = buf_getptr(buf, len);
437
438 /* decompress the payload, incrementally resizing the output buffer */
439 while (1) {
440
441 zstream->avail_out = ret->size - ret->pos;
442 zstream->next_out = buf_getwriteptr(ret, zstream->avail_out);
443
444 result = inflate(zstream, Z_SYNC_FLUSH);
445
446 buf_setlen(ret, ret->size - zstream->avail_out);
447 buf_setpos(ret, ret->len);
448
449 if (result != Z_BUF_ERROR && result != Z_OK) {
450 dropbear_exit("zlib error");
451 }
452
453 if (zstream->avail_in == 0 &&
454 (zstream->avail_out != 0 || result == Z_BUF_ERROR)) {
455 /* we can only exit if avail_out hasn't all been used,
456 * and there's no remaining input */
457 return ret;
458 }
459
460 if (zstream->avail_out == 0) {
461 int new_size = 0;
462 if (ret->size >= RECV_MAX_PAYLOAD_LEN) {
463 /* Already been increased as large as it can go,
464 * yet didn't finish up the decompression */
465 dropbear_exit("bad packet, oversized decompressed");
466 }
467 new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR);
468 ret = buf_resize(ret, new_size);
469 }
470 }
471 }
472 #endif
473
474
475 /* returns 1 if the packet is a valid type during kex (see 7.1 of rfc4253) */
packet_is_okay_kex(unsigned char type)476 static int packet_is_okay_kex(unsigned char type) {
477 if (type >= SSH_MSG_USERAUTH_REQUEST) {
478 return 0;
479 }
480 if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) {
481 return 0;
482 }
483 if (type == SSH_MSG_KEXINIT) {
484 /* XXX should this die horribly if !dataallowed ?? */
485 return 0;
486 }
487 return 1;
488 }
489
enqueue_reply_packet()490 static void enqueue_reply_packet() {
491 struct packetlist * new_item = NULL;
492 new_item = m_malloc(sizeof(struct packetlist));
493 new_item->next = NULL;
494
495 new_item->payload = buf_newcopy(ses.writepayload);
496 buf_setpos(ses.writepayload, 0);
497 buf_setlen(ses.writepayload, 0);
498
499 if (ses.reply_queue_tail) {
500 ses.reply_queue_tail->next = new_item;
501 } else {
502 ses.reply_queue_head = new_item;
503 }
504 ses.reply_queue_tail = new_item;
505 }
506
maybe_flush_reply_queue()507 void maybe_flush_reply_queue() {
508 struct packetlist *tmp_item = NULL, *curr_item = NULL;
509 if (!ses.dataallowed)
510 {
511 TRACE(("maybe_empty_reply_queue - no data allowed"))
512 return;
513 }
514
515 for (curr_item = ses.reply_queue_head; curr_item; ) {
516 CHECKCLEARTOWRITE();
517 buf_putbytes(ses.writepayload,
518 curr_item->payload->data, curr_item->payload->len);
519
520 buf_free(curr_item->payload);
521 tmp_item = curr_item;
522 curr_item = curr_item->next;
523 m_free(tmp_item);
524 encrypt_packet();
525 }
526 ses.reply_queue_head = ses.reply_queue_tail = NULL;
527 }
528
529 /* encrypt the writepayload, putting into writebuf, ready for write_packet()
530 * to put on the wire */
encrypt_packet()531 void encrypt_packet() {
532
533 unsigned char padlen;
534 unsigned char blocksize, mac_size;
535 buffer * writebuf; /* the packet which will go on the wire. This is
536 encrypted in-place. */
537 unsigned char packet_type;
538 unsigned int len, encrypt_buf_size;
539 unsigned char mac_bytes[MAX_MAC_LEN];
540
541 time_t now;
542
543 TRACE2(("enter encrypt_packet()"))
544
545 buf_setpos(ses.writepayload, 0);
546 packet_type = buf_getbyte(ses.writepayload);
547 buf_setpos(ses.writepayload, 0);
548
549 TRACE2(("encrypt_packet type is %d", packet_type))
550
551 if ((!ses.dataallowed && !packet_is_okay_kex(packet_type))) {
552 /* During key exchange only particular packets are allowed.
553 Since this packet_type isn't OK we just enqueue it to send
554 after the KEX, see maybe_flush_reply_queue */
555 enqueue_reply_packet();
556 return;
557 }
558
559 blocksize = ses.keys->trans.algo_crypt->blocksize;
560 mac_size = ses.keys->trans.algo_mac->hashsize;
561
562 /* Encrypted packet len is payload+5. We need to then make sure
563 * there is enough space for padding or MIN_PACKET_LEN.
564 * Add extra 3 since we need at least 4 bytes of padding */
565 encrypt_buf_size = (ses.writepayload->len+4+1)
566 + MAX(MIN_PACKET_LEN, blocksize) + 3
567 /* add space for the MAC at the end */
568 + mac_size
569 #ifndef DISABLE_ZLIB
570 /* some extra in case 'compression' makes it larger */
571 + ZLIB_COMPRESS_EXPANSION
572 #endif
573 /* and an extra cleartext (stripped before transmission) byte for the
574 * packet type */
575 + 1;
576
577 writebuf = buf_new(encrypt_buf_size);
578 buf_setlen(writebuf, PACKET_PAYLOAD_OFF);
579 buf_setpos(writebuf, PACKET_PAYLOAD_OFF);
580
581 #ifndef DISABLE_ZLIB
582 /* compression */
583 if (is_compress_trans()) {
584 buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
585 } else
586 #endif
587 {
588 memcpy(buf_getwriteptr(writebuf, ses.writepayload->len),
589 buf_getptr(ses.writepayload, ses.writepayload->len),
590 ses.writepayload->len);
591 buf_incrwritepos(writebuf, ses.writepayload->len);
592 }
593
594 /* finished with payload */
595 buf_setpos(ses.writepayload, 0);
596 buf_setlen(ses.writepayload, 0);
597
598 /* length of padding - packet length excluding the packetlength uint32
599 * field in aead mode must be a multiple of blocksize, with a minimum of
600 * 4 bytes of padding */
601 len = writebuf->len;
602 #if DROPBEAR_AEAD_MODE
603 if (ses.keys->trans.crypt_mode->aead_crypt) {
604 len -= 4;
605 }
606 #endif
607 padlen = blocksize - len % blocksize;
608 if (padlen < 4) {
609 padlen += blocksize;
610 }
611 /* check for min packet length */
612 if (writebuf->len + padlen < MIN_PACKET_LEN) {
613 padlen += blocksize;
614 }
615
616 buf_setpos(writebuf, 0);
617 /* packet length excluding the packetlength uint32 */
618 buf_putint(writebuf, writebuf->len + padlen - 4);
619
620 /* padding len */
621 buf_putbyte(writebuf, padlen);
622 /* actual padding */
623 buf_setpos(writebuf, writebuf->len);
624 buf_incrlen(writebuf, padlen);
625 genrandom(buf_getptr(writebuf, padlen), padlen);
626
627 #if DROPBEAR_AEAD_MODE
628 if (ses.keys->trans.crypt_mode->aead_crypt) {
629 /* do the actual encryption, in-place */
630 buf_setpos(writebuf, 0);
631 /* encrypt it in-place*/
632 len = writebuf->len;
633 buf_incrlen(writebuf, mac_size);
634 if (ses.keys->trans.crypt_mode->aead_crypt(ses.transseq,
635 buf_getptr(writebuf, len),
636 buf_getwriteptr(writebuf, len + mac_size),
637 len, mac_size,
638 &ses.keys->trans.cipher_state, LTC_ENCRYPT) != CRYPT_OK) {
639 dropbear_exit("Error encrypting");
640 }
641 buf_incrpos(writebuf, len + mac_size);
642 } else
643 #endif
644 {
645 make_mac(ses.transseq, &ses.keys->trans, writebuf, writebuf->len, mac_bytes);
646
647 /* do the actual encryption, in-place */
648 buf_setpos(writebuf, 0);
649 /* encrypt it in-place*/
650 len = writebuf->len;
651 if (ses.keys->trans.crypt_mode->encrypt(
652 buf_getptr(writebuf, len),
653 buf_getwriteptr(writebuf, len),
654 len,
655 &ses.keys->trans.cipher_state) != CRYPT_OK) {
656 dropbear_exit("Error encrypting");
657 }
658 buf_incrpos(writebuf, len);
659
660 /* stick the MAC on it */
661 buf_putbytes(writebuf, mac_bytes, mac_size);
662 }
663
664 /* Update counts */
665 ses.kexstate.datatrans += writebuf->len;
666
667 writebuf_enqueue(writebuf);
668
669 /* Update counts */
670 ses.transseq++;
671
672 now = monotonic_now();
673 ses.last_packet_time_any_sent = now;
674 /* idle timeout shouldn't be affected by responses to keepalives.
675 send_msg_keepalive() itself also does tricks with
676 ses.last_packet_idle_time - read that if modifying this code */
677 if (packet_type != SSH_MSG_REQUEST_FAILURE
678 && packet_type != SSH_MSG_UNIMPLEMENTED
679 && packet_type != SSH_MSG_IGNORE) {
680 ses.last_packet_time_idle = now;
681
682 }
683
684 TRACE2(("leave encrypt_packet()"))
685 }
686
writebuf_enqueue(buffer * writebuf)687 void writebuf_enqueue(buffer * writebuf) {
688 /* enqueue the packet for sending. It will get freed after transmission. */
689 buf_setpos(writebuf, 0);
690 enqueue(&ses.writequeue, (void*)writebuf);
691 ses.writequeue_len += writebuf->len;
692 }
693
694
695 /* Create the packet mac, and append H(seqno|clearbuf) to the output */
696 /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */
make_mac(unsigned int seqno,const struct key_context_directional * key_state,buffer * clear_buf,unsigned int clear_len,unsigned char * output_mac)697 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
698 buffer * clear_buf, unsigned int clear_len,
699 unsigned char *output_mac) {
700 unsigned char seqbuf[4];
701 unsigned long bufsize;
702 hmac_state hmac;
703
704 if (key_state->algo_mac->hashsize > 0) {
705 /* calculate the mac */
706 if (hmac_init(&hmac,
707 key_state->hash_index,
708 key_state->mackey,
709 key_state->algo_mac->keysize) != CRYPT_OK) {
710 dropbear_exit("HMAC error");
711 }
712
713 /* sequence number */
714 STORE32H(seqno, seqbuf);
715 if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
716 dropbear_exit("HMAC error");
717 }
718
719 /* the actual contents */
720 buf_setpos(clear_buf, 0);
721 if (hmac_process(&hmac,
722 buf_getptr(clear_buf, clear_len),
723 clear_len) != CRYPT_OK) {
724 dropbear_exit("HMAC error");
725 }
726
727 bufsize = MAX_MAC_LEN;
728 if (hmac_done(&hmac, output_mac, &bufsize) != CRYPT_OK) {
729 dropbear_exit("HMAC error");
730 }
731 }
732 TRACE2(("leave writemac"))
733 }
734
735 #ifndef DISABLE_ZLIB
736 /* compresses len bytes from src, outputting to dest (starting from the
737 * respective current positions. dest must have sufficient space,
738 * len+ZLIB_COMPRESS_EXPANSION */
buf_compress(buffer * dest,buffer * src,unsigned int len)739 static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
740
741 unsigned int endpos = src->pos + len;
742 int result;
743
744 TRACE2(("enter buf_compress"))
745
746 dropbear_assert(dest->size - dest->pos >= len+ZLIB_COMPRESS_EXPANSION);
747
748 ses.keys->trans.zstream->avail_in = endpos - src->pos;
749 ses.keys->trans.zstream->next_in =
750 buf_getptr(src, ses.keys->trans.zstream->avail_in);
751
752 ses.keys->trans.zstream->avail_out = dest->size - dest->pos;
753 ses.keys->trans.zstream->next_out =
754 buf_getwriteptr(dest, ses.keys->trans.zstream->avail_out);
755
756 result = deflate(ses.keys->trans.zstream, Z_SYNC_FLUSH);
757
758 buf_setpos(src, endpos - ses.keys->trans.zstream->avail_in);
759 buf_setlen(dest, dest->size - ses.keys->trans.zstream->avail_out);
760 buf_setpos(dest, dest->len);
761
762 if (result != Z_OK) {
763 dropbear_exit("zlib error");
764 }
765
766 /* fails if destination buffer wasn't large enough */
767 dropbear_assert(ses.keys->trans.zstream->avail_in == 0);
768 TRACE2(("leave buf_compress"))
769 }
770 #endif
771