summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-04-04 23:46:07 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-04-04 23:46:07 +0000
commitbe2cc43c3ad65dc7af5bdd350eccecefa05c80ff (patch)
tree87743bbb2501bd579088303769f73c4f79fd0ad7 /kex.c
parent78c261ab4afa9236b54b51663eb35460d2fea635 (diff)
- markus@cvs.openbsd.org 2001/04/04 20:25:38
[channels.c channels.h clientloop.c kex.c kex.h serverloop.c sshconnect2.c sshd.c] more robust rekeying don't send channel data after rekeying is started.
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/kex.c b/kex.c
index ee1e17e02..da9c56eb0 100644
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kex.c,v 1.29 2001/04/04 14:34:58 markus Exp $"); 26RCSID("$OpenBSD: kex.c,v 1.30 2001/04/04 20:25:37 markus Exp $");
27 27
28#include <openssl/crypto.h> 28#include <openssl/crypto.h>
29 29
@@ -136,7 +136,7 @@ kex_finish(Kex *kex)
136 debug("waiting for SSH2_MSG_NEWKEYS"); 136 debug("waiting for SSH2_MSG_NEWKEYS");
137 packet_read_expect(&plen, SSH2_MSG_NEWKEYS); 137 packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
138 debug("SSH2_MSG_NEWKEYS received"); 138 debug("SSH2_MSG_NEWKEYS received");
139 kex->newkeys = 1; 139 kex->done = 1;
140 buffer_clear(&kex->peer); 140 buffer_clear(&kex->peer);
141 /* buffer_clear(&kex->my); */ 141 /* buffer_clear(&kex->my); */
142 kex->flags &= ~KEX_INIT_SENT; 142 kex->flags &= ~KEX_INIT_SENT;
@@ -153,6 +153,7 @@ kex_send_kexinit(Kex *kex)
153 debug("KEX_INIT_SENT"); 153 debug("KEX_INIT_SENT");
154 return; 154 return;
155 } 155 }
156 kex->done = 0;
156 packet_start(SSH2_MSG_KEXINIT); 157 packet_start(SSH2_MSG_KEXINIT);
157 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); 158 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
158 packet_send(); 159 packet_send();
@@ -187,7 +188,7 @@ kex_setup(char *proposal[PROPOSAL_MAX])
187 buffer_init(&kex->peer); 188 buffer_init(&kex->peer);
188 buffer_init(&kex->my); 189 buffer_init(&kex->my);
189 kex_prop2buf(&kex->my, proposal); 190 kex_prop2buf(&kex->my, proposal);
190 kex->newkeys = 0; 191 kex->done = 0;
191 192
192 kex_send_kexinit(kex); /* we start */ 193 kex_send_kexinit(kex); /* we start */
193 kex_clear_dispatch(); 194 kex_clear_dispatch();
@@ -307,10 +308,11 @@ kex_choose_conf(Kex *kex)
307 sprop=peer; 308 sprop=peer;
308 } 309 }
309 310
311 /* Algorithm Negotiation */
310 for (mode = 0; mode < MODE_MAX; mode++) { 312 for (mode = 0; mode < MODE_MAX; mode++) {
311 newkeys = xmalloc(sizeof(*newkeys)); 313 newkeys = xmalloc(sizeof(*newkeys));
312 memset(newkeys, 0, sizeof(*newkeys)); 314 memset(newkeys, 0, sizeof(*newkeys));
313 kex->keys[mode] = newkeys; 315 kex->newkeys[mode] = newkeys;
314 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); 316 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
315 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; 317 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
316 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; 318 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
@@ -329,7 +331,7 @@ kex_choose_conf(Kex *kex)
329 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); 331 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
330 need = 0; 332 need = 0;
331 for (mode = 0; mode < MODE_MAX; mode++) { 333 for (mode = 0; mode < MODE_MAX; mode++) {
332 newkeys = kex->keys[mode]; 334 newkeys = kex->newkeys[mode];
333 if (need < newkeys->enc.cipher->key_len) 335 if (need < newkeys->enc.cipher->key_len)
334 need = newkeys->enc.cipher->key_len; 336 need = newkeys->enc.cipher->key_len;
335 if (need < newkeys->enc.cipher->block_size) 337 if (need < newkeys->enc.cipher->block_size)
@@ -353,19 +355,24 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
353 char c = id; 355 char c = id;
354 int have; 356 int have;
355 int mdsz = evp_md->md_size; 357 int mdsz = evp_md->md_size;
356 u_char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz); 358 u_char *digest = xmalloc(roundup(need, mdsz));
357 359
358 buffer_init(&b); 360 buffer_init(&b);
359 buffer_put_bignum2(&b, shared_secret); 361 buffer_put_bignum2(&b, shared_secret);
360 362
363 /* K1 = HASH(K || H || "A" || session_id) */
361 EVP_DigestInit(&md, evp_md); 364 EVP_DigestInit(&md, evp_md);
362 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */ 365 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
363 EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */ 366 EVP_DigestUpdate(&md, hash, mdsz);
364 EVP_DigestUpdate(&md, &c, 1); /* key id */ 367 EVP_DigestUpdate(&md, &c, 1);
365 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); 368 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
366 EVP_DigestFinal(&md, digest, NULL); 369 EVP_DigestFinal(&md, digest, NULL);
367 370
368 /* expand */ 371 /*
372 * expand key:
373 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
374 * Key = K1 || K2 || ... || Kn
375 */
369 for (have = mdsz; need > have; have += mdsz) { 376 for (have = mdsz; need > have; have += mdsz) {
370 EVP_DigestInit(&md, evp_md); 377 EVP_DigestInit(&md, evp_md);
371 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 378 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
@@ -381,13 +388,12 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
381 return digest; 388 return digest;
382} 389}
383 390
384Newkeys *x_newkeys[MODE_MAX]; 391Newkeys *current_keys[MODE_MAX];
385 392
386#define NKEYS 6 393#define NKEYS 6
387void 394void
388kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) 395kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
389{ 396{
390 Newkeys *newkeys;
391 u_char *keys[NKEYS]; 397 u_char *keys[NKEYS];
392 int i, mode, ctos; 398 int i, mode, ctos;
393 399
@@ -396,19 +402,23 @@ kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
396 402
397 debug("kex_derive_keys"); 403 debug("kex_derive_keys");
398 for (mode = 0; mode < MODE_MAX; mode++) { 404 for (mode = 0; mode < MODE_MAX; mode++) {
399 newkeys = kex->keys[mode]; 405 current_keys[mode] = kex->newkeys[mode];
406 kex->newkeys[mode] = NULL;
400 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); 407 ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
401 newkeys->enc.iv = keys[ctos ? 0 : 1]; 408 current_keys[mode]->enc.iv = keys[ctos ? 0 : 1];
402 newkeys->enc.key = keys[ctos ? 2 : 3]; 409 current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
403 newkeys->mac.key = keys[ctos ? 4 : 5]; 410 current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
404 x_newkeys[mode] = newkeys;
405 } 411 }
406} 412}
407 413
408Newkeys * 414Newkeys *
409kex_get_newkeys(int mode) 415kex_get_newkeys(int mode)
410{ 416{
411 return x_newkeys[mode]; 417 Newkeys *ret;
418
419 ret = current_keys[mode];
420 current_keys[mode] = NULL;
421 return ret;
412} 422}
413 423
414#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) 424#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)