From 9285c1b93c4ffdb970d43f26921e4aee31bc6613 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Wed, 23 Jan 2019 07:29:53 +0000 Subject: [PATCH] Identify hash function implementations in the Event Log. Similarly to the 'AES (unaccelerated)' naming scheme I added in the AES rewrite, the hash functions that have multiple implementations now each come with an annotation saying which one they are. This was more tricky for hashes than for ciphers, because the annotation for a hash has to be a separate string literal from the base text name, so that it can propagate into the name field for each HMAC wrapper without looking silly. --- ssh.h | 10 +++++++++- ssh2kex-client.c | 10 +++++----- ssh2kex-server.c | 6 +++--- sshhmac.c | 22 ++++++++++++++++------ sshmd5.c | 2 +- sshsh256.c | 11 ++++++----- sshsh512.c | 6 ++++-- sshsha.c | 11 ++++++----- 8 files changed, 50 insertions(+), 28 deletions(-) diff --git a/ssh.h b/ssh.h index d0eff519..ef502834 100644 --- a/ssh.h +++ b/ssh.h @@ -664,7 +664,9 @@ struct ssh_hashalg { void (*free)(ssh_hash *); int hlen; /* output length in bytes */ int blocklen; /* length of the hash's input block, or 0 for N/A */ - const char *text_name; + const char *text_basename; /* the semantic name of the hash */ + const char *annotation; /* extra info, e.g. which of multiple impls */ + const char *text_name; /* both combined, e.g. "SHA-n (unaccelerated)" */ }; #define ssh_hash_new(alg) ((alg)->new(alg)) @@ -673,6 +675,12 @@ struct ssh_hashalg { #define ssh_hash_free(ctx) ((ctx)->vt->free(ctx)) #define ssh_hash_alg(ctx) ((ctx)->vt) +/* Handy macros for defining all those text-name fields at once */ +#define HASHALG_NAMES_BARE(base) \ + base, NULL, base +#define HASHALG_NAMES_ANNOTATED(base, annotation) \ + base, annotation, base " (" annotation ")" + void hash_simple(const ssh_hashalg *alg, ptrlen data, void *output); struct ssh_kex { diff --git a/ssh2kex-client.c b/ssh2kex-client.c index a5e48e00..ba3d689b 100644 --- a/ssh2kex-client.c +++ b/ssh2kex-client.c @@ -94,7 +94,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) ppl_logevent("Doing Diffie-Hellman key exchange using %d-bit " "modulus and hash %s with a server-supplied group", dh_modulus_bit_size(s->dh_ctx), - s->kex_alg->hash->text_name); + ssh_hash_alg(s->exhash)->text_name); } else { s->ppl.bpp->pls->kctx = SSH2_PKTCTX_DHGROUP; s->dh_ctx = dh_setup_group(s->kex_alg); @@ -104,7 +104,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) ppl_logevent("Doing Diffie-Hellman key exchange using %d-bit " "modulus and hash %s with standard group \"%s\"", dh_modulus_bit_size(s->dh_ctx), - s->kex_alg->hash->text_name, + ssh_hash_alg(s->exhash)->text_name, s->kex_alg->groupname); } @@ -180,7 +180,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) ppl_logevent("Doing ECDH key exchange with curve %s and hash %s", ssh_ecdhkex_curve_textname(s->kex_alg), - s->kex_alg->hash->text_name); + ssh_hash_alg(s->exhash)->text_name); s->ppl.bpp->pls->kctx = SSH2_PKTCTX_ECDHKEX; s->ecdh_key = ssh_ecdhkex_newkey(s->kex_alg); @@ -314,7 +314,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) } ppl_logevent("Doing GSSAPI (with Kerberos V5) Diffie-Hellman key " - "exchange with hash %s", s->kex_alg->hash->text_name); + "exchange with hash %s", ssh_hash_alg(s->exhash)->text_name); /* Now generate e for Diffie-Hellman. */ seat_set_busy_status(s->ppl.seat, BUSY_CPU); s->e = dh_create_e(s->dh_ctx, s->nbits * 2); @@ -513,7 +513,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) assert(s->kex_alg->main_type == KEXTYPE_RSA); ppl_logevent("Doing RSA key exchange with hash %s", - s->kex_alg->hash->text_name); + ssh_hash_alg(s->exhash)->text_name); s->ppl.bpp->pls->kctx = SSH2_PKTCTX_RSAKEX; /* * RSA key exchange. First expect a KEXRSA_PUBKEY packet diff --git a/ssh2kex-server.c b/ssh2kex-server.c index eb2c898f..d86a59f6 100644 --- a/ssh2kex-server.c +++ b/ssh2kex-server.c @@ -119,7 +119,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) } ppl_logevent("Doing Diffie-Hellman key exchange with hash %s", - s->kex_alg->hash->text_name); + ssh_hash_alg(s->exhash)->text_name); /* * Generate e for Diffie-Hellman. @@ -187,7 +187,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) } else if (s->kex_alg->main_type == KEXTYPE_ECDH) { ppl_logevent("Doing ECDH key exchange with curve %s and hash %s", ssh_ecdhkex_curve_textname(s->kex_alg), - s->kex_alg->hash->text_name); + ssh_hash_alg(s->exhash)->text_name); s->ppl.bpp->pls->kctx = SSH2_PKTCTX_ECDHKEX; s->ecdh_key = ssh_ecdhkex_newkey(s->kex_alg); @@ -240,7 +240,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted) } else { assert(s->kex_alg->main_type == KEXTYPE_RSA); ppl_logevent("Doing RSA key exchange with hash %s", - s->kex_alg->hash->text_name); + ssh_hash_alg(s->exhash)->text_name); s->ppl.bpp->pls->kctx = SSH2_PKTCTX_RSAKEX; { diff --git a/sshhmac.c b/sshhmac.c index 9bbce124..13c18e4a 100644 --- a/sshhmac.c +++ b/sshhmac.c @@ -16,7 +16,7 @@ struct hmac { struct hmac_extra { const ssh_hashalg *hashalg_base; - const char *suffix; + const char *suffix, *annotation; }; static ssh2_mac *hmac_new(const ssh2_macalg *alg, ssh_cipher *cipher) @@ -44,8 +44,21 @@ static ssh2_mac *hmac_new(const ssh2_macalg *alg, ssh_cipher *cipher) ctx->digest = snewn(ctx->hashalg->hlen, uint8_t); ctx->text_name = strbuf_new(); - strbuf_catf(ctx->text_name, "HMAC-%s%s", - ctx->hashalg->text_name, extra->suffix); + strbuf_catf(ctx->text_name, "HMAC-%s", + ctx->hashalg->text_basename, extra->suffix); + if (extra->annotation || ctx->hashalg->annotation) { + strbuf_catf(ctx->text_name, " ("); + const char *sep = ""; + if (extra->annotation) { + strbuf_catf(ctx->text_name, "%s%s", sep, extra->annotation); + sep = ", "; + } + if (ctx->hashalg->annotation) { + strbuf_catf(ctx->text_name, "%s%s", sep, ctx->hashalg->annotation); + sep = ", "; + } + strbuf_catf(ctx->text_name, ")"); + } ctx->mac.vt = alg; BinarySink_DELEGATE_INIT(&ctx->mac, ctx->h_live); @@ -56,7 +69,6 @@ static ssh2_mac *hmac_new(const ssh2_macalg *alg, ssh_cipher *cipher) static void hmac_free(ssh2_mac *mac) { struct hmac *ctx = container_of(mac, struct hmac, mac); - const struct hmac_extra *extra = (const struct hmac_extra *)mac->vt->extra; ssh_hash_free(ctx->h_outer); ssh_hash_free(ctx->h_inner); @@ -75,7 +87,6 @@ static void hmac_free(ssh2_mac *mac) static void hmac_key(ssh2_mac *mac, ptrlen key) { struct hmac *ctx = container_of(mac, struct hmac, mac); - const struct hmac_extra *extra = (const struct hmac_extra *)mac->vt->extra; const uint8_t *kp; size_t klen; @@ -149,7 +160,6 @@ static void hmac_start(ssh2_mac *mac) static void hmac_genresult(ssh2_mac *mac, unsigned char *output) { struct hmac *ctx = container_of(mac, struct hmac, mac); - const struct hmac_extra *extra = (const struct hmac_extra *)mac->vt->extra; ssh_hash *htmp; /* Leave h_live in place, so that the SSH-2 BPP can continue diff --git a/sshmd5.c b/sshmd5.c index 2a083f8d..504211f8 100644 --- a/sshmd5.c +++ b/sshmd5.c @@ -271,5 +271,5 @@ static void md5_final(ssh_hash *hash, unsigned char *output) } const ssh_hashalg ssh_md5 = { - md5_new, md5_copy, md5_final, md5_free, 16, 64, "MD5" + md5_new, md5_copy, md5_final, md5_free, 16, 64, HASHALG_NAMES_BARE("MD5"), }; diff --git a/sshsh256.c b/sshsh256.c index 9a54ea99..d90cd9d9 100644 --- a/sshsh256.c +++ b/sshsh256.c @@ -99,7 +99,7 @@ static ssh_hash *sha256_select(const ssh_hashalg *alg) const ssh_hashalg ssh_sha256 = { sha256_select, NULL, NULL, NULL, - 32, 64, "SHA-256", + 32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "dummy selector vtable"), }; /* ---------------------------------------------------------------------- @@ -327,7 +327,7 @@ static void sha256_sw_final(ssh_hash *hash, uint8_t *digest) const ssh_hashalg ssh_sha256_sw = { sha256_sw_new, sha256_sw_copy, sha256_sw_final, sha256_sw_free, - 32, 64, "SHA-256", + 32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "unaccelerated"), }; /* ---------------------------------------------------------------------- @@ -684,7 +684,7 @@ FUNC_ISA static void sha256_ni_final(ssh_hash *hash, uint8_t *digest) const ssh_hashalg ssh_sha256_hw = { sha256_ni_new, sha256_ni_copy, sha256_ni_final, sha256_ni_free, - 32, 64, "SHA-256", + 32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "SHA-NI accelerated"), }; /* ---------------------------------------------------------------------- @@ -871,7 +871,7 @@ static void sha256_neon_final(ssh_hash *hash, uint8_t *digest) const ssh_hashalg ssh_sha256_hw = { sha256_neon_new, sha256_neon_copy, sha256_neon_final, sha256_neon_free, - 32, 64, "SHA-256", + 32, 64, HASHALG_NAMES_ANNOTATED("SHA-256", "NEON accelerated"), }; /* ---------------------------------------------------------------------- @@ -902,7 +902,8 @@ static void sha256_stub_final(ssh_hash *hash, uint8_t *digest) STUB_BODY const ssh_hashalg ssh_sha256_hw = { sha256_stub_new, sha256_stub_copy, sha256_stub_final, sha256_stub_free, - 32, 64, "SHA-256", + 32, 64, HASHALG_NAMES_ANNOTATED( + "SHA-256", "!NONEXISTENT ACCELERATED VERSION!"), }; #endif /* HW_SHA256 */ diff --git a/sshsh512.c b/sshsh512.c index bacba0d4..30c1a09d 100644 --- a/sshsh512.c +++ b/sshsh512.c @@ -343,7 +343,8 @@ static void sha512_final(ssh_hash *hash, unsigned char *output) } const ssh_hashalg ssh_sha512 = { - sha512_new, sha512_copy, sha512_final, sha512_free, 64, BLKSIZE, "SHA-512" + sha512_new, sha512_copy, sha512_final, sha512_free, + 64, BLKSIZE, HASHALG_NAMES_BARE("SHA-512"), }; static ssh_hash *sha384_new(const ssh_hashalg *alg) @@ -363,5 +364,6 @@ static void sha384_final(ssh_hash *hash, unsigned char *output) } const ssh_hashalg ssh_sha384 = { - sha384_new, sha512_copy, sha384_final, sha512_free, 48, BLKSIZE, "SHA-384" + sha384_new, sha512_copy, sha384_final, sha512_free, + 48, BLKSIZE, HASHALG_NAMES_BARE("SHA-384"), }; diff --git a/sshsha.c b/sshsha.c index 52626b74..eaf81c51 100644 --- a/sshsha.c +++ b/sshsha.c @@ -99,7 +99,7 @@ static ssh_hash *sha1_select(const ssh_hashalg *alg) const ssh_hashalg ssh_sha1 = { sha1_select, NULL, NULL, NULL, - 20, 64, "SHA-1", + 20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "dummy selector vtable"), }; /* ---------------------------------------------------------------------- @@ -310,7 +310,7 @@ static void sha1_sw_final(ssh_hash *hash, uint8_t *digest) const ssh_hashalg ssh_sha1_sw = { sha1_sw_new, sha1_sw_copy, sha1_sw_final, sha1_sw_free, - 20, 64, "SHA-1", + 20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "unaccelerated"), }; /* ---------------------------------------------------------------------- @@ -651,7 +651,7 @@ FUNC_ISA static void sha1_ni_final(ssh_hash *hash, uint8_t *digest) const ssh_hashalg ssh_sha1_hw = { sha1_ni_new, sha1_ni_copy, sha1_ni_final, sha1_ni_free, - 20, 64, "SHA-1", + 20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "SHA-NI accelerated"), }; /* ---------------------------------------------------------------------- @@ -867,7 +867,7 @@ static void sha1_neon_final(ssh_hash *hash, uint8_t *digest) const ssh_hashalg ssh_sha1_hw = { sha1_neon_new, sha1_neon_copy, sha1_neon_final, sha1_neon_free, - 20, 64, "SHA-1", + 20, 64, HASHALG_NAMES_ANNOTATED("SHA-1", "NEON accelerated"), }; /* ---------------------------------------------------------------------- @@ -898,7 +898,8 @@ static void sha1_stub_final(ssh_hash *hash, uint8_t *digest) STUB_BODY const ssh_hashalg ssh_sha1_hw = { sha1_stub_new, sha1_stub_copy, sha1_stub_final, sha1_stub_free, - 20, 64, "SHA-1", + 20, 64, HASHALG_NAMES_ANNOTATED( + "SHA-1", "!NONEXISTENT ACCELERATED VERSION!"), }; #endif /* HW_SHA1 */