#include <stdio.h>
#include <gmp.h>
+#include <limits.h>
#include "secnet.h"
#include "util.h"
MP_INT p,g; /* prime modulus and generator */
};
-static string_t dh_makepublic(void *sst, uint8_t *secret, uint32_t secretlen)
+static string_t dh_makepublic(void *sst, uint8_t *secret, int32_t secretlen)
{
struct dh *st=sst;
string_t r;
}
static dh_makeshared_fn dh_makeshared;
-static void dh_makeshared(void *sst, uint8_t *secret, uint32_t secretlen,
+static void dh_makeshared(void *sst, uint8_t *secret, int32_t secretlen,
cstring_t rempublic, uint8_t *sharedsecret,
- uint32_t buflen)
+ int32_t buflen)
{
struct dh *st=sst;
MP_INT a, b, c;
cfgfatal(loc,"diffie-hellman","modulus must be a prime\n");
}
}
- st->ops.len=mpz_sizeinbase(&st->p,2)/8;
+
+ size_t sz=mpz_sizeinbase(&st->p,2)/8;
+ if (sz>INT_MAX) {
+ cfgfatal(loc,"diffie-hellman","modulus far too large\n");
+ }
+ if (mpz_cmp(&st->g,&st->p) >= 0) {
+ cfgfatal(loc,"diffie-hellman","generator must be less than modulus\n");
+ }
+
+ st->ops.len=sz;
+
+ st->ops.ceil_len=(mpz_sizeinbase(&st->p,2)+7)/8;
+ /* According to the docs, mpz_sizeinbase(,256) is allowed to return
+ * an answer which is 1 too large. But mpz_sizeinbase(,2) isn't. */
return new_closure(&st->cl);
}