mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Add an extra HMAC constructor function.
This takes a plain ssh_hashalg, and constructs the most natural kind of HMAC wrapper around it, taking its key length and output length to be the hash's output length. In other words, it converts SHA-foo into exactly the thing usually called HMAC-SHA-foo. It does it by constructing a new ssh2_macalg vtable, and including it in the same memory allocation as the actual hash object. That's the first time in PuTTY I've done it this way. Nothing yet uses this, but a new piece of code is about to.
This commit is contained in:
parent
c96fb0f10a
commit
dea3ddca05
@ -18,9 +18,10 @@ struct hmac_extra {
|
|||||||
const char *suffix, *annotation;
|
const char *suffix, *annotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssh2_mac *hmac_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
/* Most of hmac_new(). Takes the actual 'struct hmac' as a parameter,
|
||||||
|
* because sometimes it will have been allocated in a special way. */
|
||||||
|
static ssh2_mac *hmac_new_inner(struct hmac *ctx, const ssh2_macalg *alg)
|
||||||
{
|
{
|
||||||
struct hmac *ctx = snew(struct hmac);
|
|
||||||
const struct hmac_extra *extra = (const struct hmac_extra *)alg->extra;
|
const struct hmac_extra *extra = (const struct hmac_extra *)alg->extra;
|
||||||
|
|
||||||
ctx->h_outer = ssh_hash_new(extra->hashalg_base);
|
ctx->h_outer = ssh_hash_new(extra->hashalg_base);
|
||||||
@ -64,6 +65,11 @@ static ssh2_mac *hmac_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
|||||||
return &ctx->mac;
|
return &ctx->mac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssh2_mac *hmac_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||||
|
{
|
||||||
|
return hmac_new_inner(snew(struct hmac), alg); /* cipher isn't needed */
|
||||||
|
}
|
||||||
|
|
||||||
static void hmac_free(ssh2_mac *mac)
|
static void hmac_free(ssh2_mac *mac)
|
||||||
{
|
{
|
||||||
struct hmac *ctx = container_of(mac, struct hmac, mac);
|
struct hmac *ctx = container_of(mac, struct hmac, mac);
|
||||||
@ -277,3 +283,38 @@ const ssh2_macalg ssh_hmac_sha1_96_buggy = {
|
|||||||
.keylen = 16,
|
.keylen = 16,
|
||||||
.extra = &ssh_hmac_sha1_96_buggy_extra,
|
.extra = &ssh_hmac_sha1_96_buggy_extra,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ssh2_mac *hmac_new_from_hash(const ssh_hashalg *hash)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Construct a custom ssh2_macalg, derived directly from the
|
||||||
|
* provided hash vtable. It's included in the same memory
|
||||||
|
* allocation as the struct hmac, so that it all gets freed
|
||||||
|
* together.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct alloc {
|
||||||
|
struct hmac hmac;
|
||||||
|
ssh2_macalg alg;
|
||||||
|
struct hmac_extra extra;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct alloc *alloc = snew(struct alloc);
|
||||||
|
alloc->alg.new = hmac_new;
|
||||||
|
alloc->alg.free = hmac_free;
|
||||||
|
alloc->alg.setkey = hmac_key;
|
||||||
|
alloc->alg.start = hmac_start;
|
||||||
|
alloc->alg.genresult = hmac_genresult;
|
||||||
|
alloc->alg.next_message = nullmac_next_message;
|
||||||
|
alloc->alg.text_name = hmac_text_name;
|
||||||
|
alloc->alg.name = NULL;
|
||||||
|
alloc->alg.etm_name = NULL;
|
||||||
|
alloc->alg.len = hash->hlen;
|
||||||
|
alloc->alg.keylen = hash->hlen;
|
||||||
|
alloc->alg.extra = &alloc->extra;
|
||||||
|
alloc->extra.hashalg_base = hash;
|
||||||
|
alloc->extra.suffix = "";
|
||||||
|
alloc->extra.annotation = NULL;
|
||||||
|
|
||||||
|
return hmac_new_inner(&alloc->hmac, &alloc->alg);
|
||||||
|
}
|
||||||
|
5
ssh.h
5
ssh.h
@ -762,6 +762,11 @@ void nullmac_next_message(ssh2_mac *m);
|
|||||||
* string with a given key in the most obvious way. */
|
* string with a given key in the most obvious way. */
|
||||||
void mac_simple(const ssh2_macalg *alg, ptrlen key, ptrlen data, void *output);
|
void mac_simple(const ssh2_macalg *alg, ptrlen key, ptrlen data, void *output);
|
||||||
|
|
||||||
|
/* Constructor that makes an HMAC object given just a MAC. This object
|
||||||
|
* will have empty 'name' and 'etm_name' fields, so it's not suitable
|
||||||
|
* for use in SSH. It's used as a subroutine in RFC 6979. */
|
||||||
|
ssh2_mac *hmac_new_from_hash(const ssh_hashalg *hash);
|
||||||
|
|
||||||
struct ssh_hash {
|
struct ssh_hash {
|
||||||
const ssh_hashalg *vt;
|
const ssh_hashalg *vt;
|
||||||
BinarySink_DELEGATE_IMPLEMENTATION;
|
BinarySink_DELEGATE_IMPLEMENTATION;
|
||||||
|
Loading…
Reference in New Issue
Block a user