~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

1 by Matt Johnston
Import upstream version 0.42
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 */
50
void write_packet() {
51
52
	int len, written;
1.1.1 by Gerrit Pape
Import upstream version 0.43
53
	buffer * writebuf = NULL;
1 by Matt Johnston
Import upstream version 0.42
54
	
1.2.1 by Gerrit Pape
Import upstream version 0.45
55
	TRACE(("enter write_packet"))
1.2.2 by Matt Johnston
Import upstream version 0.47
56
	dropbear_assert(!isempty(&ses.writequeue));
1 by Matt Johnston
Import upstream version 0.42
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;
1.2.2 by Matt Johnston
Import upstream version 0.47
62
	dropbear_assert(len > 0);
1 by Matt Johnston
Import upstream version 0.42
63
	/* Try to write as much as possible */
1.4.2 by Gerrit Pape
Import upstream version 0.52
64
	written = write(ses.sock_out, buf_getptr(writebuf, len), len);
1 by Matt Johnston
Import upstream version 0.42
65
66
	if (written < 0) {
67
		if (errno == EINTR) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
68
			TRACE(("leave writepacket: EINTR"))
1 by Matt Johnston
Import upstream version 0.42
69
			return;
70
		} else {
71
			dropbear_exit("error writing");
72
		}
73
	} 
1.3.3 by Gerrit Pape
Import upstream version 0.50
74
	
1.4.2 by Gerrit Pape
Import upstream version 0.52
75
	ses.last_trx_packet_time = time(NULL);
1.3.3 by Gerrit Pape
Import upstream version 0.50
76
	ses.last_packet_time = time(NULL);
1 by Matt Johnston
Import upstream version 0.42
77
78
	if (written == 0) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
79
		ses.remoteclosed();
1 by Matt Johnston
Import upstream version 0.42
80
	}
81
82
	if (written == len) {
83
		/* We've finished with the packet, free it */
84
		dequeue(&ses.writequeue);
85
		buf_free(writebuf);
1.2.1 by Gerrit Pape
Import upstream version 0.45
86
		writebuf = NULL;
1 by Matt Johnston
Import upstream version 0.42
87
	} else {
88
		/* More packet left to write, leave it in the queue for later */
89
		buf_incrpos(writebuf, written);
90
	}
91
1.2.1 by Gerrit Pape
Import upstream version 0.45
92
	TRACE(("leave write_packet"))
1 by Matt Johnston
Import upstream version 0.42
93
}
94
95
/* Non-blocking function reading available portion of a packet into the
96
 * ses's buffer, decrypting the length if encrypted, decrypting the
97
 * full portion if possible */
98
void read_packet() {
99
100
	int len;
101
	unsigned int maxlen;
102
	unsigned char blocksize;
103
1.2.1 by Gerrit Pape
Import upstream version 0.45
104
	TRACE(("enter read_packet"))
1 by Matt Johnston
Import upstream version 0.42
105
	blocksize = ses.keys->recv_algo_crypt->blocksize;
106
	
107
	if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
108
		/* In the first blocksize of a packet */
109
110
		/* Read the first blocksize of the packet, so we can decrypt it and
111
		 * find the length of the whole packet */
112
		read_packet_init();
113
114
		/* If we don't have the length of decryptreadbuf, we didn't read
115
		 * a whole blocksize and should exit */
116
		if (ses.decryptreadbuf->len == 0) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
117
			TRACE(("leave read_packet: packetinit done"))
1 by Matt Johnston
Import upstream version 0.42
118
			return;
119
		}
120
	}
121
122
	/* Attempt to read the remainder of the packet, note that there
123
	 * mightn't be any available (EAGAIN) */
1.2.2 by Matt Johnston
Import upstream version 0.47
124
	dropbear_assert(ses.readbuf != NULL);
1 by Matt Johnston
Import upstream version 0.42
125
	maxlen = ses.readbuf->len - ses.readbuf->pos;
1.4.2 by Gerrit Pape
Import upstream version 0.52
126
	len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen);
1 by Matt Johnston
Import upstream version 0.42
127
128
	if (len == 0) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
129
		ses.remoteclosed();
1 by Matt Johnston
Import upstream version 0.42
130
	}
