ssh2bpp.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /*
  2. * Binary packet protocol for SSH-2.
  3. */
  4. #include <assert.h>
  5. #include "putty.h"
  6. #include "ssh.h"
  7. #include "sshbpp.h"
  8. #include "sshcr.h"
  9. struct ssh2_bpp_direction {
  10. unsigned long sequence;
  11. ssh2_cipher *cipher;
  12. ssh2_mac *mac;
  13. int etm_mode;
  14. };
  15. struct ssh2_bpp_state {
  16. int crState;
  17. long len, pad, payload, packetlen, maclen, length, maxlen;
  18. unsigned char *buf;
  19. size_t bufsize;
  20. unsigned char *data;
  21. unsigned cipherblk;
  22. PktIn *pktin;
  23. struct DataTransferStats *stats;
  24. int cbc_ignore_workaround;
  25. struct ssh2_bpp_direction in, out;
  26. /* comp and decomp logically belong in the per-direction
  27. * substructure, except that they have different types */
  28. ssh_decompressor *in_decomp;
  29. ssh_compressor *out_comp;
  30. int pending_newkeys;
  31. BinaryPacketProtocol bpp;
  32. };
  33. static void ssh2_bpp_free(BinaryPacketProtocol *bpp);
  34. static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp);
  35. static void ssh2_bpp_handle_output(BinaryPacketProtocol *bpp);
  36. static PktOut *ssh2_bpp_new_pktout(int type);
  37. static const struct BinaryPacketProtocolVtable ssh2_bpp_vtable = {
  38. ssh2_bpp_free,
  39. ssh2_bpp_handle_input,
  40. ssh2_bpp_handle_output,
  41. ssh2_bpp_new_pktout,
  42. ssh2_bpp_queue_disconnect, /* in sshcommon.c */
  43. };
  44. BinaryPacketProtocol *ssh2_bpp_new(
  45. Frontend *frontend, struct DataTransferStats *stats)
  46. {
  47. struct ssh2_bpp_state *s = snew(struct ssh2_bpp_state);
  48. memset(s, 0, sizeof(*s));
  49. s->bpp.vt = &ssh2_bpp_vtable;
  50. s->bpp.frontend = frontend;
  51. s->stats = stats;
  52. ssh_bpp_common_setup(&s->bpp);
  53. return &s->bpp;
  54. }
  55. static void ssh2_bpp_free(BinaryPacketProtocol *bpp)
  56. {
  57. struct ssh2_bpp_state *s = FROMFIELD(bpp, struct ssh2_bpp_state, bpp);
  58. sfree(s->buf);
  59. if (s->out.cipher)
  60. ssh2_cipher_free(s->out.cipher);
  61. if (s->out.mac)
  62. ssh2_mac_free(s->out.mac);
  63. if (s->out_comp)
  64. ssh_compressor_free(s->out_comp);
  65. if (s->in.cipher)
  66. ssh2_cipher_free(s->in.cipher);
  67. if (s->in.mac)
  68. ssh2_mac_free(s->in.mac);
  69. if (s->in_decomp)
  70. ssh_decompressor_free(s->in_decomp);
  71. sfree(s->pktin);
  72. sfree(s);
  73. }
  74. void ssh2_bpp_new_outgoing_crypto(
  75. BinaryPacketProtocol *bpp,
  76. const struct ssh2_cipheralg *cipher, const void *ckey, const void *iv,
  77. const struct ssh2_macalg *mac, int etm_mode, const void *mac_key,
  78. const struct ssh_compression_alg *compression)
  79. {
  80. struct ssh2_bpp_state *s;
  81. assert(bpp->vt == &ssh2_bpp_vtable);
  82. s = FROMFIELD(bpp, struct ssh2_bpp_state, bpp);
  83. if (s->out.cipher)
  84. ssh2_cipher_free(s->out.cipher);
  85. if (s->out.mac)
  86. ssh2_mac_free(s->out.mac);
  87. if (s->out_comp)
  88. ssh_compressor_free(s->out_comp);
  89. if (cipher) {
  90. s->out.cipher = ssh2_cipher_new(cipher);
  91. ssh2_cipher_setkey(s->out.cipher, ckey);
  92. ssh2_cipher_setiv(s->out.cipher, iv);
  93. s->cbc_ignore_workaround = (
  94. (ssh2_cipher_alg(s->out.cipher)->flags & SSH_CIPHER_IS_CBC) &&
  95. !(s->bpp.remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE));
  96. } else {
  97. s->out.cipher = NULL;
  98. s->cbc_ignore_workaround = FALSE;
  99. }
  100. s->out.etm_mode = etm_mode;
  101. if (mac) {
  102. s->out.mac = ssh2_mac_new(mac, s->out.cipher);
  103. mac->setkey(s->out.mac, mac_key);
  104. } else {
  105. s->out.mac = NULL;
  106. }
  107. /* 'compression' is always non-NULL, because no compression is
  108. * indicated by ssh_comp_none. But this setup call may return a
  109. * null out_comp. */
  110. s->out_comp = ssh_compressor_new(compression);
  111. }
  112. void ssh2_bpp_new_incoming_crypto(
  113. BinaryPacketProtocol *bpp,
  114. const struct ssh2_cipheralg *cipher, const void *ckey, const void *iv,
  115. const struct ssh2_macalg *mac, int etm_mode, const void *mac_key,
  116. const struct ssh_compression_alg *compression)
  117. {
  118. struct ssh2_bpp_state *s;
  119. assert(bpp->vt == &ssh2_bpp_vtable);
  120. s = FROMFIELD(bpp, struct ssh2_bpp_state, bpp);
  121. if (s->in.cipher)
  122. ssh2_cipher_free(s->in.cipher);
  123. if (s->in.mac)
  124. ssh2_mac_free(s->in.mac);
  125. if (s->in_decomp)
  126. ssh_decompressor_free(s->in_decomp);
  127. if (cipher) {
  128. s->in.cipher = ssh2_cipher_new(cipher);
  129. ssh2_cipher_setkey(s->in.cipher, ckey);
  130. ssh2_cipher_setiv(s->in.cipher, iv);
  131. } else {
  132. s->in.cipher = NULL;
  133. }
  134. s->in.etm_mode = etm_mode;
  135. if (mac) {
  136. s->in.mac = ssh2_mac_new(mac, s->in.cipher);
  137. mac->setkey(s->in.mac, mac_key);
  138. } else {
  139. s->in.mac = NULL;
  140. }
  141. /* 'compression' is always non-NULL, because no compression is
  142. * indicated by ssh_comp_none. But this setup call may return a
  143. * null in_decomp. */
  144. s->in_decomp = ssh_decompressor_new(compression);
  145. /* Clear the pending_newkeys flag, so that handle_input below will
  146. * start consuming the input data again. */
  147. s->pending_newkeys = FALSE;
  148. }
  149. #define BPP_READ(ptr, len) do \
  150. { \
  151. crMaybeWaitUntilV(s->bpp.input_eof || \
  152. bufchain_try_fetch_consume( \
  153. s->bpp.in_raw, ptr, len)); \
  154. if (s->bpp.input_eof) \
  155. goto eof; \
  156. } while (0)
  157. static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
  158. {
  159. struct ssh2_bpp_state *s = FROMFIELD(bpp, struct ssh2_bpp_state, bpp);
  160. crBegin(s->crState);
  161. while (1) {
  162. s->maxlen = 0;
  163. s->length = 0;
  164. if (s->in.cipher)
  165. s->cipherblk = ssh2_cipher_alg(s->in.cipher)->blksize;
  166. else
  167. s->cipherblk = 8;
  168. if (s->cipherblk < 8)
  169. s->cipherblk = 8;
  170. s->maclen = s->in.mac ? ssh2_mac_alg(s->in.mac)->len : 0;
  171. if (s->in.cipher &&
  172. (ssh2_cipher_alg(s->in.cipher)->flags & SSH_CIPHER_IS_CBC) &&
  173. s->in.mac && !s->in.etm_mode) {
  174. /*
  175. * When dealing with a CBC-mode cipher, we want to avoid the
  176. * possibility of an attacker's tweaking the ciphertext stream
  177. * so as to cause us to feed the same block to the block
  178. * cipher more than once and thus leak information
  179. * (VU#958563). The way we do this is not to take any
  180. * decisions on the basis of anything we've decrypted until
  181. * we've verified it with a MAC. That includes the packet
  182. * length, so we just read data and check the MAC repeatedly,
  183. * and when the MAC passes, see if the length we've got is
  184. * plausible.
  185. *
  186. * This defence is unnecessary in OpenSSH ETM mode, because
  187. * the whole point of ETM mode is that the attacker can't
  188. * tweak the ciphertext stream at all without the MAC
  189. * detecting it before we decrypt anything.
  190. */
  191. /*
  192. * Make sure we have buffer space for a maximum-size packet.
  193. */
  194. unsigned buflimit = OUR_V2_PACKETLIMIT + s->maclen;
  195. if (s->bufsize < buflimit) {
  196. s->bufsize = buflimit;
  197. s->buf = sresize(s->buf, s->bufsize, unsigned char);
  198. }
  199. /* Read an amount corresponding to the MAC. */
  200. BPP_READ(s->buf, s->maclen);
  201. s->packetlen = 0;
  202. ssh2_mac_start(s->in.mac);
  203. put_uint32(s->in.mac, s->in.sequence);
  204. for (;;) { /* Once around this loop per cipher block. */
  205. /* Read another cipher-block's worth, and tack it on to
  206. * the end. */
  207. BPP_READ(s->buf + (s->packetlen + s->maclen), s->cipherblk);
  208. /* Decrypt one more block (a little further back in
  209. * the stream). */
  210. ssh2_cipher_decrypt(s->in.cipher,
  211. s->buf + s->packetlen, s->cipherblk);
  212. /* Feed that block to the MAC. */
  213. put_data(s->in.mac,
  214. s->buf + s->packetlen, s->cipherblk);
  215. s->packetlen += s->cipherblk;
  216. /* See if that gives us a valid packet. */
  217. if (ssh2_mac_verresult(s->in.mac, s->buf + s->packetlen) &&
  218. ((s->len = toint(GET_32BIT(s->buf))) ==
  219. s->packetlen-4))
  220. break;
  221. if (s->packetlen >= (long)OUR_V2_PACKETLIMIT) {
  222. ssh_sw_abort(s->bpp.ssh,
  223. "No valid incoming packet found");
  224. crStopV;
  225. }
  226. }
  227. s->maxlen = s->packetlen + s->maclen;
  228. /*
  229. * Now transfer the data into an output packet.
  230. */
  231. s->pktin = snew_plus(PktIn, s->maxlen);
  232. s->pktin->qnode.prev = s->pktin->qnode.next = NULL;
  233. s->pktin->type = 0;
  234. s->pktin->qnode.on_free_queue = FALSE;
  235. s->data = snew_plus_get_aux(s->pktin);
  236. memcpy(s->data, s->buf, s->maxlen);
  237. } else if (s->in.mac && s->in.etm_mode) {
  238. if (s->bufsize < 4) {
  239. s->bufsize = 4;
  240. s->buf = sresize(s->buf, s->bufsize, unsigned char);
  241. }
  242. /*
  243. * OpenSSH encrypt-then-MAC mode: the packet length is
  244. * unencrypted, unless the cipher supports length encryption.
  245. */
  246. BPP_READ(s->buf, 4);
  247. /* Cipher supports length decryption, so do it */
  248. if (s->in.cipher && (ssh2_cipher_alg(s->in.cipher)->flags &
  249. SSH_CIPHER_SEPARATE_LENGTH)) {
  250. /* Keep the packet the same though, so the MAC passes */
  251. unsigned char len[4];
  252. memcpy(len, s->buf, 4);
  253. ssh2_cipher_decrypt_length(
  254. s->in.cipher, len, 4, s->in.sequence);
  255. s->len = toint(GET_32BIT(len));
  256. } else {
  257. s->len = toint(GET_32BIT(s->buf));
  258. }
  259. /*
  260. * _Completely_ silly lengths should be stomped on before they
  261. * do us any more damage.
  262. */
  263. if (s->len < 0 || s->len > (long)OUR_V2_PACKETLIMIT ||
  264. s->len % s->cipherblk != 0) {
  265. ssh_sw_abort(s->bpp.ssh,
  266. "Incoming packet length field was garbled");
  267. crStopV;
  268. }
  269. /*
  270. * So now we can work out the total packet length.
  271. */
  272. s->packetlen = s->len + 4;
  273. /*
  274. * Allocate the packet to return, now we know its length.
  275. */
  276. s->pktin = snew_plus(PktIn, OUR_V2_PACKETLIMIT + s->maclen);
  277. s->pktin->qnode.prev = s->pktin->qnode.next = NULL;
  278. s->pktin->type = 0;
  279. s->pktin->qnode.on_free_queue = FALSE;
  280. s->data = snew_plus_get_aux(s->pktin);
  281. memcpy(s->data, s->buf, 4);
  282. /*
  283. * Read the remainder of the packet.
  284. */
  285. BPP_READ(s->data + 4, s->packetlen + s->maclen - 4);
  286. /*
  287. * Check the MAC.
  288. */
  289. if (s->in.mac && !ssh2_mac_verify(
  290. s->in.mac, s->data, s->len + 4, s->in.sequence)) {
  291. ssh_sw_abort(s->bpp.ssh, "Incorrect MAC received on packet");
  292. crStopV;
  293. }
  294. /* Decrypt everything between the length field and the MAC. */
  295. if (s->in.cipher)
  296. ssh2_cipher_decrypt(
  297. s->in.cipher, s->data + 4, s->packetlen - 4);
  298. } else {
  299. if (s->bufsize < s->cipherblk) {
  300. s->bufsize = s->cipherblk;
  301. s->buf = sresize(s->buf, s->bufsize, unsigned char);
  302. }
  303. /*
  304. * Acquire and decrypt the first block of the packet. This will
  305. * contain the length and padding details.
  306. */
  307. BPP_READ(s->buf, s->cipherblk);
  308. if (s->in.cipher)
  309. ssh2_cipher_decrypt(
  310. s->in.cipher, s->buf, s->cipherblk);
  311. /*
  312. * Now get the length figure.
  313. */
  314. s->len = toint(GET_32BIT(s->buf));
  315. /*
  316. * _Completely_ silly lengths should be stomped on before they
  317. * do us any more damage.
  318. */
  319. if (s->len < 0 || s->len > (long)OUR_V2_PACKETLIMIT ||
  320. (s->len + 4) % s->cipherblk != 0) {
  321. ssh_sw_abort(s->bpp.ssh,
  322. "Incoming packet was garbled on decryption");
  323. crStopV;
  324. }
  325. /*
  326. * So now we can work out the total packet length.
  327. */
  328. s->packetlen = s->len + 4;
  329. /*
  330. * Allocate the packet to return, now we know its length.
  331. */
  332. s->maxlen = s->packetlen + s->maclen;
  333. s->pktin = snew_plus(PktIn, s->maxlen);
  334. s->pktin->qnode.prev = s->pktin->qnode.next = NULL;
  335. s->pktin->type = 0;
  336. s->pktin->qnode.on_free_queue = FALSE;
  337. s->data = snew_plus_get_aux(s->pktin);
  338. memcpy(s->data, s->buf, s->cipherblk);
  339. /*
  340. * Read and decrypt the remainder of the packet.
  341. */
  342. BPP_READ(s->data + s->cipherblk,
  343. s->packetlen + s->maclen - s->cipherblk);
  344. /* Decrypt everything _except_ the MAC. */
  345. if (s->in.cipher)
  346. ssh2_cipher_decrypt(
  347. s->in.cipher,
  348. s->data + s->cipherblk, s->packetlen - s->cipherblk);
  349. /*
  350. * Check the MAC.
  351. */
  352. if (s->in.mac && !ssh2_mac_verify(
  353. s->in.mac, s->data, s->len + 4, s->in.sequence)) {
  354. ssh_sw_abort(s->bpp.ssh, "Incorrect MAC received on packet");
  355. crStopV;
  356. }
  357. }
  358. /* Get and sanity-check the amount of random padding. */
  359. s->pad = s->data[4];
  360. if (s->pad < 4 || s->len - s->pad < 1) {
  361. ssh_sw_abort(s->bpp.ssh,
  362. "Invalid padding length on received packet");
  363. crStopV;
  364. }
  365. /*
  366. * This enables us to deduce the payload length.
  367. */
  368. s->payload = s->len - s->pad - 1;
  369. s->length = s->payload + 5;
  370. DTS_CONSUME(s->stats, in, s->packetlen);
  371. s->pktin->sequence = s->in.sequence++;
  372. s->length = s->packetlen - s->pad;
  373. assert(s->length >= 0);
  374. /*
  375. * Decompress packet payload.
  376. */
  377. {
  378. unsigned char *newpayload;
  379. int newlen;
  380. if (s->in_decomp && ssh_decompressor_decompress(
  381. s->in_decomp, s->data + 5, s->length - 5,
  382. &newpayload, &newlen)) {
  383. if (s->maxlen < newlen + 5) {
  384. PktIn *old_pktin = s->pktin;
  385. s->maxlen = newlen + 5;
  386. s->pktin = snew_plus(PktIn, s->maxlen);
  387. *s->pktin = *old_pktin; /* structure copy */
  388. s->data = snew_plus_get_aux(s->pktin);
  389. smemclr(old_pktin, s->packetlen + s->maclen);
  390. sfree(old_pktin);
  391. }
  392. s->length = 5 + newlen;
  393. memcpy(s->data + 5, newpayload, newlen);
  394. sfree(newpayload);
  395. }
  396. }
  397. /*
  398. * Now we can identify the semantic content of the packet,
  399. * and also the initial type byte.
  400. */
  401. if (s->length <= 5) { /* == 5 we hope, but robustness */
  402. /*
  403. * RFC 4253 doesn't explicitly say that completely empty
  404. * packets with no type byte are forbidden. We handle them
  405. * here by giving them a type code larger than 0xFF, which
  406. * will be picked up at the next layer and trigger
  407. * SSH_MSG_UNIMPLEMENTED.
  408. */
  409. s->pktin->type = SSH_MSG_NO_TYPE_CODE;
  410. s->length = 0;
  411. BinarySource_INIT(s->pktin, s->data + 5, 0);
  412. } else {
  413. s->pktin->type = s->data[5];
  414. s->length -= 6;
  415. BinarySource_INIT(s->pktin, s->data + 6, s->length);
  416. }
  417. if (s->bpp.logctx) {
  418. logblank_t blanks[MAX_BLANKS];
  419. int nblanks = ssh2_censor_packet(
  420. s->bpp.pls, s->pktin->type, FALSE,
  421. make_ptrlen(s->data, s->length), blanks);
  422. log_packet(s->bpp.logctx, PKT_INCOMING, s->pktin->type,
  423. ssh2_pkt_type(s->bpp.pls->kctx, s->bpp.pls->actx,
  424. s->pktin->type),
  425. get_ptr(s->pktin), get_avail(s->pktin), nblanks, blanks,
  426. &s->pktin->sequence, 0, NULL);
  427. }
  428. if (ssh2_bpp_check_unimplemented(&s->bpp, s->pktin)) {
  429. sfree(s->pktin);
  430. s->pktin = NULL;
  431. continue;
  432. }
  433. pq_push(&s->bpp.in_pq, s->pktin);
  434. {
  435. int type = s->pktin->type;
  436. s->pktin = NULL;
  437. if (type == SSH2_MSG_NEWKEYS) {
  438. /*
  439. * Mild layer violation: in this situation we must
  440. * suspend processing of the input byte stream until
  441. * the transport layer has initialised the new keys by
  442. * calling ssh2_bpp_new_incoming_crypto above.
  443. */
  444. s->pending_newkeys = TRUE;
  445. crWaitUntilV(!s->pending_newkeys);
  446. }
  447. }
  448. }
  449. eof:
  450. if (!s->bpp.expect_close) {
  451. ssh_remote_error(s->bpp.ssh,
  452. "Server unexpectedly closed network connection");
  453. } else {
  454. ssh_remote_eof(s->bpp.ssh, "Server closed network connection");
  455. }
  456. crFinishV;
  457. }
  458. static PktOut *ssh2_bpp_new_pktout(int pkt_type)
  459. {
  460. PktOut *pkt = ssh_new_packet();
  461. pkt->length = 5; /* space for packet length + padding length */
  462. pkt->minlen = 0;
  463. pkt->type = pkt_type;
  464. put_byte(pkt, pkt_type);
  465. pkt->prefix = pkt->length;
  466. return pkt;
  467. }
  468. static void ssh2_bpp_format_packet_inner(struct ssh2_bpp_state *s, PktOut *pkt)
  469. {
  470. int origlen, cipherblk, maclen, padding, unencrypted_prefix, i;
  471. if (s->bpp.logctx) {
  472. ptrlen pktdata = make_ptrlen(pkt->data + pkt->prefix,
  473. pkt->length - pkt->prefix);
  474. logblank_t blanks[MAX_BLANKS];
  475. int nblanks = ssh2_censor_packet(
  476. s->bpp.pls, pkt->type, TRUE, pktdata, blanks);
  477. log_packet(s->bpp.logctx, PKT_OUTGOING, pkt->type,
  478. ssh2_pkt_type(s->bpp.pls->kctx, s->bpp.pls->actx,
  479. pkt->type),
  480. pktdata.ptr, pktdata.len, nblanks, blanks, &s->out.sequence,
  481. pkt->downstream_id, pkt->additional_log_text);
  482. }
  483. cipherblk = s->out.cipher ? ssh2_cipher_alg(s->out.cipher)->blksize : 8;
  484. cipherblk = cipherblk < 8 ? 8 : cipherblk; /* or 8 if blksize < 8 */
  485. if (s->out_comp) {
  486. unsigned char *newpayload;
  487. int minlen, newlen;
  488. /*
  489. * Compress packet payload.
  490. */
  491. minlen = pkt->minlen;
  492. if (minlen) {
  493. /*
  494. * Work out how much compressed data we need (at least) to
  495. * make the overall packet length come to pkt->minlen.
  496. */
  497. if (s->out.mac)
  498. minlen -= ssh2_mac_alg(s->out.mac)->len;
  499. minlen -= 8; /* length field + min padding */
  500. }
  501. ssh_compressor_compress(s->out_comp, pkt->data + 5, pkt->length - 5,
  502. &newpayload, &newlen, minlen);
  503. pkt->length = 5;
  504. put_data(pkt, newpayload, newlen);
  505. sfree(newpayload);
  506. }
  507. /*
  508. * Add padding. At least four bytes, and must also bring total
  509. * length (minus MAC) up to a multiple of the block size.
  510. * If pkt->forcepad is set, make sure the packet is at least that size
  511. * after padding.
  512. */
  513. padding = 4;
  514. unencrypted_prefix = (s->out.mac && s->out.etm_mode) ? 4 : 0;
  515. padding +=
  516. (cipherblk - (pkt->length - unencrypted_prefix + padding) % cipherblk)
  517. % cipherblk;
  518. assert(padding <= 255);
  519. maclen = s->out.mac ? ssh2_mac_alg(s->out.mac)->len : 0;
  520. origlen = pkt->length;
  521. for (i = 0; i < padding; i++)
  522. put_byte(pkt, random_byte());
  523. pkt->data[4] = padding;
  524. PUT_32BIT(pkt->data, origlen + padding - 4);
  525. /* Encrypt length if the scheme requires it */
  526. if (s->out.cipher &&
  527. (ssh2_cipher_alg(s->out.cipher)->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
  528. ssh2_cipher_encrypt_length(s->out.cipher, pkt->data, 4,
  529. s->out.sequence);
  530. }
  531. put_padding(pkt, maclen, 0);
  532. if (s->out.mac && s->out.etm_mode) {
  533. /*
  534. * OpenSSH-defined encrypt-then-MAC protocol.
  535. */
  536. if (s->out.cipher)
  537. ssh2_cipher_encrypt(s->out.cipher,
  538. pkt->data + 4, origlen + padding - 4);
  539. ssh2_mac_generate(s->out.mac, pkt->data, origlen + padding,
  540. s->out.sequence);
  541. } else {
  542. /*
  543. * SSH-2 standard protocol.
  544. */
  545. if (s->out.mac)
  546. ssh2_mac_generate(s->out.mac, pkt->data, origlen + padding,
  547. s->out.sequence);
  548. if (s->out.cipher)
  549. ssh2_cipher_encrypt(s->out.cipher, pkt->data, origlen + padding);
  550. }
  551. s->out.sequence++; /* whether or not we MACed */
  552. DTS_CONSUME(s->stats, out, origlen + padding);
  553. }
  554. static void ssh2_bpp_format_packet(struct ssh2_bpp_state *s, PktOut *pkt)
  555. {
  556. if (pkt->minlen > 0 && !s->out_comp) {
  557. /*
  558. * If we've been told to pad the packet out to a given minimum
  559. * length, but we're not compressing (and hence can't get the
  560. * compression to do the padding by pointlessly opening and
  561. * closing zlib blocks), then our other strategy is to precede
  562. * this message with an SSH_MSG_IGNORE that makes it up to the
  563. * right length.
  564. *
  565. * A third option in principle, and the most obviously
  566. * sensible, would be to set the explicit padding field in the
  567. * packet to more than its minimum value. Sadly, that turns
  568. * out to break some servers (our institutional memory thinks
  569. * Cisco in particular) and so we abandoned that idea shortly
  570. * after trying it.
  571. */
  572. /*
  573. * Calculate the length we expect the real packet to have.
  574. */
  575. int block, length;
  576. PktOut *ignore_pkt;
  577. block = s->out.cipher ? ssh2_cipher_alg(s->out.cipher)->blksize : 0;
  578. if (block < 8)
  579. block = 8;
  580. length = pkt->length;
  581. length += 4; /* minimum 4 byte padding */
  582. length += block-1;
  583. length -= (length % block);
  584. if (s->out.mac)
  585. length += ssh2_mac_alg(s->out.mac)->len;
  586. if (length < pkt->minlen) {
  587. /*
  588. * We need an ignore message. Calculate its length.
  589. */
  590. length = pkt->minlen - length;
  591. /*
  592. * And work backwards from that to the length of the
  593. * contained string.
  594. */
  595. if (s->out.mac)
  596. length -= ssh2_mac_alg(s->out.mac)->len;
  597. length -= 8; /* length field + min padding */
  598. length -= 5; /* type code + string length prefix */
  599. if (length < 0)
  600. length = 0;
  601. ignore_pkt = ssh2_bpp_new_pktout(SSH2_MSG_IGNORE);
  602. put_uint32(ignore_pkt, length);
  603. while (length-- > 0)
  604. put_byte(ignore_pkt, random_byte());
  605. ssh2_bpp_format_packet_inner(s, ignore_pkt);
  606. bufchain_add(s->bpp.out_raw, ignore_pkt->data, ignore_pkt->length);
  607. ssh_free_pktout(ignore_pkt);
  608. }
  609. }
  610. ssh2_bpp_format_packet_inner(s, pkt);
  611. bufchain_add(s->bpp.out_raw, pkt->data, pkt->length);
  612. }
  613. static void ssh2_bpp_handle_output(BinaryPacketProtocol *bpp)
  614. {
  615. struct ssh2_bpp_state *s = FROMFIELD(bpp, struct ssh2_bpp_state, bpp);
  616. PktOut *pkt;
  617. if (s->cbc_ignore_workaround) {
  618. /*
  619. * When using a CBC-mode cipher in SSH-2, it's necessary to
  620. * ensure that an attacker can't provide data to be encrypted
  621. * using an IV that they know. We ensure this by inserting an
  622. * SSH_MSG_IGNORE if the last cipher block of the previous
  623. * packet has already been sent to the network (which we
  624. * approximate conservatively by checking if it's vanished
  625. * from out_raw).
  626. */
  627. if (bufchain_size(s->bpp.out_raw) <
  628. (ssh2_cipher_alg(s->out.cipher)->blksize +
  629. ssh2_mac_alg(s->out.mac)->len)) {
  630. /*
  631. * There's less data in out_raw than the MAC size plus the
  632. * cipher block size, which means at least one byte of
  633. * that cipher block must already have left. Add an
  634. * IGNORE.
  635. */
  636. pkt = ssh_bpp_new_pktout(&s->bpp, SSH2_MSG_IGNORE);
  637. put_stringz(pkt, "");
  638. ssh2_bpp_format_packet(s, pkt);
  639. }
  640. }
  641. while ((pkt = pq_pop(&s->bpp.out_pq)) != NULL) {
  642. ssh2_bpp_format_packet(s, pkt);
  643. ssh_free_pktout(pkt);
  644. }
  645. }
  646. #ifdef MPEXT
  647. const ssh2_cipher * ssh2_bpp_get_cscipher(BinaryPacketProtocol *bpp)
  648. {
  649. return FROMFIELD(bpp, struct ssh2_bpp_state, bpp)->out.cipher;
  650. }
  651. const ssh2_cipher * ssh2_bpp_get_sccipher(BinaryPacketProtocol *bpp)
  652. {
  653. return FROMFIELD(bpp, struct ssh2_bpp_state, bpp)->in.cipher;
  654. }
  655. const struct ssh_compressor * ssh2_bpp_get_cscomp(BinaryPacketProtocol *bpp)
  656. {
  657. return FROMFIELD(bpp, struct ssh2_bpp_state, bpp)->out_comp;
  658. }
  659. const struct ssh_decompressor * ssh2_bpp_get_sccomp(BinaryPacketProtocol *bpp)
  660. {
  661. return FROMFIELD(bpp, struct ssh2_bpp_state, bpp)->in_decomp;
  662. }
  663. #endif