1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-13 00:57:33 -05:00

Mitigation for VU#958563: When using a CBC-mode server-to-client cipher

under SSH-2, don't risk looking at the length field of an incoming packet
until we've successfully MAC'ed the packet.

This requires a change to the MAC mechanics so that we can calculate MACs
incrementally, and output a MAC for the packet so far while still being
able to add more data to the packet later.

[originally from svn r8334]
This commit is contained in:
Ben Harris
2008-11-26 12:49:25 +00:00
parent e5eabee3c0
commit 86c183f8e8
4 changed files with 253 additions and 89 deletions

View File

@ -227,7 +227,7 @@ const struct ssh_hash ssh_sha1 = {
static void *sha1_make_context(void)
{
return snewn(2, SHA_State);
return snewn(3, SHA_State);
}
static void sha1_free_context(void *handle)
@ -266,33 +266,61 @@ static void sha1_key_buggy(void *handle, unsigned char *key)
sha1_key_internal(handle, key, 16);
}
static void sha1_do_hmac(void *handle, unsigned char *blk, int len,
unsigned long seq, unsigned char *hmac)
static void hmacsha1_start(void *handle)
{
SHA_State *keys = (SHA_State *)handle;
keys[2] = keys[0]; /* structure copy */
}
static void hmacsha1_bytes(void *handle, unsigned char const *blk, int len)
{
SHA_State *keys = (SHA_State *)handle;
SHA_Bytes(&keys[2], (void *)blk, len);
}
static void hmacsha1_genresult(void *handle, unsigned char *hmac)
{
SHA_State *keys = (SHA_State *)handle;
SHA_State s;
unsigned char intermediate[20];
intermediate[0] = (unsigned char) ((seq >> 24) & 0xFF);
intermediate[1] = (unsigned char) ((seq >> 16) & 0xFF);
intermediate[2] = (unsigned char) ((seq >> 8) & 0xFF);
intermediate[3] = (unsigned char) ((seq) & 0xFF);
s = keys[0]; /* structure copy */
SHA_Bytes(&s, intermediate, 4);
SHA_Bytes(&s, blk, len);
s = keys[2]; /* structure copy */
SHA_Final(&s, intermediate);
s = keys[1]; /* structure copy */
SHA_Bytes(&s, intermediate, 20);
SHA_Final(&s, hmac);
}
static void sha1_do_hmac(void *handle, unsigned char *blk, int len,
unsigned long seq, unsigned char *hmac)
{
unsigned char seqbuf[4];
seqbuf[0] = (unsigned char) ((seq >> 24) & 0xFF);
seqbuf[1] = (unsigned char) ((seq >> 16) & 0xFF);
seqbuf[2] = (unsigned char) ((seq >> 8) & 0xFF);
seqbuf[3] = (unsigned char) ((seq) & 0xFF);
hmacsha1_start(handle);
hmacsha1_bytes(handle, seqbuf, 4);
hmacsha1_bytes(handle, blk, len);
hmacsha1_genresult(handle, hmac);
}
static void sha1_generate(void *handle, unsigned char *blk, int len,
unsigned long seq)
{
sha1_do_hmac(handle, blk, len, seq, blk + len);
}
static int hmacsha1_verresult(void *handle, unsigned char const *hmac)
{
unsigned char correct[20];
hmacsha1_genresult(handle, correct);
return !memcmp(correct, hmac, 20);
}
static int sha1_verify(void *handle, unsigned char *blk, int len,
unsigned long seq)
{
@ -301,6 +329,13 @@ static int sha1_verify(void *handle, unsigned char *blk, int len,
return !memcmp(correct, blk + len, 20);
}
static void hmacsha1_96_genresult(void *handle, unsigned char *hmac)
{
unsigned char full[20];
hmacsha1_genresult(handle, full);
memcpy(hmac, full, 12);
}
static void sha1_96_generate(void *handle, unsigned char *blk, int len,
unsigned long seq)
{
@ -309,6 +344,13 @@ static void sha1_96_generate(void *handle, unsigned char *blk, int len,
memcpy(blk + len, full, 12);
}
static int hmacsha1_96_verresult(void *handle, unsigned char const *hmac)
{
unsigned char correct[20];
hmacsha1_genresult(handle, correct);
return !memcmp(correct, hmac, 12);
}
static int sha1_96_verify(void *handle, unsigned char *blk, int len,
unsigned long seq)
{
@ -333,6 +375,7 @@ void hmac_sha1_simple(void *key, int keylen, void *data, int datalen,
const struct ssh_mac ssh_hmac_sha1 = {
sha1_make_context, sha1_free_context, sha1_key,
sha1_generate, sha1_verify,
hmacsha1_start, hmacsha1_bytes, hmacsha1_genresult, hmacsha1_verresult,
"hmac-sha1",
20,
"HMAC-SHA1"
@ -341,6 +384,8 @@ const struct ssh_mac ssh_hmac_sha1 = {
const struct ssh_mac ssh_hmac_sha1_96 = {
sha1_make_context, sha1_free_context, sha1_key,
sha1_96_generate, sha1_96_verify,
hmacsha1_start, hmacsha1_bytes,
hmacsha1_96_genresult, hmacsha1_96_verresult,
"hmac-sha1-96",
12,
"HMAC-SHA1-96"
@ -349,6 +394,7 @@ const struct ssh_mac ssh_hmac_sha1_96 = {
const struct ssh_mac ssh_hmac_sha1_buggy = {
sha1_make_context, sha1_free_context, sha1_key_buggy,
sha1_generate, sha1_verify,
hmacsha1_start, hmacsha1_bytes, hmacsha1_genresult, hmacsha1_verresult,
"hmac-sha1",
20,
"bug-compatible HMAC-SHA1"
@ -357,6 +403,8 @@ const struct ssh_mac ssh_hmac_sha1_buggy = {
const struct ssh_mac ssh_hmac_sha1_96_buggy = {
sha1_make_context, sha1_free_context, sha1_key_buggy,
sha1_96_generate, sha1_96_verify,
hmacsha1_start, hmacsha1_bytes,
hmacsha1_96_genresult, hmacsha1_96_verresult,
"hmac-sha1-96",
12,
"bug-compatible HMAC-SHA1-96"