131
132
	if (len < 0) {
133
		if (errno == EINTR || errno == EAGAIN) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
134
			TRACE(("leave read_packet: EINTR or EAGAIN"))
1 by Matt Johnston
Import upstream version 0.42
135
			return;
136
		} else {
137
			dropbear_exit("error reading: %s", strerror(errno));
138
		}
139
	}
140
141
	buf_incrpos(ses.readbuf, len);
142
143
	if ((unsigned int)len == maxlen) {
144
		/* The whole packet has been read */
145
		decrypt_packet();
1.2.1 by Gerrit Pape
Import upstream version 0.45
146
		/* The main select() loop process_packet() to
1 by Matt Johnston
Import upstream version 0.42
147
		 * handle the packet contents... */
148
	}
1.2.1 by Gerrit Pape
Import upstream version 0.45
149
	TRACE(("leave read_packet"))
1 by Matt Johnston
Import upstream version 0.42
150
}
151
152
/* Function used to read the initial portion of a packet, and determine the
153
 * length. Only called during the first BLOCKSIZE of a packet. */
154
static void read_packet_init() {
155
156
	unsigned int maxlen;
157
	int len;
158
	unsigned char blocksize;
159
	unsigned char macsize;
160
161
162
	blocksize = ses.keys->recv_algo_crypt->blocksize;
163
	macsize = ses.keys->recv_algo_mac->hashsize;
164
165
	if (ses.readbuf == NULL) {
166
		/* start of a new packet */
167
		ses.readbuf = buf_new(INIT_READBUF);
1.2.2 by Matt Johnston
Import upstream version 0.47
168
		dropbear_assert(ses.decryptreadbuf == NULL);
1 by Matt Johnston
Import upstream version 0.42
169
		ses.decryptreadbuf = buf_new(blocksize);
170
	}
171
172
	maxlen = blocksize - ses.readbuf->pos;
173
			
174
	/* read the rest of the packet if possible */
1.4.2 by Gerrit Pape
Import upstream version 0.52
175
	len = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
1 by Matt Johnston
Import upstream version 0.42
176
			maxlen);
177
	if (len == 0) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
178
		ses.remoteclosed();
1 by Matt Johnston
Import upstream version 0.42
179
	}
180
	if (len < 0) {
181
		if (errno == EINTR) {
1.2.1 by Gerrit Pape
Import upstream version 0.45
182
			TRACE(("leave read_packet_init: EINTR"))
1 by Matt Johnston
Import upstream version 0.42
183
			return;
184
		}
185
		dropbear_exit("error reading: %s", strerror(errno));
186
	}
187
188
	buf_incrwritepos(ses.readbuf, len);
189
190
	if ((unsigned int)len != maxlen) {
191
		/* don't have enough bytes to determine length, get next time */
192
		return;
193
	}
194
195
	/* now we have the first block, need to get packet length, so we decrypt
196
	 * the first block (only need first 4 bytes) */
197
	buf_setpos(ses.readbuf, 0);
1.4.2 by Gerrit Pape
Import upstream version 0.52
198
	if (ses.keys->recv_crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize), 
199
				buf_getwriteptr(ses.decryptreadbuf,blocksize),
200
				blocksize,
201
				&ses.keys->recv_cipher_state) != CRYPT_OK) {
202
		dropbear_exit("error decrypting");
1 by Matt Johnston
Import upstream version 0.42
203
	}
204
	buf_setlen(ses.decryptreadbuf, blocksize);
205
	len = buf_getint(ses.decryptreadbuf) + 4 + macsize;
206
207
	buf_setpos(ses.readbuf, blocksize);
208
209
	/* check packet length */
1.3.3 by Gerrit Pape
Import upstream version 0.50
210
	if ((len > RECV_MAX_PACKET_LEN) ||
1 by Matt Johnston
Import upstream version 0.42
211
		(len < MIN_PACKET_LEN + macsize) ||
212
		((len - macsize) % blocksize != 0)) {
1.2.2 by Matt Johnston
Import upstream version 0.47
213
		dropbear_exit("bad packet size %d", len);
1 by Matt Johnston
Import upstream version 0.42
214
	}
215
216
	buf_resize(ses.readbuf, len);
