summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c113
1 files changed, 76 insertions, 37 deletions
diff --git a/packet.c b/packet.c
index b75c081f0..be8907854 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.177 2012/09/17 13:04:11 markus Exp $ */ 1/* $OpenBSD: packet.c,v 1.178 2012/12/11 22:31:18 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -275,7 +275,7 @@ packet_stop_discard(void)
275static void 275static void
276packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) 276packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
277{ 277{
278 if (enc == NULL || !cipher_is_cbc(enc->cipher)) 278 if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm))
279 packet_disconnect("Packet corrupt"); 279 packet_disconnect("Packet corrupt");
280 if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) 280 if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
281 active_state->packet_discard_mac = mac; 281 active_state->packet_discard_mac = mac;
@@ -709,7 +709,7 @@ packet_send1(void)
709 buffer_len(&active_state->outgoing_packet)); 709 buffer_len(&active_state->outgoing_packet));
710 cipher_crypt(&active_state->send_context, cp, 710 cipher_crypt(&active_state->send_context, cp,
711 buffer_ptr(&active_state->outgoing_packet), 711 buffer_ptr(&active_state->outgoing_packet),
712 buffer_len(&active_state->outgoing_packet)); 712 buffer_len(&active_state->outgoing_packet), 0);
713 713
714#ifdef PACKET_DEBUG 714#ifdef PACKET_DEBUG
715 fprintf(stderr, "encrypted: "); 715 fprintf(stderr, "encrypted: ");
@@ -845,9 +845,8 @@ static void
845packet_send2_wrapped(void) 845packet_send2_wrapped(void)
846{ 846{
847 u_char type, *cp, *macbuf = NULL; 847 u_char type, *cp, *macbuf = NULL;
848 u_char padlen, pad; 848 u_char padlen, pad = 0;
849 u_int packet_length = 0; 849 u_int i, len, aadlen = 0;
850 u_int i, len;
851 u_int32_t rnd = 0; 850 u_int32_t rnd = 0;
852 Enc *enc = NULL; 851 Enc *enc = NULL;
853 Mac *mac = NULL; 852 Mac *mac = NULL;
@@ -860,6 +859,7 @@ packet_send2_wrapped(void)
860 comp = &active_state->newkeys[MODE_OUT]->comp; 859 comp = &active_state->newkeys[MODE_OUT]->comp;
861 } 860 }
862 block_size = enc ? enc->block_size : 8; 861 block_size = enc ? enc->block_size : 8;
862 aadlen = mac && mac->enabled && mac->etm ? 4 : 0;
863 863
864 cp = buffer_ptr(&active_state->outgoing_packet); 864 cp = buffer_ptr(&active_state->outgoing_packet);
865 type = cp[5]; 865 type = cp[5];
@@ -892,6 +892,7 @@ packet_send2_wrapped(void)
892 * calc size of padding, alloc space, get random data, 892 * calc size of padding, alloc space, get random data,
893 * minimum padding is 4 bytes 893 * minimum padding is 4 bytes
894 */ 894 */
895 len -= aadlen; /* packet length is not encrypted for EtM modes */
895 padlen = block_size - (len % block_size); 896 padlen = block_size - (len % block_size);
896 if (padlen < 4) 897 if (padlen < 4)
897 padlen += block_size; 898 padlen += block_size;
@@ -919,29 +920,37 @@ packet_send2_wrapped(void)
919 /* clear padding */ 920 /* clear padding */
920 memset(cp, 0, padlen); 921 memset(cp, 0, padlen);
921 } 922 }
922 /* packet_length includes payload, padding and padding length field */ 923 /* sizeof (packet_len + pad_len + payload + padding) */
923 packet_length = buffer_len(&active_state->outgoing_packet) - 4; 924 len = buffer_len(&active_state->outgoing_packet);
924 cp = buffer_ptr(&active_state->outgoing_packet); 925 cp = buffer_ptr(&active_state->outgoing_packet);
925 put_u32(cp, packet_length); 926 /* packet_length includes payload, padding and padding length field */
927 put_u32(cp, len - 4);
926 cp[4] = padlen; 928 cp[4] = padlen;
927 DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); 929 DBG(debug("send: len %d (includes padlen %d, aadlen %d)",
930 len, padlen, aadlen));
928 931
929 /* compute MAC over seqnr and packet(length fields, payload, padding) */ 932 /* compute MAC over seqnr and packet(length fields, payload, padding) */
930 if (mac && mac->enabled) { 933 if (mac && mac->enabled && !mac->etm) {
931 macbuf = mac_compute(mac, active_state->p_send.seqnr, 934 macbuf = mac_compute(mac, active_state->p_send.seqnr,
932 buffer_ptr(&active_state->outgoing_packet), 935 buffer_ptr(&active_state->outgoing_packet), len);
933 buffer_len(&active_state->outgoing_packet));
934 DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); 936 DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
935 } 937 }
936 /* encrypt packet and append to output buffer. */ 938 /* encrypt packet and append to output buffer. */
937 cp = buffer_append_space(&active_state->output, 939 cp = buffer_append_space(&active_state->output, len);
938 buffer_len(&active_state->outgoing_packet));
939 cipher_crypt(&active_state->send_context, cp, 940 cipher_crypt(&active_state->send_context, cp,
940 buffer_ptr(&active_state->outgoing_packet), 941 buffer_ptr(&active_state->outgoing_packet),
941 buffer_len(&active_state->outgoing_packet)); 942 len - aadlen, aadlen);
942 /* append unencrypted MAC */ 943 /* append unencrypted MAC */
943 if (mac && mac->enabled) 944 if (mac && mac->enabled) {
945 if (mac->etm) {
946 /* EtM: compute mac over aadlen + cipher text */
947 macbuf = mac_compute(mac,
948 active_state->p_send.seqnr, cp, len);
949 DBG(debug("done calc MAC(EtM) out #%d",
950 active_state->p_send.seqnr));
951 }
944 buffer_append(&active_state->output, macbuf, mac->mac_len); 952 buffer_append(&active_state->output, macbuf, mac->mac_len);
953 }
945#ifdef PACKET_DEBUG 954#ifdef PACKET_DEBUG
946 fprintf(stderr, "encrypted: "); 955 fprintf(stderr, "encrypted: ");
947 buffer_dump(&active_state->output); 956 buffer_dump(&active_state->output);
@@ -952,8 +961,8 @@ packet_send2_wrapped(void)
952 if (++active_state->p_send.packets == 0) 961 if (++active_state->p_send.packets == 0)
953 if (!(datafellows & SSH_BUG_NOREKEY)) 962 if (!(datafellows & SSH_BUG_NOREKEY))
954 fatal("XXX too many packets with same key"); 963 fatal("XXX too many packets with same key");
955 active_state->p_send.blocks += (packet_length + 4) / block_size; 964 active_state->p_send.blocks += len / block_size;
956 active_state->p_send.bytes += packet_length + 4; 965 active_state->p_send.bytes += len;
957 buffer_clear(&active_state->outgoing_packet); 966 buffer_clear(&active_state->outgoing_packet);
958 967
959 if (type == SSH2_MSG_NEWKEYS) 968 if (type == SSH2_MSG_NEWKEYS)
@@ -1190,7 +1199,7 @@ packet_read_poll1(void)
1190 buffer_clear(&active_state->incoming_packet); 1199 buffer_clear(&active_state->incoming_packet);
1191 cp = buffer_append_space(&active_state->incoming_packet, padded_len); 1200 cp = buffer_append_space(&active_state->incoming_packet, padded_len);
1192 cipher_crypt(&active_state->receive_context, cp, 1201 cipher_crypt(&active_state->receive_context, cp,
1193 buffer_ptr(&active_state->input), padded_len); 1202 buffer_ptr(&active_state->input), padded_len, 0);
1194 1203
1195 buffer_consume(&active_state->input, padded_len); 1204 buffer_consume(&active_state->input, padded_len);
1196 1205
@@ -1238,8 +1247,8 @@ static int
1238packet_read_poll2(u_int32_t *seqnr_p) 1247packet_read_poll2(u_int32_t *seqnr_p)
1239{ 1248{
1240 u_int padlen, need; 1249 u_int padlen, need;
1241 u_char *macbuf, *cp, type; 1250 u_char *macbuf = NULL, *cp, type;
1242 u_int maclen, block_size; 1251 u_int maclen, aadlen = 0, block_size;
1243 Enc *enc = NULL; 1252 Enc *enc = NULL;
1244 Mac *mac = NULL; 1253 Mac *mac = NULL;
1245 Comp *comp = NULL; 1254 Comp *comp = NULL;
@@ -1254,8 +1263,22 @@ packet_read_poll2(u_int32_t *seqnr_p)
1254 } 1263 }
1255 maclen = mac && mac->enabled ? mac->mac_len : 0; 1264 maclen = mac && mac->enabled ? mac->mac_len : 0;
1256 block_size = enc ? enc->block_size : 8; 1265 block_size = enc ? enc->block_size : 8;
1266 aadlen = mac && mac->enabled && mac->etm ? 4 : 0;
1257 1267
1258 if (active_state->packlen == 0) { 1268 if (aadlen && active_state->packlen == 0) {
1269 if (buffer_len(&active_state->input) < 4)
1270 return SSH_MSG_NONE;
1271 cp = buffer_ptr(&active_state->input);
1272 active_state->packlen = get_u32(cp);
1273 if (active_state->packlen < 1 + 4 ||
1274 active_state->packlen > PACKET_MAX_SIZE) {
1275#ifdef PACKET_DEBUG
1276 buffer_dump(&active_state->input);
1277#endif
1278 logit("Bad packet length %u.", active_state->packlen);
1279 packet_disconnect("Packet corrupt");
1280 }
1281 } else if (active_state->packlen == 0) {
1259 /* 1282 /*
1260 * check if input size is less than the cipher block size, 1283 * check if input size is less than the cipher block size,
1261 * decrypt first block and extract length of incoming packet 1284 * decrypt first block and extract length of incoming packet
@@ -1266,7 +1289,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
1266 cp = buffer_append_space(&active_state->incoming_packet, 1289 cp = buffer_append_space(&active_state->incoming_packet,
1267 block_size); 1290 block_size);
1268 cipher_crypt(&active_state->receive_context, cp, 1291 cipher_crypt(&active_state->receive_context, cp,
1269 buffer_ptr(&active_state->input), block_size); 1292 buffer_ptr(&active_state->input), block_size, 0);
1270 cp = buffer_ptr(&active_state->incoming_packet); 1293 cp = buffer_ptr(&active_state->incoming_packet);
1271 active_state->packlen = get_u32(cp); 1294 active_state->packlen = get_u32(cp);
1272 if (active_state->packlen < 1 + 4 || 1295 if (active_state->packlen < 1 + 4 ||
@@ -1279,13 +1302,21 @@ packet_read_poll2(u_int32_t *seqnr_p)
1279 PACKET_MAX_SIZE); 1302 PACKET_MAX_SIZE);
1280 return SSH_MSG_NONE; 1303 return SSH_MSG_NONE;
1281 } 1304 }
1282 DBG(debug("input: packet len %u", active_state->packlen+4));
1283 buffer_consume(&active_state->input, block_size); 1305 buffer_consume(&active_state->input, block_size);
1284 } 1306 }
1285 /* we have a partial packet of block_size bytes */ 1307 DBG(debug("input: packet len %u", active_state->packlen+4));
1286 need = 4 + active_state->packlen - block_size; 1308 if (aadlen) {
1287 DBG(debug("partial packet %d, need %d, maclen %d", block_size, 1309 /* only the payload is encrypted */
1288 need, maclen)); 1310 need = active_state->packlen;
1311 } else {
1312 /*
1313 * the payload size and the payload are encrypted, but we
1314 * have a partial packet of block_size bytes
1315 */
1316 need = 4 + active_state->packlen - block_size;
1317 }
1318 DBG(debug("partial packet: block %d, need %d, maclen %d, aadlen %d",
1319 block_size, need, maclen, aadlen));
1289 if (need % block_size != 0) { 1320 if (need % block_size != 0) {
1290 logit("padding error: need %d block %d mod %d", 1321 logit("padding error: need %d block %d mod %d",
1291 need, block_size, need % block_size); 1322 need, block_size, need % block_size);
@@ -1295,26 +1326,34 @@ packet_read_poll2(u_int32_t *seqnr_p)
1295 } 1326 }
1296 /* 1327 /*
1297 * check if the entire packet has been received and 1328 * check if the entire packet has been received and
1298 * decrypt into incoming_packet 1329 * decrypt into incoming_packet:
1330 * 'aadlen' bytes are unencrypted, but authenticated.
1331 * 'need' bytes are encrypted, followed by
1332 * 'maclen' bytes of message authentication code.
1299 */ 1333 */
1300 if (buffer_len(&active_state->input) < need + maclen) 1334 if (buffer_len(&active_state->input) < aadlen + need + maclen)
1301 return SSH_MSG_NONE; 1335 return SSH_MSG_NONE;
1302#ifdef PACKET_DEBUG 1336#ifdef PACKET_DEBUG
1303 fprintf(stderr, "read_poll enc/full: "); 1337 fprintf(stderr, "read_poll enc/full: ");
1304 buffer_dump(&active_state->input); 1338 buffer_dump(&active_state->input);
1305#endif 1339#endif
1306 cp = buffer_append_space(&active_state->incoming_packet, need); 1340 /* EtM: compute mac over encrypted input */
1341 if (mac && mac->enabled && mac->etm)
1342 macbuf = mac_compute(mac, active_state->p_read.seqnr,
1343 buffer_ptr(&active_state->input), aadlen + need);
1344 cp = buffer_append_space(&active_state->incoming_packet, aadlen + need);
1307 cipher_crypt(&active_state->receive_context, cp, 1345 cipher_crypt(&active_state->receive_context, cp,
1308 buffer_ptr(&active_state->input), need); 1346 buffer_ptr(&active_state->input), need, aadlen);
1309 buffer_consume(&active_state->input, need); 1347 buffer_consume(&active_state->input, aadlen + need);
1310 /* 1348 /*
1311 * compute MAC over seqnr and packet, 1349 * compute MAC over seqnr and packet,
1312 * increment sequence number for incoming packet 1350 * increment sequence number for incoming packet
1313 */ 1351 */
1314 if (mac && mac->enabled) { 1352 if (mac && mac->enabled) {
1315 macbuf = mac_compute(mac, active_state->p_read.seqnr, 1353 if (!mac->etm)
1316 buffer_ptr(&active_state->incoming_packet), 1354 macbuf = mac_compute(mac, active_state->p_read.seqnr,
1317 buffer_len(&active_state->incoming_packet)); 1355 buffer_ptr(&active_state->incoming_packet),
1356 buffer_len(&active_state->incoming_packet));
1318 if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), 1357 if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
1319 mac->mac_len) != 0) { 1358 mac->mac_len) != 0) {
1320 logit("Corrupted MAC on input."); 1359 logit("Corrupted MAC on input.");