summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/kex.c b/kex.c
index 8cd851d23..47983f8d9 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.64 2005/07/25 11:59:39 markus Exp $"); 26RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $");
27 27
28#include <openssl/crypto.h> 28#include <openssl/crypto.h>
29 29
@@ -298,21 +298,27 @@ choose_kex(Kex *k, char *client, char *server)
298 fatal("no kex alg"); 298 fatal("no kex alg");
299 if (strcmp(k->name, KEX_DH1) == 0) { 299 if (strcmp(k->name, KEX_DH1) == 0) {
300 k->kex_type = KEX_DH_GRP1_SHA1; 300 k->kex_type = KEX_DH_GRP1_SHA1;
301 k->evp_md = EVP_sha1();
301 } else if (strcmp(k->name, KEX_DH14) == 0) { 302 } else if (strcmp(k->name, KEX_DH14) == 0) {
302 k->kex_type = KEX_DH_GRP14_SHA1; 303 k->kex_type = KEX_DH_GRP14_SHA1;
303 } else if (strcmp(k->name, KEX_DHGEX) == 0) { 304 k->evp_md = EVP_sha1();
305 } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
304 k->kex_type = KEX_DH_GEX_SHA1; 306 k->kex_type = KEX_DH_GEX_SHA1;
307 k->evp_md = EVP_sha1();
305#ifdef GSSAPI 308#ifdef GSSAPI
306 } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID, 309 } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
307 sizeof(KEX_GSS_GEX_SHA1_ID)-1) == 0) { 310 sizeof(KEX_GSS_GEX_SHA1_ID)-1) == 0) {
308 k->kex_type = KEX_GSS_GEX_SHA1; 311 k->kex_type = KEX_GSS_GEX_SHA1;
309 } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID, 312 k->evp_md = EVP_sha1();
313 } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
310 sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) { 314 sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) {
311 k->kex_type = KEX_GSS_GRP1_SHA1; 315 k->kex_type = KEX_GSS_GRP1_SHA1;
316 k->evp_md = EVP_sha1();
312#endif 317#endif
313 } else 318 } else
314 fatal("bad kex alg %s", k->name); 319 fatal("bad kex alg %s", k->name);
315} 320}
321
316static void 322static void
317choose_hostkeyalg(Kex *k, char *client, char *server) 323choose_hostkeyalg(Kex *k, char *client, char *server)
318{ 324{
@@ -416,28 +422,28 @@ kex_choose_conf(Kex *kex)
416} 422}
417 423
418static u_char * 424static u_char *
419derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) 425derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
426 BIGNUM *shared_secret)
420{ 427{
421 Buffer b; 428 Buffer b;
422 const EVP_MD *evp_md = EVP_sha1();
423 EVP_MD_CTX md; 429 EVP_MD_CTX md;
424 char c = id; 430 char c = id;
425 u_int have; 431 u_int have;
426 int mdsz = EVP_MD_size(evp_md); 432 int mdsz;
427 u_char *digest; 433 u_char *digest;
428 434
429 if (mdsz < 0) 435 if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
430 fatal("derive_key: mdsz < 0"); 436 fatal("bad kex md size %d", mdsz);
431 digest = xmalloc(roundup(need, mdsz)); 437 digest = xmalloc(roundup(need, mdsz));
432 438
433 buffer_init(&b); 439 buffer_init(&b);
434 buffer_put_bignum2(&b, shared_secret); 440 buffer_put_bignum2(&b, shared_secret);
435 441
436 /* K1 = HASH(K || H || "A" || session_id) */ 442 /* K1 = HASH(K || H || "A" || session_id) */
437 EVP_DigestInit(&md, evp_md); 443 EVP_DigestInit(&md, kex->evp_md);
438 if (!(datafellows & SSH_BUG_DERIVEKEY)) 444 if (!(datafellows & SSH_BUG_DERIVEKEY))
439 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 445 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
440 EVP_DigestUpdate(&md, hash, mdsz); 446 EVP_DigestUpdate(&md, hash, hashlen);
441 EVP_DigestUpdate(&md, &c, 1); 447 EVP_DigestUpdate(&md, &c, 1);
442 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); 448 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
443 EVP_DigestFinal(&md, digest, NULL); 449 EVP_DigestFinal(&md, digest, NULL);
@@ -448,10 +454,10 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret)
448 * Key = K1 || K2 || ... || Kn 454 * Key = K1 || K2 || ... || Kn
449 */ 455 */
450 for (have = mdsz; need > have; have += mdsz) { 456 for (have = mdsz; need > have; have += mdsz) {
451 EVP_DigestInit(&md, evp_md); 457 EVP_DigestInit(&md, kex->evp_md);
452 if (!(datafellows & SSH_BUG_DERIVEKEY)) 458 if (!(datafellows & SSH_BUG_DERIVEKEY))
453 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 459 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
454 EVP_DigestUpdate(&md, hash, mdsz); 460 EVP_DigestUpdate(&md, hash, hashlen);
455 EVP_DigestUpdate(&md, digest, have); 461 EVP_DigestUpdate(&md, digest, have);
456 EVP_DigestFinal(&md, digest + have, NULL); 462 EVP_DigestFinal(&md, digest + have, NULL);
457 } 463 }
@@ -467,13 +473,15 @@ Newkeys *current_keys[MODE_MAX];
467 473
468#define NKEYS 6 474#define NKEYS 6
469void 475void
470kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) 476kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
471{ 477{
472 u_char *keys[NKEYS]; 478 u_char *keys[NKEYS];
473 u_int i, mode, ctos; 479 u_int i, mode, ctos;
474 480
475 for (i = 0; i < NKEYS; i++) 481 for (i = 0; i < NKEYS; i++) {
476 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); 482 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
483 shared_secret);
484 }
477 485
478 debug2("kex_derive_keys"); 486 debug2("kex_derive_keys");
479 for (mode = 0; mode < MODE_MAX; mode++) { 487 for (mode = 0; mode < MODE_MAX; mode++) {