217
	buf_setlen(ses.readbuf, len);
218
219
}
220
221
/* handle the received packet */
222
void decrypt_packet() {
223
224
	unsigned char blocksize;
225
	unsigned char macsize;
226
	unsigned int padlen;
227
	unsigned int len;
228
1.2.1 by Gerrit Pape
Import upstream version 0.45
229
	TRACE(("enter decrypt_packet"))
1 by Matt Johnston
Import upstream version 0.42
230
	blocksize = ses.keys->recv_algo_crypt->blocksize;
231
	macsize = ses.keys->recv_algo_mac->hashsize;
232
233
	ses.kexstate.datarecv += ses.readbuf->len;
234
235
	/* we've already decrypted the first blocksize in read_packet_init */
236
	buf_setpos(ses.readbuf, blocksize);
237
238
	buf_resize(ses.decryptreadbuf, ses.readbuf->len - macsize);
239
	buf_setlen(ses.decryptreadbuf, ses.decryptreadbuf->size);
240
	buf_setpos(ses.decryptreadbuf, blocksize);
241
1.4.2 by Gerrit Pape
Import upstream version 0.52
242
	/* decrypt it */
243
	while (ses.readbuf->pos < ses.readbuf->len - macsize) {
244
		if (ses.keys->recv_crypt_mode->decrypt(
245
					buf_getptr(ses.readbuf, blocksize), 
246
					buf_getwriteptr(ses.decryptreadbuf, blocksize),
247
					blocksize,
248
					&ses.keys->recv_cipher_state) != CRYPT_OK) {
249
			dropbear_exit("error decrypting");
1 by Matt Johnston
Import upstream version 0.42
250
		}
1.4.2 by Gerrit Pape
Import upstream version 0.52
251
		buf_incrpos(ses.readbuf, blocksize);
252
		buf_incrwritepos(ses.decryptreadbuf, blocksize);
1 by Matt Johnston
Import upstream version 0.42
253
	}
254
255
	/* check the hmac */
256
	buf_setpos(ses.readbuf, ses.readbuf->len - macsize);
257
	if (checkmac(ses.readbuf, ses.decryptreadbuf) != DROPBEAR_SUCCESS) {
258
		dropbear_exit("Integrity error");
259
	}
260
261
	/* readbuf no longer required */
262
	buf_free(ses.readbuf);
263
	ses.readbuf = NULL;
264
265
	/* get padding length */
266
	buf_setpos(ses.decryptreadbuf, PACKET_PADDING_OFF);
267
	padlen = buf_getbyte(ses.decryptreadbuf);
268
		
269
	/* payload length */
270
	/* - 4 - 1 is for LEN and PADLEN values */
271
	len = ses.decryptreadbuf->len - padlen - 4 - 1;
1.3.3 by Gerrit Pape
Import upstream version 0.50
272
	if ((len > RECV_MAX_PAYLOAD_LEN) || (len < 1)) {
1 by Matt Johnston
Import upstream version 0.42
273
		dropbear_exit("bad packet size");
274
	}
275
276
	buf_setpos(ses.decryptreadbuf, PACKET_PAYLOAD_OFF);
277
278
#ifndef DISABLE_ZLIB
1.4.2 by Gerrit Pape
Import upstream version 0.52
279
	if (is_compress_recv()) {
1 by Matt Johnston
Import upstream version 0.42
280
		/* decompress */
281
		ses.payload = buf_decompress(ses.decryptreadbuf, len);
282
	} else 
283
#endif
284
	{
285
		/* copy payload */
286
		ses.payload = buf_new(len);
287
		memcpy(ses.payload->data, buf_getptr(ses.decryptreadbuf, len), len);
288
		buf_incrlen(ses.payload, len);
289
	}
290
291
	buf_free(ses.decryptreadbuf);
292
	ses.decryptreadbuf = NULL;
293
	buf_setpos(ses.payload, 0);
294
295
	ses.recvseq++;
296
1.2.1 by Gerrit Pape
Import upstream version 0.45
297
	TRACE(("leave decrypt_packet"))
1 by Matt Johnston
Import upstream version 0.42
298
}
299
300
/* Checks the mac in hashbuf, for the data in readbuf.
301
 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
302
static int checkmac(buffer* macbuf, buffer* sourcebuf) {
303
1.2.2 by Matt Johnston
Import upstream version 0.47
304
	unsigned int macsize;
1 by Matt Johnston
Import upstream version 0.42
305
	hmac_state hmac;
306
	unsigned char tempbuf[MAX_MAC_LEN];
1.2.2 by Matt Johnston
Import upstream version 0.47
307
	unsigned long bufsize;
308
	unsigned int len;
1 by Matt Johnston
Import upstream version 0.42
309
310
	macsize = ses.keys->recv_algo_mac->hashsize;
311
	if (macsize == 0) {
312
		return DROPBEAR_SUCCESS;
313
	}
314
315
	/* calculate the mac */
