diff options
author | Damien Miller <djm@mindrot.org> | 2005-11-05 15:19:35 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2005-11-05 15:19:35 +1100 |
commit | 19bb3a57f88adc789d61964fcb8f50165026b322 (patch) | |
tree | ba18e185c014c1da12ce4422a7e7bad9e71725f5 /kex.c | |
parent | 24ecf612614d83622d9777349b4ecd21ee22bb2a (diff) |
- djm@cvs.openbsd.org 2005/11/04 05:15:59
[kex.c kex.h kexdh.c kexdhc.c kexdhs.c kexgex.c kexgexc.c kexgexs.c]
remove hardcoded hash lengths in key exchange code, allowing
implementation of KEX methods with different hashes (e.g. SHA-256);
ok markus@ dtucker@ stevesk@
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 36 |
1 files changed, 21 insertions, 15 deletions
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: kex.c,v 1.64 2005/07/25 11:59:39 markus Exp $"); | 26 | RCSID("$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 | ||
@@ -294,13 +294,17 @@ choose_kex(Kex *k, char *client, char *server) | |||
294 | fatal("no kex alg"); | 294 | fatal("no kex alg"); |
295 | if (strcmp(k->name, KEX_DH1) == 0) { | 295 | if (strcmp(k->name, KEX_DH1) == 0) { |
296 | k->kex_type = KEX_DH_GRP1_SHA1; | 296 | k->kex_type = KEX_DH_GRP1_SHA1; |
297 | k->evp_md = EVP_sha1(); | ||
297 | } else if (strcmp(k->name, KEX_DH14) == 0) { | 298 | } else if (strcmp(k->name, KEX_DH14) == 0) { |
298 | k->kex_type = KEX_DH_GRP14_SHA1; | 299 | k->kex_type = KEX_DH_GRP14_SHA1; |
299 | } else if (strcmp(k->name, KEX_DHGEX) == 0) { | 300 | k->evp_md = EVP_sha1(); |
301 | } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) { | ||
300 | k->kex_type = KEX_DH_GEX_SHA1; | 302 | k->kex_type = KEX_DH_GEX_SHA1; |
303 | k->evp_md = EVP_sha1(); | ||
301 | } else | 304 | } else |
302 | fatal("bad kex alg %s", k->name); | 305 | fatal("bad kex alg %s", k->name); |
303 | } | 306 | } |
307 | |||
304 | static void | 308 | static void |
305 | choose_hostkeyalg(Kex *k, char *client, char *server) | 309 | choose_hostkeyalg(Kex *k, char *client, char *server) |
306 | { | 310 | { |
@@ -404,28 +408,28 @@ kex_choose_conf(Kex *kex) | |||
404 | } | 408 | } |
405 | 409 | ||
406 | static u_char * | 410 | static u_char * |
407 | derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) | 411 | derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, |
412 | BIGNUM *shared_secret) | ||
408 | { | 413 | { |
409 | Buffer b; | 414 | Buffer b; |
410 | const EVP_MD *evp_md = EVP_sha1(); | ||
411 | EVP_MD_CTX md; | 415 | EVP_MD_CTX md; |
412 | char c = id; | 416 | char c = id; |
413 | u_int have; | 417 | u_int have; |
414 | int mdsz = EVP_MD_size(evp_md); | 418 | int mdsz; |
415 | u_char *digest; | 419 | u_char *digest; |
416 | 420 | ||
417 | if (mdsz < 0) | 421 | if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) |
418 | fatal("derive_key: mdsz < 0"); | 422 | fatal("bad kex md size %d", mdsz); |
419 | digest = xmalloc(roundup(need, mdsz)); | 423 | digest = xmalloc(roundup(need, mdsz)); |
420 | 424 | ||
421 | buffer_init(&b); | 425 | buffer_init(&b); |
422 | buffer_put_bignum2(&b, shared_secret); | 426 | buffer_put_bignum2(&b, shared_secret); |
423 | 427 | ||
424 | /* K1 = HASH(K || H || "A" || session_id) */ | 428 | /* K1 = HASH(K || H || "A" || session_id) */ |
425 | EVP_DigestInit(&md, evp_md); | 429 | EVP_DigestInit(&md, kex->evp_md); |
426 | if (!(datafellows & SSH_BUG_DERIVEKEY)) | 430 | if (!(datafellows & SSH_BUG_DERIVEKEY)) |
427 | EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); | 431 | EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); |
428 | EVP_DigestUpdate(&md, hash, mdsz); | 432 | EVP_DigestUpdate(&md, hash, hashlen); |
429 | EVP_DigestUpdate(&md, &c, 1); | 433 | EVP_DigestUpdate(&md, &c, 1); |
430 | EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); | 434 | EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); |
431 | EVP_DigestFinal(&md, digest, NULL); | 435 | EVP_DigestFinal(&md, digest, NULL); |
@@ -436,10 +440,10 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) | |||
436 | * Key = K1 || K2 || ... || Kn | 440 | * Key = K1 || K2 || ... || Kn |
437 | */ | 441 | */ |
438 | for (have = mdsz; need > have; have += mdsz) { | 442 | for (have = mdsz; need > have; have += mdsz) { |
439 | EVP_DigestInit(&md, evp_md); | 443 | EVP_DigestInit(&md, kex->evp_md); |
440 | if (!(datafellows & SSH_BUG_DERIVEKEY)) | 444 | if (!(datafellows & SSH_BUG_DERIVEKEY)) |
441 | EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); | 445 | EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); |
442 | EVP_DigestUpdate(&md, hash, mdsz); | 446 | EVP_DigestUpdate(&md, hash, hashlen); |
443 | EVP_DigestUpdate(&md, digest, have); | 447 | EVP_DigestUpdate(&md, digest, have); |
444 | EVP_DigestFinal(&md, digest + have, NULL); | 448 | EVP_DigestFinal(&md, digest + have, NULL); |
445 | } | 449 | } |
@@ -455,13 +459,15 @@ Newkeys *current_keys[MODE_MAX]; | |||
455 | 459 | ||
456 | #define NKEYS 6 | 460 | #define NKEYS 6 |
457 | void | 461 | void |
458 | kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) | 462 | kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) |
459 | { | 463 | { |
460 | u_char *keys[NKEYS]; | 464 | u_char *keys[NKEYS]; |
461 | u_int i, mode, ctos; | 465 | u_int i, mode, ctos; |
462 | 466 | ||
463 | for (i = 0; i < NKEYS; i++) | 467 | for (i = 0; i < NKEYS; i++) { |
464 | keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); | 468 | keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, |
469 | shared_secret); | ||
470 | } | ||
465 | 471 | ||
466 | debug2("kex_derive_keys"); | 472 | debug2("kex_derive_keys"); |
467 | for (mode = 0; mode < MODE_MAX; mode++) { | 473 | for (mode = 0; mode < MODE_MAX; mode++) { |