From e27ddf6d282ad47a6a84b8c1adf0edd1edffaae7 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 24 May 2018 13:05:48 +0100 Subject: [PATCH] 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(). --- ssh.c | 121 ++++++++++++++++++++--------------------------------- ssh.h | 4 +- sshccp.c | 32 ++++++++------ sshecc.c | 4 +- sshmd5.c | 11 ++--- sshrsa.c | 9 ++-- sshsh256.c | 21 ++++------ sshsh512.c | 9 ++-- sshsha.c | 27 ++++++------ 9 files changed, 105 insertions(+), 133 deletions(-) diff --git a/ssh.c b/ssh.c index 8372aa25..464072e8 100644 --- a/ssh.c +++ b/ssh.c @@ -871,6 +871,7 @@ struct ssh_tag { char *v_c, *v_s; void *exhash; + BinarySink *exhash_bs; Socket s; @@ -892,6 +893,7 @@ struct ssh_tag { const struct ssh_mac *csmac, *scmac; int csmac_etm, scmac_etm; void *cs_mac_ctx, *sc_mac_ctx; + BinarySink *sc_mac_bs; const struct ssh_compress *cscomp, *sccomp; void *cs_comp_ctx, *sc_comp_ctx; const struct ssh_kex *kex; @@ -1800,12 +1802,9 @@ static void ssh2_rdpkt(Ssh ssh) st->pktin->data, st->maclen)); st->packetlen = 0; - { - unsigned char seq[4]; - ssh->scmac->start(ssh->sc_mac_ctx); - PUT_32BIT(seq, st->incoming_sequence); - ssh->scmac->bytes(ssh->sc_mac_ctx, seq, 4); - } + ssh->scmac->start(ssh->sc_mac_ctx); + ssh->sc_mac_bs = ssh->scmac->sink(ssh->sc_mac_ctx); + put_uint32(ssh->sc_mac_bs, st->incoming_sequence); for (;;) { /* Once around this loop per cipher block. */ /* 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->cipherblk); /* Feed that block to the MAC. */ - ssh->scmac->bytes(ssh->sc_mac_ctx, - st->pktin->data + st->packetlen, st->cipherblk); + put_data(ssh->sc_mac_bs, + st->pktin->data + st->packetlen, st->cipherblk); st->packetlen += st->cipherblk; /* See if that gives us a valid packet. */ if (ssh->scmac->verresult(ssh->sc_mac_ctx, @@ -2284,25 +2283,6 @@ static int ssh_versioncmp(const char *a, const char *b) 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. */ @@ -2733,14 +2713,6 @@ void bndebug(char *string, Bignum b) } #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. */ @@ -6340,6 +6312,7 @@ static unsigned char *ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, int keylen_padded; unsigned char *key; void *s, *s2; + BinarySink *bs; if (keylen == 0) return NULL; @@ -6351,11 +6324,12 @@ static unsigned char *ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, /* First hlen bytes. */ s = h->init(); + bs = h->sink(s); if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) - hash_mpint(h, s, K); - h->bytes(s, H, h->hlen); - h->bytes(s, &chr, 1); - h->bytes(s, ssh->v2_session_id, ssh->v2_session_id_len); + put_mp_ssh2(bs, K); + put_data(bs, H, h->hlen); + put_byte(bs, chr); + put_data(bs, ssh->v2_session_id, ssh->v2_session_id_len); h->final(s, key); /* Subsequent blocks of hlen bytes. */ @@ -6363,12 +6337,13 @@ static unsigned char *ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, int offset; s = h->init(); + bs = h->sink(s); if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) - hash_mpint(h, s, K); - h->bytes(s, H, h->hlen); + put_mp_ssh2(bs, K); + put_data(bs, H, 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); h->final(s2, key + offset); } @@ -7155,14 +7130,13 @@ static void do_ssh2_transport(void *vctx) s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok; ssh->exhash = ssh->kex->hash->init(); - hash_string(ssh->kex->hash, ssh->exhash, ssh->v_c, strlen(ssh->v_c)); - hash_string(ssh->kex->hash, ssh->exhash, ssh->v_s, strlen(ssh->v_s)); - hash_string(ssh->kex->hash, ssh->exhash, - s->our_kexinit, s->our_kexinitlen); + ssh->exhash_bs = ssh->kex->hash->sink(ssh->exhash); + put_stringz(ssh->exhash_bs, ssh->v_c); + put_stringz(ssh->exhash_bs, ssh->v_s); + put_string(ssh->exhash_bs, s->our_kexinit, s->our_kexinitlen); sfree(s->our_kexinit); /* Include the type byte in the hash of server's KEXINIT */ - hash_string(ssh->kex->hash, ssh->exhash, - pktin->body - 1, pktin->length + 1); + put_string(ssh->exhash_bs, pktin->body - 1, pktin->length + 1); if (s->warn_kex) { ssh_set_frozen(ssh, 1); @@ -7402,18 +7376,18 @@ static void do_ssh2_transport(void *vctx) * involve user interaction. */ 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 (!(ssh->remote_bugs & BUG_SSH2_OLDGEX)) - hash_uint32(ssh->kex->hash, ssh->exhash, DH_MIN_SIZE); - hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); + put_uint32(ssh->exhash_bs, DH_MIN_SIZE); + put_uint32(ssh->exhash_bs, s->pbits); if (!(ssh->remote_bugs & BUG_SSH2_OLDGEX)) - hash_uint32(ssh->kex->hash, ssh->exhash, DH_MAX_SIZE); - hash_mpint(ssh->kex->hash, ssh->exhash, s->p); - hash_mpint(ssh->kex->hash, ssh->exhash, s->g); + put_uint32(ssh->exhash_bs, DH_MAX_SIZE); + put_mp_ssh2(ssh->exhash_bs, s->p); + put_mp_ssh2(ssh->exhash_bs, s->g); } - hash_mpint(ssh->kex->hash, ssh->exhash, s->e); - hash_mpint(ssh->kex->hash, ssh->exhash, s->f); + put_mp_ssh2(ssh->exhash_bs, s->e); + put_mp_ssh2(ssh->exhash_bs, s->f); dh_cleanup(ssh->kex_ctx); freebn(s->f); @@ -7455,15 +7429,14 @@ static void do_ssh2_transport(void *vctx) bombout(("unable to parse ECDH reply packet")); 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->hostkeydata, s->hostkeylen); { strbuf *pubpoint = strbuf_new(); ssh_ecdhkex_getpublic(s->eckey, BinarySink_UPCAST(pubpoint)); - hash_string(ssh->kex->hash, ssh->exhash, - pubpoint->u, pubpoint->len); + put_string(ssh->exhash_bs, pubpoint->u, pubpoint->len); strbuf_free(pubpoint); } @@ -7475,7 +7448,7 @@ static void do_ssh2_transport(void *vctx) bombout(("unable to parse ECDH reply packet")); 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); if (!s->K) { ssh_ecdhkex_freekey(s->eckey); @@ -7673,8 +7646,7 @@ static void do_ssh2_transport(void *vctx) s->hkey = ssh->hostkey->newkey(ssh->hostkey, s->hostkeydata, s->hostkeylen); - hash_string(ssh->kex->hash, ssh->exhash, - s->hostkeydata, s->hostkeylen); + put_string(ssh->exhash_bs, s->hostkeydata, s->hostkeylen); } /* * 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); if (!s->hkey) - hash_string(ssh->kex->hash, ssh->exhash, NULL, 0); + put_stringz(ssh->exhash_bs, ""); if (dh_is_gex(ssh->kex)) { /* min, preferred, max */ - hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); - hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits); - hash_uint32(ssh->kex->hash, ssh->exhash, s->pbits * 2); + put_uint32(ssh->exhash_bs, s->pbits); + put_uint32(ssh->exhash_bs, s->pbits); + put_uint32(ssh->exhash_bs, s->pbits * 2); - hash_mpint(ssh->kex->hash, ssh->exhash, s->p); - hash_mpint(ssh->kex->hash, ssh->exhash, s->g); + put_mp_ssh2(ssh->exhash_bs, s->p); + put_mp_ssh2(ssh->exhash_bs, s->g); } - hash_mpint(ssh->kex->hash, ssh->exhash, s->e); - hash_mpint(ssh->kex->hash, ssh->exhash, s->f); + put_mp_ssh2(ssh->exhash_bs, s->e); + put_mp_ssh2(ssh->exhash_bs, s->f); /* * 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")); 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->hostkeydata, s->hostkeylen); @@ -7790,7 +7761,7 @@ static void do_ssh2_transport(void *vctx) 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 - @@ -7836,7 +7807,7 @@ static void do_ssh2_transport(void *vctx) put_string(s->pktout, outstr, outstrlen); 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); sfree(outstr); @@ -7860,7 +7831,7 @@ static void do_ssh2_transport(void *vctx) 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)); ssh->kex->hash->final(ssh->exhash, s->exchange_hash); diff --git a/ssh.h b/ssh.h index bf341ceb..591c0bb6 100644 --- a/ssh.h +++ b/ssh.h @@ -365,7 +365,7 @@ struct ssh_mac { int (*verify) (void *, unsigned char *blk, int len, unsigned long seq); /* partial-packet operations */ void (*start) (void *); - void (*bytes) (void *, unsigned char const *, int); + BinarySink *(*sink) (void *); void (*genresult) (void *, unsigned char *); int (*verresult) (void *, unsigned char const *); const char *name, *etm_name; @@ -376,7 +376,7 @@ struct ssh_mac { struct ssh_hash { void *(*init)(void); /* also allocates context */ void *(*copy)(const void *); - void (*bytes)(void *, const void *, int); + BinarySink *(*sink) (void *); void (*final)(void *, unsigned char *); /* also frees context */ void (*free)(void *); int hlen; /* output length in bytes */ diff --git a/sshccp.c b/sshccp.c index 835b8fe5..be5e9acf 100644 --- a/sshccp.c +++ b/sshccp.c @@ -864,6 +864,8 @@ struct ccp_context { unsigned char mac_iv[8]; struct poly1305 mac; + + BinarySink_IMPLEMENTATION; }; static void *poly_make_context(void *ctx) @@ -890,9 +892,10 @@ static void poly_start(void *handle) 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 */ 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) { 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 */ static void poly_op(void *handle, unsigned char *blk, int len, unsigned long seq) { - unsigned char iv[4]; - poly_start(handle); - PUT_32BIT_MSB_FIRST(iv, seq); - /* poly_bytes expects the first 4 bytes to be the IV */ - poly_bytes(handle, iv, 4); - smemclr(iv, sizeof(iv)); - poly_bytes(handle, blk, len); + struct ccp_context *ctx = (struct ccp_context *)handle; + poly_start(ctx); + /* the data receiver expects the first 4 bytes to be the IV */ + put_uint32(ctx, seq); + put_data(ctx, blk, len); } 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, /* 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 */ 16, 0, "Poly1305" @@ -979,9 +986,8 @@ static const struct ssh_mac ssh2_poly1305 = { static void *ccp_make_context(void) { struct ccp_context *ctx = snew(struct ccp_context); - if (ctx) { - poly1305_init(&ctx->mac); - } + BinarySink_INIT(ctx, poly_BinarySink_write); + poly1305_init(&ctx->mac); return ctx; } diff --git a/sshecc.c b/sshecc.c index 1a632d9f..41b8b6cf 100644 --- a/sshecc.c +++ b/sshecc.c @@ -2294,7 +2294,7 @@ static int ecdsa_verifysig(void *key, const char *sig, int siglen, digestLen = extra->hash->hlen; assert(digestLen <= sizeof(digest)); hashctx = extra->hash->init(); - extra->hash->bytes(hashctx, data, datalen); + put_data(extra->hash->sink(hashctx), data, datalen); extra->hash->final(hashctx, digest); /* Verify the signature */ @@ -2421,7 +2421,7 @@ static void ecdsa_sign(void *key, const char *data, int datalen, digestLen = extra->hash->hlen; assert(digestLen <= sizeof(digest)); hashctx = extra->hash->init(); - extra->hash->bytes(hashctx, data, datalen); + put_data(extra->hash->sink(hashctx), data, datalen); extra->hash->final(hashctx, digest); /* Do the signature */ diff --git a/sshmd5.c b/sshmd5.c index 67f776ad..5bd0ccb4 100644 --- a/sshmd5.c +++ b/sshmd5.c @@ -274,10 +274,10 @@ static void hmacmd5_start(void *handle) 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; - put_data(&keys[2], blk, len); + return BinarySink_UPCAST(&keys[2]); } 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 *hmac) { + BinarySink *bs = hmacmd5_sink(handle); hmacmd5_start(handle); - hmacmd5_bytes(handle, blk, len); - if (blk2) hmacmd5_bytes(handle, blk2, len2); + put_data(bs, blk, len); + if (blk2) put_data(bs, blk2, len2); 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 = { hmacmd5_make_context, hmacmd5_free_context, hmacmd5_key_16, 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", 16, 16, "HMAC-MD5" diff --git a/sshrsa.c b/sshrsa.c index 107739b4..da5cebbf 100644 --- a/sshrsa.c +++ b/sshrsa.c @@ -838,13 +838,14 @@ static void oaep_mask(const struct ssh_hash *h, void *seed, int seedlen, while (datalen > 0) { int i, max = (datalen > h->hlen ? h->hlen : datalen); 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); - PUT_32BIT(counter, count); s = h->init(); - h->bytes(s, seed, seedlen); - h->bytes(s, counter, 4); + bs = h->sink(s); + put_data(bs, seed, seedlen); + put_uint32(bs, count); h->final(s, hash); count++; diff --git a/sshsh256.c b/sshsh256.c index 67fe329e..0a0a9546 100644 --- a/sshsh256.c +++ b/sshsh256.c @@ -232,11 +232,10 @@ static void sha256_free(void *handle) sfree(s); } -static void sha256_bytes(void *handle, const void *p, int len) +static BinarySink *sha256_sink(void *handle) { SHA256_State *s = handle; - - put_data(s, p, len); + return BinarySink_UPCAST(s); } 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 = { - sha256_init, sha256_copy, sha256_bytes, sha256_final, sha256_free, + sha256_init, sha256_copy, sha256_sink, sha256_final, sha256_free, 32, "SHA-256" }; @@ -302,10 +301,10 @@ static void hmacsha256_start(void *handle) 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; - put_data(&keys[2], blk, len); + return BinarySink_UPCAST(&keys[2]); } 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, unsigned long seq, unsigned char *hmac) { - unsigned char seqbuf[4]; - - PUT_32BIT_MSB_FIRST(seqbuf, seq); + BinarySink *bs = hmacsha256_sink(handle); hmacsha256_start(handle); - hmacsha256_bytes(handle, seqbuf, 4); - hmacsha256_bytes(handle, blk, len); + put_uint32(bs, seq); + put_data(bs, blk, len); 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 = { sha256_make_context, sha256_free_context, sha256_key, sha256_generate, sha256_verify, - hmacsha256_start, hmacsha256_bytes, + hmacsha256_start, hmacsha256_sink, hmacsha256_genresult, hmacsha256_verresult, "hmac-sha2-256", "hmac-sha2-256-etm@openssh.com", 32, 32, diff --git a/sshsh512.c b/sshsh512.c index 8878d33a..e16e8c9f 100644 --- a/sshsh512.c +++ b/sshsh512.c @@ -355,11 +355,10 @@ static void sha512_free(void *handle) sfree(s); } -static void sha512_bytes(void *handle, const void *p, int len) +static BinarySink *sha512_sink(void *handle) { SHA512_State *s = handle; - - put_data(s, p, len); + return BinarySink_UPCAST(s); } 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 = { - sha512_init, sha512_copy, sha512_bytes, sha512_final, sha512_free, + sha512_init, sha512_copy, sha512_sink, sha512_final, sha512_free, 64, "SHA-512" }; @@ -394,7 +393,7 @@ static void sha384_final(void *handle, unsigned char *output) } 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" }; diff --git a/sshsha.c b/sshsha.c index 7558497b..ddcab81e 100644 --- a/sshsha.c +++ b/sshsha.c @@ -260,11 +260,10 @@ static void sha1_free(void *handle) sfree(s); } -static void sha1_bytes(void *handle, const void *p, int len) +static BinarySink *sha1_sink(void *handle) { SHA_State *s = handle; - - put_data(s, p, len); + return BinarySink_UPCAST(s); } 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 = { - 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]); } -static void hmacsha1_bytes(void *handle, unsigned char const *blk, int len) +static BinarySink *hmacsha1_sink(void *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) @@ -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, unsigned long seq, unsigned char *hmac) { - unsigned char seqbuf[4]; - - PUT_32BIT_MSB_FIRST(seqbuf, seq); + BinarySink *bs = hmacsha1_sink(handle); hmacsha1_start(handle); - hmacsha1_bytes(handle, seqbuf, 4); - hmacsha1_bytes(handle, blk, len); + put_uint32(bs, seq); + put_data(bs, blk, len); 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 = { sha1_make_context, sha1_free_context, sha1_key, 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", 20, 20, "HMAC-SHA1" @@ -443,7 +440,7 @@ const struct ssh_mac ssh_hmac_sha1 = { const struct ssh_mac ssh_hmac_sha1_96 = { sha1_make_context, sha1_free_context, sha1_key, sha1_96_generate, sha1_96_verify, - hmacsha1_start, hmacsha1_bytes, + hmacsha1_start, hmacsha1_sink, hmacsha1_96_genresult, hmacsha1_96_verresult, "hmac-sha1-96", "hmac-sha1-96-etm@openssh.com", 12, 20, @@ -453,7 +450,7 @@ const struct ssh_mac ssh_hmac_sha1_96 = { const struct ssh_mac ssh_hmac_sha1_buggy = { sha1_make_context, sha1_free_context, sha1_key_buggy, sha1_generate, sha1_verify, - hmacsha1_start, hmacsha1_bytes, hmacsha1_genresult, hmacsha1_verresult, + hmacsha1_start, hmacsha1_sink, hmacsha1_genresult, hmacsha1_verresult, "hmac-sha1", NULL, 20, 16, "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 = { sha1_make_context, sha1_free_context, sha1_key_buggy, sha1_96_generate, sha1_96_verify, - hmacsha1_start, hmacsha1_bytes, + hmacsha1_start, hmacsha1_sink, hmacsha1_96_genresult, hmacsha1_96_verresult, "hmac-sha1-96", NULL, 12, 16,