316
	if (hmac_init(&hmac, 
317
				find_hash(ses.keys->recv_algo_mac->hashdesc->name), 
318
				ses.keys->recvmackey, 
319
				ses.keys->recv_algo_mac->keysize) 
320
				!= CRYPT_OK) {
321
		dropbear_exit("HMAC error");
322
	}
323
	
324
	/* sequence number */
325
	STORE32H(ses.recvseq, tempbuf);
326
	if (hmac_process(&hmac, tempbuf, 4) != CRYPT_OK) {
327
		dropbear_exit("HMAC error");
328
	}
329
330
	buf_setpos(sourcebuf, 0);
331
	len = sourcebuf->len;
332
	if (hmac_process(&hmac, buf_getptr(sourcebuf, len), len) != CRYPT_OK) {
333
		dropbear_exit("HMAC error");
334
	}
335
1.2.2 by Matt Johnston
Import upstream version 0.47
336
	bufsize = sizeof(tempbuf);
337
	if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) {
1 by Matt Johnston
Import upstream version 0.42
338
		dropbear_exit("HMAC error");
339
	}
340
341
	/* compare the hash */
342
	if (memcmp(tempbuf, buf_getptr(macbuf, macsize), macsize) != 0) {
343
		return DROPBEAR_FAILURE;
344
	} else {
345
		return DROPBEAR_SUCCESS;
346
	}
347
}
348
349
#ifndef DISABLE_ZLIB
350
/* returns a pointer to a newly created buffer */
351
static buffer* buf_decompress(buffer* buf, unsigned int len) {
352
353
	int result;
354
	buffer * ret;
355
	z_streamp zstream;
356
357
	zstream = ses.keys->recv_zstream;
358
	ret = buf_new(len);
359
360
	zstream->avail_in = len;
361
	zstream->next_in = buf_getptr(buf, len);
362
363
	/* decompress the payload, incrementally resizing the output buffer */
364
	while (1) {
365
366
		zstream->avail_out = ret->size - ret->pos;
367
		zstream->next_out = buf_getwriteptr(ret, zstream->avail_out);
368
369
		result = inflate(zstream, Z_SYNC_FLUSH);
370
371
		buf_setlen(ret, ret->size - zstream->avail_out);
372
		buf_setpos(ret, ret->len);
373
374
		if (result != Z_BUF_ERROR && result != Z_OK) {
375
			dropbear_exit("zlib error");
376
		}
377
378
		if (zstream->avail_in == 0 &&
379
		   		(zstream->avail_out != 0 || result == Z_BUF_ERROR)) {
380
			/* we can only exit if avail_out hasn't all been used,
381
			 * and there's no remaining input */
382
			return ret;
383
		}
384
385
		if (zstream->avail_out == 0) {
386
			buf_resize(ret, ret->size + ZLIB_DECOMPRESS_INCR);
387
		}
388
	}
389
}
390
#endif
391
392
1.3.3 by Gerrit Pape
Import upstream version 0.50
393
/* returns 1 if the packet is a valid type during kex (see 7.1 of rfc4253) */
394
static int packet_is_okay_kex(unsigned char type) {
395
	if (type >= SSH_MSG_USERAUTH_REQUEST) {
396
		return 0;
397
	}
398
	if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) {
399
		return 0;
400
	}
401
	if (type == SSH_MSG_KEXINIT) {
402
		/* XXX should this die horribly if !dataallowed ?? */
403
		return 0;
404
	}
405
	return 1;
