chiark / gitweb /
sigpubkey/sigprivkey: Provide a hash_if
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 29 Sep 2019 12:58:02 +0000 (13:58 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 30 Dec 2019 13:15:49 +0000 (13:15 +0000)
Sometimes, the caller is going to want to hash things for themselves.
(Notably, site.c will want to hash the advertisements of public key
set updates.)

The hash to be used should be the one used by the signature scheme, as
that has the same security properties.

In rsa.c this moves the hash_if from common to ops, and it is now
convenient to abolish rsa_hash which is a pointless veneer over
hash_hash.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
rsa.c
secnet.h

diff --git a/rsa.c b/rsa.c
index 83f6e7d99a345774de5df43ff16e912f33bb3d2e..4761d1607294e15fbeb85837ecba054b5d3d9ba5 100644 (file)
--- a/rsa.c
+++ b/rsa.c
@@ -42,7 +42,6 @@
 #define mpp(s,n) do { char *p = mpz_get_str(NULL,16,n); printf("%s 0x%sL\n", s, p); free(p); } while (0)
 
 struct rsacommon {
-    struct hash_if *hashi;
     uint8_t *hashbuf;
 };
 
@@ -74,25 +73,22 @@ struct rsapub {
 
 static const char *hexchars="0123456789abcdef";
 
-static void rsa_sethash(struct rsacommon *c, struct hash_if *hash)
+static void rsa_sethash(struct rsacommon *c, struct hash_if *hash,
+                       const struct hash_if **in_ops)
 {
     free(c->hashbuf);
     c->hashbuf=safe_malloc(hash->hlen, "generate_msg");
-    c->hashi=hash;
+    *in_ops=hash;
 }
 static void rsa_pub_sethash(void *sst, struct hash_if *hash)
 {
     struct rsapub *st=sst;
-    rsa_sethash(&st->common, hash);
+    rsa_sethash(&st->common, hash, &st->ops.hash);
 }
 static void rsa_priv_sethash(void *sst, struct hash_if *hash)
 {
     struct rsapriv *st=sst;
-    rsa_sethash(&st->common, hash);
-}
-static void rsa_hash(struct rsacommon *c, const uint8_t *buf, int32_t len)
-{
-    hash_hash(c->hashi,buf,len,c->hashbuf);
+    rsa_sethash(&st->common, hash, &st->ops.hash);
 }
 
 static void emsa_pkcs1(MP_INT *n, MP_INT *m,
@@ -154,9 +150,9 @@ static bool_t rsa_sign(void *sst, uint8_t *data, int32_t datalen,
     mpz_init(&a);
     mpz_init(&b);
 
-    rsa_hash(&st->common,data,datalen);
+    hash_hash(st->ops.hash,data,datalen,st->common.hashbuf);
     /* Construct the message representative. */
-    emsa_pkcs1(&st->n, &a, st->common.hashbuf, st->common.hashi->hlen);
+    emsa_pkcs1(&st->n, &a, st->common.hashbuf, st->ops.hash->hlen);
 
     /*
      * Produce an RSA signature (a^d mod n) using the Chinese
@@ -242,8 +238,8 @@ static bool_t rsa_sig_check(void *sst, uint8_t *data, int32_t datalen,
     mpz_init(&b);
     mpz_init(&c);
 
-    rsa_hash(&st->common,data,datalen);
-    emsa_pkcs1(&st->n, &a, st->common.hashbuf, st->common.hashi->hlen);
+    hash_hash(st->ops.hash,data,datalen,st->common.hashbuf);
+    emsa_pkcs1(&st->n, &a, st->common.hashbuf, st->ops.hash->hlen);
 
     /* Terminate signature with a '0' - already checked that this will fit */
     int save = sig->start[sig->len];
@@ -279,6 +275,7 @@ static list_t *rsapub_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->common.hashbuf=NULL;
     st->ops.unpick=rsa_sig_unpick;
     st->ops.check=rsa_sig_check;
+    st->ops.hash=0;
     st->loc=loc;
 
     i=list_elem(args,0);
@@ -359,6 +356,7 @@ static list_t *rsapriv_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->ops.sethash=rsa_priv_sethash;
     st->common.hashbuf=NULL;
     st->ops.sign=rsa_sign;
+    st->ops.hash=0;
     st->loc=loc;
 
     /* Argument is filename pointing to SSH1 private key file */
index 24894f2759579a7b8410cfc332a4e7cdb070e531..b72bfc7fc42bc6ca26b65017851b8ffb6147f323 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -457,9 +457,10 @@ typedef bool_t sig_checksig_fn(void *st, uint8_t *data, int32_t datalen,
                               const struct alg_msg_data *sig);
 struct sigpubkey_if {
     void *st;
-    sig_sethash_fn *sethash; /* must be called before check, if non-0 */
+    sig_sethash_fn *sethash; /* must be called before use, if non-0 */
     sig_unpick_fn *unpick;
     sig_checksig_fn *check;
+    const struct hash_if *hash;
 };
 
 /* SIGPRIVKEY interface */
@@ -470,8 +471,9 @@ typedef bool_t sig_makesig_fn(void *st, uint8_t *data, int32_t datalen,
                              struct buffer_if *msg);
 struct sigprivkey_if {
     void *st;
-    sig_sethash_fn *sethash; /* must be called before sign, if non-0 */
+    sig_sethash_fn *sethash; /* must be called before use, if non-0 */
     sig_makesig_fn *sign;
+    const struct hash_if *hash;
 };
 
 /* COMM interface */