summaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-11-05 15:19:35 +1100
committerDamien Miller <djm@mindrot.org>2005-11-05 15:19:35 +1100
commit19bb3a57f88adc789d61964fcb8f50165026b322 (patch)
treeba18e185c014c1da12ce4422a7e7bad9e71725f5 /kex.c
parent24ecf612614d83622d9777349b4ecd21ee22bb2a (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.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/kex.c b/kex.c
index 5dce335fe..cd71be9ca 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
@@ -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
304static void 308static void
305choose_hostkeyalg(Kex *k, char *client, char *server) 309choose_hostkeyalg(Kex *k, char *client, char *server)
306{ 310{
@@ -404,28 +408,28 @@ kex_choose_conf(Kex *kex)
404} 408}
405 409
406static u_char * 410static u_char *
407derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) 411derive_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
457void 461void
458kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) 462kex_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++) {