406
}
407
408
static void enqueue_reply_packet() {
409
	struct packetlist * new_item = NULL;
410
	new_item = m_malloc(sizeof(struct packetlist));
411
	new_item->next = NULL;
412
	
413
	new_item->payload = buf_newcopy(ses.writepayload);
414
	buf_setpos(ses.writepayload, 0);
415
	buf_setlen(ses.writepayload, 0);
416
	
417
	if (ses.reply_queue_tail) {
418
		ses.reply_queue_tail->next = new_item;
419
	} else {
420
		ses.reply_queue_head = new_item;
421
	}
422
	ses.reply_queue_tail = new_item;
423
	TRACE(("leave enqueue_reply_packet"))
424
}
425
426
void maybe_flush_reply_queue() {
427
	struct packetlist *tmp_item = NULL, *curr_item = NULL;
428
	if (!ses.dataallowed)
429
	{
430
		TRACE(("maybe_empty_reply_queue - no data allowed"))
431
		return;
432
	}
433
		
434
	for (curr_item = ses.reply_queue_head; curr_item; ) {
435
		CHECKCLEARTOWRITE();
436
		buf_putbytes(ses.writepayload,
437
			curr_item->payload->data, curr_item->payload->len);
438
			
439
		buf_free(curr_item->payload);
440
		tmp_item = curr_item;
441
		curr_item = curr_item->next;
442
		m_free(tmp_item);
443
		encrypt_packet();
444
	}
445
	ses.reply_queue_head = ses.reply_queue_tail = NULL;
446
}
1.2.1 by Gerrit Pape
Import upstream version 0.45
447
	
1 by Matt Johnston
Import upstream version 0.42
448
/* encrypt the writepayload, putting into writebuf, ready for write_packet()
449
 * to put on the wire */
