summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kex.h22
-rw-r--r--mac.c93
-rw-r--r--mac.h30
-rw-r--r--monitor_wrap.c4
-rw-r--r--packet.c35
5 files changed, 102 insertions, 82 deletions
diff --git a/kex.h b/kex.h
index 4c40ec851..dbcc0816f 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.64 2014/05/02 03:27:54 djm Exp $ */ 1/* $OpenBSD: kex.h,v 1.65 2015/01/13 19:31:40 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -26,10 +26,9 @@
26#ifndef KEX_H 26#ifndef KEX_H
27#define KEX_H 27#define KEX_H
28 28
29#include <signal.h> 29#include "mac.h"
30#include <openssl/evp.h> 30
31#include <openssl/hmac.h> 31#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
32#ifdef OPENSSL_HAS_ECC
33#include <openssl/ec.h> 32#include <openssl/ec.h>
34#endif 33#endif
35 34
@@ -82,8 +81,8 @@ enum kex_exchange {
82#define KEX_INIT_SENT 0x0001 81#define KEX_INIT_SENT 0x0001
83 82
84typedef struct Kex Kex; 83typedef struct Kex Kex;
85typedef struct Mac Mac;
86typedef struct Comp Comp; 84typedef struct Comp Comp;
85typedef struct sshmac Mac;
87typedef struct Enc Enc; 86typedef struct Enc Enc;
88typedef struct Newkeys Newkeys; 87typedef struct Newkeys Newkeys;
89 88
@@ -97,17 +96,6 @@ struct Enc {
97 u_char *key; 96 u_char *key;
98 u_char *iv; 97 u_char *iv;
99}; 98};
100struct Mac {
101 char *name;
102 int enabled;
103 u_int mac_len;
104 u_char *key;
105 u_int key_len;
106 int type;
107 int etm; /* Encrypt-then-MAC */
108 struct ssh_hmac_ctx *hmac_ctx;
109 struct umac_ctx *umac_ctx;
110};
111struct Comp { 99struct Comp {
112 int type; 100 int type;
113 int enabled; 101 int enabled;
diff --git a/mac.c b/mac.c
index 402dc984c..11c30a1c5 100644
--- a/mac.c
+++ b/mac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mac.c,v 1.30 2014/04/30 19:07:48 naddy Exp $ */ 1/* $OpenBSD: mac.c,v 1.31 2015/01/13 19:31:40 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -27,22 +27,16 @@
27 27
28#include <sys/types.h> 28#include <sys/types.h>
29 29
30#include <stdarg.h>
31#include <string.h> 30#include <string.h>
32#include <signal.h> 31#include <stdio.h>
33
34#include "xmalloc.h"
35#include "log.h"
36#include "cipher.h"
37#include "buffer.h"
38#include "key.h"
39#include "kex.h"
40#include "mac.h"
41#include "misc.h"
42 32
43#include "digest.h" 33#include "digest.h"
44#include "hmac.h" 34#include "hmac.h"
45#include "umac.h" 35#include "umac.h"
36#include "mac.h"
37#include "misc.h"
38#include "ssherr.h"
39#include "sshbuf.h"
46 40
47#include "openbsd-compat/openssl-compat.h" 41#include "openbsd-compat/openssl-compat.h"
48 42
@@ -95,7 +89,7 @@ static const struct macalg macs[] = {
95char * 89char *
96mac_alg_list(char sep) 90mac_alg_list(char sep)
97{ 91{
98 char *ret = NULL; 92 char *ret = NULL, *tmp;
99 size_t nlen, rlen = 0; 93 size_t nlen, rlen = 0;
100 const struct macalg *m; 94 const struct macalg *m;
101 95
@@ -103,20 +97,24 @@ mac_alg_list(char sep)
103 if (ret != NULL) 97 if (ret != NULL)
104 ret[rlen++] = sep; 98 ret[rlen++] = sep;
105 nlen = strlen(m->name); 99 nlen = strlen(m->name);
106 ret = xrealloc(ret, 1, rlen + nlen + 2); 100 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
101 free(ret);
102 return NULL;
103 }
104 ret = tmp;
107 memcpy(ret + rlen, m->name, nlen + 1); 105 memcpy(ret + rlen, m->name, nlen + 1);
108 rlen += nlen; 106 rlen += nlen;
109 } 107 }
110 return ret; 108 return ret;
111} 109}
112 110
113static void 111static int
114mac_setup_by_alg(Mac *mac, const struct macalg *macalg) 112mac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg)
115{ 113{
116 mac->type = macalg->type; 114 mac->type = macalg->type;
117 if (mac->type == SSH_DIGEST) { 115 if (mac->type == SSH_DIGEST) {
118 if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL) 116 if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL)
119 fatal("ssh_hmac_start(alg=%d) failed", macalg->alg); 117 return SSH_ERR_ALLOC_FAIL;
120 mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg); 118 mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg);
121 } else { 119 } else {
122 mac->mac_len = macalg->len / 8; 120 mac->mac_len = macalg->len / 8;
@@ -126,61 +124,60 @@ mac_setup_by_alg(Mac *mac, const struct macalg *macalg)
126 if (macalg->truncatebits != 0) 124 if (macalg->truncatebits != 0)
127 mac->mac_len = macalg->truncatebits / 8; 125 mac->mac_len = macalg->truncatebits / 8;
128 mac->etm = macalg->etm; 126 mac->etm = macalg->etm;
127 return 0;
129} 128}
130 129
131int 130int
132mac_setup(Mac *mac, char *name) 131mac_setup(struct sshmac *mac, char *name)
133{ 132{
134 const struct macalg *m; 133 const struct macalg *m;
135 134
136 for (m = macs; m->name != NULL; m++) { 135 for (m = macs; m->name != NULL; m++) {
137 if (strcmp(name, m->name) != 0) 136 if (strcmp(name, m->name) != 0)
138 continue; 137 continue;
139 if (mac != NULL) { 138 if (mac != NULL)
140 mac_setup_by_alg(mac, m); 139 return mac_setup_by_alg(mac, m);
141 debug2("mac_setup: setup %s", name); 140 return 0;
142 }
143 return (0);
144 } 141 }
145 debug2("mac_setup: unknown %s", name); 142 return SSH_ERR_INVALID_ARGUMENT;
146 return (-1);
147} 143}
148 144
149int 145int
150mac_init(Mac *mac) 146mac_init(struct sshmac *mac)
151{ 147{
152 if (mac->key == NULL) 148 if (mac->key == NULL)
153 fatal("%s: no key", __func__); 149 return SSH_ERR_INVALID_ARGUMENT;
154 switch (mac->type) { 150 switch (mac->type) {
155 case SSH_DIGEST: 151 case SSH_DIGEST:
156 if (mac->hmac_ctx == NULL || 152 if (mac->hmac_ctx == NULL ||
157 ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0) 153 ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0)
158 return -1; 154 return SSH_ERR_INVALID_ARGUMENT;
159 return 0; 155 return 0;
160 case SSH_UMAC: 156 case SSH_UMAC:
161 mac->umac_ctx = umac_new(mac->key); 157 if ((mac->umac_ctx = umac_new(mac->key)) == NULL)
158 return SSH_ERR_ALLOC_FAIL;
162 return 0; 159 return 0;
163 case SSH_UMAC128: 160 case SSH_UMAC128:
164 mac->umac_ctx = umac128_new(mac->key); 161 mac->umac_ctx = umac128_new(mac->key);
165 return 0; 162 return 0;
166 default: 163 default:
167 return -1; 164 return SSH_ERR_INVALID_ARGUMENT;
168 } 165 }
169} 166}
170 167
171u_char * 168int
172mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) 169mac_compute(struct sshmac *mac, u_int32_t seqno, const u_char *data, int datalen,
170 u_char *digest, size_t dlen)
173{ 171{
174 static union { 172 static union {
175 u_char m[EVP_MAX_MD_SIZE]; 173 u_char m[SSH_DIGEST_MAX_LENGTH];
176 u_int64_t for_align; 174 u_int64_t for_align;
177 } u; 175 } u;
178 u_char b[4]; 176 u_char b[4];
179 u_char nonce[8]; 177 u_char nonce[8];
180 178
181 if (mac->mac_len > sizeof(u)) 179 if (mac->mac_len > sizeof(u))
182 fatal("mac_compute: mac too long %u %zu", 180 return SSH_ERR_INTERNAL_ERROR;
183 mac->mac_len, sizeof(u));
184 181
185 switch (mac->type) { 182 switch (mac->type) {
186 case SSH_DIGEST: 183 case SSH_DIGEST:
@@ -190,10 +187,10 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
190 ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 || 187 ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 ||
191 ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 || 188 ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 ||
192 ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) 189 ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0)
193 fatal("ssh_hmac failed"); 190 return SSH_ERR_LIBCRYPTO_ERROR;
194 break; 191 break;
195 case SSH_UMAC: 192 case SSH_UMAC:
196 put_u64(nonce, seqno); 193 POKE_U64(nonce, seqno);
197 umac_update(mac->umac_ctx, data, datalen); 194 umac_update(mac->umac_ctx, data, datalen);
198 umac_final(mac->umac_ctx, u.m, nonce); 195 umac_final(mac->umac_ctx, u.m, nonce);
199 break; 196 break;
@@ -203,13 +200,18 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
203 umac128_final(mac->umac_ctx, u.m, nonce); 200 umac128_final(mac->umac_ctx, u.m, nonce);
204 break; 201 break;
205 default: 202 default:
206 fatal("mac_compute: unknown MAC type"); 203 return SSH_ERR_INVALID_ARGUMENT;
207 } 204 }
208 return (u.m); 205 if (digest != NULL) {
206 if (dlen > mac->mac_len)
207 dlen = mac->mac_len;
208 memcpy(digest, u.m, dlen);
209 }
210 return 0;
209} 211}
210 212
211void 213void
212mac_clear(Mac *mac) 214mac_clear(struct sshmac *mac)
213{ 215{
214 if (mac->type == SSH_UMAC) { 216 if (mac->type == SSH_UMAC) {
215 if (mac->umac_ctx != NULL) 217 if (mac->umac_ctx != NULL)
@@ -231,17 +233,16 @@ mac_valid(const char *names)
231 char *maclist, *cp, *p; 233 char *maclist, *cp, *p;
232 234
233 if (names == NULL || strcmp(names, "") == 0) 235 if (names == NULL || strcmp(names, "") == 0)
234 return (0); 236 return 0;
235 maclist = cp = xstrdup(names); 237 if ((maclist = cp = strdup(names)) == NULL)
238 return 0;
236 for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; 239 for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
237 (p = strsep(&cp, MAC_SEP))) { 240 (p = strsep(&cp, MAC_SEP))) {
238 if (mac_setup(NULL, p) < 0) { 241 if (mac_setup(NULL, p) < 0) {
239 debug("bad mac %s [%s]", p, names);
240 free(maclist); 242 free(maclist);
241 return (0); 243 return 0;
242 } 244 }
243 } 245 }
244 debug3("macs ok: [%s]", names);
245 free(maclist); 246 free(maclist);
246 return (1); 247 return 1;
247} 248}
diff --git a/mac.h b/mac.h
index fbe18c463..e5f6b84d9 100644
--- a/mac.h
+++ b/mac.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: mac.h,v 1.8 2013/11/07 11:58:27 dtucker Exp $ */ 1/* $OpenBSD: mac.h,v 1.9 2015/01/13 19:31:40 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -23,9 +23,29 @@
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25 25
26#ifndef SSHMAC_H
27#define SSHMAC_H
28
29#include <sys/types.h>
30
31struct sshmac {
32 char *name;
33 int enabled;
34 u_int mac_len;
35 u_char *key;
36 u_int key_len;
37 int type;
38 int etm; /* Encrypt-then-MAC */
39 struct ssh_hmac_ctx *hmac_ctx;
40 struct umac_ctx *umac_ctx;
41};
42
26int mac_valid(const char *); 43int mac_valid(const char *);
27char *mac_alg_list(char); 44char *mac_alg_list(char);
28int mac_setup(Mac *, char *); 45int mac_setup(struct sshmac *, char *);
29int mac_init(Mac *); 46int mac_init(struct sshmac *);
30u_char *mac_compute(Mac *, u_int32_t, u_char *, int); 47int mac_compute(struct sshmac *, u_int32_t, const u_char *, int,
31void mac_clear(Mac *); 48 u_char *, size_t);
49void mac_clear(struct sshmac *);
50
51#endif /* SSHMAC_H */
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 45dc16951..f4e11c966 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.80 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.81 2015/01/13 19:31:40 markus Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -506,7 +506,7 @@ mm_newkeys_from_blob(u_char *blob, int blen)
506 /* Mac structure */ 506 /* Mac structure */
507 if (cipher_authlen(enc->cipher) == 0) { 507 if (cipher_authlen(enc->cipher) == 0) {
508 mac->name = buffer_get_string(&b, NULL); 508 mac->name = buffer_get_string(&b, NULL);
509 if (mac->name == NULL || mac_setup(mac, mac->name) == -1) 509 if (mac->name == NULL || mac_setup(mac, mac->name) != 0)
510 fatal("%s: can not setup mac %s", __func__, mac->name); 510 fatal("%s: can not setup mac %s", __func__, mac->name);
511 mac->enabled = buffer_get_int(&b); 511 mac->enabled = buffer_get_int(&b);
512 mac->key = buffer_get_string(&b, &len); 512 mac->key = buffer_get_string(&b, &len);
diff --git a/packet.c b/packet.c
index 4674a203f..6b326f367 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.199 2014/10/24 02:01:20 lteo Exp $ */ 1/* $OpenBSD: packet.c,v 1.200 2015/01/13 19:31:40 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
@@ -72,6 +72,7 @@
72#include "cipher.h" 72#include "cipher.h"
73#include "key.h" 73#include "key.h"
74#include "kex.h" 74#include "kex.h"
75#include "digest.h"
75#include "mac.h" 76#include "mac.h"
76#include "log.h" 77#include "log.h"
77#include "canohost.h" 78#include "canohost.h"
@@ -275,7 +276,7 @@ packet_stop_discard(void)
275 (void) mac_compute(active_state->packet_discard_mac, 276 (void) mac_compute(active_state->packet_discard_mac,
276 active_state->p_read.seqnr, 277 active_state->p_read.seqnr,
277 buffer_ptr(&active_state->incoming_packet), 278 buffer_ptr(&active_state->incoming_packet),
278 PACKET_MAX_SIZE); 279 PACKET_MAX_SIZE, NULL, 0);
279 } 280 }
280 logit("Finished discarding for %.200s", get_remote_ipaddr()); 281 logit("Finished discarding for %.200s", get_remote_ipaddr());
281 cleanup_exit(255); 282 cleanup_exit(255);
@@ -863,7 +864,7 @@ packet_enable_delayed_compress(void)
863static void 864static void
864packet_send2_wrapped(void) 865packet_send2_wrapped(void)
865{ 866{
866 u_char type, *cp, *macbuf = NULL; 867 u_char type, *cp, macbuf[SSH_DIGEST_MAX_LENGTH];
867 u_char padlen, pad = 0; 868 u_char padlen, pad = 0;
868 u_int i, len, authlen = 0, aadlen = 0; 869 u_int i, len, authlen = 0, aadlen = 0;
869 u_int32_t rnd = 0; 870 u_int32_t rnd = 0;
@@ -871,6 +872,7 @@ packet_send2_wrapped(void)
871 Mac *mac = NULL; 872 Mac *mac = NULL;
872 Comp *comp = NULL; 873 Comp *comp = NULL;
873 int block_size; 874 int block_size;
875 int r;
874 876
875 if (active_state->newkeys[MODE_OUT] != NULL) { 877 if (active_state->newkeys[MODE_OUT] != NULL) {
876 enc = &active_state->newkeys[MODE_OUT]->enc; 878 enc = &active_state->newkeys[MODE_OUT]->enc;
@@ -953,8 +955,10 @@ packet_send2_wrapped(void)
953 955
954 /* compute MAC over seqnr and packet(length fields, payload, padding) */ 956 /* compute MAC over seqnr and packet(length fields, payload, padding) */
955 if (mac && mac->enabled && !mac->etm) { 957 if (mac && mac->enabled && !mac->etm) {
956 macbuf = mac_compute(mac, active_state->p_send.seqnr, 958 if ((r = mac_compute(mac, active_state->p_send.seqnr,
957 buffer_ptr(&active_state->outgoing_packet), len); 959 buffer_ptr(&active_state->outgoing_packet), len,
960 macbuf, sizeof(macbuf))) != 0)
961 fatal("%s: mac_compute: %s", __func__, ssh_err(r));
958 DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); 962 DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
959 } 963 }
960 /* encrypt packet and append to output buffer. */ 964 /* encrypt packet and append to output buffer. */
@@ -967,8 +971,10 @@ packet_send2_wrapped(void)
967 if (mac && mac->enabled) { 971 if (mac && mac->enabled) {
968 if (mac->etm) { 972 if (mac->etm) {
969 /* EtM: compute mac over aadlen + cipher text */ 973 /* EtM: compute mac over aadlen + cipher text */
970 macbuf = mac_compute(mac, 974 if ((r = mac_compute(mac,
971 active_state->p_send.seqnr, cp, len); 975 active_state->p_send.seqnr, cp, len,
976 macbuf, sizeof(macbuf))) != 0)
977 fatal("%s: mac_compute: %s", __func__, ssh_err(r));
972 DBG(debug("done calc MAC(EtM) out #%d", 978 DBG(debug("done calc MAC(EtM) out #%d",
973 active_state->p_send.seqnr)); 979 active_state->p_send.seqnr));
974 } 980 }
@@ -1272,8 +1278,9 @@ static int
1272packet_read_poll2(u_int32_t *seqnr_p) 1278packet_read_poll2(u_int32_t *seqnr_p)
1273{ 1279{
1274 u_int padlen, need; 1280 u_int padlen, need;
1275 u_char *macbuf = NULL, *cp, type; 1281 u_char type, *cp, macbuf[SSH_DIGEST_MAX_LENGTH];
1276 u_int maclen, authlen = 0, aadlen = 0, block_size; 1282 u_int maclen, authlen = 0, aadlen = 0, block_size;
1283 int r;
1277 Enc *enc = NULL; 1284 Enc *enc = NULL;
1278 Mac *mac = NULL; 1285 Mac *mac = NULL;
1279 Comp *comp = NULL; 1286 Comp *comp = NULL;
@@ -1373,8 +1380,10 @@ packet_read_poll2(u_int32_t *seqnr_p)
1373#endif 1380#endif
1374 /* EtM: compute mac over encrypted input */ 1381 /* EtM: compute mac over encrypted input */
1375 if (mac && mac->enabled && mac->etm) 1382 if (mac && mac->enabled && mac->etm)
1376 macbuf = mac_compute(mac, active_state->p_read.seqnr, 1383 if ((r = mac_compute(mac, active_state->p_read.seqnr,
1377 buffer_ptr(&active_state->input), aadlen + need); 1384 buffer_ptr(&active_state->input), aadlen + need,
1385 macbuf, sizeof(macbuf))) != 0)
1386 fatal("%s: mac_compute: %s", __func__, ssh_err(r));
1378 cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); 1387 cp = buffer_append_space(&active_state->incoming_packet, aadlen + need);
1379 if (cipher_crypt(&active_state->receive_context, 1388 if (cipher_crypt(&active_state->receive_context,
1380 active_state->p_read.seqnr, cp, 1389 active_state->p_read.seqnr, cp,
@@ -1387,9 +1396,11 @@ packet_read_poll2(u_int32_t *seqnr_p)
1387 */ 1396 */
1388 if (mac && mac->enabled) { 1397 if (mac && mac->enabled) {
1389 if (!mac->etm) 1398 if (!mac->etm)
1390 macbuf = mac_compute(mac, active_state->p_read.seqnr, 1399 if ((r = mac_compute(mac, active_state->p_read.seqnr,
1391 buffer_ptr(&active_state->incoming_packet), 1400 buffer_ptr(&active_state->incoming_packet),
1392 buffer_len(&active_state->incoming_packet)); 1401 buffer_len(&active_state->incoming_packet),
1402 macbuf, sizeof(macbuf))) != 0)
1403 fatal("%s: mac_compute: %s", __func__, ssh_err(r));
1393 if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), 1404 if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
1394 mac->mac_len) != 0) { 1405 mac->mac_len) != 0) {
1395 logit("Corrupted MAC on input."); 1406 logit("Corrupted MAC on input.");