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,43 +342,52 @@ static struct lsh_string *kex_make_key(struct hash_instance *secret, ...@@ -342,43 +342,52 @@ 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
{
/* FIXME: This code could probably be simplified a little, but
* it should do for now. */
unsigned key_ofs, max; else
{
unsigned left = key_length;
UINT8 *dst = key->data;
max = MIN(key_length, hash->hash_size); KILL(hash);
hash = HASH_COPY(secret);
memcpy(key->data, digest, max); while (1)
if (max != key_length)
{ {
struct hash_instance *prev_hash = HASH_COPY(secret); /* The n:th time we enter this loop, digest holds K_n (using
* 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}) */
key_ofs = max; struct hash_instance *tmp;
while (key_length - key_ofs > 0)
{
KILL(hash);
hash = prev_hash; /* 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); HASH_UPDATE(hash, hash->hash_size, digest);
KILL(prev_hash); if (left <= hash->hash_size)
prev_hash = HASH_COPY(hash); break;
HASH_DIGEST(hash, digest);
max = MIN(key_length - key_ofs, hash->hash_size); /* Get a new digest, without disturbing the hash object (as
memcpy(key->data + key_ofs, digest, max); * we'll need it again). We use another temporary hash for
* extracting the digest. */
key_ofs += max; tmp = HASH_COPY(hash);
} HASH_DIGEST(tmp, digest);
KILL(prev_hash); KILL(tmp);
} }
/* Get the final digest, and use some of it for the key. */
HASH_DIGEST(hash, digest);
memcpy(dst, digest, left);
} }
KILL(hash); KILL(hash);
......
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