From a209b9044e6536243b4c1b662300b2055776bab2 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Tue, 19 May 2015 08:42:23 +0100 Subject: [PATCH] Log which elliptic curve we're using for ECDH kex. It seems like quite an important thing to mention in the event log! Suppose there's a bug affecting only one curve, for example? Fixed- group Diffie-Hellman has always logged the group, but the ECDH log message just told you the hash and not also the curve. To implement this, I've added a 'textname' field to all elliptic curves, whether they're used for kex or signing or both, suitable for use in this log message and any others we might find a need for in future. --- ssh.c | 3 ++- ssh.h | 10 +++++++++- sshecc.c | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/ssh.c b/ssh.c index b56e155e..9cf64a16 100644 --- a/ssh.c +++ b/ssh.c @@ -6770,7 +6770,8 @@ static void do_ssh2_transport(Ssh ssh, const void *vin, int inlen, } } else if (ssh->kex->main_type == KEXTYPE_ECDH) { - logeventf(ssh, "Doing ECDH key exchange with hash %s", + logeventf(ssh, "Doing ECDH key exchange with curve %s and hash %s", + ssh_ecdhkex_curve_textname(ssh->kex), ssh->kex->hash->text_name); ssh->pkt_kctx = SSH2_PKTCTX_ECDHKEX; diff --git a/ssh.h b/ssh.h index 1317ca4b..81c003ba 100644 --- a/ssh.h +++ b/ssh.h @@ -134,7 +134,14 @@ struct ec_ecurve struct ec_curve { enum { EC_WEIERSTRASS, EC_MONTGOMERY, EC_EDWARDS } type; - const char *name; + /* 'name' is the identifier of the curve when it has to appear in + * wire protocol encodings, as it does in e.g. the public key and + * signature formats for NIST curves. Curves which do not format + * their keys or signatures in this way just have name==NULL. + * + * 'textname' is non-NULL for all curves, and is a human-readable + * identification suitable for putting in log messages. */ + const char *name, *textname; unsigned int fieldBits; Bignum p; union { @@ -210,6 +217,7 @@ void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen, * SSH2 ECDH key exchange functions */ struct ssh_kex; +const char *ssh_ecdhkex_curve_textname(const struct ssh_kex *kex); void *ssh_ecdhkex_newkey(const struct ssh_kex *kex); void ssh_ecdhkex_freekey(void *key); char *ssh_ecdhkex_getpublic(void *key, int *len); diff --git a/sshecc.c b/sshecc.c index 32f14de3..13b3cdd3 100644 --- a/sshecc.c +++ b/sshecc.c @@ -157,7 +157,7 @@ static struct ec_curve *ec_p256(void) }; initialise_wcurve(&curve, 256, p, a, b, n, Gx, Gy); - curve.name = "nistp256"; + curve.textname = curve.name = "nistp256"; /* Now initialised, no need to do it again */ initialised = 1; @@ -223,7 +223,7 @@ static struct ec_curve *ec_p384(void) }; initialise_wcurve(&curve, 384, p, a, b, n, Gx, Gy); - curve.name = "nistp384"; + curve.textname = curve.name = "nistp384"; /* Now initialised, no need to do it again */ initialised = 1; @@ -307,7 +307,7 @@ static struct ec_curve *ec_p521(void) }; initialise_wcurve(&curve, 521, p, a, b, n, Gx, Gy); - curve.name = "nistp521"; + curve.textname = curve.name = "nistp521"; /* Now initialised, no need to do it again */ initialised = 1; @@ -352,6 +352,7 @@ static struct ec_curve *ec_curve25519(void) /* This curve doesn't need a name, because it's never used in * any format that embeds the curve name */ curve.name = NULL; + curve.textname = "Curve25519"; /* Now initialised, no need to do it again */ initialised = 1; @@ -403,6 +404,7 @@ static struct ec_curve *ec_ed25519(void) curve.name = NULL; initialise_ecurve(&curve, 256, q, l, d, Bx, By); + curve.textname = "Ed25519"; /* Now initialised, no need to do it again */ initialised = 1; @@ -2704,6 +2706,13 @@ static Bignum ecdh_calculate(const Bignum private, return ret; } +const char *ssh_ecdhkex_curve_textname(const struct ssh_kex *kex) +{ + const struct eckex_extra *extra = (const struct eckex_extra *)kex->extra; + struct ec_curve *curve = extra->curve(); + return curve->textname; +} + void *ssh_ecdhkex_newkey(const struct ssh_kex *kex) { const struct eckex_extra *extra = (const struct eckex_extra *)kex->extra;