packet.c 19 KB

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