X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/8b810a45dec25017a6256e4ef134236444a00921..42ca150ce7fa024a8fd6a4c9433b613175270eb4:/dsa.h diff --git a/dsa.h b/dsa.h index 1958d50..43ff845 100644 --- a/dsa.h +++ b/dsa.h @@ -1,13 +1,13 @@ /* -*-c-*- * - * $Id: dsa.h,v 1.1 1999/11/19 19:28:00 mdw Exp $ + * $Id: dsa.h,v 1.9 2004/04/08 01:36:15 mdw Exp $ * * Digital Signature Algorithm * * (c) 1999 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of Catacomb. * @@ -15,28 +15,20 @@ * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. - * + * * Catacomb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. - * + * * You should have received a copy of the GNU Library General Public * License along with Catacomb; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: dsa.h,v $ - * Revision 1.1 1999/11/19 19:28:00 mdw - * Implementation of the Digital Signature Algorithm. - * - */ - -#ifndef DSA_H -#define DSA_H +#ifndef CATACOMB_DSA_H +#define CATACOMB_DSA_H #ifdef __cplusplus extern "C" { @@ -53,41 +45,41 @@ /*----- Header files ------------------------------------------------------*/ -#ifndef MP_H -# include "mp.h" +#ifndef CATACOMB_DH_H +# include "dh.h" #endif -/*----- Event codes -------------------------------------------------------*/ - -enum { - DSAEV_OK, /* Everything is fine */ +#ifndef CATACOMB_KEY_H +# include "key.h" +#endif - DSAEV_FAILQ, /* @q@ failed primality test */ - DSAEV_PASSQ, /* @q@ passeed one iteration */ - DSAEV_GOODQ, /* Found good prime @q@ */ +#ifndef CATACOMB_KEYCHECK_H +# include "keycheck.h" +#endif - DSAEV_TRYP, /* Try prospective @p@ */ - DSAEV_FAILP, /* @p@ failed primality test */ - DSAEV_PASSP, /* @p@ passed one iteration */ - DSAEV_GOODP, /* @p@ accepted as being prime */ +#ifndef CATACOMB_MP_H +# include "mp.h" +#endif - DSAEV_TRYH, /* Try prospective @h@ */ - DSAEV_FAILH, /* @h@ failed */ - DSAEV_GOODG /* @g@ accepted as a generator */ -}; +#ifndef CATACOMB_PGEN_H +# include "pgen.h" +#endif /*----- Data structures ---------------------------------------------------*/ -/* --- DSA parameter structure --- * - * - * These parameters can, and probably should, be shared among a group of - * users. - */ +/* --- The parameters and keys are the same as for Diffie-Hellman --- */ + +typedef dh_param dsa_param; +typedef dh_pub dsa_pub; +typedef dh_priv dsa_priv; -typedef struct dsa_param { - mp *p, *q; /* Prime numbers %$p$% and %$q$% */ - mp *g; /* Generates order-%$q$% subgroup */ -} dsa_param; +/* --- DSA key seed structure --- */ + +typedef struct dsa_seed { + void *p; /* Pointer to seed material */ + size_t sz; /* Size of seed material */ + unsigned count; /* Iterations to find @p@ */ +} dsa_seed; /* --- DSA signature structure --- * * @@ -103,43 +95,109 @@ typedef struct dsa_sig { octet s[DSA_SIGLEN]; /* 160-bit @s@ value */ } dsa_sig; +/*----- Key fetching ------------------------------------------------------*/ + +#define dsa_paramfetch dh_paramfetch +#define dsa_pubfetch dh_pubfetch +#define dsa_privfetch dh_privfetch + +#define DSA_PARAMFETCHSZ DH_PARAMFETCHSZ +#define DSA_PUBFETCHSZ DH_PUBFETCHSZ +#define DSA_PRIVFETCHSZ DH_PRIVFETCHSZ + +#define dsa_paramfree dh_paramfree +#define dsa_pubfree dh_pubfree +#define dsa_privfree dh_privfree + +/*----- DSA stepper -------------------------------------------------------*/ + +typedef struct dsa_stepctx { + + /* --- To be initialized by the client --- */ + + grand *r; /* Random number generator */ + mp *q; /* Force @p@ to be a multiple */ + size_t bits; /* Number of bits in the result */ + unsigned or; /* OR mask for low order bits */ + unsigned count; /* Counts the number of steps made */ + void *seedbuf; /* Pointer to seed buffer */ +} dsa_stepctx; + +/* --- @dsa_step@ --- * + * + * The stepper chooses random integers, ensures that they are a multiple of + * @q@ (if specified), sets the low-order bits, and then tests for + * divisibility by small primes. + */ + +extern pgen_proc dsa_step; + /*----- Functions provided ------------------------------------------------*/ -/* --- @dsa_seed@ --- * +/* --- @dsa_gen@ --- * * * Arguments: @dsa_param *dp@ = where to store parameters - * @unsigned l@ = bitlength of @p@ in bits + * @unsigned ql@ = length of @q@ in bits + * @unsigned pl@ = length of @p@ in bits + * @unsigned steps@ = number of steps to find @q@ * @const void *k@ = pointer to key material * @size_t sz@ = size of key material - * @void (*proc)(int ev, mp *m, void *p)@ = event procedure - * @void *p@ = argument for event procedure + * @dsa_seed *sd@ = optional pointer for output seed information + * @pgen_proc *event@ = event handler function + * @void *ectx@ = argument for event handler * - * Returns: Zero if all went well, nonzero if key material was - * unsuitable (one of the @DSAEV@ codes). + * Returns: @PGEN_DONE@ if everything worked ok; @PGEN_ABORT@ otherwise. * * Use: Generates the DSA shared parameters from a given seed value. - * This can take quite a long time. The size of @p@ in bits is - * %$l = 512 + 64l'$%. The DSA standard, FIPS 186, only allows - * %$0 \le l' \le 8$%. This implementation has no such limit, - * although @l@ must be a multiple of 8. - * - * The event procedure is informed of various happenings during - * generation. It is passed an event code describing what - * happened, and a multiprecision number which pertains to the - * event code. + * This can take quite a long time. + * + * The algorithm used is a compatible extension of the method + * described in the DSA standard, FIPS 186. The standard + * requires that %$q$% be 160 bits in size (i.e., @ql == 160@) + * and that the length of %$p$% be %$L = 512 + 64l$% for some + * %$l$%. Neither limitation applies to this implementation. + */ + +extern int dsa_gen(dsa_param */*dp*/, unsigned /*ql*/, unsigned /*pl*/, + unsigned /*steps*/, const void */*k*/, size_t /*sz*/, + dsa_seed */*sd*/, pgen_proc */*event*/, void */*ectx*/); + +/* --- @dsa_checkparam@ --- * + * + * Arguments: @keycheck *kc@ = keycheck state + * @const dsa_param *dp@ = pointer to the parameter set + * @const dsa_seed *ds@ = pointer to seed information + * + * Returns: Zero if all OK, or return status from function. + * + * Use: Checks a set of DSA parameters for consistency and security. + */ + +extern int dsa_checkparam(keycheck */*kc*/, const dsa_param */*dp*/, + const dsa_seed */*ds*/); + +/* --- @dsa_h2n@ --- * + * + * Arguments: @mp *d@ = destination integer + * @mp *r@ = order of the DSA group + * @const void *h@ = pointer to message hash + * @size_t hsz@ = size (in bytes) of the hash output + * + * Returns: Resulting integer. + * + * Use: Converts a hash to an integer in the demented way necessary + * for DSA/ECDSA. This is, of course, completely insane, but + * there you go. */ -extern int dsa_seed(dsa_param */*dp*/, unsigned /*l*/, - const void */*k*/, size_t /*sz*/, - void (*proc)(int /*ev*/, mp */*m*/, void */*p*/), - void */*p*/); +extern mp *dsa_h2n(mp */*d*/, mp */*r*/, const void */*h*/, size_t /*hsz*/); /* --- @dsa_mksig@ --- * * * Arguments: @const dsa_param *dp@ = pointer to DSA parameters - * @const mp *a@ = secret signing key - * @const mp *m@ = message to be signed - * @const mp *k@ = random data + * @mp *a@ = secret signing key + * @mp *m@ = message to be signed + * @mp *k@ = random data * @mp **rr, **ss@ = where to put output parameters * * Returns: --- @@ -147,8 +205,8 @@ extern int dsa_seed(dsa_param */*dp*/, unsigned /*l*/, * Use: Computes a DSA signature of a message. */ -extern void dsa_mksig(const dsa_param */*dp*/, const mp */*a*/, - const mp */*m*/, const mp */*k*/, +extern void dsa_mksig(const dsa_param */*dp*/, mp */*a*/, + mp */*m*/, mp */*k*/, mp **/*rr*/, mp **/*ss*/); /* --- @dsa_sign@ --- * @@ -179,22 +237,22 @@ extern void dsa_sign(dsa_param */*dp*/, mp */*a*/, /* --- @dsa_vrfy@ --- * * * Arguments: @const dsa_param *dp@ = pointer to DSA parameters - * @const mp *y@ = public verification key - * @const mp *m@ = message which was signed - * @const mp *r, *s@ = the signature + * @mp *y@ = public verification key + * @mp *m@ = message which was signed + * @mp *r, *s@ = the signature * * Returns: Zero if the signature is a forgery, nonzero if it's valid. * * Use: Verifies a DSA digital signature. */ -extern int dsa_vrfy(const dsa_param */*dp*/, const mp */*y*/, - const mp */*m*/, const mp */*r*/, const mp */*s*/); +extern int dsa_vrfy(const dsa_param */*dp*/, mp */*y*/, + mp */*m*/, mp */*r*/, mp */*s*/); /* --- @dsa_verify@ --- * * * Arguments: @const dsa_param *dp@ = pointer to DSA parameters - * @const mp *y@ = public verification key + * @mp *y@ = public verification key * @const void *m@ = pointer to message block * @size_t msz@ = size of message block * @const void *r@ = pointer to @r@ signature half @@ -207,10 +265,10 @@ extern int dsa_vrfy(const dsa_param */*dp*/, const mp */*y*/, * Use: Verifies a DSA digital signature. */ -extern int dsa_verify(const dsa_param */*dp*/, const mp */*y*/, - const void */*m*/, size_t /*msz*/, - const void */*r*/, size_t /*rsz*/, - const void */*s*/, size_t /*ssz*/); +extern int dsa_verify(const dsa_param */*dp*/, mp */*y*/, + const void */*m*/, size_t /*msz*/, + const void */*r*/, size_t /*rsz*/, + const void */*s*/, size_t /*ssz*/); /*----- That's all, folks -------------------------------------------------*/