X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;ds=sidebyside;f=sshdh.c;h=8f8ab2d26aa6ef9ad7e5fe74710edca473272245;hb=a063e522970946bf7d5dc052079d7773c0dee76d;hp=9d24908e0fd711274324fa8b3fdce971c4c42148;hpb=a59356aa741fe92d73a4574027fae11927e72fdd;p=PuTTY.git diff --git a/sshdh.c b/sshdh.c index 9d24908e..8f8ab2d2 100644 --- a/sshdh.c +++ b/sshdh.c @@ -1,3 +1,7 @@ +/* + * Diffie-Hellman implementation for PuTTY. + */ + #include "ssh.h" /* @@ -46,19 +50,52 @@ static const unsigned char P14[] = { */ static const unsigned char G[] = { 2 }; -const struct ssh_kex ssh_diffiehellman_group1 = { +static const struct ssh_kex ssh_diffiehellman_group1_sha1 = { "diffie-hellman-group1-sha1", "group1", - P1, G, lenof(P1), lenof(G), &ssh_sha1 + KEXTYPE_DH, P1, G, lenof(P1), lenof(G), &ssh_sha1 +}; + +static const struct ssh_kex *const group1_list[] = { + &ssh_diffiehellman_group1_sha1 +}; + +const struct ssh_kexes ssh_diffiehellman_group1 = { + sizeof(group1_list) / sizeof(*group1_list), + group1_list }; -const struct ssh_kex ssh_diffiehellman_group14 = { +static const struct ssh_kex ssh_diffiehellman_group14_sha1 = { "diffie-hellman-group14-sha1", "group14", - P14, G, lenof(P14), lenof(G), &ssh_sha1 + KEXTYPE_DH, P14, G, lenof(P14), lenof(G), &ssh_sha1 +}; + +static const struct ssh_kex *const group14_list[] = { + &ssh_diffiehellman_group14_sha1 }; -const struct ssh_kex ssh_diffiehellman_gex = { +const struct ssh_kexes ssh_diffiehellman_group14 = { + sizeof(group14_list) / sizeof(*group14_list), + group14_list +}; + +static const struct ssh_kex ssh_diffiehellman_gex_sha256 = { + "diffie-hellman-group-exchange-sha256", NULL, + KEXTYPE_DH, NULL, NULL, 0, 0, &ssh_sha256 +}; + +static const struct ssh_kex ssh_diffiehellman_gex_sha1 = { "diffie-hellman-group-exchange-sha1", NULL, - NULL, NULL, 0, 0, &ssh_sha1 + KEXTYPE_DH, NULL, NULL, 0, 0, &ssh_sha1 +}; + +static const struct ssh_kex *const gex_list[] = { + &ssh_diffiehellman_gex_sha256, + &ssh_diffiehellman_gex_sha1 +}; + +const struct ssh_kexes ssh_diffiehellman_gex = { + sizeof(gex_list) / sizeof(*gex_list), + gex_list }; /* @@ -181,6 +218,29 @@ Bignum dh_create_e(void *handle, int nbits) return ctx->e; } +/* + * DH stage 2-epsilon: given a number f, validate it to ensure it's in + * range. (RFC 4253 section 8: "Values of 'e' or 'f' that are not in + * the range [1, p-1] MUST NOT be sent or accepted by either side." + * Also, we rule out 1 and p-1 too, since that's easy to do and since + * they lead to obviously weak keys that even a passive eavesdropper + * can figure out.) + */ +const char *dh_validate_f(void *handle, Bignum f) +{ + struct dh_ctx *ctx = (struct dh_ctx *)handle; + if (bignum_cmp(f, One) <= 0) { + return "f value received is too small"; + } else { + Bignum pm1 = bigsub(ctx->p, One); + int cmp = bignum_cmp(f, pm1); + freebn(pm1); + if (cmp >= 0) + return "f value received is too large"; + } + return NULL; +} + /* * DH stage 2: given a number f, compute K = f^x mod p. */