comparison packet.c @ 641:2b1bb792cd4d dropbear-tfm

- Update tfm changes to current default tip
author Matt Johnston <matt@ucc.asn.au>
date Mon, 21 Nov 2011 19:52:28 +0800
parents 895fbe068f2c
children f4232b65b316
comparison
equal deleted inserted replaced
640:76097ec1a29a 641:2b1bb792cd4d
33 #include "random.h" 33 #include "random.h"
34 #include "service.h" 34 #include "service.h"
35 #include "auth.h" 35 #include "auth.h"
36 #include "channel.h" 36 #include "channel.h"
37 37
38 static void read_packet_init(); 38 static int read_packet_init();
39 static void writemac(buffer * outputbuffer, buffer * clearwritebuf); 39 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
40 static int checkmac(buffer* hashbuf, buffer* readbuf); 40 buffer * clear_buf, unsigned int clear_len,
41 41 unsigned char *output_mac);
42 #define ZLIB_COMPRESS_INCR 20 /* this is 12 bytes + 0.1% of 8000 bytes */ 42 static int checkmac();
43
44 #define ZLIB_COMPRESS_INCR 100
43 #define ZLIB_DECOMPRESS_INCR 100 45 #define ZLIB_DECOMPRESS_INCR 100
44 #ifndef DISABLE_ZLIB 46 #ifndef DISABLE_ZLIB
45 static buffer* buf_decompress(buffer* buf, unsigned int len); 47 static buffer* buf_decompress(buffer* buf, unsigned int len);
46 static void buf_compress(buffer * dest, buffer * src, unsigned int len); 48 static void buf_compress(buffer * dest, buffer * src, unsigned int len);
47 #endif 49 #endif
49 /* non-blocking function writing out a current encrypted packet */ 51 /* non-blocking function writing out a current encrypted packet */
50 void write_packet() { 52 void write_packet() {
51 53
52 int len, written; 54 int len, written;
53 buffer * writebuf = NULL; 55 buffer * writebuf = NULL;
56 time_t now;
57 unsigned packet_type;
54 58
55 TRACE(("enter write_packet")) 59 TRACE(("enter write_packet"))
56 dropbear_assert(!isempty(&ses.writequeue)); 60 dropbear_assert(!isempty(&ses.writequeue));
57 61
58 /* Get the next buffer in the queue of encrypted packets to write*/ 62 /* Get the next buffer in the queue of encrypted packets to write*/
59 writebuf = (buffer*)examine(&ses.writequeue); 63 writebuf = (buffer*)examine(&ses.writequeue);
60 64
61 len = writebuf->len - writebuf->pos; 65 /* The last byte of the buffer is not to be transmitted, but is
66 * a cleartext packet_type indicator */
67 packet_type = writebuf->data[writebuf->len-1];
68 len = writebuf->len - 1 - writebuf->pos;
62 dropbear_assert(len > 0); 69 dropbear_assert(len > 0);
63 /* Try to write as much as possible */ 70 /* Try to write as much as possible */
64 written = write(ses.sock_out, buf_getptr(writebuf, len), len); 71 written = write(ses.sock_out, buf_getptr(writebuf, len), len);
65 72
66 if (written < 0) { 73 if (written < 0) {
67 if (errno == EINTR) { 74 if (errno == EINTR) {
68 TRACE(("leave writepacket: EINTR")) 75 TRACE(("leave writepacket: EINTR"))
69 return; 76 return;
70 } else { 77 } else {
71 dropbear_exit("error writing"); 78 dropbear_exit("Error writing");
72 } 79 }
73 } 80 }
74 81
75 ses.last_trx_packet_time = time(NULL); 82 now = time(NULL);
76 ses.last_packet_time = time(NULL); 83 ses.last_trx_packet_time = now;
84
85 if (packet_type != SSH_MSG_IGNORE) {
86 ses.last_packet_time = now;
87 }
77 88
78 if (written == 0) { 89 if (written == 0) {
79 ses.remoteclosed(); 90 ses.remoteclosed();
80 } 91 }
81 92
100 int len; 111 int len;
101 unsigned int maxlen; 112 unsigned int maxlen;
102 unsigned char blocksize; 113 unsigned char blocksize;
103 114
104 TRACE(("enter read_packet")) 115 TRACE(("enter read_packet"))
105 blocksize = ses.keys->recv_algo_crypt->blocksize; 116 blocksize = ses.keys->recv.algo_crypt->blocksize;
106 117
107 if (ses.readbuf == NULL || ses.readbuf->len < blocksize) { 118 if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
119 int ret;
108 /* In the first blocksize of a packet */ 120 /* In the first blocksize of a packet */
109 121
110 /* Read the first blocksize of the packet, so we can decrypt it and 122 /* Read the first blocksize of the packet, so we can decrypt it and
111 * find the length of the whole packet */ 123 * find the length of the whole packet */
112 read_packet_init(); 124 ret = read_packet_init();
113 125
114 /* If we don't have the length of decryptreadbuf, we didn't read 126 if (ret == DROPBEAR_FAILURE) {
115 * a whole blocksize and should exit */ 127 /* didn't read enough to determine the length */
116 if (ses.decryptreadbuf->len == 0) {
117 TRACE(("leave read_packet: packetinit done")) 128 TRACE(("leave read_packet: packetinit done"))
118 return; 129 return;
119 } 130 }
120 } 131 }
121 132
122 /* Attempt to read the remainder of the packet, note that there 133 /* Attempt to read the remainder of the packet, note that there
123 * mightn't be any available (EAGAIN) */ 134 * mightn't be any available (EAGAIN) */
124 dropbear_assert(ses.readbuf != NULL);
125 maxlen = ses.readbuf->len - ses.readbuf->pos; 135 maxlen = ses.readbuf->len - ses.readbuf->pos;
126 len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen); 136 len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen);
127 137
128 if (len == 0) { 138 if (len == 0) {
129 ses.remoteclosed(); 139 ses.remoteclosed();
132 if (len < 0) { 142 if (len < 0) {
133 if (errno == EINTR || errno == EAGAIN) { 143 if (errno == EINTR || errno == EAGAIN) {
134 TRACE(("leave read_packet: EINTR or EAGAIN")) 144 TRACE(("leave read_packet: EINTR or EAGAIN"))
135 return; 145 return;
136 } else { 146 } else {
137 dropbear_exit("error reading: %s", strerror(errno)); 147 dropbear_exit("Error reading: %s", strerror(errno));
138 } 148 }
139 } 149 }
140 150
141 buf_incrpos(ses.readbuf, len); 151 buf_incrpos(ses.readbuf, len);
142 152
149 TRACE(("leave read_packet")) 159 TRACE(("leave read_packet"))
150 } 160 }
151 161
152 /* Function used to read the initial portion of a packet, and determine the 162 /* Function used to read the initial portion of a packet, and determine the
153 * length. Only called during the first BLOCKSIZE of a packet. */ 163 * length. Only called during the first BLOCKSIZE of a packet. */
154 static void read_packet_init() { 164 /* Returns DROPBEAR_SUCCESS if the length is determined,
165 * DROPBEAR_FAILURE otherwise */
166 static int read_packet_init() {
155 167
156 unsigned int maxlen; 168 unsigned int maxlen;
157 int len; 169 int slen;
158 unsigned char blocksize; 170 unsigned int len;
159 unsigned char macsize; 171 unsigned int blocksize;
160 172 unsigned int macsize;
161 173
162 blocksize = ses.keys->recv_algo_crypt->blocksize; 174
163 macsize = ses.keys->recv_algo_mac->hashsize; 175 blocksize = ses.keys->recv.algo_crypt->blocksize;
176 macsize = ses.keys->recv.algo_mac->hashsize;
164 177
165 if (ses.readbuf == NULL) { 178 if (ses.readbuf == NULL) {
166 /* start of a new packet */ 179 /* start of a new packet */
167 ses.readbuf = buf_new(INIT_READBUF); 180 ses.readbuf = buf_new(INIT_READBUF);
168 dropbear_assert(ses.decryptreadbuf == NULL);
169 ses.decryptreadbuf = buf_new(blocksize);
170 } 181 }
171 182
172 maxlen = blocksize - ses.readbuf->pos; 183 maxlen = blocksize - ses.readbuf->pos;
173 184
174 /* read the rest of the packet if possible */ 185 /* read the rest of the packet if possible */
175 len = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen), 186 slen = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
176 maxlen); 187 maxlen);
177 if (len == 0) { 188 if (slen == 0) {
178 ses.remoteclosed(); 189 ses.remoteclosed();
179 } 190 }
180 if (len < 0) { 191 if (slen < 0) {
181 if (errno == EINTR) { 192 if (errno == EINTR) {
182 TRACE(("leave read_packet_init: EINTR")) 193 TRACE(("leave read_packet_init: EINTR"))
183 return; 194 return DROPBEAR_FAILURE;
184 } 195 }
185 dropbear_exit("error reading: %s", strerror(errno)); 196 dropbear_exit("Error reading: %s", strerror(errno));
186 } 197 }
187 198
188 buf_incrwritepos(ses.readbuf, len); 199 buf_incrwritepos(ses.readbuf, slen);
189 200
190 if ((unsigned int)len != maxlen) { 201 if ((unsigned int)slen != maxlen) {
191 /* don't have enough bytes to determine length, get next time */ 202 /* don't have enough bytes to determine length, get next time */
192 return; 203 return DROPBEAR_FAILURE;
193 } 204 }
194 205
195 /* now we have the first block, need to get packet length, so we decrypt 206 /* now we have the first block, need to get packet length, so we decrypt
196 * the first block (only need first 4 bytes) */ 207 * the first block (only need first 4 bytes) */
197 buf_setpos(ses.readbuf, 0); 208 buf_setpos(ses.readbuf, 0);
198 if (ses.keys->recv_crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize), 209 if (ses.keys->recv.crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize),
199 buf_getwriteptr(ses.decryptreadbuf,blocksize), 210 buf_getwriteptr(ses.readbuf, blocksize),
200 blocksize, 211 blocksize,
201 &ses.keys->recv_cipher_state) != CRYPT_OK) { 212 &ses.keys->recv.cipher_state) != CRYPT_OK) {
202 dropbear_exit("error decrypting"); 213 dropbear_exit("Error decrypting");
203 } 214 }
204 buf_setlen(ses.decryptreadbuf, blocksize); 215 len = buf_getint(ses.readbuf) + 4 + macsize;
205 len = buf_getint(ses.decryptreadbuf) + 4 + macsize; 216
206 217 TRACE(("packet size is %d, block %d mac %d", len, blocksize, macsize))
207 buf_setpos(ses.readbuf, blocksize); 218
208 219
209 /* check packet length */ 220 /* check packet length */
210 if ((len > RECV_MAX_PACKET_LEN) || 221 if ((len > RECV_MAX_PACKET_LEN) ||
211 (len < MIN_PACKET_LEN + macsize) || 222 (len < MIN_PACKET_LEN + macsize) ||
212 ((len - macsize) % blocksize != 0)) { 223 ((len - macsize) % blocksize != 0)) {
213 dropbear_exit("bad packet size %d", len); 224 dropbear_exit("Integrity error (bad packet size %d)", len);
214 } 225 }
215 226
216 buf_resize(ses.readbuf, len); 227 if (len > ses.readbuf->size) {
228 buf_resize(ses.readbuf, len);
229 }
217 buf_setlen(ses.readbuf, len); 230 buf_setlen(ses.readbuf, len);
218 231 buf_setpos(ses.readbuf, blocksize);
232 return DROPBEAR_SUCCESS;
219 } 233 }
220 234
221 /* handle the received packet */ 235 /* handle the received packet */
222 void decrypt_packet() { 236 void decrypt_packet() {
223 237
225 unsigned char macsize; 239 unsigned char macsize;
226 unsigned int padlen; 240 unsigned int padlen;
227 unsigned int len; 241 unsigned int len;
228 242
229 TRACE(("enter decrypt_packet")) 243 TRACE(("enter decrypt_packet"))
230 blocksize = ses.keys->recv_algo_crypt->blocksize; 244 blocksize = ses.keys->recv.algo_crypt->blocksize;
231 macsize = ses.keys->recv_algo_mac->hashsize; 245 macsize = ses.keys->recv.algo_mac->hashsize;
232 246
233 ses.kexstate.datarecv += ses.readbuf->len; 247 ses.kexstate.datarecv += ses.readbuf->len;
234 248
235 /* we've already decrypted the first blocksize in read_packet_init */ 249 /* we've already decrypted the first blocksize in read_packet_init */
236 buf_setpos(ses.readbuf, blocksize); 250 buf_setpos(ses.readbuf, blocksize);
237 251
238 buf_resize(ses.decryptreadbuf, ses.readbuf->len - macsize); 252 /* decrypt it in-place */
239 buf_setlen(ses.decryptreadbuf, ses.decryptreadbuf->size); 253 len = ses.readbuf->len - macsize - ses.readbuf->pos;
240 buf_setpos(ses.decryptreadbuf, blocksize); 254 if (ses.keys->recv.crypt_mode->decrypt(
241 255 buf_getptr(ses.readbuf, len),
242 /* decrypt it */ 256 buf_getwriteptr(ses.readbuf, len),
243 while (ses.readbuf->pos < ses.readbuf->len - macsize) { 257 len,
244 if (ses.keys->recv_crypt_mode->decrypt( 258 &ses.keys->recv.cipher_state) != CRYPT_OK) {
245 buf_getptr(ses.readbuf, blocksize), 259 dropbear_exit("Error decrypting");
246 buf_getwriteptr(ses.decryptreadbuf, blocksize), 260 }
247 blocksize, 261 buf_incrpos(ses.readbuf, len);
248 &ses.keys->recv_cipher_state) != CRYPT_OK) {
249 dropbear_exit("error decrypting");
250 }
251 buf_incrpos(ses.readbuf, blocksize);
252 buf_incrwritepos(ses.decryptreadbuf, blocksize);
253 }
254 262
255 /* check the hmac */ 263 /* check the hmac */
256 buf_setpos(ses.readbuf, ses.readbuf->len - macsize); 264 if (checkmac() != DROPBEAR_SUCCESS) {
257 if (checkmac(ses.readbuf, ses.decryptreadbuf) != DROPBEAR_SUCCESS) {
258 dropbear_exit("Integrity error"); 265 dropbear_exit("Integrity error");
259 } 266 }
260 267
261 /* readbuf no longer required */
262 buf_free(ses.readbuf);
263 ses.readbuf = NULL;
264
265 /* get padding length */ 268 /* get padding length */
266 buf_setpos(ses.decryptreadbuf, PACKET_PADDING_OFF); 269 buf_setpos(ses.readbuf, PACKET_PADDING_OFF);
267 padlen = buf_getbyte(ses.decryptreadbuf); 270 padlen = buf_getbyte(ses.readbuf);
268 271
269 /* payload length */ 272 /* payload length */
270 /* - 4 - 1 is for LEN and PADLEN values */ 273 /* - 4 - 1 is for LEN and PADLEN values */
271 len = ses.decryptreadbuf->len - padlen - 4 - 1; 274 len = ses.readbuf->len - padlen - 4 - 1 - macsize;
272 if ((len > RECV_MAX_PAYLOAD_LEN) || (len < 1)) { 275 if ((len > RECV_MAX_PAYLOAD_LEN) || (len < 1)) {
273 dropbear_exit("bad packet size"); 276 dropbear_exit("Bad packet size %d", len);
274 } 277 }
275 278
276 buf_setpos(ses.decryptreadbuf, PACKET_PAYLOAD_OFF); 279 buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF);
277 280
278 #ifndef DISABLE_ZLIB 281 #ifndef DISABLE_ZLIB
279 if (is_compress_recv()) { 282 if (is_compress_recv()) {
280 /* decompress */ 283 /* decompress */
281 ses.payload = buf_decompress(ses.decryptreadbuf, len); 284 ses.payload = buf_decompress(ses.readbuf, len);
282 } else 285 } else
283 #endif 286 #endif
284 { 287 {
285 /* copy payload */ 288 /* copy payload */
286 ses.payload = buf_new(len); 289 ses.payload = buf_new(len);
287 memcpy(ses.payload->data, buf_getptr(ses.decryptreadbuf, len), len); 290 memcpy(ses.payload->data, buf_getptr(ses.readbuf, len), len);
288 buf_incrlen(ses.payload, len); 291 buf_incrlen(ses.payload, len);
289 } 292 }
290 293
291 buf_free(ses.decryptreadbuf); 294 buf_free(ses.readbuf);
292 ses.decryptreadbuf = NULL; 295 ses.readbuf = NULL;
293 buf_setpos(ses.payload, 0); 296 buf_setpos(ses.payload, 0);
294 297
295 ses.recvseq++; 298 ses.recvseq++;
296 299
297 TRACE(("leave decrypt_packet")) 300 TRACE(("leave decrypt_packet"))
298 } 301 }
299 302
300 /* Checks the mac in hashbuf, for the data in readbuf. 303 /* Checks the mac at the end of a decrypted readbuf.
301 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 304 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
302 static int checkmac(buffer* macbuf, buffer* sourcebuf) { 305 static int checkmac() {
303 306
304 unsigned int macsize; 307 unsigned char mac_bytes[MAX_MAC_LEN];
305 hmac_state hmac; 308 unsigned int mac_size, contents_len;
306 unsigned char tempbuf[MAX_MAC_LEN]; 309
307 unsigned long bufsize; 310 mac_size = ses.keys->trans.algo_mac->hashsize;
308 unsigned int len; 311 contents_len = ses.readbuf->len - mac_size;
309 312
310 macsize = ses.keys->recv_algo_mac->hashsize; 313 buf_setpos(ses.readbuf, 0);
311 if (macsize == 0) { 314 make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes);
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
336 bufsize = sizeof(tempbuf);
337 if (hmac_done(&hmac, tempbuf, &bufsize) != CRYPT_OK) {
338 dropbear_exit("HMAC error");
339 }
340 315
341 /* compare the hash */ 316 /* compare the hash */
342 if (memcmp(tempbuf, buf_getptr(macbuf, macsize), macsize) != 0) { 317 buf_setpos(ses.readbuf, contents_len);
318 if (memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
343 return DROPBEAR_FAILURE; 319 return DROPBEAR_FAILURE;
344 } else { 320 } else {
345 return DROPBEAR_SUCCESS; 321 return DROPBEAR_SUCCESS;
346 } 322 }
347 } 323 }
352 328
353 int result; 329 int result;
354 buffer * ret; 330 buffer * ret;
355 z_streamp zstream; 331 z_streamp zstream;
356 332
357 zstream = ses.keys->recv_zstream; 333 zstream = ses.keys->recv.zstream;
358 ret = buf_new(len); 334 ret = buf_new(len);
359 335
360 zstream->avail_in = len; 336 zstream->avail_in = len;
361 zstream->next_in = buf_getptr(buf, len); 337 zstream->next_in = buf_getptr(buf, len);
362 338
448 /* encrypt the writepayload, putting into writebuf, ready for write_packet() 424 /* encrypt the writepayload, putting into writebuf, ready for write_packet()
449 * to put on the wire */ 425 * to put on the wire */
450 void encrypt_packet() { 426 void encrypt_packet() {
451 427
452 unsigned char padlen; 428 unsigned char padlen;
453 unsigned char blocksize, macsize; 429 unsigned char blocksize, mac_size;
454 buffer * writebuf; /* the packet which will go on the wire */ 430 buffer * writebuf; /* the packet which will go on the wire. This is
455 buffer * clearwritebuf; /* unencrypted, possibly compressed */ 431 encrypted in-place. */
456 unsigned char type; 432 unsigned char packet_type;
457 unsigned int clear_len; 433 unsigned int len, encrypt_buf_size;
458 434 unsigned char mac_bytes[MAX_MAC_LEN];
459 type = ses.writepayload->data[0]; 435
460 TRACE(("enter encrypt_packet()")) 436 TRACE(("enter encrypt_packet()"))
461 TRACE(("encrypt_packet type is %d", type)) 437
462 438 buf_setpos(ses.writepayload, 0);
463 if (!ses.dataallowed && !packet_is_okay_kex(type)) { 439 packet_type = buf_getbyte(ses.writepayload);
440 buf_setpos(ses.writepayload, 0);
441
442 TRACE(("encrypt_packet type is %d", packet_type))
443
444 if ((!ses.dataallowed && !packet_is_okay_kex(packet_type))
445 || ses.kexstate.sentnewkeys) {
464 /* During key exchange only particular packets are allowed. 446 /* During key exchange only particular packets are allowed.
465 Since this type isn't OK we just enqueue it to send 447 Since this packet_type isn't OK we just enqueue it to send
466 after the KEX, see maybe_flush_reply_queue */ 448 after the KEX, see maybe_flush_reply_queue */
449
450 /* We also enqueue packets here when we have sent a MSG_NEWKEYS
451 * packet but are yet to received one. For simplicity we just switch
452 * over all the keys at once. This is the 'ses.kexstate.sentnewkeys'
453 * case. */
467 enqueue_reply_packet(); 454 enqueue_reply_packet();
468 return; 455 return;
469 } 456 }
470 457
471 blocksize = ses.keys->trans_algo_crypt->blocksize; 458 blocksize = ses.keys->trans.algo_crypt->blocksize;
472 macsize = ses.keys->trans_algo_mac->hashsize; 459 mac_size = ses.keys->trans.algo_mac->hashsize;
473 460
474 /* Encrypted packet len is payload+5, then worst case is if we are 3 away 461 /* Encrypted packet len is payload+5. We need to then make sure
475 * from a blocksize multiple. In which case we need to pad to the 462 * there is enough space for padding or MIN_PACKET_LEN.
476 * multiple, then add another blocksize (or MIN_PACKET_LEN) */ 463 * Add extra 3 since we need at least 4 bytes of padding */
477 clear_len = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3; 464 encrypt_buf_size = (ses.writepayload->len+4+1)
478 465 + MAX(MIN_PACKET_LEN, blocksize) + 3
466 /* add space for the MAC at the end */
467 + mac_size
479 #ifndef DISABLE_ZLIB 468 #ifndef DISABLE_ZLIB
480 clear_len += ZLIB_COMPRESS_INCR; /* bit of a kludge, but we can't know len*/ 469 /* some extra in case 'compression' makes it larger */
470 + ZLIB_COMPRESS_INCR
481 #endif 471 #endif
482 clearwritebuf = buf_new(clear_len); 472 /* and an extra cleartext (stripped before transmission) byte for the
483 buf_setlen(clearwritebuf, PACKET_PAYLOAD_OFF); 473 * packet type */
484 buf_setpos(clearwritebuf, PACKET_PAYLOAD_OFF); 474 + 1;
485 475
486 buf_setpos(ses.writepayload, 0); 476 writebuf = buf_new(encrypt_buf_size);
477 buf_setlen(writebuf, PACKET_PAYLOAD_OFF);
478 buf_setpos(writebuf, PACKET_PAYLOAD_OFF);
487 479
488 #ifndef DISABLE_ZLIB 480 #ifndef DISABLE_ZLIB
489 /* compression */ 481 /* compression */
490 if (is_compress_trans()) { 482 if (is_compress_trans()) {
491 buf_compress(clearwritebuf, ses.writepayload, ses.writepayload->len); 483 int compress_delta;
484 buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
485 compress_delta = (writebuf->len - PACKET_PAYLOAD_OFF) - ses.writepayload->len;
486
487 /* Handle the case where 'compress' increased the size. */
488 if (compress_delta > ZLIB_COMPRESS_INCR) {
489 buf_resize(writebuf, writebuf->size + compress_delta);
490 }
492 } else 491 } else
493 #endif 492 #endif
494 { 493 {
495 memcpy(buf_getwriteptr(clearwritebuf, ses.writepayload->len), 494 memcpy(buf_getwriteptr(writebuf, ses.writepayload->len),
496 buf_getptr(ses.writepayload, ses.writepayload->len), 495 buf_getptr(ses.writepayload, ses.writepayload->len),
497 ses.writepayload->len); 496 ses.writepayload->len);
498 buf_incrwritepos(clearwritebuf, ses.writepayload->len); 497 buf_incrwritepos(writebuf, ses.writepayload->len);
499 } 498 }
500 499
501 /* finished with payload */ 500 /* finished with payload */
502 buf_setpos(ses.writepayload, 0); 501 buf_setpos(ses.writepayload, 0);
503 buf_setlen(ses.writepayload, 0); 502 buf_setlen(ses.writepayload, 0);
504 503
505 /* length of padding - packet length must be a multiple of blocksize, 504 /* length of padding - packet length must be a multiple of blocksize,
506 * with a minimum of 4 bytes of padding */ 505 * with a minimum of 4 bytes of padding */
507 padlen = blocksize - (clearwritebuf->len) % blocksize; 506 padlen = blocksize - (writebuf->len) % blocksize;
508 if (padlen < 4) { 507 if (padlen < 4) {
509 padlen += blocksize; 508 padlen += blocksize;
510 } 509 }
511 /* check for min packet length */ 510 /* check for min packet length */
512 if (clearwritebuf->len + padlen < MIN_PACKET_LEN) { 511 if (writebuf->len + padlen < MIN_PACKET_LEN) {
513 padlen += blocksize; 512 padlen += blocksize;
514 } 513 }
515 514
516 buf_setpos(clearwritebuf, 0); 515 buf_setpos(writebuf, 0);
517 /* packet length excluding the packetlength uint32 */ 516 /* packet length excluding the packetlength uint32 */
518 buf_putint(clearwritebuf, clearwritebuf->len + padlen - 4); 517 buf_putint(writebuf, writebuf->len + padlen - 4);
519 518
520 /* padding len */ 519 /* padding len */
521 buf_putbyte(clearwritebuf, padlen); 520 buf_putbyte(writebuf, padlen);
522 /* actual padding */ 521 /* actual padding */
523 buf_setpos(clearwritebuf, clearwritebuf->len); 522 buf_setpos(writebuf, writebuf->len);
524 buf_incrlen(clearwritebuf, padlen); 523 buf_incrlen(writebuf, padlen);
525 genrandom(buf_getptr(clearwritebuf, padlen), padlen); 524 genrandom(buf_getptr(writebuf, padlen), padlen);
526 525
527 /* do the actual encryption */ 526 make_mac(ses.transseq, &ses.keys->trans, writebuf, writebuf->len, mac_bytes);
528 buf_setpos(clearwritebuf, 0); 527
529 /* create a new writebuffer, this is freed when it has been put on the 528 /* do the actual encryption, in-place */
530 * wire by writepacket() */ 529 buf_setpos(writebuf, 0);
531 writebuf = buf_new(clearwritebuf->len + macsize); 530 /* encrypt it in-place*/
532 531 len = writebuf->len;
533 /* encrypt it */ 532 if (ses.keys->trans.crypt_mode->encrypt(
534 while (clearwritebuf->pos < clearwritebuf->len) { 533 buf_getptr(writebuf, len),
535 if (ses.keys->trans_crypt_mode->encrypt( 534 buf_getwriteptr(writebuf, len),
536 buf_getptr(clearwritebuf, blocksize), 535 len,
537 buf_getwriteptr(writebuf, blocksize), 536 &ses.keys->trans.cipher_state) != CRYPT_OK) {
538 blocksize, 537 dropbear_exit("Error encrypting");
539 &ses.keys->trans_cipher_state) != CRYPT_OK) { 538 }
540 dropbear_exit("error encrypting"); 539 buf_incrpos(writebuf, len);
541 } 540
542 buf_incrpos(clearwritebuf, blocksize); 541 /* stick the MAC on it */
543 buf_incrwritepos(writebuf, blocksize); 542 buf_putbytes(writebuf, mac_bytes, mac_size);
544 } 543
545 544 /* The last byte of the buffer stores the cleartext packet_type. It is not
546 /* now add a hmac and we're done */ 545 * transmitted but is used for transmit timeout purposes */
547 writemac(writebuf, clearwritebuf); 546 buf_putbyte(writebuf, packet_type);
548 547 /* enqueue the packet for sending. It will get freed after transmission. */
549 /* clearwritebuf is finished with */
550 buf_free(clearwritebuf);
551 clearwritebuf = NULL;
552
553 /* enqueue the packet for sending */
554 buf_setpos(writebuf, 0); 548 buf_setpos(writebuf, 0);
555 enqueue(&ses.writequeue, (void*)writebuf); 549 enqueue(&ses.writequeue, (void*)writebuf);
556 550
557 /* Update counts */ 551 /* Update counts */
558 ses.kexstate.datatrans += writebuf->len; 552 ses.kexstate.datatrans += writebuf->len;
561 TRACE(("leave encrypt_packet()")) 555 TRACE(("leave encrypt_packet()"))
562 } 556 }
563 557
564 558
565 /* Create the packet mac, and append H(seqno|clearbuf) to the output */ 559 /* Create the packet mac, and append H(seqno|clearbuf) to the output */
566 static void writemac(buffer * outputbuffer, buffer * clearwritebuf) { 560 /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */
567 561 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
568 unsigned int macsize; 562 buffer * clear_buf, unsigned int clear_len,
563 unsigned char *output_mac) {
569 unsigned char seqbuf[4]; 564 unsigned char seqbuf[4];
570 unsigned char tempbuf[MAX_MAC_LEN];
571 unsigned long bufsize; 565 unsigned long bufsize;
572 hmac_state hmac; 566 hmac_state hmac;
573 567
574 TRACE(("enter writemac")) 568 TRACE(("enter writemac"))
575 569
576 macsize = ses.keys->trans_algo_mac->hashsize; 570 if (key_state->algo_mac->hashsize > 0) {
577 if (macsize > 0) {
578 /* calculate the mac */ 571 /* calculate the mac */
579 if (hmac_init(&hmac, 572 if (hmac_init(&hmac,
580 find_hash(ses.keys->trans_algo_mac->hashdesc->name), 573 key_state->hash_index,
581 ses.keys->transmackey, 574 key_state->mackey,
582 ses.keys->trans_algo_mac->keysize) != CRYPT_OK) { 575 key_state->algo_mac->keysize) != CRYPT_OK) {
583 dropbear_exit("HMAC error"); 576 dropbear_exit("HMAC error");
584 } 577 }
585 578
586 /* sequence number */ 579 /* sequence number */
587 STORE32H(ses.transseq, seqbuf); 580 STORE32H(seqno, seqbuf);
588 if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) { 581 if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
589 dropbear_exit("HMAC error"); 582 dropbear_exit("HMAC error");
590 } 583 }
591 584
592 /* the actual contents */ 585 /* the actual contents */
593 buf_setpos(clearwritebuf, 0); 586 buf_setpos(clear_buf, 0);
594 if (hmac_process(&hmac, 587 if (hmac_process(&hmac,
595 buf_getptr(clearwritebuf, 588 buf_getptr(clear_buf, clear_len),
596 clearwritebuf->len), 589 clear_len) != CRYPT_OK) {
597 clearwritebuf->len) != CRYPT_OK) {
598 dropbear_exit("HMAC error"); 590 dropbear_exit("HMAC error");
599 } 591 }
600 592
601 bufsize = sizeof(tempbuf); 593 bufsize = MAX_MAC_LEN;
602 if (hmac_done(&hmac, tempbuf, &bufsize) 594 if (hmac_done(&hmac, output_mac, &bufsize) != CRYPT_OK) {
603 != CRYPT_OK) {
604 dropbear_exit("HMAC error"); 595 dropbear_exit("HMAC error");
605 } 596 }
606 buf_putbytes(outputbuffer, tempbuf, macsize);
607 } 597 }
608 TRACE(("leave writemac")) 598 TRACE(("leave writemac"))
609 } 599 }
610 600
611 #ifndef DISABLE_ZLIB 601 #ifndef DISABLE_ZLIB
618 608
619 TRACE(("enter buf_compress")) 609 TRACE(("enter buf_compress"))
620 610
621 while (1) { 611 while (1) {
622 612
623 ses.keys->trans_zstream->avail_in = endpos - src->pos; 613 ses.keys->trans.zstream->avail_in = endpos - src->pos;
624 ses.keys->trans_zstream->next_in = 614 ses.keys->trans.zstream->next_in =
625 buf_getptr(src, ses.keys->trans_zstream->avail_in); 615 buf_getptr(src, ses.keys->trans.zstream->avail_in);
626 616
627 ses.keys->trans_zstream->avail_out = dest->size - dest->pos; 617 ses.keys->trans.zstream->avail_out = dest->size - dest->pos;
628 ses.keys->trans_zstream->next_out = 618 ses.keys->trans.zstream->next_out =
629 buf_getwriteptr(dest, ses.keys->trans_zstream->avail_out); 619 buf_getwriteptr(dest, ses.keys->trans.zstream->avail_out);
630 620
631 result = deflate(ses.keys->trans_zstream, Z_SYNC_FLUSH); 621 result = deflate(ses.keys->trans.zstream, Z_SYNC_FLUSH);
632 622
633 buf_setpos(src, endpos - ses.keys->trans_zstream->avail_in); 623 buf_setpos(src, endpos - ses.keys->trans.zstream->avail_in);
634 buf_setlen(dest, dest->size - ses.keys->trans_zstream->avail_out); 624 buf_setlen(dest, dest->size - ses.keys->trans.zstream->avail_out);
635 buf_setpos(dest, dest->len); 625 buf_setpos(dest, dest->len);
636 626
637 if (result != Z_OK) { 627 if (result != Z_OK) {
638 dropbear_exit("zlib error"); 628 dropbear_exit("zlib error");
639 } 629 }
640 630
641 if (ses.keys->trans_zstream->avail_in == 0) { 631 if (ses.keys->trans.zstream->avail_in == 0) {
642 break; 632 break;
643 } 633 }
644 634
645 dropbear_assert(ses.keys->trans_zstream->avail_out == 0); 635 dropbear_assert(ses.keys->trans.zstream->avail_out == 0);
646 636
647 /* the buffer has been filled, we must extend. This only happens in 637 /* the buffer has been filled, we must extend. This only happens in
648 * unusual circumstances where the data grows in size after deflate(), 638 * unusual circumstances where the data grows in size after deflate(),
649 * but it is possible */ 639 * but it is possible */
650 buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR); 640 buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR);