+/*
+ * Diffie-Hellman implementation for PuTTY.
+ */
+
#include "ssh.h"
/*
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[] = {
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[] = {
static const struct ssh_kex ssh_diffiehellman_gex_sha256 = {
"diffie-hellman-group-exchange-sha256", NULL,
- NULL, NULL, 0, 0, &ssh_sha256
+ 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[] = {
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.
*/