mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Add support for HMAC-SHA-256 as an SSH-2 MAC algorithm ("hmac-sha2-256")
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. [originally from svn r9759]
This commit is contained in:
parent
3045a9ac8c
commit
8f3cc4a9bf
2
ssh.c
2
ssh.c
@ -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
|
||||
|
1
ssh.h
1
ssh.h
@ -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);
|
||||
|
110
sshsh256.c
110
sshsh256.c
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user