Description: Be more careful about key lengths
Generate keys more carefully, so that when the user asks for an nbit key
they always get an nbit number instead of n1. The latter was perfectly
harmless but kept confusing users.
Origin: upstream, http://svn.tartarus.org/sgt?view=rev&revision=9421
Origin: upstream, http://svn.tartarus.org/sgt?view=rev&revision=9422
Forwarded: notneeded
LastUpdate: 20120304
Index: b/doc/pubkey.but
===================================================================
 a/doc/pubkey.but
+++ b/doc/pubkey.but
@@ 151,18 +151,6 @@
Currently 1024 bits should be sufficient for most purposes.
Note that an RSA key is generated by finding two primes of half the
length requested, and then multiplying them together. For example,
if you ask PuTTYgen for a 1024bit RSA key, it will create two
512bit primes and multiply them. The result of this multiplication
might be 1024 bits long, or it might be only 1023; so you may not
get the exact length of key you asked for. This is perfectly normal,
and you do not need to worry. The lengths should only ever differ by
one, and there is no perceptible drop in security as a result.

DSA keys are not created by multiplying primes together, so they
should always be exactly the length you asked for.

\S{puttygengenerate} The \q{Generate} button
\cfg{winhelptopic}{puttygen.generate}
Index: b/ssh.h
===================================================================
 a/ssh.h
+++ b/ssh.h
@@ 550,7 +550,8 @@
int dsa_generate(struct dss_key *key, int bits, progfn_t pfn,
void *pfnparam);
Bignum primegen(int bits, int modulus, int residue, Bignum factor,
 int phase, progfn_t pfn, void *pfnparam);
+ int phase, progfn_t pfn, void *pfnparam, unsigned firstbits);
+void invent_firstbits(unsigned *one, unsigned *two);
/*
Index: b/sshdssg.c
===================================================================
 a/sshdssg.c
+++ b/sshdssg.c
@@ 9,6 +9,7 @@
void *pfnparam)
{
Bignum qm1, power, g, h, tmp;
+ unsigned pfirst, qfirst;
int progress;
/*
@@ 70,15 +71,16 @@
pfn(pfnparam, PROGFN_READY, 0, 0);
+ invent_firstbits(&pfirst, &qfirst);
/*
* Generate q: a prime of length 160.
*/
 key>q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam);
+ key>q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam, qfirst);
/*
* Now generate p: a prime of length `bits', such that p1 is
* divisible by q.
*/
 key>p = primegen(bits160, 2, 2, key>q, 2, pfn, pfnparam);
+ key>p = primegen(bits160, 2, 2, key>q, 2, pfn, pfnparam, pfirst);
/*
* Next we need g. Raise 2 to the power (p1)/q modulo p, and
Index: b/sshprime.c
===================================================================
 a/sshprime.c
+++ b/sshprime.c
@@ 1193,11 +1193,19 @@
* more than a multiple of a dirty great bignum. In this case
* `bits' gives the size of the factor by which we _multiply_
* that bignum, rather than the size of the whole number.
+ *
+ *  for the basically cosmetic purposes of generating keys of the
+ * length actually specified rather than off by one bit, we permit
+ * the caller to provide an unsigned integer 'firstbits' which will
+ * match the top few bits of the returned prime. (That is, there
+ * will exist some n such that (returnvalue >> n) == firstbits.) If
+ * 'firstbits' is not needed, specifying it to either 0 or 1 is
+ * an adequate noop.
*/
Bignum primegen(int bits, int modulus, int residue, Bignum factor,
 int phase, progfn_t pfn, void *pfnparam)
+ int phase, progfn_t pfn, void *pfnparam, unsigned firstbits)
{
 int i, k, v, byte, bitsleft, check, checks;
+ int i, k, v, byte, bitsleft, check, checks, fbsize;
unsigned long delta;
unsigned long moduli[NPRIMES + 1];
unsigned long residues[NPRIMES + 1];
@@ 1208,6 +1216,10 @@
byte = 0;
bitsleft = 0;
+ fbsize = 0;
+ while (firstbits >> fbsize) /* work out how to align this */
+ fbsize++;
+
STARTOVER:
pfn(pfnparam, PROGFN_PROGRESS, phase, ++progress);
@@ 1220,9 +1232,11 @@
*/
p = bn_power_2(bits  1);
for (i = 0; i < bits; i++) {
 if (i == 0  i == bits  1)
+ if (i == 0  i == bits  1) {
v = (i != 0  !factor) ? 1 : 0;
 else {
+ } else if (i >= bits  fbsize) {
+ v = (firstbits >> (i  (bits  fbsize))) & 1;
+ } else {
if (bitsleft <= 0)
bitsleft = 8, byte = random_byte();
v = byte & 1;
@@ 1396,3 +1410,32 @@
freebn(pm1);
return p;
}
+
+/*
+ * Invent a pair of values suitable for use as 'firstbits' in the
+ * above function, such that their product is at least 2.
+ *
+ * This is used for generating both RSA and DSA keys which have
+ * exactly the specified number of bits rather than one fewer  if you
+ * generate an abit and a bbit number completely at random and
+ * multiply them together, you could end up with either an (ab1)bit
+ * number or an (ab)bit number. The former happens log(2)*21 of the
+ * time (about 39%) and, though actually harmless, every time it
+ * occurs it has a nonzero probability of sparking a user email along
+ * the lines of 'Hey, I asked PuTTYgen for a 2048bit key and I only
+ * got 2047 bits! Bug!'
+ */
+void invent_firstbits(unsigned *one, unsigned *two)
+{
+ /*
+ * Our criterion is that any number in the range [one,one+1)
+ * multiplied by any number in the range [two,two+1) should have
+ * the highest bit set. It should be clear that we can trivially
+ * test this by multiplying the smallest values in each interval,
+ * i.e. the ones we actually invented.
+ */
+ do {
+ *one = 0x100  random_byte();
+ *two = 0x100  random_byte();
+ } while (*one * *two < 0x20000);
+}
Index: b/sshrsag.c
===================================================================
 a/sshrsag.c
+++ b/sshrsag.c
@@ 10,6 +10,7 @@
void *pfnparam)
{
Bignum pm1, qm1, phi_n;
+ unsigned pfirst, qfirst;
/*
* Set up the phase limits for the progress report. We do this
@@ 59,10 +60,11 @@
* general that's slightly more fiddly to arrange. By choosing
* a prime e, we can simplify the criterion.)
*/
+ invent_firstbits(&pfirst, &qfirst);
key>p = primegen(bits / 2, RSA_EXPONENT, 1, NULL,
 1, pfn, pfnparam);
+ 1, pfn, pfnparam, pfirst);
key>q = primegen(bits  bits / 2, RSA_EXPONENT, 1, NULL,
 2, pfn, pfnparam);
+ 2, pfn, pfnparam, qfirst);
/*
* Ensure p > q, by swapping them if not.