Commit 15083318 authored by Niels Möller's avatar Niels Möller
Browse files

* keyexchange.c (kex_make_key): Fixed key expansion.

Rev: src/keyexchange.c:1.40
parent 5c2511f5
...@@ -330,7 +330,7 @@ static struct lsh_string *kex_make_key(struct hash_instance *secret, ...@@ -330,7 +330,7 @@ static struct lsh_string *kex_make_key(struct hash_instance *secret,
key = lsh_string_alloc(key_length); key = lsh_string_alloc(key_length);
debug("Constructing session key of type %d\n", type); debug("\nConstructing session key of type %d\n", type);
if (!key_length) if (!key_length)
return key; return key;
...@@ -342,44 +342,53 @@ static struct lsh_string *kex_make_key(struct hash_instance *secret, ...@@ -342,44 +342,53 @@ static struct lsh_string *kex_make_key(struct hash_instance *secret,
HASH_UPDATE(hash, session_id->length, session_id->data); HASH_UPDATE(hash, session_id->length, session_id->data);
HASH_DIGEST(hash, digest); HASH_DIGEST(hash, digest);
#if 0 /* Is one digest large anough? */
/* This is the simplest special case */
if (key_length <= hash->hash_size) if (key_length <= hash->hash_size)
memcpy(key->data, digest, key_length); memcpy(key->data, digest, key_length);
#endif
{ else
/* FIXME: This code could probably be simplified a little, but {
* it should do for now. */ unsigned left = key_length;
UINT8 *dst = key->data;
unsigned key_ofs, max;
KILL(hash);
max = MIN(key_length, hash->hash_size); hash = HASH_COPY(secret);
memcpy(key->data, digest, max); while (1)
if (max != key_length) {
{ /* The n:th time we enter this loop, digest holds K_n (using
struct hash_instance *prev_hash = HASH_COPY(secret); * the notation of section 5.2 of the ssh "transport"
* specification), and hash contains the hash state
* corresponding to
*
* H(secret | K_1 | ... | K_{n-1}) */
struct hash_instance *tmp;
/* Append digest to the key data. */
memcpy(dst, digest, hash->hash_size);
dst += hash->hash_size;
left -= hash->hash_size;
/* And to the hash state */
HASH_UPDATE(hash, hash->hash_size, digest);
if (left <= hash->hash_size)
break;
key_ofs = max; /* Get a new digest, without disturbing the hash object (as
while (key_length - key_ofs > 0) * we'll need it again). We use another temporary hash for
{ * extracting the digest. */
KILL(hash);
tmp = HASH_COPY(hash);
hash = prev_hash; HASH_DIGEST(tmp, digest);
HASH_UPDATE(hash, hash->hash_size, digest); KILL(tmp);
}
KILL(prev_hash);
prev_hash = HASH_COPY(hash); /* Get the final digest, and use some of it for the key. */
HASH_DIGEST(hash, digest); HASH_DIGEST(hash, digest);
memcpy(dst, digest, left);
max = MIN(key_length - key_ofs, hash->hash_size); }
memcpy(key->data + key_ofs, digest, max);
key_ofs += max;
}
KILL(prev_hash);
}
}
KILL(hash); KILL(hash);
debug("Expanded key: "); debug("Expanded key: ");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment