dss_sign() is unused outside this file. Make it static.
[u/mdw/putty] / sshdss.c
index b2179a8..7489467 100644 (file)
--- a/sshdss.c
+++ b/sshdss.c
@@ -19,7 +19,6 @@
 
 static void sha_mpint(SHA_State * s, Bignum b)
 {
-    unsigned char *p;
     unsigned char lenbuf[4];
     int len;
     len = (bignum_bitcount(b) + 8) / 8;
@@ -34,7 +33,6 @@ static void sha_mpint(SHA_State * s, Bignum b)
 
 static void sha512_mpint(SHA512_State * s, Bignum b)
 {
-    unsigned char *p;
     unsigned char lenbuf[4];
     int len;
     len = (bignum_bitcount(b) + 8) / 8;
@@ -72,7 +70,7 @@ static Bignum getmp(char **data, int *datalen)
        return NULL;
     if (p[0] & 0x80)
        return NULL;                   /* negative mp */
-    b = bignum_from_bytes(p, length);
+    b = bignum_from_bytes((unsigned char *)p, length);
     return b;
 }
 
@@ -80,7 +78,7 @@ static Bignum get160(char **data, int *datalen)
 {
     Bignum b;
 
-    b = bignum_from_bytes(*data, 20);
+    b = bignum_from_bytes((unsigned char *)*data, 20);
     *data += 20;
     *datalen -= 20;
 
@@ -190,7 +188,7 @@ static char *dss_fingerprint(void *key)
     int numlen, i;
 
     MD5Init(&md5c);
-    MD5Update(&md5c, "\0\0\0\7ssh-dss", 11);
+    MD5Update(&md5c, (unsigned char *)"\0\0\0\7ssh-dss", 11);
 
 #define ADD_BIGNUM(bignum) \
     numlen = (bignum_bitcount(bignum)+8)/8; \
@@ -270,7 +268,7 @@ static int dss_verifysig(void *key, char *sig, int siglen,
     /*
      * Step 2. u1 <- SHA(message) * w mod q.
      */
-    SHA_Simple(data, datalen, hash);
+    SHA_Simple(data, datalen, (unsigned char *)hash);
     p = hash;
     slen = 20;
     sha = get160(&p, &slen);
@@ -357,31 +355,19 @@ static unsigned char *dss_private_blob(void *key, int *len)
     int xlen, bloblen;
     int i;
     unsigned char *blob, *p;
-    SHA_State s;
-    unsigned char digest[20];
 
     xlen = (bignum_bitcount(dss->x) + 8) / 8;
 
     /*
-     * mpint x, string[20] the SHA of p||q||g. Total 28 + xlen.
-     * (two length fields and twenty bytes, 20+8=28).
+     * mpint x, string[20] the SHA of p||q||g. Total 4 + xlen.
      */
-    bloblen = 28 + xlen;
+    bloblen = 4 + xlen;
     blob = smalloc(bloblen);
     p = blob;
     PUT_32BIT(p, xlen);
     p += 4;
     for (i = xlen; i--;)
        *p++ = bignum_byte(dss->x, i);
-    PUT_32BIT(p, 20);
-    SHA_Init(&s);
-    sha_mpint(&s, dss->p);
-    sha_mpint(&s, dss->q);
-    sha_mpint(&s, dss->g);
-    SHA_Final(&s, digest);
-    p += 4;
-    for (i = 0; i < 20; i++)
-       *p++ = digest[i];
     assert(p == blob + bloblen);
     *len = bloblen;
     return blob;
@@ -400,24 +386,22 @@ static void *dss_createkey(unsigned char *pub_blob, int pub_len,
 
     dss = dss_newkey((char *) pub_blob, pub_len);
     dss->x = getmp(&pb, &priv_len);
-    getstring(&pb, &priv_len, &hash, &hashlen);
 
     /*
-     * Verify details of the key. First check that the hash is
-     * indeed a hash of p||q||g.
+     * Check the obsolete hash in the old DSS key format.
      */
-    if (hashlen != 20) {
-       dss_freekey(dss);
-       return NULL;
-    }
-    SHA_Init(&s);
-    sha_mpint(&s, dss->p);
-    sha_mpint(&s, dss->q);
-    sha_mpint(&s, dss->g);
-    SHA_Final(&s, digest);
-    if (0 != memcmp(hash, digest, 20)) {
-       dss_freekey(dss);
-       return NULL;
+    hashlen = -1;
+    getstring(&pb, &priv_len, &hash, &hashlen);
+    if (hashlen == 20) {
+       SHA_Init(&s);
+       sha_mpint(&s, dss->p);
+       sha_mpint(&s, dss->q);
+       sha_mpint(&s, dss->g);
+       SHA_Final(&s, digest);
+       if (0 != memcmp(hash, digest, 20)) {
+           dss_freekey(dss);
+           return NULL;
+       }
     }
 
     /*
@@ -489,7 +473,7 @@ static int dss_openssh_fmtkey(void *key, unsigned char *blob, int len)
     return bloblen;
 }
 
-unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen)
+static unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen)
 {
     /*
      * The basic DSS signing algorithm is:
@@ -546,9 +530,16 @@ unsigned char *dss_sign(void *key, char *data, int datalen, int *siglen)
      * signing the same hash twice with the same key yields the
      * same signature.
      * 
-     * (It doesn't, _per se_, protect against reuse of k. Reuse of
-     * k is left to chance; all it does is prevent _excessively
-     * high_ chances of reuse of k due to entropy problems.)
+     * Despite this determinism, it's still not predictable to an
+     * attacker, because in order to repeat the SHA-512
+     * construction that created it, the attacker would have to
+     * know the private key value x - and by assumption he doesn't,
+     * because if he knew that he wouldn't be attacking k!
+     *
+     * (This trick doesn't, _per se_, protect against reuse of k.
+     * Reuse of k is left to chance; all it does is prevent
+     * _excessively high_ chances of reuse of k due to entropy
+     * problems.)
      * 
      * Thanks to Colin Plumb for the general idea of using x to
      * ensure k is hard to guess, and to the Cambridge University