summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:50 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 14:23:50 +0100
commitbaccdb349b31c47cd76fb63211f754ed33a9707e (patch)
treed03653f975fd4eb8bf71bb0c9d168614401202fa /kex.c
parent487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (diff)
parent9f82e5a9042f2d872e98f48a876fcab3e25dd9bb (diff)
Import openssh_6.8p1.orig.tar.gz
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c657
1 files changed, 397 insertions, 260 deletions
diff --git a/kex.c b/kex.c
index a173e70e3..8c2b00179 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */ 1/* $OpenBSD: kex.c,v 1.105 2015/01/30 00:22:25 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -25,7 +25,7 @@
25 25
26#include "includes.h" 26#include "includes.h"
27 27
28#include <sys/param.h> 28#include <sys/param.h> /* MAX roundup */
29 29
30#include <signal.h> 30#include <signal.h>
31#include <stdarg.h> 31#include <stdarg.h>
@@ -37,20 +37,22 @@
37#include <openssl/crypto.h> 37#include <openssl/crypto.h>
38#endif 38#endif
39 39
40#include "xmalloc.h"
41#include "ssh2.h" 40#include "ssh2.h"
42#include "buffer.h"
43#include "packet.h" 41#include "packet.h"
44#include "compat.h" 42#include "compat.h"
45#include "cipher.h" 43#include "cipher.h"
46#include "key.h" 44#include "sshkey.h"
47#include "kex.h" 45#include "kex.h"
48#include "log.h" 46#include "log.h"
49#include "mac.h" 47#include "mac.h"
50#include "match.h" 48#include "match.h"
49#include "misc.h"
51#include "dispatch.h" 50#include "dispatch.h"
52#include "monitor.h" 51#include "monitor.h"
53#include "roaming.h" 52#include "roaming.h"
53
54#include "ssherr.h"
55#include "sshbuf.h"
54#include "digest.h" 56#include "digest.h"
55 57
56#if OPENSSL_VERSION_NUMBER >= 0x00907000L 58#if OPENSSL_VERSION_NUMBER >= 0x00907000L
@@ -62,12 +64,12 @@ extern const EVP_MD *evp_ssh_sha256(void);
62#endif 64#endif
63 65
64/* prototype */ 66/* prototype */
65static void kex_kexinit_finish(Kex *); 67static int kex_choose_conf(struct ssh *);
66static void kex_choose_conf(Kex *); 68static int kex_input_newkeys(int, u_int32_t, void *);
67 69
68struct kexalg { 70struct kexalg {
69 char *name; 71 char *name;
70 int type; 72 u_int type;
71 int ec_nid; 73 int ec_nid;
72 int hash_alg; 74 int hash_alg;
73}; 75};
@@ -89,18 +91,17 @@ static const struct kexalg kexalgs[] = {
89 SSH_DIGEST_SHA512 }, 91 SSH_DIGEST_SHA512 },
90# endif /* OPENSSL_HAS_NISTP521 */ 92# endif /* OPENSSL_HAS_NISTP521 */
91#endif /* OPENSSL_HAS_ECC */ 93#endif /* OPENSSL_HAS_ECC */
92 { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
93#endif /* WITH_OPENSSL */ 94#endif /* WITH_OPENSSL */
94#ifdef HAVE_EVP_SHA256 95#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
95 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, 96 { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
96#endif /* HAVE_EVP_SHA256 */ 97#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
97 { NULL, -1, -1, -1}, 98 { NULL, -1, -1, -1},
98}; 99};
99 100
100char * 101char *
101kex_alg_list(char sep) 102kex_alg_list(char sep)
102{ 103{
103 char *ret = NULL; 104 char *ret = NULL, *tmp;
104 size_t nlen, rlen = 0; 105 size_t nlen, rlen = 0;
105 const struct kexalg *k; 106 const struct kexalg *k;
106 107
@@ -108,7 +109,11 @@ kex_alg_list(char sep)
108 if (ret != NULL) 109 if (ret != NULL)
109 ret[rlen++] = sep; 110 ret[rlen++] = sep;
110 nlen = strlen(k->name); 111 nlen = strlen(k->name);
111 ret = xrealloc(ret, 1, rlen + nlen + 2); 112 if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) {
113 free(ret);
114 return NULL;
115 }
116 ret = tmp;
112 memcpy(ret + rlen, k->name, nlen + 1); 117 memcpy(ret + rlen, k->name, nlen + 1);
113 rlen += nlen; 118 rlen += nlen;
114 } 119 }
@@ -135,7 +140,8 @@ kex_names_valid(const char *names)
135 140
136 if (names == NULL || strcmp(names, "") == 0) 141 if (names == NULL || strcmp(names, "") == 0)
137 return 0; 142 return 0;
138 s = cp = xstrdup(names); 143 if ((s = cp = strdup(names)) == NULL)
144 return 0;
139 for ((p = strsep(&cp, ",")); p && *p != '\0'; 145 for ((p = strsep(&cp, ",")); p && *p != '\0';
140 (p = strsep(&cp, ","))) { 146 (p = strsep(&cp, ","))) {
141 if (kex_alg_by_name(p) == NULL) { 147 if (kex_alg_by_name(p) == NULL) {
@@ -150,56 +156,75 @@ kex_names_valid(const char *names)
150} 156}
151 157
152/* put algorithm proposal into buffer */ 158/* put algorithm proposal into buffer */
153static void 159int
154kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) 160kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
155{ 161{
156 u_int i; 162 u_int i;
163 int r;
164
165 sshbuf_reset(b);
157 166
158 buffer_clear(b);
159 /* 167 /*
160 * add a dummy cookie, the cookie will be overwritten by 168 * add a dummy cookie, the cookie will be overwritten by
161 * kex_send_kexinit(), each time a kexinit is set 169 * kex_send_kexinit(), each time a kexinit is set
162 */ 170 */
163 for (i = 0; i < KEX_COOKIE_LEN; i++) 171 for (i = 0; i < KEX_COOKIE_LEN; i++) {
164 buffer_put_char(b, 0); 172 if ((r = sshbuf_put_u8(b, 0)) != 0)
165 for (i = 0; i < PROPOSAL_MAX; i++) 173 return r;
166 buffer_put_cstring(b, proposal[i]); 174 }
167 buffer_put_char(b, 0); /* first_kex_packet_follows */ 175 for (i = 0; i < PROPOSAL_MAX; i++) {
168 buffer_put_int(b, 0); /* uint32 reserved */ 176 if ((r = sshbuf_put_cstring(b, proposal[i])) != 0)
177 return r;
178 }
179 if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */
180 (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */
181 return r;
182 return 0;
169} 183}
170 184
171/* parse buffer and return algorithm proposal */ 185/* parse buffer and return algorithm proposal */
172static char ** 186int
173kex_buf2prop(Buffer *raw, int *first_kex_follows) 187kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
174{ 188{
175 Buffer b; 189 struct sshbuf *b = NULL;
190 u_char v;
176 u_int i; 191 u_int i;
177 char **proposal; 192 char **proposal = NULL;
178 193 int r;
179 proposal = xcalloc(PROPOSAL_MAX, sizeof(char *)); 194
180 195 *propp = NULL;
181 buffer_init(&b); 196 if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
182 buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); 197 return SSH_ERR_ALLOC_FAIL;
183 /* skip cookie */ 198 if ((b = sshbuf_fromb(raw)) == NULL) {
184 for (i = 0; i < KEX_COOKIE_LEN; i++) 199 r = SSH_ERR_ALLOC_FAIL;
185 buffer_get_char(&b); 200 goto out;
201 }
202 if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
203 goto out;
186 /* extract kex init proposal strings */ 204 /* extract kex init proposal strings */
187 for (i = 0; i < PROPOSAL_MAX; i++) { 205 for (i = 0; i < PROPOSAL_MAX; i++) {
188 proposal[i] = buffer_get_cstring(&b,NULL); 206 if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
207 goto out;
189 debug2("kex_parse_kexinit: %s", proposal[i]); 208 debug2("kex_parse_kexinit: %s", proposal[i]);
190 } 209 }
191 /* first kex follows / reserved */ 210 /* first kex follows / reserved */
192 i = buffer_get_char(&b); 211 if ((r = sshbuf_get_u8(b, &v)) != 0 ||
212 (r = sshbuf_get_u32(b, &i)) != 0)
213 goto out;
193 if (first_kex_follows != NULL) 214 if (first_kex_follows != NULL)
194 *first_kex_follows = i; 215 *first_kex_follows = i;
195 debug2("kex_parse_kexinit: first_kex_follows %d ", i); 216 debug2("kex_parse_kexinit: first_kex_follows %d ", v);
196 i = buffer_get_int(&b);
197 debug2("kex_parse_kexinit: reserved %u ", i); 217 debug2("kex_parse_kexinit: reserved %u ", i);
198 buffer_free(&b); 218 r = 0;
199 return proposal; 219 *propp = proposal;
220 out:
221 if (r != 0 && proposal != NULL)
222 kex_prop_free(proposal);
223 sshbuf_free(b);
224 return r;
200} 225}
201 226
202static void 227void
203kex_prop_free(char **proposal) 228kex_prop_free(char **proposal)
204{ 229{
205 u_int i; 230 u_int i;
@@ -210,97 +235,111 @@ kex_prop_free(char **proposal)
210} 235}
211 236
212/* ARGSUSED */ 237/* ARGSUSED */
213static void 238static int
214kex_protocol_error(int type, u_int32_t seq, void *ctxt) 239kex_protocol_error(int type, u_int32_t seq, void *ctxt)
215{ 240{
216 error("Hm, kex protocol error: type %d seq %u", type, seq); 241 error("Hm, kex protocol error: type %d seq %u", type, seq);
242 return 0;
217} 243}
218 244
219static void 245static void
220kex_reset_dispatch(void) 246kex_reset_dispatch(struct ssh *ssh)
221{ 247{
222 dispatch_range(SSH2_MSG_TRANSPORT_MIN, 248 ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN,
223 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); 249 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
224 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 250 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
225} 251}
226 252
227void 253int
228kex_finish(Kex *kex) 254kex_send_newkeys(struct ssh *ssh)
229{ 255{
230 kex_reset_dispatch(); 256 int r;
231 257
232 packet_start(SSH2_MSG_NEWKEYS); 258 kex_reset_dispatch(ssh);
233 packet_send(); 259 if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 ||
234 /* packet_write_wait(); */ 260 (r = sshpkt_send(ssh)) != 0)
261 return r;
235 debug("SSH2_MSG_NEWKEYS sent"); 262 debug("SSH2_MSG_NEWKEYS sent");
236
237 debug("expecting SSH2_MSG_NEWKEYS"); 263 debug("expecting SSH2_MSG_NEWKEYS");
238 packet_read_expect(SSH2_MSG_NEWKEYS); 264 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys);
239 packet_check_eom(); 265 return 0;
240 debug("SSH2_MSG_NEWKEYS received"); 266}
267
268static int
269kex_input_newkeys(int type, u_int32_t seq, void *ctxt)
270{
271 struct ssh *ssh = ctxt;
272 struct kex *kex = ssh->kex;
273 int r;
241 274
275 debug("SSH2_MSG_NEWKEYS received");
276 ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error);
277 if ((r = sshpkt_get_end(ssh)) != 0)
278 return r;
242 kex->done = 1; 279 kex->done = 1;
243 buffer_clear(&kex->peer); 280 sshbuf_reset(kex->peer);
244 /* buffer_clear(&kex->my); */ 281 /* sshbuf_reset(kex->my); */
245 kex->flags &= ~KEX_INIT_SENT; 282 kex->flags &= ~KEX_INIT_SENT;
246 free(kex->name); 283 free(kex->name);
247 kex->name = NULL; 284 kex->name = NULL;
285 return 0;
248} 286}
249 287
250void 288int
251kex_send_kexinit(Kex *kex) 289kex_send_kexinit(struct ssh *ssh)
252{ 290{
253 u_int32_t rnd = 0;
254 u_char *cookie; 291 u_char *cookie;
255 u_int i; 292 struct kex *kex = ssh->kex;
293 int r;
256 294
257 if (kex == NULL) { 295 if (kex == NULL)
258 error("kex_send_kexinit: no kex, cannot rekey"); 296 return SSH_ERR_INTERNAL_ERROR;
259 return; 297 if (kex->flags & KEX_INIT_SENT)
260 } 298 return 0;
261 if (kex->flags & KEX_INIT_SENT) {
262 debug("KEX_INIT_SENT");
263 return;
264 }
265 kex->done = 0; 299 kex->done = 0;
266 300
267 /* generate a random cookie */ 301 /* generate a random cookie */
268 if (buffer_len(&kex->my) < KEX_COOKIE_LEN) 302 if (sshbuf_len(kex->my) < KEX_COOKIE_LEN)
269 fatal("kex_send_kexinit: kex proposal too short"); 303 return SSH_ERR_INVALID_FORMAT;
270 cookie = buffer_ptr(&kex->my); 304 if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL)
271 for (i = 0; i < KEX_COOKIE_LEN; i++) { 305 return SSH_ERR_INTERNAL_ERROR;
272 if (i % 4 == 0) 306 arc4random_buf(cookie, KEX_COOKIE_LEN);
273 rnd = arc4random(); 307
274 cookie[i] = rnd; 308 if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 ||
275 rnd >>= 8; 309 (r = sshpkt_putb(ssh, kex->my)) != 0 ||
276 } 310 (r = sshpkt_send(ssh)) != 0)
277 packet_start(SSH2_MSG_KEXINIT); 311 return r;
278 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
279 packet_send();
280 debug("SSH2_MSG_KEXINIT sent"); 312 debug("SSH2_MSG_KEXINIT sent");
281 kex->flags |= KEX_INIT_SENT; 313 kex->flags |= KEX_INIT_SENT;
314 return 0;
282} 315}
283 316
284/* ARGSUSED */ 317/* ARGSUSED */
285void 318int
286kex_input_kexinit(int type, u_int32_t seq, void *ctxt) 319kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
287{ 320{
288 char *ptr; 321 struct ssh *ssh = ctxt;
289 u_int i, dlen; 322 struct kex *kex = ssh->kex;
290 Kex *kex = (Kex *)ctxt; 323 const u_char *ptr;
324 u_int i;
325 size_t dlen;
326 int r;
291 327
292 debug("SSH2_MSG_KEXINIT received"); 328 debug("SSH2_MSG_KEXINIT received");
293 if (kex == NULL) 329 if (kex == NULL)
294 fatal("kex_input_kexinit: no kex, cannot rekey"); 330 return SSH_ERR_INVALID_ARGUMENT;
295 331
296 ptr = packet_get_raw(&dlen); 332 ptr = sshpkt_ptr(ssh, &dlen);
297 buffer_append(&kex->peer, ptr, dlen); 333 if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
334 return r;
298 335
299 /* discard packet */ 336 /* discard packet */
300 for (i = 0; i < KEX_COOKIE_LEN; i++) 337 for (i = 0; i < KEX_COOKIE_LEN; i++)
301 packet_get_char(); 338 if ((r = sshpkt_get_u8(ssh, NULL)) != 0)
339 return r;
302 for (i = 0; i < PROPOSAL_MAX; i++) 340 for (i = 0; i < PROPOSAL_MAX; i++)
303 free(packet_get_string(NULL)); 341 if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0)
342 return r;
304 /* 343 /*
305 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported 344 * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
306 * KEX method has the server move first, but a server might be using 345 * KEX method has the server move first, but a server might be using
@@ -311,55 +350,129 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
311 * for cases where the server *doesn't* go first. I guess we should 350 * for cases where the server *doesn't* go first. I guess we should
312 * ignore it when it is set for these cases, which is what we do now. 351 * ignore it when it is set for these cases, which is what we do now.
313 */ 352 */
314 (void) packet_get_char(); /* first_kex_follows */ 353 if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */
315 (void) packet_get_int(); /* reserved */ 354 (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */
316 packet_check_eom(); 355 (r = sshpkt_get_end(ssh)) != 0)
356 return r;
357
358 if (!(kex->flags & KEX_INIT_SENT))
359 if ((r = kex_send_kexinit(ssh)) != 0)
360 return r;
361 if ((r = kex_choose_conf(ssh)) != 0)
362 return r;
363
364 if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
365 return (kex->kex[kex->kex_type])(ssh);
317 366
318 kex_kexinit_finish(kex); 367 return SSH_ERR_INTERNAL_ERROR;
319} 368}
320 369
321Kex * 370int
322kex_setup(char *proposal[PROPOSAL_MAX]) 371kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp)
323{ 372{
324 Kex *kex; 373 struct kex *kex;
325 374 int r;
326 kex = xcalloc(1, sizeof(*kex)); 375
327 buffer_init(&kex->peer); 376 *kexp = NULL;
328 buffer_init(&kex->my); 377 if ((kex = calloc(1, sizeof(*kex))) == NULL)
329 kex_prop2buf(&kex->my, proposal); 378 return SSH_ERR_ALLOC_FAIL;
379 if ((kex->peer = sshbuf_new()) == NULL ||
380 (kex->my = sshbuf_new()) == NULL) {
381 r = SSH_ERR_ALLOC_FAIL;
382 goto out;
383 }
384 if ((r = kex_prop2buf(kex->my, proposal)) != 0)
385 goto out;
330 kex->done = 0; 386 kex->done = 0;
387 kex_reset_dispatch(ssh);
388 r = 0;
389 *kexp = kex;
390 out:
391 if (r != 0)
392 kex_free(kex);
393 return r;
394}
331 395
332 kex_send_kexinit(kex); /* we start */ 396void
333 kex_reset_dispatch(); 397kex_free_newkeys(struct newkeys *newkeys)
334 398{
335 return kex; 399 if (newkeys == NULL)
400 return;
401 if (newkeys->enc.key) {
402 explicit_bzero(newkeys->enc.key, newkeys->enc.key_len);
403 free(newkeys->enc.key);
404 newkeys->enc.key = NULL;
405 }
406 if (newkeys->enc.iv) {
407 explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size);
408 free(newkeys->enc.iv);
409 newkeys->enc.iv = NULL;
410 }
411 free(newkeys->enc.name);
412 explicit_bzero(&newkeys->enc, sizeof(newkeys->enc));
413 free(newkeys->comp.name);
414 explicit_bzero(&newkeys->comp, sizeof(newkeys->comp));
415 mac_clear(&newkeys->mac);
416 if (newkeys->mac.key) {
417 explicit_bzero(newkeys->mac.key, newkeys->mac.key_len);
418 free(newkeys->mac.key);
419 newkeys->mac.key = NULL;
420 }
421 free(newkeys->mac.name);
422 explicit_bzero(&newkeys->mac, sizeof(newkeys->mac));
423 explicit_bzero(newkeys, sizeof(*newkeys));
424 free(newkeys);
336} 425}
337 426
338static void 427void
339kex_kexinit_finish(Kex *kex) 428kex_free(struct kex *kex)
340{ 429{
341 if (!(kex->flags & KEX_INIT_SENT)) 430 u_int mode;
342 kex_send_kexinit(kex);
343 431
344 kex_choose_conf(kex); 432#ifdef WITH_OPENSSL
433 if (kex->dh)
434 DH_free(kex->dh);
435#ifdef OPENSSL_HAS_ECC
436 if (kex->ec_client_key)
437 EC_KEY_free(kex->ec_client_key);
438#endif /* OPENSSL_HAS_ECC */
439#endif /* WITH_OPENSSL */
440 for (mode = 0; mode < MODE_MAX; mode++) {
441 kex_free_newkeys(kex->newkeys[mode]);
442 kex->newkeys[mode] = NULL;
443 }
444 sshbuf_free(kex->peer);
445 sshbuf_free(kex->my);
446 free(kex->session_id);
447 free(kex->client_version_string);
448 free(kex->server_version_string);
449 free(kex);
450}
345 451
346 if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && 452int
347 kex->kex[kex->kex_type] != NULL) { 453kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX])
348 (kex->kex[kex->kex_type])(kex); 454{
349 } else { 455 int r;
350 fatal("Unsupported key exchange %d", kex->kex_type); 456
457 if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0)
458 return r;
459 if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */
460 kex_free(ssh->kex);
461 ssh->kex = NULL;
462 return r;
351 } 463 }
464 return 0;
352} 465}
353 466
354static void 467static int
355choose_enc(Enc *enc, char *client, char *server) 468choose_enc(struct sshenc *enc, char *client, char *server)
356{ 469{
357 char *name = match_list(client, server, NULL); 470 char *name = match_list(client, server, NULL);
471
358 if (name == NULL) 472 if (name == NULL)
359 fatal("no matching cipher found: client %s server %s", 473 return SSH_ERR_NO_CIPHER_ALG_MATCH;
360 client, server);
361 if ((enc->cipher = cipher_by_name(name)) == NULL) 474 if ((enc->cipher = cipher_by_name(name)) == NULL)
362 fatal("matching cipher is not supported: %s", name); 475 return SSH_ERR_INTERNAL_ERROR;
363 enc->name = name; 476 enc->name = name;
364 enc->enabled = 0; 477 enc->enabled = 0;
365 enc->iv = NULL; 478 enc->iv = NULL;
@@ -367,31 +480,34 @@ choose_enc(Enc *enc, char *client, char *server)
367 enc->key = NULL; 480 enc->key = NULL;
368 enc->key_len = cipher_keylen(enc->cipher); 481 enc->key_len = cipher_keylen(enc->cipher);
369 enc->block_size = cipher_blocksize(enc->cipher); 482 enc->block_size = cipher_blocksize(enc->cipher);
483 return 0;
370} 484}
371 485
372static void 486static int
373choose_mac(Mac *mac, char *client, char *server) 487choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server)
374{ 488{
375 char *name = match_list(client, server, NULL); 489 char *name = match_list(client, server, NULL);
490
376 if (name == NULL) 491 if (name == NULL)
377 fatal("no matching mac found: client %s server %s", 492 return SSH_ERR_NO_MAC_ALG_MATCH;
378 client, server);
379 if (mac_setup(mac, name) < 0) 493 if (mac_setup(mac, name) < 0)
380 fatal("unsupported mac %s", name); 494 return SSH_ERR_INTERNAL_ERROR;
381 /* truncate the key */ 495 /* truncate the key */
382 if (datafellows & SSH_BUG_HMAC) 496 if (ssh->compat & SSH_BUG_HMAC)
383 mac->key_len = 16; 497 mac->key_len = 16;
384 mac->name = name; 498 mac->name = name;
385 mac->key = NULL; 499 mac->key = NULL;
386 mac->enabled = 0; 500 mac->enabled = 0;
501 return 0;
387} 502}
388 503
389static void 504static int
390choose_comp(Comp *comp, char *client, char *server) 505choose_comp(struct sshcomp *comp, char *client, char *server)
391{ 506{
392 char *name = match_list(client, server, NULL); 507 char *name = match_list(client, server, NULL);
508
393 if (name == NULL) 509 if (name == NULL)
394 fatal("no matching comp found: client %s server %s", client, server); 510 return SSH_ERR_NO_COMPRESS_ALG_MATCH;
395 if (strcmp(name, "zlib@openssh.com") == 0) { 511 if (strcmp(name, "zlib@openssh.com") == 0) {
396 comp->type = COMP_DELAYED; 512 comp->type = COMP_DELAYED;
397 } else if (strcmp(name, "zlib") == 0) { 513 } else if (strcmp(name, "zlib") == 0) {
@@ -399,36 +515,42 @@ choose_comp(Comp *comp, char *client, char *server)
399 } else if (strcmp(name, "none") == 0) { 515 } else if (strcmp(name, "none") == 0) {
400 comp->type = COMP_NONE; 516 comp->type = COMP_NONE;
401 } else { 517 } else {
402 fatal("unsupported comp %s", name); 518 return SSH_ERR_INTERNAL_ERROR;
403 } 519 }
404 comp->name = name; 520 comp->name = name;
521 return 0;
405} 522}
406 523
407static void 524static int
408choose_kex(Kex *k, char *client, char *server) 525choose_kex(struct kex *k, char *client, char *server)
409{ 526{
410 const struct kexalg *kexalg; 527 const struct kexalg *kexalg;
411 528
412 k->name = match_list(client, server, NULL); 529 k->name = match_list(client, server, NULL);
530
413 if (k->name == NULL) 531 if (k->name == NULL)
414 fatal("Unable to negotiate a key exchange method"); 532 return SSH_ERR_NO_KEX_ALG_MATCH;
415 if ((kexalg = kex_alg_by_name(k->name)) == NULL) 533 if ((kexalg = kex_alg_by_name(k->name)) == NULL)
416 fatal("unsupported kex alg %s", k->name); 534 return SSH_ERR_INTERNAL_ERROR;
417 k->kex_type = kexalg->type; 535 k->kex_type = kexalg->type;
418 k->hash_alg = kexalg->hash_alg; 536 k->hash_alg = kexalg->hash_alg;
419 k->ec_nid = kexalg->ec_nid; 537 k->ec_nid = kexalg->ec_nid;
538 return 0;
420} 539}
421 540
422static void 541static int
423choose_hostkeyalg(Kex *k, char *client, char *server) 542choose_hostkeyalg(struct kex *k, char *client, char *server)
424{ 543{
425 char *hostkeyalg = match_list(client, server, NULL); 544 char *hostkeyalg = match_list(client, server, NULL);
545
426 if (hostkeyalg == NULL) 546 if (hostkeyalg == NULL)
427 fatal("no hostkey alg"); 547 return SSH_ERR_NO_HOSTKEY_ALG_MATCH;
428 k->hostkey_type = key_type_from_name(hostkeyalg); 548 k->hostkey_type = sshkey_type_from_name(hostkeyalg);
429 if (k->hostkey_type == KEY_UNSPEC) 549 if (k->hostkey_type == KEY_UNSPEC)
430 fatal("bad hostkey alg '%s'", hostkeyalg); 550 return SSH_ERR_INTERNAL_ERROR;
551 k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg);
431 free(hostkeyalg); 552 free(hostkeyalg);
553 return 0;
432} 554}
433 555
434static int 556static int
@@ -455,18 +577,20 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
455 return (1); 577 return (1);
456} 578}
457 579
458static void 580static int
459kex_choose_conf(Kex *kex) 581kex_choose_conf(struct ssh *ssh)
460{ 582{
461 Newkeys *newkeys; 583 struct kex *kex = ssh->kex;
462 char **my, **peer; 584 struct newkeys *newkeys;
585 char **my = NULL, **peer = NULL;
463 char **cprop, **sprop; 586 char **cprop, **sprop;
464 int nenc, nmac, ncomp; 587 int nenc, nmac, ncomp;
465 u_int mode, ctos, need, dh_need, authlen; 588 u_int mode, ctos, need, dh_need, authlen;
466 int first_kex_follows, type; 589 int r, first_kex_follows;
467 590
468 my = kex_buf2prop(&kex->my, NULL); 591 if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 ||
469 peer = kex_buf2prop(&kex->peer, &first_kex_follows); 592 (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0)
593 goto out;
470 594
471 if (kex->server) { 595 if (kex->server) {
472 cprop=peer; 596 cprop=peer;
@@ -478,8 +602,9 @@ kex_choose_conf(Kex *kex)
478 602
479 /* Check whether server offers roaming */ 603 /* Check whether server offers roaming */
480 if (!kex->server) { 604 if (!kex->server) {
481 char *roaming; 605 char *roaming = match_list(KEX_RESUME,
482 roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); 606 peer[PROPOSAL_KEX_ALGS], NULL);
607
483 if (roaming) { 608 if (roaming) {
484 kex->roaming = 1; 609 kex->roaming = 1;
485 free(roaming); 610 free(roaming);
@@ -488,28 +613,39 @@ kex_choose_conf(Kex *kex)
488 613
489 /* Algorithm Negotiation */ 614 /* Algorithm Negotiation */
490 for (mode = 0; mode < MODE_MAX; mode++) { 615 for (mode = 0; mode < MODE_MAX; mode++) {
491 newkeys = xcalloc(1, sizeof(*newkeys)); 616 if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) {
617 r = SSH_ERR_ALLOC_FAIL;
618 goto out;
619 }
492 kex->newkeys[mode] = newkeys; 620 kex->newkeys[mode] = newkeys;
493 ctos = (!kex->server && mode == MODE_OUT) || 621 ctos = (!kex->server && mode == MODE_OUT) ||
494 (kex->server && mode == MODE_IN); 622 (kex->server && mode == MODE_IN);
495 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; 623 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
496 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; 624 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
497 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; 625 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
498 choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]); 626 if ((r = choose_enc(&newkeys->enc, cprop[nenc],
499 /* ignore mac for authenticated encryption */ 627 sprop[nenc])) != 0)
628 goto out;
500 authlen = cipher_authlen(newkeys->enc.cipher); 629 authlen = cipher_authlen(newkeys->enc.cipher);
501 if (authlen == 0) 630 /* ignore mac for authenticated encryption */
502 choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]); 631 if (authlen == 0 &&
503 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); 632 (r = choose_mac(ssh, &newkeys->mac, cprop[nmac],
633 sprop[nmac])) != 0)
634 goto out;
635 if ((r = choose_comp(&newkeys->comp, cprop[ncomp],
636 sprop[ncomp])) != 0)
637 goto out;
504 debug("kex: %s %s %s %s", 638 debug("kex: %s %s %s %s",
505 ctos ? "client->server" : "server->client", 639 ctos ? "client->server" : "server->client",
506 newkeys->enc.name, 640 newkeys->enc.name,
507 authlen == 0 ? newkeys->mac.name : "<implicit>", 641 authlen == 0 ? newkeys->mac.name : "<implicit>",
508 newkeys->comp.name); 642 newkeys->comp.name);
509 } 643 }
510 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); 644 if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS],
511 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], 645 sprop[PROPOSAL_KEX_ALGS])) != 0 ||
512 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); 646 (r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
647 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0)
648 goto out;
513 need = dh_need = 0; 649 need = dh_need = 0;
514 for (mode = 0; mode < MODE_MAX; mode++) { 650 for (mode = 0; mode < MODE_MAX; mode++) {
515 newkeys = kex->newkeys[mode]; 651 newkeys = kex->newkeys[mode];
@@ -528,45 +664,47 @@ kex_choose_conf(Kex *kex)
528 664
529 /* ignore the next message if the proposals do not match */ 665 /* ignore the next message if the proposals do not match */
530 if (first_kex_follows && !proposals_match(my, peer) && 666 if (first_kex_follows && !proposals_match(my, peer) &&
531 !(datafellows & SSH_BUG_FIRSTKEX)) { 667 !(ssh->compat & SSH_BUG_FIRSTKEX))
532 type = packet_read(); 668 ssh->dispatch_skip_packets = 1;
533 debug2("skipping next packet (type %u)", type); 669 r = 0;
534 } 670 out:
535
536 kex_prop_free(my); 671 kex_prop_free(my);
537 kex_prop_free(peer); 672 kex_prop_free(peer);
673 return r;
538} 674}
539 675
540static u_char * 676static int
541derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, 677derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
542 const u_char *shared_secret, u_int slen) 678 const struct sshbuf *shared_secret, u_char **keyp)
543{ 679{
544 Buffer b; 680 struct kex *kex = ssh->kex;
545 struct ssh_digest_ctx *hashctx; 681 struct ssh_digest_ctx *hashctx = NULL;
546 char c = id; 682 char c = id;
547 u_int have; 683 u_int have;
548 size_t mdsz; 684 size_t mdsz;
549 u_char *digest; 685 u_char *digest;
686 int r;
550 687
551 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) 688 if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
552 fatal("bad kex md size %zu", mdsz); 689 return SSH_ERR_INVALID_ARGUMENT;
553 digest = xmalloc(roundup(need, mdsz)); 690 if ((digest = calloc(1, roundup(need, mdsz))) == NULL) {
554 691 r = SSH_ERR_ALLOC_FAIL;
555 buffer_init(&b); 692 goto out;
556 buffer_append(&b, shared_secret, slen); 693 }
557 694
558 /* K1 = HASH(K || H || "A" || session_id) */ 695 /* K1 = HASH(K || H || "A" || session_id) */
559 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) 696 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
560 fatal("%s: ssh_digest_start failed", __func__); 697 ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
561 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
562 ssh_digest_update(hashctx, hash, hashlen) != 0 || 698 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
563 ssh_digest_update(hashctx, &c, 1) != 0 || 699 ssh_digest_update(hashctx, &c, 1) != 0 ||
564 ssh_digest_update(hashctx, kex->session_id, 700 ssh_digest_update(hashctx, kex->session_id,
565 kex->session_id_len) != 0) 701 kex->session_id_len) != 0 ||
566 fatal("%s: ssh_digest_update failed", __func__); 702 ssh_digest_final(hashctx, digest, mdsz) != 0) {
567 if (ssh_digest_final(hashctx, digest, mdsz) != 0) 703 r = SSH_ERR_LIBCRYPTO_ERROR;
568 fatal("%s: ssh_digest_final failed", __func__); 704 goto out;
705 }
569 ssh_digest_free(hashctx); 706 ssh_digest_free(hashctx);
707 hashctx = NULL;
570 708
571 /* 709 /*
572 * expand key: 710 * expand key:
@@ -574,107 +712,115 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
574 * Key = K1 || K2 || ... || Kn 712 * Key = K1 || K2 || ... || Kn
575 */ 713 */
576 for (have = mdsz; need > have; have += mdsz) { 714 for (have = mdsz; need > have; have += mdsz) {
577 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) 715 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL ||
578 fatal("%s: ssh_digest_start failed", __func__); 716 ssh_digest_update_buffer(hashctx, shared_secret) != 0 ||
579 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
580 ssh_digest_update(hashctx, hash, hashlen) != 0 || 717 ssh_digest_update(hashctx, hash, hashlen) != 0 ||
581 ssh_digest_update(hashctx, digest, have) != 0) 718 ssh_digest_update(hashctx, digest, have) != 0 ||
582 fatal("%s: ssh_digest_update failed", __func__); 719 ssh_digest_final(hashctx, digest + have, mdsz) != 0) {
583 if (ssh_digest_final(hashctx, digest + have, mdsz) != 0) 720 r = SSH_ERR_LIBCRYPTO_ERROR;
584 fatal("%s: ssh_digest_final failed", __func__); 721 goto out;
722 }
585 ssh_digest_free(hashctx); 723 ssh_digest_free(hashctx);
724 hashctx = NULL;
586 } 725 }
587 buffer_free(&b);
588#ifdef DEBUG_KEX 726#ifdef DEBUG_KEX
589 fprintf(stderr, "key '%c'== ", c); 727 fprintf(stderr, "key '%c'== ", c);
590 dump_digest("key", digest, need); 728 dump_digest("key", digest, need);
591#endif 729#endif
592 return digest; 730 *keyp = digest;
731 digest = NULL;
732 r = 0;
733 out:
734 if (digest)
735 free(digest);
736 ssh_digest_free(hashctx);
737 return r;
593} 738}
594 739
595Newkeys *current_keys[MODE_MAX];
596
597#define NKEYS 6 740#define NKEYS 6
598void 741int
599kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, 742kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
600 const u_char *shared_secret, u_int slen) 743 const struct sshbuf *shared_secret)
601{ 744{
745 struct kex *kex = ssh->kex;
602 u_char *keys[NKEYS]; 746 u_char *keys[NKEYS];
603 u_int i, mode, ctos; 747 u_int i, j, mode, ctos;
748 int r;
604 749
605 for (i = 0; i < NKEYS; i++) { 750 for (i = 0; i < NKEYS; i++) {
606 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, 751 if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen,
607 shared_secret, slen); 752 shared_secret, &keys[i])) != 0) {
753 for (j = 0; j < i; j++)
754 free(keys[j]);
755 return r;
756 }
608 } 757 }
609
610 debug2("kex_derive_keys");
611 for (mode = 0; mode < MODE_MAX; mode++) { 758 for (mode = 0; mode < MODE_MAX; mode++) {
612 current_keys[mode] = kex->newkeys[mode];
613 kex->newkeys[mode] = NULL;
614 ctos = (!kex->server && mode == MODE_OUT) || 759 ctos = (!kex->server && mode == MODE_OUT) ||
615 (kex->server && mode == MODE_IN); 760 (kex->server && mode == MODE_IN);
616 current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; 761 kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1];
617 current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; 762 kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3];
618 current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; 763 kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5];
619 } 764 }
765 return 0;
620} 766}
621 767
622#ifdef WITH_OPENSSL 768#ifdef WITH_OPENSSL
623void 769int
624kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret) 770kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
771 const BIGNUM *secret)
625{ 772{
626 Buffer shared_secret; 773 struct sshbuf *shared_secret;
627 774 int r;
628 buffer_init(&shared_secret); 775
629 buffer_put_bignum2(&shared_secret, secret); 776 if ((shared_secret = sshbuf_new()) == NULL)
630 kex_derive_keys(kex, hash, hashlen, 777 return SSH_ERR_ALLOC_FAIL;
631 buffer_ptr(&shared_secret), buffer_len(&shared_secret)); 778 if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
632 buffer_free(&shared_secret); 779 r = kex_derive_keys(ssh, hash, hashlen, shared_secret);
780 sshbuf_free(shared_secret);
781 return r;
633} 782}
634#endif 783#endif
635 784
636Newkeys *
637kex_get_newkeys(int mode)
638{
639 Newkeys *ret;
640
641 ret = current_keys[mode];
642 current_keys[mode] = NULL;
643 return ret;
644}
645
646#ifdef WITH_SSH1 785#ifdef WITH_SSH1
647void 786int
648derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, 787derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
649 u_int8_t cookie[8], u_int8_t id[16]) 788 u_int8_t cookie[8], u_int8_t id[16])
650{ 789{
651 u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH]; 790 u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
652 int len; 791 struct ssh_digest_ctx *hashctx = NULL;
653 struct ssh_digest_ctx *hashctx; 792 size_t hlen, slen;
654 793 int r;
655 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) 794
656 fatal("%s: ssh_digest_start", __func__); 795 hlen = BN_num_bytes(host_modulus);
657 796 slen = BN_num_bytes(server_modulus);
658 len = BN_num_bytes(host_modulus); 797 if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
659 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 798 slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
660 fatal("%s: bad host modulus (len %d)", __func__, len); 799 return SSH_ERR_KEY_BITS_MISMATCH;
661 BN_bn2bin(host_modulus, nbuf); 800 if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
662 if (ssh_digest_update(hashctx, nbuf, len) != 0) 801 BN_bn2bin(server_modulus, sbuf) <= 0) {
663 fatal("%s: ssh_digest_update failed", __func__); 802 r = SSH_ERR_LIBCRYPTO_ERROR;
664 803 goto out;
665 len = BN_num_bytes(server_modulus); 804 }
666 if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) 805 if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
667 fatal("%s: bad server modulus (len %d)", __func__, len); 806 r = SSH_ERR_ALLOC_FAIL;
668 BN_bn2bin(server_modulus, nbuf); 807 goto out;
669 if (ssh_digest_update(hashctx, nbuf, len) != 0 || 808 }
670 ssh_digest_update(hashctx, cookie, 8) != 0) 809 if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
671 fatal("%s: ssh_digest_update failed", __func__); 810 ssh_digest_update(hashctx, sbuf, slen) != 0 ||
672 if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) 811 ssh_digest_update(hashctx, cookie, 8) != 0 ||
673 fatal("%s: ssh_digest_final failed", __func__); 812 ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
813 r = SSH_ERR_LIBCRYPTO_ERROR;
814 goto out;
815 }
674 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); 816 memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
675 817 r = 0;
676 explicit_bzero(nbuf, sizeof(nbuf)); 818 out:
819 ssh_digest_free(hashctx);
820 explicit_bzero(hbuf, sizeof(hbuf));
821 explicit_bzero(sbuf, sizeof(sbuf));
677 explicit_bzero(obuf, sizeof(obuf)); 822 explicit_bzero(obuf, sizeof(obuf));
823 return r;
678} 824}
679#endif 825#endif
680 826
@@ -682,16 +828,7 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
682void 828void
683dump_digest(char *msg, u_char *digest, int len) 829dump_digest(char *msg, u_char *digest, int len)
684{ 830{
685 int i;
686
687 fprintf(stderr, "%s\n", msg); 831 fprintf(stderr, "%s\n", msg);
688 for (i = 0; i < len; i++) { 832 sshbuf_dump_data(digest, len, stderr);
689 fprintf(stderr, "%02x", digest[i]);
690 if (i%32 == 31)
691 fprintf(stderr, "\n");
692 else if (i%8 == 7)
693 fprintf(stderr, " ");
694 }
695 fprintf(stderr, "\n");
696} 833}
697#endif 834#endif