450
void encrypt_packet() {
451
452
	unsigned char padlen;
453
	unsigned char blocksize, macsize;
454
	buffer * writebuf; /* the packet which will go on the wire */
455
	buffer * clearwritebuf; /* unencrypted, possibly compressed */
1.3.3 by Gerrit Pape
Import upstream version 0.50
456
	unsigned char type;
1.4.2 by Gerrit Pape
Import upstream version 0.52
457
	unsigned int clear_len;
1 by Matt Johnston
Import upstream version 0.42
458
	
1.3.3 by Gerrit Pape
Import upstream version 0.50
459
	type = ses.writepayload->data[0];
1.2.1 by Gerrit Pape
Import upstream version 0.45
460
	TRACE(("enter encrypt_packet()"))
1.3.3 by Gerrit Pape
Import upstream version 0.50
461
	TRACE(("encrypt_packet type is %d", type))
462
	
463
	if (!ses.dataallowed && !packet_is_okay_kex(type)) {
464
		/* During key exchange only particular packets are allowed.
465
			Since this type isn't OK we just enqueue it to send 
466
			after the KEX, see maybe_flush_reply_queue */
467
		enqueue_reply_packet();
468
		return;
469
	}
470
		
1 by Matt Johnston
Import upstream version 0.42
471
	blocksize = ses.keys->trans_algo_crypt->blocksize;
472
	macsize = ses.keys->trans_algo_mac->hashsize;
473
474
	/* Encrypted packet len is payload+5, then worst case is if we are 3 away
475
	 * from a blocksize multiple. In which case we need to pad to the
476
	 * multiple, then add another blocksize (or MIN_PACKET_LEN) */
1.4.2 by Gerrit Pape
Import upstream version 0.52
477
	clear_len = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3;
478
1 by Matt Johnston
Import upstream version 0.42
479
#ifndef DISABLE_ZLIB
1.4.2 by Gerrit Pape
Import upstream version 0.52
480
	clear_len += ZLIB_COMPRESS_INCR; /* bit of a kludge, but we can't know len*/
1 by Matt Johnston
Import upstream version 0.42
481
#endif
1.4.2 by Gerrit Pape
Import upstream version 0.52
482
	clearwritebuf = buf_new(clear_len);
1 by Matt Johnston
Import upstream version 0.42
483
	buf_setlen(clearwritebuf, PACKET_PAYLOAD_OFF);
484
	buf_setpos(clearwritebuf, PACKET_PAYLOAD_OFF);
485
486
	buf_setpos(ses.writepayload, 0);
487
488
#ifndef DISABLE_ZLIB
489
	/* compression */
1.4.2 by Gerrit Pape
Import upstream version 0.52
490
	if (is_compress_trans()) {
1 by Matt Johnston
Import upstream version 0.42
491
		buf_compress(clearwritebuf, ses.writepayload, ses.writepayload->len);
492
	} else
493
#endif
494
	{
495
		memcpy(buf_getwriteptr(clearwritebuf, ses.writepayload->len),
496
				buf_getptr(ses.writepayload, ses.writepayload->len),
497
				ses.writepayload->len);
498
		buf_incrwritepos(clearwritebuf, ses.writepayload->len);
499
	}
500
501
	/* finished with payload */
502
	buf_setpos(ses.writepayload, 0);
503
	buf_setlen(ses.writepayload, 0);
504
505
	/* length of padding - packet length must be a multiple of blocksize,
506
	 * with a minimum of 4 bytes of padding */
507
	padlen = blocksize - (clearwritebuf->len) % blocksize;
508
	if (padlen < 4) {
509
		padlen += blocksize;
510
	}
511
	/* check for min packet length */
512
	if (clearwritebuf->len + padlen < MIN_PACKET_LEN) {
513
		padlen += blocksize;
514
	}
515
516
	buf_setpos(clearwritebuf, 0);
517
	/* packet length excluding the packetlength uint32 */
518
	buf_putint(clearwritebuf, clearwritebuf->len + padlen - 4);
519
520
	/* padding len */
521
	buf_putbyte(clearwritebuf, padlen);
522
	/* actual padding */
523
	buf_setpos(clearwritebuf, clearwritebuf->len);
524
	buf_incrlen(clearwritebuf, padlen);
525
	genrandom(buf_getptr(clearwritebuf, padlen), padlen);
526
527
	/* do the actual encryption */
528
	buf_setpos(clearwritebuf, 0);
529
	/* create a new writebuffer, this is freed when it has been put on the 
530
	 * wire by writepacket() */
531
	writebuf = buf_new(clearwritebuf->len + macsize);
532
1.4.2 by Gerrit Pape
Import upstream version 0.52
533
	/* encrypt it */
534
	while (clearwritebuf->pos < clearwritebuf->len) {
535
		if (ses.keys->trans_crypt_mode->encrypt(
536
					buf_getptr(clearwritebuf, blocksize),
537
					buf_getwriteptr(writebuf, blocksize),
538
					blocksize,
539
					&ses.keys->trans_cipher_state) != CRYPT_OK) {
540
			dropbear_exit("error encrypting");
1 by Matt Johnston
Import upstream version 0.42
541
		}
1.4.2 by Gerrit Pape
Import upstream version 0.52
542
		buf_incrpos(clearwritebuf, blocksize);
543
		buf_incrwritepos(writebuf, blocksize);
1 by Matt Johnston
Import upstream version 0.42
544
	}
545
546
	/* now add a hmac and we're done */
547
	writemac(writebuf, clearwritebuf);
548
549
	/* clearwritebuf is finished with */
550
	buf_free(clearwritebuf);
1.2.1 by Gerrit Pape
Import upstream version 0.45
551
	clearwritebuf = NULL;
1 by Matt Johnston
Import upstream version 0.42
552
553
	/* enqueue the packet for sending */
554
	buf_setpos(writebuf, 0);
555
	enqueue(&ses.writequeue, (void*)writebuf);
556
557
	/* Update counts */
558
	ses.kexstate.datatrans += writebuf->len;
559
	ses.transseq++;
560
1.2.1 by Gerrit Pape
Import upstream version 0.45
561
	TRACE(("leave encrypt_packet()"))
1 by Matt Johnston
Import upstream version 0.42
562
}
563
564
565
/* Create the packet mac, and append H(seqno|clearbuf) to the output */
566
static void writemac(buffer * outputbuffer, buffer * clearwritebuf) {
567
1.2.2 by Matt Johnston
Import upstream version 0.47
568
	unsigned int macsize;
1 by Matt Johnston
Import upstream version 0.42
569
	unsigned char seqbuf[4];
1.2.2 by Matt Johnston
Import upstream version 0.47
570
	unsigned char tempbuf[MAX_MAC_LEN];
571
	unsigned long bufsize;
1 by Matt Johnston
Import upstream version 0.42
572
	hmac_state hmac;
573
1.2.1 by Gerrit Pape
Import upstream version 0.45
574
	TRACE(("enter writemac"))
1 by Matt Johnston
Import upstream version 0.42
575
576
	macsize = ses.keys->trans_algo_mac->hashsize;
577
	if (macsize > 0) {
578
		/* calculate the mac */
579
		if (hmac_init(&hmac, 
580
					find_hash(ses.keys->trans_algo_mac->hashdesc->name), 
581
					ses.keys->transmackey, 
582
					ses.keys->trans_algo_mac->keysize) != CRYPT_OK) {
583
			dropbear_exit("HMAC error");
584
		}
585
	
586
		/* sequence number */
587
		STORE32H(ses.transseq, seqbuf);
588
		if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
589
			dropbear_exit("HMAC error");
590
		}
591
	
592
		/* the actual contents */
593
		buf_setpos(clearwritebuf, 0);
594
		if (hmac_process(&hmac, 
595
					buf_getptr(clearwritebuf, 
596
						clearwritebuf->len),
597
					clearwritebuf->len) != CRYPT_OK) {
598
			dropbear_exit("HMAC error");
599
		}
600
	
1.2.2 by Matt Johnston
Import upstream version 0.47
601
		bufsize = sizeof(tempbuf);
602
		if (hmac_done(&hmac, tempbuf, &bufsize) 
1 by Matt Johnston
Import upstream version 0.42
603
				!= CRYPT_OK) {
604
			dropbear_exit("HMAC error");
605
		}
1.2.2 by Matt Johnston
Import upstream version 0.47
606
		buf_putbytes(outputbuffer, tempbuf, macsize);
1 by Matt Johnston
Import upstream version 0.42
607
	}
