Mercurial > dropbear
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); |