1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

Make ssh_hash and ssh_mac expose a BinarySink.

Just as I did a few commits ago with the low-level SHA_Bytes type
functions, the ssh_hash and ssh_mac abstract types now no longer have
a direct foo->bytes() update method at all. Instead, each one has a
foo->sink() function that returns a BinarySink with the same lifetime
as the hash context, and then the caller can feed data into that in
the usual way.

This lets me get rid of a couple more duplicate marshalling routines
in ssh.c: hash_string(), hash_uint32(), hash_mpint().
This commit is contained in:
Simon Tatham 2018-05-24 13:05:48 +01:00
parent 67de463cca
commit e27ddf6d28
9 changed files with 105 additions and 133 deletions

121
ssh.c
View File

@ -871,6 +871,7 @@ struct ssh_tag {
char *v_c, *v_s; char *v_c, *v_s;
void *exhash; void *exhash;
BinarySink *exhash_bs;
Socket s; Socket s;
@ -892,6 +893,7 @@ struct ssh_tag {
const struct ssh_mac *csmac, *scmac; const struct ssh_mac *csmac, *scmac;
int csmac_etm, scmac_etm; int csmac_etm, scmac_etm;
void *cs_mac_ctx, *sc_mac_ctx; void *cs_mac_ctx, *sc_mac_ctx;
BinarySink *sc_mac_bs;
const struct ssh_compress *cscomp, *sccomp; const struct ssh_compress *cscomp, *sccomp;
void *cs_comp_ctx, *sc_comp_ctx; void *cs_comp_ctx, *sc_comp_ctx;
const struct ssh_kex *kex; const struct ssh_kex *kex;
@ -1800,12 +1802,9 @@ static void ssh2_rdpkt(Ssh ssh)
st->pktin->data, st->maclen)); st->pktin->data, st->maclen));
st->packetlen = 0; st->packetlen = 0;
{ ssh->scmac->start(ssh->sc_mac_ctx);
unsigned char seq[4]; ssh->sc_mac_bs = ssh->scmac->sink(ssh->sc_mac_ctx);
ssh->scmac->start(ssh->sc_mac_ctx); put_uint32(ssh->sc_mac_bs, st->incoming_sequence);
PUT_32BIT(seq, st->incoming_sequence);
ssh->scmac->bytes(ssh->sc_mac_ctx, seq, 4);
}
for (;;) { /* Once around this loop per cipher block. */ for (;;) { /* Once around this loop per cipher block. */
/* Read another cipher-block's worth, and tack it onto the end. */ /* Read another cipher-block's worth, and tack it onto the end. */
@ -1819,8 +1818,8 @@ static void ssh2_rdpkt(Ssh ssh)
st->pktin->data + st->packetlen, st->pktin->data + st->packetlen,
st->cipherblk); st->cipherblk);
/* Feed that block to the MAC. */ /* Feed that block to the MAC. */
ssh->scmac->bytes(ssh->sc_mac_ctx, put_data(ssh->sc_mac_bs,
st->pktin->data + st->packetlen, st->cipherblk); st->pktin->data + st->packetlen, st->cipherblk);
st->packetlen += st->cipherblk; st->packetlen += st->cipherblk;
/* See if that gives us a valid packet. */ /* See if that gives us a valid packet. */
if (ssh->scmac->verresult(ssh->sc_mac_ctx, if (ssh->scmac->verresult(ssh->sc_mac_ctx,
@ -2284,25 +2283,6 @@ static int ssh_versioncmp(const char *a, const char *b)
return 0; return 0;
} }
/*
* Utility routines for putting an SSH-protocol `string' and
* `uint32' into a hash state.
*/
static void hash_string(const struct ssh_hash *h, void *s, void *str, int len)
{
unsigned char lenblk[4];
PUT_32BIT(lenblk, len);
h->bytes(s, lenblk, 4);
h->bytes(s, str, len);
}
static void hash_uint32(const struct ssh_hash *h, void *s, unsigned i)
{
unsigned char intblk[4];
PUT_32BIT(intblk, i);
h->bytes(s, intblk, 4);
}
/* /*
* Packet construction functions. Mostly shared between SSH-1 and SSH-2. * Packet construction functions. Mostly shared between SSH-1 and SSH-2.
*/ */
@ -2733,14 +2713,6 @@ void bndebug(char *string, Bignum b)
} }
#endif #endif
static void hash_mpint(const struct ssh_hash *h, void *s, Bignum b)
{
strbuf *tmp = strbuf_new();
put_mp_ssh2(tmp, b);
hash_string(h, s, tmp->u, tmp->len);
strbuf_free(tmp);
}
/* /*
* Packet decode functions for both SSH-1 and SSH-2. * Packet decode functions for both SSH-1 and SSH-2.
*/ */
@ -6340,6 +6312,7 @@ static unsigned char *ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H,
int keylen_padded; int keylen_padded;
unsigned char *key; unsigned char *key;
void *s, *s2; void *s, *s2;
BinarySink *bs;
if (keylen == 0) if (keylen == 0)
return NULL; return NULL;
@ -6351,11 +6324,12 @@ static unsigned char *ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H,
/* First hlen bytes. */ /* First hlen bytes. */
s = h->init(); s = h->init();
bs = h->sink(s);
if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
hash_mpint(h, s, K); put_mp_ssh2(bs, K);
h->bytes(s, H, h->hlen); put_data(bs, H, h->hlen);
h->bytes(s, &chr, 1); put_byte(bs, chr);
h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len); put_data(bs, ssh->v2_session_id, ssh->v2_session_id_len);
h->final(s, key); h->final(s, key);
/* Subsequent blocks of hlen bytes. */ /* Subsequent blocks of hlen bytes. */
@ -6363,12 +6337,13 @@ static unsigned char *ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H,
int offset; int offset;
s = h->init(); s = h->init();
bs = h->sink(s);
if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY))
hash_mpint(h, s, K); put_mp_ssh2(bs, K);
h->bytes(s, H, h->hlen); put_data(bs, H, h->hlen);
for (offset = h->hlen; offset < keylen_padded; offset += h->hlen) { for (offset = h->hlen; offset < keylen_padded; offset += h->hlen) {
h->bytes(s, key + offset - h->hlen, h->hlen); put_data(bs, key + offset - h->hlen, h->hlen);
s2 = h->copy(s); s2 = h->copy(s);
h->final(s2, key + offset); h->final(s2, key + offset);
} }
@ -7155,14 +7130,13 @@ static void do_ssh2_transport(void *vctx)
s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok; s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
ssh->exhash = ssh->kex->hash->init(); ssh->exhash = ssh->kex->hash->init();
hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c)); ssh->exhash_bs = ssh->kex->hash->sink(ssh->exhash);
hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s)); put_stringz(ssh->exhash_bs, ssh->v_c);
hash_string(ssh->kex->hash, ssh->exhash, put_stringz(ssh->exhash_bs, ssh->v_s);
s->our_kexinit, s->our_kexinitlen); put_string(ssh->exhash_bs, s->our_kexinit, s->our_kexinitlen);
sfree(s->our_kexinit); sfree(s->our_kexinit);
/* Include the type byte in the hash of server's KEXINIT */ /* Include the type byte in the hash of server's KEXINIT */
hash_string(ssh->kex->hash, ssh->exhash, put_string(ssh->exhash_bs, pktin->body - 1, pktin->length + 1);
pktin->body - 1, pktin->length + 1);
if (s->warn_kex) { if (s->warn_kex) {
ssh_set_frozen(ssh, 1); ssh_set_frozen(ssh, 1);
@ -7402,18 +7376,18 @@ static void do_ssh2_transport(void *vctx)
* involve user interaction. */ * involve user interaction. */
set_busy_status(ssh->frontend, BUSY_NOT); set_busy_status(ssh->frontend, BUSY_NOT);
hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen); put_string(ssh->exhash_bs, s->hostkeydata, s->hostkeylen);
if (dh_is_gex(ssh->kex)) { if (dh_is_gex(ssh->kex)) {
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX)) if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
hash_uint32(ssh->kex->hash, ssh->exhash, DH_MIN_SIZE); put_uint32(ssh->exhash_bs, DH_MIN_SIZE);
hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); put_uint32(ssh->exhash_bs, s->pbits);
if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX)) if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX))
hash_uint32(ssh->kex->hash, ssh->exhash, DH_MAX_SIZE); put_uint32(ssh->exhash_bs, DH_MAX_SIZE);
hash_mpint(ssh->kex->hash, ssh->exhash, s->p); put_mp_ssh2(ssh->exhash_bs, s->p);
hash_mpint(ssh->kex->hash, ssh->exhash, s->g); put_mp_ssh2(ssh->exhash_bs, s->g);
} }
hash_mpint(ssh->kex->hash, ssh->exhash, s->e); put_mp_ssh2(ssh->exhash_bs, s->e);
hash_mpint(ssh->kex->hash, ssh->exhash, s->f); put_mp_ssh2(ssh->exhash_bs, s->f);
dh_cleanup(ssh->kex_ctx); dh_cleanup(ssh->kex_ctx);
freebn(s->f); freebn(s->f);
@ -7455,15 +7429,14 @@ static void do_ssh2_transport(void *vctx)
bombout(("unable to parse ECDH reply packet")); bombout(("unable to parse ECDH reply packet"));
crStopV; crStopV;
} }
hash_string(ssh->kex->hash, ssh->exhash, s->hostkeydata, s->hostkeylen); put_string(ssh->exhash_bs, s->hostkeydata, s->hostkeylen);
s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hkey = ssh->hostkey->newkey(ssh->hostkey,
s->hostkeydata, s->hostkeylen); s->hostkeydata, s->hostkeylen);
{ {
strbuf *pubpoint = strbuf_new(); strbuf *pubpoint = strbuf_new();
ssh_ecdhkex_getpublic(s->eckey, BinarySink_UPCAST(pubpoint)); ssh_ecdhkex_getpublic(s->eckey, BinarySink_UPCAST(pubpoint));
hash_string(ssh->kex->hash, ssh->exhash, put_string(ssh->exhash_bs, pubpoint->u, pubpoint->len);
pubpoint->u, pubpoint->len);
strbuf_free(pubpoint); strbuf_free(pubpoint);
} }
@ -7475,7 +7448,7 @@ static void do_ssh2_transport(void *vctx)
bombout(("unable to parse ECDH reply packet")); bombout(("unable to parse ECDH reply packet"));
crStopV; crStopV;
} }
hash_string(ssh->kex->hash, ssh->exhash, keydata, keylen); put_string(ssh->exhash_bs, keydata, keylen);
s->K = ssh_ecdhkex_getkey(s->eckey, keydata, keylen); s->K = ssh_ecdhkex_getkey(s->eckey, keydata, keylen);
if (!s->K) { if (!s->K) {
ssh_ecdhkex_freekey(s->eckey); ssh_ecdhkex_freekey(s->eckey);
@ -7673,8 +7646,7 @@ static void do_ssh2_transport(void *vctx)
s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hkey = ssh->hostkey->newkey(ssh->hostkey,
s->hostkeydata, s->hostkeydata,
s->hostkeylen); s->hostkeylen);
hash_string(ssh->kex->hash, ssh->exhash, put_string(ssh->exhash_bs, s->hostkeydata, s->hostkeylen);
s->hostkeydata, s->hostkeylen);
} }
/* /*
* Can't loop as we have no token to pass to * Can't loop as we have no token to pass to
@ -7722,18 +7694,18 @@ static void do_ssh2_transport(void *vctx)
set_busy_status(ssh->frontend, BUSY_NOT); set_busy_status(ssh->frontend, BUSY_NOT);
if (!s->hkey) if (!s->hkey)
hash_string(ssh->kex->hash, ssh->exhash, NULL, 0); put_stringz(ssh->exhash_bs, "");
if (dh_is_gex(ssh->kex)) { if (dh_is_gex(ssh->kex)) {
/* min, preferred, max */ /* min, preferred, max */
hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); put_uint32(ssh->exhash_bs, s->pbits);
hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); put_uint32(ssh->exhash_bs, s->pbits);
hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits * 2); put_uint32(ssh->exhash_bs, s->pbits * 2);
hash_mpint(ssh->kex->hash, ssh->exhash, s->p); put_mp_ssh2(ssh->exhash_bs, s->p);
hash_mpint(ssh->kex->hash, ssh->exhash, s->g); put_mp_ssh2(ssh->exhash_bs, s->g);
} }
hash_mpint(ssh->kex->hash, ssh->exhash, s->e); put_mp_ssh2(ssh->exhash_bs, s->e);
hash_mpint(ssh->kex->hash, ssh->exhash, s->f); put_mp_ssh2(ssh->exhash_bs, s->f);
/* /*
* MIC verification is done below, after we compute the hash * MIC verification is done below, after we compute the hash
@ -7767,8 +7739,7 @@ static void do_ssh2_transport(void *vctx)
bombout(("unable to parse RSA public key packet")); bombout(("unable to parse RSA public key packet"));
crStopV; crStopV;
} }
hash_string(ssh->kex->hash, ssh->exhash, put_string(ssh->exhash_bs, s->hostkeydata, s->hostkeylen);
s->hostkeydata, s->hostkeylen);
s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hkey = ssh->hostkey->newkey(ssh->hostkey,
s->hostkeydata, s->hostkeylen); s->hostkeydata, s->hostkeylen);
@ -7790,7 +7761,7 @@ static void do_ssh2_transport(void *vctx)
crStopV; crStopV;
} }
hash_string(ssh->kex->hash, ssh->exhash, s->rsakeydata, s->rsakeylen); put_string(ssh->exhash_bs, s->rsakeydata, s->rsakeylen);
/* /*
* Next, set up a shared secret K, of precisely KLEN - * Next, set up a shared secret K, of precisely KLEN -
@ -7836,7 +7807,7 @@ static void do_ssh2_transport(void *vctx)
put_string(s->pktout, outstr, outstrlen); put_string(s->pktout, outstr, outstrlen);
ssh2_pkt_send_noqueue(ssh, s->pktout); ssh2_pkt_send_noqueue(ssh, s->pktout);
hash_string(ssh->kex->hash, ssh->exhash, outstr, outstrlen); put_string(ssh->exhash_bs, outstr, outstrlen);
strbuf_free(buf); strbuf_free(buf);
sfree(outstr); sfree(outstr);
@ -7860,7 +7831,7 @@ static void do_ssh2_transport(void *vctx)
sfree(s->rsakeydata); sfree(s->rsakeydata);
} }
hash_mpint(ssh->kex->hash, ssh->exhash, s->K); put_mp_ssh2(ssh->exhash_bs, s->K);
assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash)); assert(ssh->kex->hash->hlen <= sizeof(s->exchange_hash));
ssh->kex->hash->final(ssh->exhash, s->exchange_hash); ssh->kex->hash->final(ssh->exhash, s->exchange_hash);

4
ssh.h
View File

@ -365,7 +365,7 @@ struct ssh_mac {
int (*verify) (void *, unsigned char *blk, int len, unsigned long seq); int (*verify) (void *, unsigned char *blk, int len, unsigned long seq);
/* partial-packet operations */ /* partial-packet operations */
void (*start) (void *); void (*start) (void *);
void (*bytes) (void *, unsigned char const *, int); BinarySink *(*sink) (void *);
void (*genresult) (void *, unsigned char *); void (*genresult) (void *, unsigned char *);
int (*verresult) (void *, unsigned char const *); int (*verresult) (void *, unsigned char const *);
const char *name, *etm_name; const char *name, *etm_name;
@ -376,7 +376,7 @@ struct ssh_mac {
struct ssh_hash { struct ssh_hash {
void *(*init)(void); /* also allocates context */ void *(*init)(void); /* also allocates context */
void *(*copy)(const void *); void *(*copy)(const void *);
void (*bytes)(void *, const void *, int); BinarySink *(*sink) (void *);
void (*final)(void *, unsigned char *); /* also frees context */ void (*final)(void *, unsigned char *); /* also frees context */
void (*free)(void *); void (*free)(void *);
int hlen; /* output length in bytes */ int hlen; /* output length in bytes */

View File

@ -864,6 +864,8 @@ struct ccp_context {
unsigned char mac_iv[8]; unsigned char mac_iv[8];
struct poly1305 mac; struct poly1305 mac;
BinarySink_IMPLEMENTATION;
}; };
static void *poly_make_context(void *ctx) static void *poly_make_context(void *ctx)
@ -890,9 +892,10 @@ static void poly_start(void *handle)
poly1305_init(&ctx->mac); poly1305_init(&ctx->mac);
} }
static void poly_bytes(void *handle, unsigned char const *blk, int len) static void poly_BinarySink_write(BinarySink *bs, const void *blkv, size_t len)
{ {
struct ccp_context *ctx = (struct ccp_context *)handle; struct ccp_context *ctx = BinarySink_DOWNCAST(bs, struct ccp_context);
const unsigned char *blk = (const unsigned char *)blkv;
/* First 4 bytes are the IV */ /* First 4 bytes are the IV */
while (ctx->mac_initialised < 4 && len) { while (ctx->mac_initialised < 4 && len) {
@ -922,6 +925,12 @@ static void poly_bytes(void *handle, unsigned char const *blk, int len)
} }
} }
static BinarySink *poly_sink(void *handle)
{
struct ccp_context *ctx = (struct ccp_context *)handle;
return BinarySink_UPCAST(ctx);
}
static void poly_genresult(void *handle, unsigned char *blk) static void poly_genresult(void *handle, unsigned char *blk)
{ {
struct ccp_context *ctx = (struct ccp_context *)handle; struct ccp_context *ctx = (struct ccp_context *)handle;
@ -941,13 +950,11 @@ static int poly_verresult(void *handle, unsigned char const *blk)
/* The generic poly operation used before generate and verify */ /* The generic poly operation used before generate and verify */
static void poly_op(void *handle, unsigned char *blk, int len, unsigned long seq) static void poly_op(void *handle, unsigned char *blk, int len, unsigned long seq)
{ {
unsigned char iv[4]; struct ccp_context *ctx = (struct ccp_context *)handle;
poly_start(handle); poly_start(ctx);
PUT_32BIT_MSB_FIRST(iv, seq); /* the data receiver expects the first 4 bytes to be the IV */
/* poly_bytes expects the first 4 bytes to be the IV */ put_uint32(ctx, seq);
poly_bytes(handle, iv, 4); put_data(ctx, blk, len);
smemclr(iv, sizeof(iv));
poly_bytes(handle, blk, len);
} }
static void poly_generate(void *handle, unsigned char *blk, int len, unsigned long seq) static void poly_generate(void *handle, unsigned char *blk, int len, unsigned long seq)
@ -970,7 +977,7 @@ static const struct ssh_mac ssh2_poly1305 = {
poly_generate, poly_verify, poly_generate, poly_verify,
/* partial-packet operations */ /* partial-packet operations */
poly_start, poly_bytes, poly_genresult, poly_verresult, poly_start, poly_sink, poly_genresult, poly_verresult,
"", "", /* Not selectable individually, just part of ChaCha20-Poly1305 */ "", "", /* Not selectable individually, just part of ChaCha20-Poly1305 */
16, 0, "Poly1305" 16, 0, "Poly1305"
@ -979,9 +986,8 @@ static const struct ssh_mac ssh2_poly1305 = {
static void *ccp_make_context(void) static void *ccp_make_context(void)
{ {
struct ccp_context *ctx = snew(struct ccp_context); struct ccp_context *ctx = snew(struct ccp_context);
if (ctx) { BinarySink_INIT(ctx, poly_BinarySink_write);
poly1305_init(&ctx->mac); poly1305_init(&ctx->mac);
}
return ctx; return ctx;
} }

View File

@ -2294,7 +2294,7 @@ static int ecdsa_verifysig(void *key, const char *sig, int siglen,
digestLen = extra->hash->hlen; digestLen = extra->hash->hlen;
assert(digestLen <= sizeof(digest)); assert(digestLen <= sizeof(digest));
hashctx = extra->hash->init(); hashctx = extra->hash->init();
extra->hash->bytes(hashctx, data, datalen); put_data(extra->hash->sink(hashctx), data, datalen);
extra->hash->final(hashctx, digest); extra->hash->final(hashctx, digest);
/* Verify the signature */ /* Verify the signature */
@ -2421,7 +2421,7 @@ static void ecdsa_sign(void *key, const char *data, int datalen,
digestLen = extra->hash->hlen; digestLen = extra->hash->hlen;
assert(digestLen <= sizeof(digest)); assert(digestLen <= sizeof(digest));
hashctx = extra->hash->init(); hashctx = extra->hash->init();
extra->hash->bytes(hashctx, data, datalen); put_data(extra->hash->sink(hashctx), data, datalen);
extra->hash->final(hashctx, digest); extra->hash->final(hashctx, digest);
/* Do the signature */ /* Do the signature */

View File

@ -274,10 +274,10 @@ static void hmacmd5_start(void *handle)
BinarySink_COPIED(&keys[2]); BinarySink_COPIED(&keys[2]);
} }
static void hmacmd5_bytes(void *handle, unsigned char const *blk, int len) static BinarySink *hmacmd5_sink(void *handle)
{ {
struct MD5Context *keys = (struct MD5Context *)handle; struct MD5Context *keys = (struct MD5Context *)handle;
put_data(&keys[2], blk, len); return BinarySink_UPCAST(&keys[2]);
} }
static void hmacmd5_genresult(void *handle, unsigned char *hmac) static void hmacmd5_genresult(void *handle, unsigned char *hmac)
@ -307,9 +307,10 @@ static void hmacmd5_do_hmac_internal(void *handle,
unsigned char const *blk2, int len2, unsigned char const *blk2, int len2,
unsigned char *hmac) unsigned char *hmac)
{ {
BinarySink *bs = hmacmd5_sink(handle);
hmacmd5_start(handle); hmacmd5_start(handle);
hmacmd5_bytes(handle, blk, len); put_data(bs, blk, len);
if (blk2) hmacmd5_bytes(handle, blk2, len2); if (blk2) put_data(bs, blk2, len2);
hmacmd5_genresult(handle, hmac); hmacmd5_genresult(handle, hmac);
} }
@ -345,7 +346,7 @@ static int hmacmd5_verify(void *handle, unsigned char *blk, int len,
const struct ssh_mac ssh_hmac_md5 = { const struct ssh_mac ssh_hmac_md5 = {
hmacmd5_make_context, hmacmd5_free_context, hmacmd5_key_16, hmacmd5_make_context, hmacmd5_free_context, hmacmd5_key_16,
hmacmd5_generate, hmacmd5_verify, hmacmd5_generate, hmacmd5_verify,
hmacmd5_start, hmacmd5_bytes, hmacmd5_genresult, hmacmd5_verresult, hmacmd5_start, hmacmd5_sink, hmacmd5_genresult, hmacmd5_verresult,
"hmac-md5", "hmac-md5-etm@openssh.com", "hmac-md5", "hmac-md5-etm@openssh.com",
16, 16, 16, 16,
"HMAC-MD5" "HMAC-MD5"

View File

@ -838,13 +838,14 @@ static void oaep_mask(const struct ssh_hash *h, void *seed, int seedlen,
while (datalen > 0) { while (datalen > 0) {
int i, max = (datalen > h->hlen ? h->hlen : datalen); int i, max = (datalen > h->hlen ? h->hlen : datalen);
void *s; void *s;
unsigned char counter[4], hash[SSH2_KEX_MAX_HASH_LEN]; BinarySink *bs;
unsigned char hash[SSH2_KEX_MAX_HASH_LEN];
assert(h->hlen <= SSH2_KEX_MAX_HASH_LEN); assert(h->hlen <= SSH2_KEX_MAX_HASH_LEN);
PUT_32BIT(counter, count);
s = h->init(); s = h->init();
h->bytes(s, seed, seedlen); bs = h->sink(s);
h->bytes(s, counter, 4); put_data(bs, seed, seedlen);
put_uint32(bs, count);
h->final(s, hash); h->final(s, hash);
count++; count++;

View File

@ -232,11 +232,10 @@ static void sha256_free(void *handle)
sfree(s); sfree(s);
} }
static void sha256_bytes(void *handle, const void *p, int len) static BinarySink *sha256_sink(void *handle)
{ {
SHA256_State *s = handle; SHA256_State *s = handle;
return BinarySink_UPCAST(s);
put_data(s, p, len);
} }
static void sha256_final(void *handle, unsigned char *output) static void sha256_final(void *handle, unsigned char *output)
@ -248,7 +247,7 @@ static void sha256_final(void *handle, unsigned char *output)
} }
const struct ssh_hash ssh_sha256 = { const struct ssh_hash ssh_sha256 = {
sha256_init, sha256_copy, sha256_bytes, sha256_final, sha256_free, sha256_init, sha256_copy, sha256_sink, sha256_final, sha256_free,
32, "SHA-256" 32, "SHA-256"
}; };
@ -302,10 +301,10 @@ static void hmacsha256_start(void *handle)
BinarySink_COPIED(&keys[2]); BinarySink_COPIED(&keys[2]);
} }
static void hmacsha256_bytes(void *handle, unsigned char const *blk, int len) static BinarySink *hmacsha256_sink(void *handle)
{ {
SHA256_State *keys = (SHA256_State *)handle; SHA256_State *keys = (SHA256_State *)handle;
put_data(&keys[2], blk, len); return BinarySink_UPCAST(&keys[2]);
} }
static void hmacsha256_genresult(void *handle, unsigned char *hmac) static void hmacsha256_genresult(void *handle, unsigned char *hmac)
@ -326,12 +325,10 @@ static void hmacsha256_genresult(void *handle, unsigned char *hmac)
static void sha256_do_hmac(void *handle, unsigned char *blk, int len, static void sha256_do_hmac(void *handle, unsigned char *blk, int len,
unsigned long seq, unsigned char *hmac) unsigned long seq, unsigned char *hmac)
{ {
unsigned char seqbuf[4]; BinarySink *bs = hmacsha256_sink(handle);
PUT_32BIT_MSB_FIRST(seqbuf, seq);
hmacsha256_start(handle); hmacsha256_start(handle);
hmacsha256_bytes(handle, seqbuf, 4); put_uint32(bs, seq);
hmacsha256_bytes(handle, blk, len); put_data(bs, blk, len);
hmacsha256_genresult(handle, hmac); hmacsha256_genresult(handle, hmac);
} }
@ -359,7 +356,7 @@ static int sha256_verify(void *handle, unsigned char *blk, int len,
const struct ssh_mac ssh_hmac_sha256 = { const struct ssh_mac ssh_hmac_sha256 = {
sha256_make_context, sha256_free_context, sha256_key, sha256_make_context, sha256_free_context, sha256_key,
sha256_generate, sha256_verify, sha256_generate, sha256_verify,
hmacsha256_start, hmacsha256_bytes, hmacsha256_start, hmacsha256_sink,
hmacsha256_genresult, hmacsha256_verresult, hmacsha256_genresult, hmacsha256_verresult,
"hmac-sha2-256", "hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-256-etm@openssh.com",
32, 32, 32, 32,

View File

@ -355,11 +355,10 @@ static void sha512_free(void *handle)
sfree(s); sfree(s);
} }
static void sha512_bytes(void *handle, const void *p, int len) static BinarySink *sha512_sink(void *handle)
{ {
SHA512_State *s = handle; SHA512_State *s = handle;
return BinarySink_UPCAST(s);
put_data(s, p, len);
} }
static void sha512_final(void *handle, unsigned char *output) static void sha512_final(void *handle, unsigned char *output)
@ -371,7 +370,7 @@ static void sha512_final(void *handle, unsigned char *output)
} }
const struct ssh_hash ssh_sha512 = { const struct ssh_hash ssh_sha512 = {
sha512_init, sha512_copy, sha512_bytes, sha512_final, sha512_free, sha512_init, sha512_copy, sha512_sink, sha512_final, sha512_free,
64, "SHA-512" 64, "SHA-512"
}; };
@ -394,7 +393,7 @@ static void sha384_final(void *handle, unsigned char *output)
} }
const struct ssh_hash ssh_sha384 = { const struct ssh_hash ssh_sha384 = {
sha384_init, sha512_copy, sha512_bytes, sha384_final, sha512_free, sha384_init, sha512_copy, sha512_sink, sha384_final, sha512_free,
48, "SHA-384" 48, "SHA-384"
}; };

