mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-12 08:43:53 -05:00
Centralised HMAC implementation.
This replaces all the separate HMAC-implementing wrappers in the various source files implementing the underlying hashes. The new HMAC code also correctly handles the case of a key longer than the underlying hash's block length, by replacing it with its own hash. This means I can reinstate the test vectors in RFC 6234 which exercise that case, which I didn't add to cryptsuite before because they'd have failed. It also allows me to remove the ad-hoc code at the call site in cproxy.c which turns out to have been doing the same thing - I think that must have been the only call site where the question came up (since MAC keys invented by the main SSH-2 BPP are always shorter than that).
This commit is contained in:
114
sshmd5.c
114
sshmd5.c
@ -273,117 +273,3 @@ static void md5_final(ssh_hash *hash, unsigned char *output)
|
||||
const ssh_hashalg ssh_md5 = {
|
||||
md5_new, md5_copy, md5_final, md5_free, 16, "MD5"
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* The above is the MD5 algorithm itself. Now we implement the
|
||||
* HMAC wrapper on it.
|
||||
*
|
||||
* Some of these functions are exported directly, because they are
|
||||
* useful elsewhere (SOCKS5 CHAP authentication uses HMAC-MD5).
|
||||
*/
|
||||
|
||||
struct hmacmd5_context {
|
||||
struct MD5Context md5[3];
|
||||
ssh2_mac mac;
|
||||
};
|
||||
|
||||
struct hmacmd5_context *hmacmd5_make_context(void)
|
||||
{
|
||||
struct hmacmd5_context *ctx = snew(struct hmacmd5_context);
|
||||
BinarySink_DELEGATE_INIT(&ctx->mac, &ctx->md5[2]);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static ssh2_mac *hmacmd5_ssh2_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||
{
|
||||
struct hmacmd5_context *ctx = hmacmd5_make_context();
|
||||
ctx->mac.vt = alg;
|
||||
return &ctx->mac;
|
||||
}
|
||||
|
||||
void hmacmd5_free_context(struct hmacmd5_context *ctx)
|
||||
{
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void hmacmd5_ssh2_free(ssh2_mac *mac)
|
||||
{
|
||||
struct hmacmd5_context *ctx =
|
||||
container_of(mac, struct hmacmd5_context, mac);
|
||||
hmacmd5_free_context(ctx);
|
||||
}
|
||||
|
||||
void hmacmd5_key(struct hmacmd5_context *ctx, void const *keyv, int len)
|
||||
{
|
||||
unsigned char foo[64];
|
||||
unsigned char const *key = (unsigned char const *)keyv;
|
||||
int i;
|
||||
|
||||
memset(foo, 0x36, 64);
|
||||
for (i = 0; i < len && i < 64; i++)
|
||||
foo[i] ^= key[i];
|
||||
MD5Init(&ctx->md5[0]);
|
||||
put_data(&ctx->md5[0], foo, 64);
|
||||
|
||||
memset(foo, 0x5C, 64);
|
||||
for (i = 0; i < len && i < 64; i++)
|
||||
foo[i] ^= key[i];
|
||||
MD5Init(&ctx->md5[1]);
|
||||
put_data(&ctx->md5[1], foo, 64);
|
||||
|
||||
smemclr(foo, 64); /* burn the evidence */
|
||||
}
|
||||
|
||||
static void hmacmd5_ssh2_setkey(ssh2_mac *mac, ptrlen key)
|
||||
{
|
||||
struct hmacmd5_context *ctx =
|
||||
container_of(mac, struct hmacmd5_context, mac);
|
||||
hmacmd5_key(ctx, key.ptr, key.len);
|
||||
}
|
||||
|
||||
static void hmacmd5_start(ssh2_mac *mac)
|
||||
{
|
||||
struct hmacmd5_context *ctx =
|
||||
container_of(mac, struct hmacmd5_context, mac);
|
||||
|
||||
ctx->md5[2] = ctx->md5[0]; /* structure copy */
|
||||
BinarySink_COPIED(&ctx->md5[2]);
|
||||
}
|
||||
|
||||
static void hmacmd5_genresult(ssh2_mac *mac, unsigned char *hmac)
|
||||
{
|
||||
struct hmacmd5_context *ctx =
|
||||
container_of(mac, struct hmacmd5_context, mac);
|
||||
struct MD5Context s;
|
||||
unsigned char intermediate[16];
|
||||
|
||||
s = ctx->md5[2]; /* structure copy */
|
||||
BinarySink_COPIED(&s);
|
||||
MD5Final(intermediate, &s);
|
||||
s = ctx->md5[1]; /* structure copy */
|
||||
BinarySink_COPIED(&s);
|
||||
put_data(&s, intermediate, 16);
|
||||
MD5Final(hmac, &s);
|
||||
smemclr(intermediate, sizeof(intermediate));
|
||||
}
|
||||
|
||||
void hmacmd5_do_hmac(struct hmacmd5_context *ctx,
|
||||
const void *blk, int len, unsigned char *hmac)
|
||||
{
|
||||
ssh2_mac_start(&ctx->mac);
|
||||
put_data(&ctx->mac, blk, len);
|
||||
ssh2_mac_genresult(&ctx->mac, hmac);
|
||||
}
|
||||
|
||||
static const char *hmacmd5_text_name(ssh2_mac *mac)
|
||||
{
|
||||
return "HMAC-MD5";
|
||||
}
|
||||
|
||||
const ssh2_macalg ssh_hmac_md5 = {
|
||||
hmacmd5_ssh2_new, hmacmd5_ssh2_free, hmacmd5_ssh2_setkey,
|
||||
hmacmd5_start, hmacmd5_genresult, hmacmd5_text_name,
|
||||
"hmac-md5", "hmac-md5-etm@openssh.com",
|
||||
16, 16,
|
||||
};
|
||||
|
Reference in New Issue
Block a user