From: Ian Jackson Date: Sun, 29 Sep 2019 12:58:02 +0000 (+0100) Subject: sigpubkey/sigprivkey: Provide a hash_if X-Git-Tag: v0.6.0~213 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=secnet.git;a=commitdiff_plain;h=1957436bba0bcd420f88ae9fa1126ad4574b0c53 sigpubkey/sigprivkey: Provide a hash_if 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 --- diff --git a/rsa.c b/rsa.c index 83f6e7d..4761d16 100644 --- 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 */ diff --git a/secnet.h b/secnet.h index 24894f2..b72bfc7 100644 --- 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 */