View File

@ -260,11 +260,10 @@ static void sha1_free(void *handle)
sfree(s); sfree(s);
} }
static void sha1_bytes(void *handle, const void *p, int len) static BinarySink *sha1_sink(void *handle)
{ {
SHA_State *s = handle; SHA_State *s = handle;
return BinarySink_UPCAST(s);
put_data(s, p, len);
} }
static void sha1_final(void *handle, unsigned char *output) static void sha1_final(void *handle, unsigned char *output)
@ -276,7 +275,7 @@ static void sha1_final(void *handle, unsigned char *output)
} }
const struct ssh_hash ssh_sha1 = { const struct ssh_hash ssh_sha1 = {
sha1_init, sha1_copy, sha1_bytes, sha1_final, sha1_free, 20, "SHA-1" sha1_init, sha1_copy, sha1_sink, sha1_final, sha1_free, 20, "SHA-1"
}; };
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -334,10 +333,10 @@ static void hmacsha1_start(void *handle)
BinarySink_COPIED(&keys[2]); BinarySink_COPIED(&keys[2]);
} }
static void hmacsha1_bytes(void *handle, unsigned char const *blk, int len) static BinarySink *hmacsha1_sink(void *handle)
{ {
SHA_State *keys = (SHA_State *)handle; SHA_State *keys = (SHA_State *)handle;
put_data(&keys[2], blk, len); return BinarySink_UPCAST(&keys[2]);
} }
static void hmacsha1_genresult(void *handle, unsigned char *hmac) static void hmacsha1_genresult(void *handle, unsigned char *hmac)
@ -358,12 +357,10 @@ static void hmacsha1_genresult(void *handle, unsigned char *hmac)
static void sha1_do_hmac(void *handle, unsigned char *blk, int len, static void sha1_do_hmac(void *handle, unsigned char *blk, int len,
unsigned long seq, unsigned char *hmac) unsigned long seq, unsigned char *hmac)
{ {
unsigned char seqbuf[4]; BinarySink *bs = hmacsha1_sink(handle);
PUT_32BIT_MSB_FIRST(seqbuf, seq);
hmacsha1_start(handle); hmacsha1_start(handle);
hmacsha1_bytes(handle, seqbuf, 4); put_uint32(bs, seq);
hmacsha1_bytes(handle, blk, len); put_data(bs, blk, len);
hmacsha1_genresult(handle, hmac); hmacsha1_genresult(handle, hmac);
} }
@ -434,7 +431,7 @@ void hmac_sha1_simple(void *key, int keylen, void *data, int datalen,
const struct ssh_mac ssh_hmac_sha1 = { const struct ssh_mac ssh_hmac_sha1 = {
sha1_make_context, sha1_free_context, sha1_key, sha1_make_context, sha1_free_context, sha1_key,
sha1_generate, sha1_verify, sha1_generate, sha1_verify,
hmacsha1_start, hmacsha1_bytes, hmacsha1_genresult, hmacsha1_verresult, hmacsha1_start, hmacsha1_sink, hmacsha1_genresult, hmacsha1_verresult,
"hmac-sha1", "hmac-sha1-etm@openssh.com", "hmac-sha1", "hmac-sha1-etm@openssh.com",
20, 20, 20, 20,
"HMAC-SHA1" "HMAC-SHA1"
@ -443,7 +440,7 @@ const struct ssh_mac ssh_hmac_sha1 = {
const struct ssh_mac ssh_hmac_sha1_96 = { const struct ssh_mac ssh_hmac_sha1_96 = {
sha1_make_context, sha1_free_context, sha1_key, sha1_make_context, sha1_free_context, sha1_key,
sha1_96_generate, sha1_96_verify, sha1_96_generate, sha1_96_verify,
hmacsha1_start, hmacsha1_bytes, hmacsha1_start, hmacsha1_sink,
hmacsha1_96_genresult, hmacsha1_96_verresult, hmacsha1_96_genresult, hmacsha1_96_verresult,
"hmac-sha1-96", "hmac-sha1-96-etm@openssh.com", "hmac-sha1-96", "hmac-sha1-96-etm@openssh.com",
12, 20, 12, 20,
@ -453,7 +450,7 @@ const struct ssh_mac ssh_hmac_sha1_96 = {
const struct ssh_mac ssh_hmac_sha1_buggy = { const struct ssh_mac ssh_hmac_sha1_buggy = {
sha1_make_context, sha1_free_context, sha1_key_buggy, sha1_make_context, sha1_free_context, sha1_key_buggy,
sha1_generate, sha1_verify, sha1_generate, sha1_verify,
hmacsha1_start, hmacsha1_bytes, hmacsha1_genresult, hmacsha1_verresult, hmacsha1_start, hmacsha1_sink, hmacsha1_genresult, hmacsha1_verresult,
"hmac-sha1", NULL, "hmac-sha1", NULL,
20, 16, 20, 16,
"bug-compatible HMAC-SHA1" "bug-compatible HMAC-SHA1"
@ -462,7 +459,7 @@ const struct ssh_mac ssh_hmac_sha1_buggy = {
const struct ssh_mac ssh_hmac_sha1_96_buggy = { const struct ssh_mac ssh_hmac_sha1_96_buggy = {
sha1_make_context, sha1_free_context, sha1_key_buggy, sha1_make_context, sha1_free_context, sha1_key_buggy,
sha1_96_generate, sha1_96_verify, sha1_96_generate, sha1_96_verify,
hmacsha1_start, hmacsha1_bytes, hmacsha1_start, hmacsha1_sink,
hmacsha1_96_genresult, hmacsha1_96_verresult, hmacsha1_96_genresult, hmacsha1_96_verresult,
"hmac-sha1-96", NULL, "hmac-sha1-96", NULL,
12, 16, 12, 16,