Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Commit

Permalink
Add support for HMAC-SHA-256 as an SSH-2 MAC algorithm ("hmac-sha2-256")
Browse files Browse the repository at this point in the history
as specified in RFC 6668.  This is not so much because I think it's 
necessary, but because scrypt uses HMAC-SHA-256 and once we've got it we 
may as well use it.

Code very closely derived from the HMAC-SHA-1 code.

Tested against OpenSSH 5.9p1 Debian-5ubuntu1.


git-svn-id: svn://svn.tartarus.org/sgt/putty@9759 cda61777-01e9-0310-a592-d414129be87e
  • Loading branch information
ben committed Feb 20, 2013
1 parent 3d4931c commit 055a8f7
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ static void ssh_channel_destroy(struct ssh_channel *c);
const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss };

const static struct ssh_mac *macs[] = {
&ssh_hmac_sha1, &ssh_hmac_sha1_96, &ssh_hmac_md5
&ssh_hmac_sha256, &ssh_hmac_sha1, &ssh_hmac_sha1_96, &ssh_hmac_md5
};
const static struct ssh_mac *buggymacs[] = {
&ssh_hmac_sha1_buggy, &ssh_hmac_sha1_96_buggy, &ssh_hmac_md5
Expand Down
1 change: 1 addition & 0 deletions ssh.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ extern const struct ssh_mac ssh_hmac_sha1;
extern const struct ssh_mac ssh_hmac_sha1_buggy;
extern const struct ssh_mac ssh_hmac_sha1_96;
extern const struct ssh_mac ssh_hmac_sha1_96_buggy;
extern const struct ssh_mac ssh_hmac_sha256;

void *aes_make_context(void);
void aes_free_context(void *handle);
Expand Down
110 changes: 110 additions & 0 deletions sshsh256.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,116 @@ const struct ssh_hash ssh_sha256 = {
sha256_init, sha256_bytes, sha256_final, 32, "SHA-256"
};

/* ----------------------------------------------------------------------
* The above is the SHA-256 algorithm itself. Now we implement the
* HMAC wrapper on it.
*/

static void *sha256_make_context(void)
{
return snewn(3, SHA256_State);
}

static void sha256_free_context(void *handle)
{
sfree(handle);
}

static void sha256_key_internal(void *handle, unsigned char *key, int len)
{
SHA256_State *keys = (SHA256_State *)handle;
unsigned char foo[64];
int i;

memset(foo, 0x36, 64);
for (i = 0; i < len && i < 64; i++)
foo[i] ^= key[i];
SHA256_Init(&keys[0]);
SHA256_Bytes(&keys[0], foo, 64);

memset(foo, 0x5C, 64);
for (i = 0; i < len && i < 64; i++)
foo[i] ^= key[i];
SHA256_Init(&keys[1]);
SHA256_Bytes(&keys[1], foo, 64);

smemclr(foo, 64); /* burn the evidence */
}

static void sha256_key(void *handle, unsigned char *key)
{
sha256_key_internal(handle, key, 32);
}

static void hmacsha256_start(void *handle)
{
SHA256_State *keys = (SHA256_State *)handle;

keys[2] = keys[0]; /* structure copy */
}

static void hmacsha256_bytes(void *handle, unsigned char const *blk, int len)
{
SHA256_State *keys = (SHA256_State *)handle;
SHA256_Bytes(&keys[2], (void *)blk, len);
}

static void hmacsha256_genresult(void *handle, unsigned char *hmac)
{
SHA256_State *keys = (SHA256_State *)handle;
SHA256_State s;
unsigned char intermediate[32];

s = keys[2]; /* structure copy */
SHA256_Final(&s, intermediate);
s = keys[1]; /* structure copy */
SHA256_Bytes(&s, intermediate, 32);
SHA256_Final(&s, hmac);
}

static void sha256_do_hmac(void *handle, unsigned char *blk, int len,
unsigned long seq, unsigned char *hmac)
{
unsigned char seqbuf[4];

PUT_32BIT_MSB_FIRST(seqbuf, seq);
hmacsha256_start(handle);
hmacsha256_bytes(handle, seqbuf, 4);
hmacsha256_bytes(handle, blk, len);
hmacsha256_genresult(handle, hmac);
}

static void sha256_generate(void *handle, unsigned char *blk, int len,
unsigned long seq)
{
sha256_do_hmac(handle, blk, len, seq, blk + len);
}

static int hmacsha256_verresult(void *handle, unsigned char const *hmac)
{
unsigned char correct[32];
hmacsha256_genresult(handle, correct);
return !memcmp(correct, hmac, 32);
}

static int sha256_verify(void *handle, unsigned char *blk, int len,
unsigned long seq)
{
unsigned char correct[32];
sha256_do_hmac(handle, blk, len, seq, correct);
return !memcmp(correct, blk + len, 32);
}

const struct ssh_mac ssh_hmac_sha256 = {
sha256_make_context, sha256_free_context, sha256_key,
sha256_generate, sha256_verify,
hmacsha256_start, hmacsha256_bytes,
hmacsha256_genresult, hmacsha256_verresult,
"hmac-sha2-256",
32,
"HMAC-SHA-256"
};

#ifdef TEST

#include <stdio.h>
Expand Down

0 comments on commit 055a8f7

Please sign in to comment.