1.2.1 by Gerrit Pape
Import upstream version 0.45
608
	TRACE(("leave writemac"))
1 by Matt Johnston
Import upstream version 0.42
609
}
610
611
#ifndef DISABLE_ZLIB
612
/* compresses len bytes from src, outputting to dest (starting from the
613
 * respective current positions. */
614
static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
615
616
	unsigned int endpos = src->pos + len;
617
	int result;
618
1.2.1 by Gerrit Pape
Import upstream version 0.45
619
	TRACE(("enter buf_compress"))
1 by Matt Johnston
Import upstream version 0.42
620
621
	while (1) {
622
623
		ses.keys->trans_zstream->avail_in = endpos - src->pos;
624
		ses.keys->trans_zstream->next_in = 
625
			buf_getptr(src, ses.keys->trans_zstream->avail_in);
626
627
		ses.keys->trans_zstream->avail_out = dest->size - dest->pos;
628
		ses.keys->trans_zstream->next_out =
629
			buf_getwriteptr(dest, ses.keys->trans_zstream->avail_out);
630
631
		result = deflate(ses.keys->trans_zstream, Z_SYNC_FLUSH);
632
633
		buf_setpos(src, endpos - ses.keys->trans_zstream->avail_in);
634
		buf_setlen(dest, dest->size - ses.keys->trans_zstream->avail_out);
635
		buf_setpos(dest, dest->len);
636
637
		if (result != Z_OK) {
638
			dropbear_exit("zlib error");
639
		}
640
641
		if (ses.keys->trans_zstream->avail_in == 0) {
642
			break;
643
		}
644
1.2.2 by Matt Johnston
Import upstream version 0.47
645
		dropbear_assert(ses.keys->trans_zstream->avail_out == 0);
1 by Matt Johnston
Import upstream version 0.42
646
647
		/* the buffer has been filled, we must extend. This only happens in
648
		 * unusual circumstances where the data grows in size after deflate(),
649
		 * but it is possible */
650
		buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR);
651
652
	}
1.2.1 by Gerrit Pape
Import upstream version 0.45
653
	TRACE(("leave buf_compress"))
1 by Matt Johnston
Import upstream version 0.42
654
}
655
#endif