summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2016-08-03 05:41:57 +0000
committerDarren Tucker <dtucker@zip.com.au>2016-08-09 09:06:52 +1000
commit4706c1d8c15cd5565b59512853c2da9bd4ca26c9 (patch)
tree81ff9de3bdf3627b382bb4b808cf0e0612f4424f /packet.c
parente600348a7afd6325cc5cd783cb424065cbc20434 (diff)
upstream commit
small refactor of cipher.c: make ciphercontext opaque to callers feedback and ok markus@ Upstream-ID: 094849f8be68c3bdad2c0f3dee551ecf7be87f6f
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c88
1 files changed, 43 insertions, 45 deletions
diff --git a/packet.c b/packet.c
index d6dad2da6..d4221d12a 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.234 2016/07/18 11:35:33 markus Exp $ */ 1/* $OpenBSD: packet.c,v 1.235 2016/08/03 05:41:57 djm 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
@@ -122,10 +122,10 @@ struct session_state {
122 u_int remote_protocol_flags; 122 u_int remote_protocol_flags;
123 123
124 /* Encryption context for receiving data. Only used for decryption. */ 124 /* Encryption context for receiving data. Only used for decryption. */
125 struct sshcipher_ctx receive_context; 125 struct sshcipher_ctx *receive_context;
126 126
127 /* Encryption context for sending data. Only used for encryption. */ 127 /* Encryption context for sending data. Only used for encryption. */
128 struct sshcipher_ctx send_context; 128 struct sshcipher_ctx *send_context;
129 129
130 /* Buffer for raw input data from the socket. */ 130 /* Buffer for raw input data from the socket. */
131 struct sshbuf *input; 131 struct sshbuf *input;
@@ -529,7 +529,6 @@ void
529ssh_packet_close(struct ssh *ssh) 529ssh_packet_close(struct ssh *ssh)
530{ 530{
531 struct session_state *state = ssh->state; 531 struct session_state *state = ssh->state;
532 int r;
533 u_int mode; 532 u_int mode;
534 533
535 if (!state->initialized) 534 if (!state->initialized)
@@ -573,10 +572,9 @@ ssh_packet_close(struct ssh *ssh)
573 inflateEnd(stream); 572 inflateEnd(stream);
574 } 573 }
575 } 574 }
576 if ((r = cipher_cleanup(&state->send_context)) != 0) 575 cipher_free(state->send_context);
577 error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); 576 cipher_free(state->receive_context);
578 if ((r = cipher_cleanup(&state->receive_context)) != 0) 577 state->send_context = state->receive_context = NULL;
579 error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r));
580 free(ssh->remote_ipaddr); 578 free(ssh->remote_ipaddr);
581 ssh->remote_ipaddr = NULL; 579 ssh->remote_ipaddr = NULL;
582 free(ssh->state); 580 free(ssh->state);
@@ -870,8 +868,8 @@ ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen,
870 NULL, 0, CIPHER_DECRYPT) != 0)) 868 NULL, 0, CIPHER_DECRYPT) != 0))
871 fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); 869 fatal("%s: cipher_init failed: %s", __func__, ssh_err(r));
872 if (!state->cipher_warning_done && 870 if (!state->cipher_warning_done &&
873 ((wmsg = cipher_warning_message(&state->send_context)) != NULL || 871 ((wmsg = cipher_warning_message(state->send_context)) != NULL ||
874 (wmsg = cipher_warning_message(&state->send_context)) != NULL)) { 872 (wmsg = cipher_warning_message(state->send_context)) != NULL)) {
875 error("Warning: %s", wmsg); 873 error("Warning: %s", wmsg);
876 state->cipher_warning_done = 1; 874 state->cipher_warning_done = 1;
877 } 875 }
@@ -917,7 +915,7 @@ ssh_packet_send1(struct ssh *ssh)
917 915
918 /* Insert padding. Initialized to zero in packet_start1() */ 916 /* Insert padding. Initialized to zero in packet_start1() */
919 padding = 8 - len % 8; 917 padding = 8 - len % 8;
920 if (!state->send_context.plaintext) { 918 if (!cipher_ctx_is_plaintext(state->send_context)) {
921 cp = sshbuf_mutable_ptr(state->outgoing_packet); 919 cp = sshbuf_mutable_ptr(state->outgoing_packet);
922 if (cp == NULL) { 920 if (cp == NULL) {
923 r = SSH_ERR_INTERNAL_ERROR; 921 r = SSH_ERR_INTERNAL_ERROR;
@@ -947,7 +945,7 @@ ssh_packet_send1(struct ssh *ssh)
947 if ((r = sshbuf_reserve(state->output, 945 if ((r = sshbuf_reserve(state->output,
948 sshbuf_len(state->outgoing_packet), &cp)) != 0) 946 sshbuf_len(state->outgoing_packet), &cp)) != 0)
949 goto out; 947 goto out;
950 if ((r = cipher_crypt(&state->send_context, 0, cp, 948 if ((r = cipher_crypt(state->send_context, 0, cp,
951 sshbuf_ptr(state->outgoing_packet), 949 sshbuf_ptr(state->outgoing_packet),
952 sshbuf_len(state->outgoing_packet), 0, 0)) != 0) 950 sshbuf_len(state->outgoing_packet), 0, 0)) != 0)
953 goto out; 951 goto out;
@@ -978,7 +976,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
978 struct sshenc *enc; 976 struct sshenc *enc;
979 struct sshmac *mac; 977 struct sshmac *mac;
980 struct sshcomp *comp; 978 struct sshcomp *comp;
981 struct sshcipher_ctx *cc; 979 struct sshcipher_ctx **ccp;
982 u_int64_t *max_blocks; 980 u_int64_t *max_blocks;
983 const char *wmsg; 981 const char *wmsg;
984 int r, crypt_type; 982 int r, crypt_type;
@@ -986,12 +984,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
986 debug2("set_newkeys: mode %d", mode); 984 debug2("set_newkeys: mode %d", mode);
987 985
988 if (mode == MODE_OUT) { 986 if (mode == MODE_OUT) {
989 cc = &state->send_context; 987 ccp = &state->send_context;
990 crypt_type = CIPHER_ENCRYPT; 988 crypt_type = CIPHER_ENCRYPT;
991 state->p_send.packets = state->p_send.blocks = 0; 989 state->p_send.packets = state->p_send.blocks = 0;
992 max_blocks = &state->max_blocks_out; 990 max_blocks = &state->max_blocks_out;
993 } else { 991 } else {
994 cc = &state->receive_context; 992 ccp = &state->receive_context;
995 crypt_type = CIPHER_DECRYPT; 993 crypt_type = CIPHER_DECRYPT;
996 state->p_read.packets = state->p_read.blocks = 0; 994 state->p_read.packets = state->p_read.blocks = 0;
997 max_blocks = &state->max_blocks_in; 995 max_blocks = &state->max_blocks_in;
@@ -1003,8 +1001,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
1003 (unsigned long long)state->p_read.blocks, 1001 (unsigned long long)state->p_read.blocks,
1004 (unsigned long long)state->p_send.bytes, 1002 (unsigned long long)state->p_send.bytes,
1005 (unsigned long long)state->p_send.blocks); 1003 (unsigned long long)state->p_send.blocks);
1006 if ((r = cipher_cleanup(cc)) != 0) 1004 cipher_free(*ccp);
1007 return r; 1005 *ccp = NULL;
1008 enc = &state->newkeys[mode]->enc; 1006 enc = &state->newkeys[mode]->enc;
1009 mac = &state->newkeys[mode]->mac; 1007 mac = &state->newkeys[mode]->mac;
1010 comp = &state->newkeys[mode]->comp; 1008 comp = &state->newkeys[mode]->comp;
@@ -1033,11 +1031,11 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
1033 } 1031 }
1034 mac->enabled = 1; 1032 mac->enabled = 1;
1035 DBG(debug("cipher_init_context: %d", mode)); 1033 DBG(debug("cipher_init_context: %d", mode));
1036 if ((r = cipher_init(cc, enc->cipher, enc->key, enc->key_len, 1034 if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len,
1037 enc->iv, enc->iv_len, crypt_type)) != 0) 1035 enc->iv, enc->iv_len, crypt_type)) != 0)
1038 return r; 1036 return r;
1039 if (!state->cipher_warning_done && 1037 if (!state->cipher_warning_done &&
1040 (wmsg = cipher_warning_message(cc)) != NULL) { 1038 (wmsg = cipher_warning_message(*ccp)) != NULL) {
1041 error("Warning: %s", wmsg); 1039 error("Warning: %s", wmsg);
1042 state->cipher_warning_done = 1; 1040 state->cipher_warning_done = 1;
1043 } 1041 }
@@ -1259,7 +1257,7 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
1259 } 1257 }
1260 if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0) 1258 if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0)
1261 goto out; 1259 goto out;
1262 if (enc && !state->send_context.plaintext) { 1260 if (enc && !cipher_ctx_is_plaintext(state->send_context)) {
1263 /* random padding */ 1261 /* random padding */
1264 arc4random_buf(cp, padlen); 1262 arc4random_buf(cp, padlen);
1265 } else { 1263 } else {
@@ -1291,7 +1289,7 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
1291 if ((r = sshbuf_reserve(state->output, 1289 if ((r = sshbuf_reserve(state->output,
1292 sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) 1290 sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0)
1293 goto out; 1291 goto out;
1294 if ((r = cipher_crypt(&state->send_context, state->p_send.seqnr, cp, 1292 if ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp,
1295 sshbuf_ptr(state->outgoing_packet), 1293 sshbuf_ptr(state->outgoing_packet),
1296 len - aadlen, aadlen, authlen)) != 0) 1294 len - aadlen, aadlen, authlen)) != 0)
1297 goto out; 1295 goto out;
@@ -1606,7 +1604,7 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep)
1606 * (C)1998 CORE-SDI, Buenos Aires Argentina 1604 * (C)1998 CORE-SDI, Buenos Aires Argentina
1607 * Ariel Futoransky(futo@core-sdi.com) 1605 * Ariel Futoransky(futo@core-sdi.com)
1608 */ 1606 */
1609 if (!state->receive_context.plaintext) { 1607 if (!cipher_ctx_is_plaintext(state->receive_context)) {
1610 emsg = NULL; 1608 emsg = NULL;
1611 switch (detect_attack(&state->deattack, 1609 switch (detect_attack(&state->deattack,
1612 sshbuf_ptr(state->input), padded_len)) { 1610 sshbuf_ptr(state->input), padded_len)) {
@@ -1635,7 +1633,7 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep)
1635 sshbuf_reset(state->incoming_packet); 1633 sshbuf_reset(state->incoming_packet);
1636 if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0) 1634 if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0)
1637 goto out; 1635 goto out;
1638 if ((r = cipher_crypt(&state->receive_context, 0, p, 1636 if ((r = cipher_crypt(state->receive_context, 0, p,
1639 sshbuf_ptr(state->input), padded_len, 0, 0)) != 0) 1637 sshbuf_ptr(state->input), padded_len, 0, 0)) != 0)
1640 goto out; 1638 goto out;
1641 1639
@@ -1733,7 +1731,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1733 aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; 1731 aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
1734 1732
1735 if (aadlen && state->packlen == 0) { 1733 if (aadlen && state->packlen == 0) {
1736 if (cipher_get_length(&state->receive_context, 1734 if (cipher_get_length(state->receive_context,
1737 &state->packlen, state->p_read.seqnr, 1735 &state->packlen, state->p_read.seqnr,
1738 sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) 1736 sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0)
1739 return 0; 1737 return 0;
@@ -1759,7 +1757,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1759 if ((r = sshbuf_reserve(state->incoming_packet, block_size, 1757 if ((r = sshbuf_reserve(state->incoming_packet, block_size,
1760 &cp)) != 0) 1758 &cp)) != 0)
1761 goto out; 1759 goto out;
1762 if ((r = cipher_crypt(&state->receive_context, 1760 if ((r = cipher_crypt(state->receive_context,
1763 state->p_send.seqnr, cp, sshbuf_ptr(state->input), 1761 state->p_send.seqnr, cp, sshbuf_ptr(state->input),
1764 block_size, 0, 0)) != 0) 1762 block_size, 0, 0)) != 0)
1765 goto out; 1763 goto out;
@@ -1827,7 +1825,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1827 if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, 1825 if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need,
1828 &cp)) != 0) 1826 &cp)) != 0)
1829 goto out; 1827 goto out;
1830 if ((r = cipher_crypt(&state->receive_context, state->p_read.seqnr, cp, 1828 if ((r = cipher_crypt(state->receive_context, state->p_read.seqnr, cp,
1831 sshbuf_ptr(state->input), need, aadlen, authlen)) != 0) 1829 sshbuf_ptr(state->input), need, aadlen, authlen)) != 0)
1832 goto out; 1830 goto out;
1833 if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) 1831 if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0)
@@ -2509,8 +2507,8 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode)
2509 enc = &newkey->enc; 2507 enc = &newkey->enc;
2510 mac = &newkey->mac; 2508 mac = &newkey->mac;
2511 comp = &newkey->comp; 2509 comp = &newkey->comp;
2512 cc = (mode == MODE_OUT) ? &ssh->state->send_context : 2510 cc = (mode == MODE_OUT) ? ssh->state->send_context :
2513 &ssh->state->receive_context; 2511 ssh->state->receive_context;
2514 if ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0) 2512 if ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0)
2515 return r; 2513 return r;
2516 if ((b = sshbuf_new()) == NULL) 2514 if ((b = sshbuf_new()) == NULL)
@@ -2549,18 +2547,18 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
2549 int r, ssh1cipher; 2547 int r, ssh1cipher;
2550 2548
2551 if (!compat20) { 2549 if (!compat20) {
2552 ssh1cipher = cipher_get_number(state->receive_context.cipher); 2550 ssh1cipher = cipher_ctx_get_number(state->receive_context);
2553 slen = cipher_get_keyiv_len(&state->send_context); 2551 slen = cipher_get_keyiv_len(state->send_context);
2554 rlen = cipher_get_keyiv_len(&state->receive_context); 2552 rlen = cipher_get_keyiv_len(state->receive_context);
2555 if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || 2553 if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 ||
2556 (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || 2554 (r = sshbuf_put_u32(m, ssh1cipher)) != 0 ||
2557 (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || 2555 (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 ||
2558 (r = sshbuf_put_u32(m, slen)) != 0 || 2556 (r = sshbuf_put_u32(m, slen)) != 0 ||
2559 (r = sshbuf_reserve(m, slen, &p)) != 0 || 2557 (r = sshbuf_reserve(m, slen, &p)) != 0 ||
2560 (r = cipher_get_keyiv(&state->send_context, p, slen)) != 0 || 2558 (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 ||
2561 (r = sshbuf_put_u32(m, rlen)) != 0 || 2559 (r = sshbuf_put_u32(m, rlen)) != 0 ||
2562 (r = sshbuf_reserve(m, rlen, &p)) != 0 || 2560 (r = sshbuf_reserve(m, rlen, &p)) != 0 ||
2563 (r = cipher_get_keyiv(&state->receive_context, p, rlen)) != 0) 2561 (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0)
2564 return r; 2562 return r;
2565 } else { 2563 } else {
2566 if ((r = kex_to_blob(m, ssh->kex)) != 0 || 2564 if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
@@ -2579,17 +2577,17 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
2579 return r; 2577 return r;
2580 } 2578 }
2581 2579
2582 slen = cipher_get_keycontext(&state->send_context, NULL); 2580 slen = cipher_get_keycontext(state->send_context, NULL);
2583 rlen = cipher_get_keycontext(&state->receive_context, NULL); 2581 rlen = cipher_get_keycontext(state->receive_context, NULL);
2584 if ((r = sshbuf_put_u32(m, slen)) != 0 || 2582 if ((r = sshbuf_put_u32(m, slen)) != 0 ||
2585 (r = sshbuf_reserve(m, slen, &p)) != 0) 2583 (r = sshbuf_reserve(m, slen, &p)) != 0)
2586 return r; 2584 return r;
2587 if (cipher_get_keycontext(&state->send_context, p) != (int)slen) 2585 if (cipher_get_keycontext(state->send_context, p) != (int)slen)
2588 return SSH_ERR_INTERNAL_ERROR; 2586 return SSH_ERR_INTERNAL_ERROR;
2589 if ((r = sshbuf_put_u32(m, rlen)) != 0 || 2587 if ((r = sshbuf_put_u32(m, rlen)) != 0 ||
2590 (r = sshbuf_reserve(m, rlen, &p)) != 0) 2588 (r = sshbuf_reserve(m, rlen, &p)) != 0)
2591 return r; 2589 return r;
2592 if (cipher_get_keycontext(&state->receive_context, p) != (int)rlen) 2590 if (cipher_get_keycontext(state->receive_context, p) != (int)rlen)
2593 return SSH_ERR_INTERNAL_ERROR; 2591 return SSH_ERR_INTERNAL_ERROR;
2594 2592
2595 if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || 2593 if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 ||
@@ -2735,11 +2733,11 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
2735 return SSH_ERR_KEY_UNKNOWN_CIPHER; 2733 return SSH_ERR_KEY_UNKNOWN_CIPHER;
2736 ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, 2734 ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen,
2737 (int)ssh1cipher); 2735 (int)ssh1cipher);
2738 if (cipher_get_keyiv_len(&state->send_context) != (int)slen || 2736 if (cipher_get_keyiv_len(state->send_context) != (int)slen ||
2739 cipher_get_keyiv_len(&state->receive_context) != (int)rlen) 2737 cipher_get_keyiv_len(state->receive_context) != (int)rlen)
2740 return SSH_ERR_INVALID_FORMAT; 2738 return SSH_ERR_INVALID_FORMAT;
2741 if ((r = cipher_set_keyiv(&state->send_context, ivout)) != 0 || 2739 if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 ||
2742 (r = cipher_set_keyiv(&state->receive_context, ivin)) != 0) 2740 (r = cipher_set_keyiv(state->receive_context, ivin)) != 0)
2743 return r; 2741 return r;
2744 } else { 2742 } else {
2745 if ((r = kex_from_blob(m, &ssh->kex)) != 0 || 2743 if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
@@ -2769,11 +2767,11 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
2769 if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || 2767 if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 ||
2770 (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) 2768 (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)
2771 return r; 2769 return r;
2772 if (cipher_get_keycontext(&state->send_context, NULL) != (int)slen || 2770 if (cipher_get_keycontext(state->send_context, NULL) != (int)slen ||
2773 cipher_get_keycontext(&state->receive_context, NULL) != (int)rlen) 2771 cipher_get_keycontext(state->receive_context, NULL) != (int)rlen)
2774 return SSH_ERR_INVALID_FORMAT; 2772 return SSH_ERR_INVALID_FORMAT;
2775 cipher_set_keycontext(&state->send_context, keyout); 2773 cipher_set_keycontext(state->send_context, keyout);
2776 cipher_set_keycontext(&state->receive_context, keyin); 2774 cipher_set_keycontext(state->receive_context, keyin);
2777 2775
2778 if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || 2776 if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 ||
2779 (r = ssh_packet_set_postauth(ssh)) != 0) 2777 (r = ssh_packet_set_postauth(ssh)) != 0)