2003-04-16 Moritz Schulte <moritz@g10code.com>
[libgcrypt.git] / cipher / md.c
1 /* md.c  -  message digest dispatcher
2  * Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "ath.h"
31
32 #include "rmd.h"
33
34 static struct {
35   const char *oidstring;
36   int algo;
37 } oid_table[] = {
38   /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 (sha1WithRSAEncryption) */
39   { "1.2.840.113549.1.1.5",  GCRY_MD_SHA1 },
40   /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
41   { "1.2.840.113549.1.1.4",  GCRY_MD_MD5 },
42   /* iso.member-body.us.x9-57.x9cm.3 (dsaWithSha1)*/
43   { "1.2.840.10040.4.3",     GCRY_MD_SHA1 },
44   /* from NIST's OIW  (sha1) */
45   { "1.3.14.3.2.26",         GCRY_MD_SHA1 },
46   /* rsaSignatureWithripemd160 */
47   { "1.3.36.3.3.1.2",       GCRY_MD_RMD160 },
48   /* RSADSI digestAlgorithm MD5 */
49   { "1.2.840.113549.2.5",   GCRY_MD_MD5 },
50   /* GNU.digestAlgorithm TIGER */
51   { "1.3.6.1.4.1.11591.12.2", GCRY_MD_TIGER },
52   /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
53   { "1.2.840.113549.2.4", GCRY_MD_MD4 },
54   /* from NIST OIW (sha-1WithRSAEncryption) */
55   { "1.3.14.3.2.29", GCRY_MD_SHA1 },
56   /* According to the OpenPGG draft rfc2440-bis06 */
57   { "2.16.840.1.101.3.4.2.1", GCRY_MD_SHA256 }, 
58   { "2.16.840.1.101.3.4.2.2", GCRY_MD_SHA384 }, 
59   { "2.16.840.1.101.3.4.2.3", GCRY_MD_SHA512 }, 
60   {NULL}
61 };
62
63 static struct
64 {
65   GcryDigestSpec *digest;
66   int flags;
67 } digest_table[] =
68   {
69 #if USE_CRC    
70     { &digest_spec_crc32, 0 },
71     { &digest_spec_crc32_rfc1510, 0 },
72     { &digest_spec_crc24_rfc2440, 0 },
73 #endif
74 #if USE_MD4
75     { &digest_spec_md4, 0 },
76 #endif
77 #if USE_MD5
78     { &digest_spec_md5, 0 },
79 #endif
80 #if USE_RMD160
81     { &digest_spec_rmd160, 0 },
82 #endif
83 #if USE_SHA1
84     { &digest_spec_sha1, 0 },
85 #endif
86 #if USE_SHA256
87     { &digest_spec_sha256, 0 },
88 #endif
89 #if USE_TIGER
90     { &digest_spec_tiger, 0 },
91 #endif
92     { NULL },
93   };
94
95 /* List of registered digests.  */
96 static GcryModule *digests_registered;
97
98 /* This is the lock protecting DIGESTS_REGISTERED.  */
99 static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
100
101 /* Flag to check wether the default ciphers have already been
102    registered.  */
103 static int default_digests_registered;
104
105 /* Convenient macro for registering the default digests.  */
106 #define REGISTER_DEFAULT_DIGESTS                   \
107   do                                               \
108     {                                              \
109       ath_mutex_lock (&digests_registered_lock);   \
110       if (! default_digests_registered)            \
111         {                                          \
112           gcry_digest_register_default ();         \
113           default_digests_registered = 1;          \
114         }                                          \
115       ath_mutex_unlock (&digests_registered_lock); \
116     }                                              \
117   while (0)
118
119 /* Internal function.  Register all the ciphers included in
120    CIPHER_TABLE.  Returns zero on success or an error code.  */
121 static void
122 gcry_digest_register_default (void)
123 {
124   int i, err = 0;
125   
126   for (i = 0; (! err) && digest_table[i].digest; i++)
127     err = _gcry_module_add (&digests_registered,
128                             (void *) digest_table[i].digest,
129                             NULL);
130
131   if (err)
132     BUG ();
133 }
134
135 /* Internal callback function.  */
136 static int
137 gcry_digest_lookup_func_id (void *spec, void *data)
138 {
139   GcryDigestSpec *digest = (GcryDigestSpec *) spec;
140   int id = *((int *) data);
141
142   return (digest->id == id);
143 }
144
145 /* Internal callback function.  */
146 static int
147 gcry_digest_lookup_func_name (void *spec, void *data)
148 {
149   GcryDigestSpec *digest = (GcryDigestSpec *) spec;
150   char *name = (char *) data;
151
152   return (! stricmp (digest->name, name));
153 }
154
155 /* Internal function.  Lookup a digest entry by it's ID.  */
156 static GcryModule *
157 gcry_digest_lookup_id (int id)
158 {
159   GcryModule *digest;
160
161   digest = _gcry_module_lookup (digests_registered, (void *) &id,
162                                 gcry_digest_lookup_func_id);
163
164   return digest;
165 }
166
167 /* Internal function.  Lookup a digest entry by it's name.  */
168 static GcryModule *
169 gcry_digest_lookup_name (const char *name)
170 {
171   GcryModule *digest;
172
173   digest = _gcry_module_lookup (digests_registered, (void *) name,
174                                 gcry_digest_lookup_func_name);
175
176   return digest;
177 }
178
179 /* Return a new, unused digest ID for a user-provided digest
180    implementation.  */
181 static int
182 gcry_digest_id_new (void)
183 {
184   int id, id_start = 500, id_end = 600; /* FIXME.  */
185   
186   for (id = id_start; id < id_end; id++)
187     if (! gcry_digest_lookup_id (id))
188       return id;
189
190   return 0;
191 }
192
193 /* Public function.  Register a provided DIGEST.  Returns zero on
194    success, in which case the chosen digest ID has been stored in
195    DIGEST, or an error code.  */
196 int
197 gcry_digest_register (GcryDigestSpec *digest, GcryModule **module)
198 {
199   int id, err = 0;
200   GcryModule *mod;
201
202   ath_mutex_lock (&digests_registered_lock);
203   id = gcry_digest_id_new ();
204   if (! id)
205     err = GCRYERR_INTERNAL;     /* FIXME.  */
206   else
207     {
208       digest->id = id;
209       err = _gcry_module_add (&digests_registered, (void *) digest,
210                               &mod);
211     }
212   ath_mutex_unlock (&digests_registered_lock);
213   
214   if (! err)
215     *module = mod;
216
217   return err;
218 }
219
220 /* Public function.  Unregister the digest identified by ID, which
221    must have been registered with gcry_digest_register.  */
222 void
223 gcry_digest_unregister (GcryModule *module)
224 {
225   ath_mutex_lock (&digests_registered_lock);
226   _gcry_module_release (module);
227   ath_mutex_unlock (&digests_registered_lock);
228 }
229
230 typedef struct gcry_md_list
231 {
232   GcryDigestSpec *digest;
233   GcryModule *module;
234   struct gcry_md_list *next;
235   PROPERLY_ALIGNED_TYPE context;
236 } GcryDigestEntry;
237
238 /* this structure is put right after the GCRY_MD_HD buffer, so that
239  * only one memory block is needed. */
240 struct gcry_md_context
241 {
242   int  magic;
243   int  secure;
244   FILE  *debug;
245   int finalized;
246   GcryDigestEntry *list;
247   byte *macpads;
248 };
249
250 #define CTX_MAGIC_NORMAL 0x11071961
251 #define CTX_MAGIC_SECURE 0x16917011
252
253 static const char * digest_algo_to_string( int algo );
254 static int check_digest_algo( int algo );
255 static GCRY_MD_HD md_open( int algo, int secure, int hmac );
256 static int  md_enable( GCRY_MD_HD hd, int algo );
257 static GCRY_MD_HD md_copy( GCRY_MD_HD a );
258 static void md_close(GCRY_MD_HD a);
259 static void md_write( GCRY_MD_HD a, byte *inbuf, size_t inlen);
260 static void md_final(GCRY_MD_HD a);
261 static byte *md_read( GCRY_MD_HD a, int algo );
262 static int md_get_algo( GCRY_MD_HD a );
263 static int md_digest_length( int algo );
264 static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
265 static void md_start_debug( GCRY_MD_HD a, const char *suffix );
266 static void md_stop_debug( GCRY_MD_HD a );
267
268 /****************
269  * Map a string to the digest algo
270  */
271 int
272 gcry_md_map_name (const char *string)
273 {
274   GcryModule *digest;
275   int id = 0;
276
277   if (!string)
278     return 0;
279
280   /* If the string starts with a digit (optionally prefixed with
281      either "OID." or "oid."), we first look into our table of ASN.1
282      object identifiers to figure out the algorithm */
283   if (digitp (string)
284       || !strncmp (string, "oid.", 4) 
285       || !strncmp (string, "OID.", 4) )
286     {
287       int i;
288       const char *s =  digitp(string)? string : (string+4);
289
290       for (i=0; oid_table[i].oidstring; i++)
291         {
292           if (!strcmp (s, oid_table[i].oidstring))
293             return oid_table[i].algo;
294         }
295     }
296
297
298   REGISTER_DEFAULT_DIGESTS;
299
300   ath_mutex_lock (&digests_registered_lock);
301   digest = gcry_digest_lookup_name (string);
302   if (digest)
303     {
304       id = ((GcryDigestSpec *) digest->spec)->id;
305       _gcry_module_release (digest);
306     }
307   ath_mutex_unlock (&digests_registered_lock);
308
309   return id;
310 }
311
312
313 /****************
314  * Map a digest algo to a string
315  */
316 static const char *
317 digest_algo_to_string (int id)
318 {
319   const char *name = NULL;
320   GcryModule *digest;
321
322   REGISTER_DEFAULT_DIGESTS;
323
324   ath_mutex_lock (&digests_registered_lock);
325   digest = gcry_digest_lookup_id (id);
326   if (digest)
327     {
328       name = ((GcryDigestSpec *) digest->spec)->name;
329       _gcry_module_release (digest);
330     }
331   ath_mutex_unlock (&digests_registered_lock);
332
333   return name;
334 }
335
336 /****************
337  * This function simply returns the name of the algorithm or some constant
338  * string when there is no algo.  It will never return NULL.
339  * Use  the macro gcry_md_test_algo() to check whether the algorithm
340  * is valid.
341  */
342 const char *
343 gcry_md_algo_name (int id)
344 {
345   const char *s = digest_algo_to_string (id);
346   return s ? s : "?";
347 }
348
349
350 static int
351 check_digest_algo (int id)
352 {
353   int rc = 0;
354   GcryModule *digest;
355
356   REGISTER_DEFAULT_DIGESTS;
357
358   ath_mutex_lock (&digests_registered_lock);
359   digest = gcry_digest_lookup_id (id);
360   if (digest)
361     _gcry_module_release (digest);
362   else
363     rc = GCRYERR_INV_MD_ALGO;
364   ath_mutex_unlock (&digests_registered_lock);
365
366   return rc;
367 }
368
369
370
371 /****************
372  * Open a message digest handle for use with algorithm ALGO.
373  * More algorithms may be added by md_enable(). The initial algorithm
374  * may be 0.
375  */
376 static GCRY_MD_HD
377 md_open( int algo, int secure, int hmac )
378 {
379   GCRY_MD_HD hd;
380   struct gcry_md_context *ctx;
381   int bufsize = secure? 512 : 1024;
382   size_t n;
383
384   /* Allocate a memory area to hold the caller visible buffer with it's
385    * control information and the data required by this module. Set the
386    * context pointer at the beginning to this area.
387    * We have to use this strange scheme because we want to hide the
388    * internal data but have a variable sized buffer.
389    *
390    *    +---+------+---........------+-------------+
391    *    !ctx! bctl !  buffer         ! private     !
392    *    +---+------+---........------+-------------+
393    *      !                           ^
394    *      !---------------------------!
395    *
396    * We have to make sture that private is well aligned.
397    */
398   n = sizeof( struct gcry_md_handle ) + bufsize;
399   n = ((n + sizeof(PROPERLY_ALIGNED_TYPE)-1)
400        / sizeof(PROPERLY_ALIGNED_TYPE) ) * sizeof(PROPERLY_ALIGNED_TYPE);
401
402   /* allocate and set the Context pointer to the private data */
403   hd = secure ? gcry_malloc_secure( n + sizeof( struct gcry_md_context ) )
404     : gcry_malloc(           n + sizeof( struct gcry_md_context ) );
405   if( !hd ) {
406     set_lasterr( GCRYERR_NO_MEM );
407     return NULL;
408   }
409
410   hd->ctx = ctx = (struct gcry_md_context*)( (char*)hd + n );
411   /* setup the globally visible data (bctl in the diagram)*/
412   hd->bufsize = n - sizeof( struct gcry_md_handle ) + 1;
413   hd->bufpos = 0;
414   /* initialize the private data */
415   memset( hd->ctx, 0, sizeof *hd->ctx );
416   ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
417   ctx->secure = secure;
418   if( hmac ) {
419     ctx->macpads = gcry_malloc_secure( 128 );
420     if( !ctx->macpads ) {
421       md_close( hd );
422       set_lasterr( GCRYERR_NO_MEM );
423       return NULL;
424     }
425   }
426   fast_random_poll(); /* FIXME: should we really do that? */
427   if( algo && md_enable( hd, algo ) ) {
428     md_close( hd );
429     return NULL;
430   }
431   return hd;
432 }
433
434
435 /* Create a message digest object for algorithm ALGO.  FLAGS may be
436    given as an bitwise OR of the gcry_md_flags values.  ALGO may be
437    given as 0 if the algorithms to be used are later set using
438    gcry_md_enable. */
439 GcryMDHd
440 gcry_md_open (int algo, unsigned int flags)
441 {
442   GCRY_MD_HD hd;
443
444   if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
445     {
446       set_lasterr (GCRYERR_INV_ARG);
447       return NULL;
448     }
449   hd = md_open (algo, (flags & GCRY_MD_FLAG_SECURE),
450                 (flags & GCRY_MD_FLAG_HMAC));
451   return hd;
452 }
453
454
455
456 static int
457 md_enable (GCRY_MD_HD hd, int id)
458 {
459   struct gcry_md_context *h = hd->ctx;
460   GcryDigestSpec *digest;
461   GcryDigestEntry *entry;
462   GcryModule *module;
463
464   for (entry = h->list; entry; entry = entry->next)
465     if (entry->digest->id == id)
466       return 0; /* already enabled */
467
468   REGISTER_DEFAULT_DIGESTS;
469
470   ath_mutex_lock (&digests_registered_lock);
471   module = gcry_digest_lookup_id (id);
472   ath_mutex_unlock (&digests_registered_lock);
473   if (! module)
474     {
475       log_debug ("md_enable: algorithm %d not available\n", id);
476       return set_lasterr (GCRYERR_INV_MD_ALGO);
477     }
478
479   digest = (GcryDigestSpec *) module->spec;
480
481   /* and allocate a new list entry */
482   entry = h->secure
483     ? gcry_malloc_secure (sizeof (*entry)
484                           + digest->contextsize
485                           - sizeof (entry->context))
486     : gcry_malloc (sizeof (*entry)
487                    + digest->contextsize
488                    - sizeof (entry->context));
489
490   if (! entry)
491     return set_lasterr (GCRYERR_NO_MEM);
492
493   entry->digest = digest;
494   entry->module = module;
495   entry->next = h->list;
496   h->list = entry;
497   
498   /* and init this instance */
499   (*entry->digest->init) (&entry->context.c);
500   return 0;
501 }
502
503
504 int
505 gcry_md_enable (GCRY_MD_HD hd, int id)
506 {
507   return md_enable ( hd, id);
508 }
509
510 static GCRY_MD_HD
511 md_copy (GCRY_MD_HD ahd)
512 {
513   struct gcry_md_context *a = ahd->ctx;
514   struct gcry_md_context *b;
515   GCRY_MD_HD bhd;
516   GcryDigestEntry *ar, *br;
517   size_t n;
518   
519   if (ahd->bufpos)
520     md_write (ahd, NULL, 0);
521
522   n = (char *) ahd->ctx - (char *) ahd;
523   bhd = a->secure
524     ? gcry_malloc_secure (n + sizeof (struct gcry_md_context))
525     : gcry_malloc (n + sizeof (struct gcry_md_context));
526
527   if (! bhd)
528     {
529       set_lasterr (GCRYERR_NO_MEM);
530       return NULL;
531     }
532
533   bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
534   /* no need to copy the buffer due to the write above */
535   assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
536   bhd->bufsize = ahd->bufsize;
537   bhd->bufpos = 0;
538   assert (! ahd->bufpos);
539   memcpy (b, a, sizeof *a);
540   b->list = NULL;
541   b->debug = NULL;
542   if (a->macpads)
543     {
544       b->macpads = gcry_malloc_secure (128);
545       memcpy (b->macpads, a->macpads, 128);
546     }
547
548   /* and now copy the complete list of algorithms */
549   /* I know that the copied list is reversed, but that doesn't matter */
550   for (ar = a->list; ar; ar = ar->next)
551     {
552       br = a->secure
553         ? gcry_xmalloc_secure (sizeof *br
554                                + ar->digest->contextsize
555                                - sizeof(ar->context))
556         : gcry_xmalloc (sizeof *br
557                         + ar->digest->contextsize
558                         - sizeof (ar->context));
559       memcpy (br, ar,
560               sizeof (*br) + ar->digest->contextsize - sizeof (ar->context));
561       br->next = b->list;
562       b->list = br;
563
564       /* Add a reference to the module.  */
565       ath_mutex_lock (&digests_registered_lock);
566       _gcry_module_use (br->module);
567       ath_mutex_unlock (&digests_registered_lock);
568     }
569
570   if (a->debug)
571     md_start_debug( bhd, "unknown" );
572   return bhd;
573 }
574
575 GCRY_MD_HD
576 gcry_md_copy (GCRY_MD_HD hd)
577 {
578   return md_copy (hd);
579 }
580
581 /****************
582  * Reset all contexts and discard any buffered stuff.  This may be used
583  * instead of a md_close(); md_open().
584  */
585 void
586 gcry_md_reset (GCRY_MD_HD a)
587 {
588   GcryDigestEntry *r;
589   
590   a->bufpos = a->ctx->finalized = 0;
591
592   for (r = a->ctx->list; r; r = r->next)
593     {
594       memset (r->context.c, 0, r->digest->contextsize);
595       (*r->digest->init) (&r->context.c);
596     }
597   if (a->ctx->macpads)
598     md_write (a, a->ctx->macpads, 64); /* inner pad */
599 }
600
601 static void
602 md_close (GCRY_MD_HD a)
603 {
604   GcryDigestEntry *r, *r2;
605
606   if (! a)
607     return;
608   if (a->ctx->debug)
609     md_stop_debug (a);
610   for (r = a->ctx->list; r; r = r2)
611     {
612       r2 = r->next;
613       ath_mutex_lock (&digests_registered_lock);
614       _gcry_module_release (r->module);
615       ath_mutex_unlock (&digests_registered_lock);
616       gcry_free (r);
617     }
618   gcry_free(a->ctx->macpads);
619   gcry_free(a);
620 }
621
622 void
623 gcry_md_close (GCRY_MD_HD hd)
624 {
625   md_close (hd);
626 }
627
628 static void
629 md_write (GCRY_MD_HD a, byte *inbuf, size_t inlen)
630 {
631   GcryDigestEntry *r;
632   
633   if (a->ctx->debug)
634     {
635       if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
636         BUG();
637       if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
638         BUG();
639     }
640
641   for (r = a->ctx->list; r; r = r->next)
642     {
643       if (a->bufpos)
644         (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
645       (*r->digest->write) (&r->context.c, inbuf, inlen);
646     }
647   a->bufpos = 0;
648 }
649
650 void
651 gcry_md_write (GCRY_MD_HD hd, const void *inbuf, size_t inlen)
652 {
653   md_write (hd, (unsigned char *) inbuf, inlen);
654 }
655
656 static void
657 md_final (GCRY_MD_HD a)
658 {
659   GcryDigestEntry *r;
660
661   if (a->ctx->finalized)
662     return;
663
664   if (a->bufpos)
665     md_write (a, NULL, 0);
666
667   for (r = a->ctx->list; r; r = r->next)
668     (*r->digest->final) (&r->context.c);
669
670   a->ctx->finalized = 1;
671
672   if (a->ctx->macpads)
673     {
674       /* finish the hmac */
675       int algo = md_get_algo (a);
676       byte *p = md_read (a, algo);
677       size_t dlen = md_digest_length (algo);
678
679       GCRY_MD_HD om = md_open (algo, a->ctx->secure, 0);
680       if (! om)
681         _gcry_fatal_error (gcry_errno (), NULL);
682       md_write (om, a->ctx->macpads+64, 64);
683       md_write (om, p, dlen);
684       md_final (om);
685       /* replace our digest with the mac (they have the same size) */
686       memcpy (p, md_read (om, algo), dlen);
687       md_close (om);
688     }
689 }
690
691 static int
692 prepare_macpads( GCRY_MD_HD hd, const byte *key, size_t keylen)
693 {
694   int i;
695   int algo = md_get_algo( hd );
696   byte *helpkey = NULL;
697   byte *ipad, *opad;
698
699   if( !algo )
700     return GCRYERR_INV_MD_ALGO; /* i.e. no algo enabled */
701
702   if( keylen > 64 ) {
703     helpkey = gcry_malloc_secure( md_digest_length( algo ) );
704     if( !helpkey )
705       return GCRYERR_NO_MEM;
706     gcry_md_hash_buffer( algo, helpkey, key, keylen );
707     key = helpkey;
708     keylen = md_digest_length( algo );
709     assert( keylen <= 64 );
710   }
711
712   memset( hd->ctx->macpads, 0, 128 );
713   ipad = hd->ctx->macpads;
714   opad = hd->ctx->macpads+64;
715   memcpy( ipad, key, keylen );
716   memcpy( opad, key, keylen );
717   for(i=0; i < 64; i++ ) {
718     ipad[i] ^= 0x36;
719     opad[i] ^= 0x5c;
720   }
721   gcry_free( helpkey );
722   return 0;
723 }
724
725 int
726 gcry_md_ctl (GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
727 {
728   int rc = 0;
729   
730   switch (cmd)
731     {
732     case GCRYCTL_FINALIZE:
733       md_final (hd);
734       break;
735     case GCRYCTL_SET_KEY:
736       rc = gcry_md_setkey (hd, buffer, buflen);
737       break;
738     case GCRYCTL_START_DUMP:
739       md_start_debug (hd, buffer);
740       break;
741     case GCRYCTL_STOP_DUMP:
742       md_stop_debug( hd );
743       break;
744     default:
745       rc = GCRYERR_INV_OP;
746     }
747   return set_lasterr( rc );
748 }
749
750 int
751 gcry_md_setkey( GCRY_MD_HD hd, const void *key, size_t keylen )
752  {
753   int rc = 0;
754
755   if( !(hd->ctx->macpads ) )
756     rc = GCRYERR_CONFLICT;
757   else if ( !(rc = prepare_macpads( hd, key, keylen )) )
758     gcry_md_reset( hd );
759
760   return rc;
761 }
762
763
764 /****************
765  * if ALGO is null get the digest for the used algo (which should be only one)
766  */
767 static byte *
768 md_read( GCRY_MD_HD a, int algo )
769 {
770   GcryDigestEntry *r = a->ctx->list;
771
772   if (! algo)
773     {
774       /* return the first algorithm */
775       if (r && r->next)
776         log_debug("more than algorithm in md_read(0)\n");
777       return (*r->digest->read)( &r->context.c );
778     }
779   else
780     {
781       for (r = a->ctx->list; r; r = r->next)
782         if (r->digest->id == algo)
783           return (*r->digest->read) (&r->context.c);
784     }
785   BUG();
786   return NULL;
787 }
788
789 /****************
790  * Read out the complete digest, this function implictly finalizes
791  * the hash.
792  */
793 byte *
794 gcry_md_read (GCRY_MD_HD hd, int algo)
795 {
796   gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
797   return md_read (hd, algo);
798 }
799
800 /****************
801  * This function combines md_final and md_read but keeps the context
802  * intact.  This function can be used to calculate intermediate
803  * digests.  The digest is copied into buffer and the digestlength is
804  * returned.  If buffer is NULL only the needed size for buffer is returned.
805  * buflen gives the max size of buffer. If the buffer is too shourt to
806  * hold the complete digest, the buffer is filled with as many bytes are
807  * possible and this value is returned.
808  */
809 #if 0
810 static int
811 md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen )
812 {
813   struct md_digest_list_s *r = NULL;
814   char *context;
815   char *digest;
816
817   if( a->bufpos )
818     md_write( a, NULL, 0 );
819
820   if( !algo ) {  /* return digest for the first algorithm */
821     if( (r=a->ctx->list) && r->next )
822       log_debug("more than algorithm in md_digest(0)\n");
823   }
824   else {
825     for(r=a->ctx->list; r; r = r->next )
826       if( r->algo == algo )
827         break;
828   }
829   if( !r )
830     BUG();
831
832   if( !buffer )
833     return r->mdlen;
834
835   /* I don't want to change the interface, so I simply work on a copy
836    * of the context (extra overhead - should be fixed)*/
837   context = a->ctx->secure ? gcry_xmalloc_secure( r->contextsize )
838     : gcry_xmalloc( r->contextsize );
839   memcpy( context, r->context.c, r->contextsize );
840   (*r->digest->final)( context );
841   digest = (*r->digest->read)( context );
842
843   if( buflen > r->mdlen )
844     buflen = r->mdlen;
845   memcpy( buffer, digest, buflen );
846
847   gcry_free(context);
848   return buflen;
849 }
850 #endif
851
852 /****************
853  * Read out an intermediate digest.
854  */
855 int
856 gcry_md_get (GCRY_MD_HD hd, int algo, byte *buffer, int buflen)
857 {
858   /*md_digest ... */
859   return GCRYERR_INTERNAL;
860 }
861
862
863 /****************
864  * Shortcut function to hash a buffer with a given algo. The only supported
865  * algorithm is RIPE-MD. The supplied digest buffer must be large enough
866  * to store the resulting hash.  No error is returned, the function will
867  * abort on an invalid algo.  DISABLED_ALGOS are ignored here.
868  */
869 void
870 gcry_md_hash_buffer (int algo, void *digest, const void *buffer, size_t length)
871 {
872   if (algo == GCRY_MD_RMD160)
873     _gcry_rmd160_hash_buffer (digest, buffer, length);
874   else
875     {
876       /* for the others we do not have a fast function, so we use the
877          normal functions to do it */
878
879       GCRY_MD_HD h = md_open (algo, 0, 0);
880       if( !h )
881         BUG(); /* algo not available */
882       md_write (h, (byte *) buffer, length);
883       md_final (h);
884       memcpy (digest, md_read (h, algo), md_digest_length (algo));
885       md_close (h);
886     }
887 }
888
889 static int
890 md_get_algo (GCRY_MD_HD a)
891 {
892   GcryDigestEntry *r = a->ctx->list;
893
894   if (r && r->next)
895     log_error("WARNING: more than algorithm in md_get_algo()\n");
896   return r->digest->id;
897 }
898
899
900 int
901 gcry_md_get_algo (GCRY_MD_HD hd)
902 {
903   int algo = md_get_algo (hd);
904   if (!algo)
905     {
906       set_lasterr (GCRYERR_GENERAL);
907       return 0;
908     }
909   return algo;
910 }
911
912
913 /****************
914  * Return the length of the digest
915  */
916 static int
917 md_digest_length (int id)
918 {
919   GcryModule *digest;
920   int mdlen = 0;
921
922   REGISTER_DEFAULT_DIGESTS;
923
924   ath_mutex_lock (&digests_registered_lock);
925   digest = gcry_digest_lookup_id (id);
926   if (digest)
927     {
928       mdlen = ((GcryDigestSpec *) digest->spec)->mdlen;
929       _gcry_module_release (digest);
930     }
931   ath_mutex_unlock (&digests_registered_lock);
932
933   return mdlen;
934 }
935
936 /****************
937  * Return the length of the digest in bytes.
938  * This function will return 0 in case of errors.
939  */
940 unsigned int
941 gcry_md_get_algo_dlen( int algo )
942 {
943   /* we cheat a little bit */
944   switch( algo )
945     {
946     case GCRY_MD_MD4:
947     case GCRY_MD_MD5: return 16;
948     case GCRY_MD_SHA1:
949     case GCRY_MD_RMD160: return 20;
950     case GCRY_MD_SHA256: return 32;
951     case GCRY_MD_SHA384: return 48;
952     case GCRY_MD_SHA512: return 64;
953     case GCRY_MD_CRC32:
954     case GCRY_MD_CRC32_RFC1510: return 4;
955     case GCRY_MD_CRC24_RFC2440: return 3;
956     default: 
957       {
958         int len = md_digest_length( algo );
959         if( !len )
960           set_lasterr( GCRYERR_INV_MD_ALGO );
961         return 0;
962       }
963     }
964 }
965
966
967 /* Hmmm: add a mode to enumerate the OIDs
968  *      to make g10/sig-check.c more portable */
969 static const byte *
970 md_asn_oid (int id, size_t *asnlen, size_t *mdlen)
971 {
972   const byte *asnoid = NULL;
973   GcryModule *digest;
974
975   REGISTER_DEFAULT_DIGESTS;
976
977   ath_mutex_lock (&digests_registered_lock);
978   digest = gcry_digest_lookup_id (id);
979   if (digest)
980     {
981       if (asnlen)
982         *asnlen = ((GcryDigestSpec *) digest->spec)->asnlen;
983       if (mdlen)
984         *mdlen = ((GcryDigestSpec *) digest->spec)->mdlen;
985       asnoid = ((GcryDigestSpec *) digest->spec)->asnoid;
986       _gcry_module_release (digest);
987     }
988   else
989     log_bug ("no asn for md algo %d\n", id);
990   ath_mutex_unlock (&digests_registered_lock);
991
992   return asnoid;
993 }
994
995
996
997 /****************
998  * Return information about the given cipher algorithm
999  * WHAT select the kind of information returned:
1000  *  GCRYCTL_TEST_ALGO:
1001  *      Returns 0 when the specified algorithm is available for use.
1002  *      buffer and nbytes must be zero.
1003  *  GCRYCTL_GET_ASNOID:
1004  *      Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
1005  *      the required length is returned.
1006  *
1007  * On error the value -1 is returned and the error reason may be
1008  * retrieved by gcry_errno().
1009  * Note:  Because this function is in most cases used to return an
1010  * integer value, we can make it easier for the caller to just look at
1011  * the return value.  The caller will in all cases consult the value
1012  * and thereby detecting whether a error occured or not (i.e. while checking
1013  * the block size)
1014  */
1015 int
1016 gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes)
1017 {
1018   switch( what ) {
1019   case GCRYCTL_TEST_ALGO:
1020     if( buffer || nbytes ) {
1021       set_lasterr( GCRYERR_INV_ARG );
1022       return -1;
1023     }
1024     if( check_digest_algo( algo ) ) {
1025       set_lasterr( GCRYERR_INV_MD_ALGO );
1026       return -1;
1027     }
1028     break;
1029
1030   case GCRYCTL_GET_ASNOID: {
1031     size_t asnlen;
1032     const char *asn = md_asn_oid( algo, &asnlen, NULL );
1033     if( buffer && *nbytes >= asnlen ) {
1034       memcpy( buffer, asn, asnlen );
1035       *nbytes = asnlen;
1036       return 0;
1037     }
1038     if( !buffer && nbytes ) {
1039       *nbytes = asnlen;
1040       return 0;
1041     }
1042     set_lasterr( buffer ? GCRYERR_TOO_SHORT : GCRYERR_INV_ARG );
1043     return -1;
1044   }
1045     break;
1046
1047   default:
1048     set_lasterr( GCRYERR_INV_OP );
1049     return -1;
1050   }
1051   return 0;
1052 }
1053
1054
1055
1056
1057 static void
1058 md_start_debug( GCRY_MD_HD md, const char *suffix )
1059 {
1060   static int idx=0;
1061   char buf[25];
1062
1063   if( md->ctx->debug ) {
1064     log_debug("Oops: md debug already started\n");
1065     return;
1066   }
1067   idx++;
1068   sprintf(buf, "dbgmd-%05d.%.10s", idx, suffix );
1069   md->ctx->debug = fopen(buf, "w");
1070   if( !md->ctx->debug )
1071     log_debug("md debug: can't open %s\n", buf );
1072 }
1073
1074 static void
1075 md_stop_debug( GCRY_MD_HD md )
1076 {
1077   if( md->ctx->debug ) {
1078     if( md->bufpos )
1079       md_write( md, NULL, 0 );
1080     fclose(md->ctx->debug);
1081     md->ctx->debug = NULL;
1082   }
1083 #ifdef HAVE_U64_TYPEDEF
1084   {  /* a kludge to pull in the __muldi3 for Solaris */
1085     volatile u32 a = (u32)(ulong)md;
1086     volatile u64 b = 42;
1087     volatile u64 c;
1088     c = a * b;
1089   }
1090 #endif
1091 }
1092
1093
1094
1095 /****************
1096  * Return information about the digest handle.
1097  *  GCRYCTL_IS_SECURE:
1098  *      Returns 1 when the handle works on secured memory
1099  *      otherwise 0 is returned.  There is no error return.
1100  *  GCRYCTL_IS_ALGO_ENABLED:
1101  *     Returns 1 if the algo is enanled for that handle.
1102  *     The algo must be passed as the address of an int.
1103  */
1104 int
1105 gcry_md_info( GCRY_MD_HD h, int cmd, void *buffer, size_t *nbytes)
1106 {
1107
1108   switch( cmd ) {
1109   case GCRYCTL_IS_SECURE:
1110     return h->ctx->secure;
1111
1112   case GCRYCTL_IS_ALGO_ENABLED:
1113     {
1114       int algo;
1115       GcryDigestEntry *r;
1116
1117       if (!buffer || (nbytes && *nbytes != sizeof (int))) {
1118         set_lasterr (GCRYERR_INV_ARG);
1119         return -1;
1120       }
1121       algo = *(int*)buffer;
1122
1123       for(r=h->ctx->list; r; r = r->next ) {
1124         if( r->digest->id == algo )
1125           return 1;
1126       }
1127     }
1128     break;
1129
1130   default:
1131     set_lasterr( GCRYERR_INV_OP );
1132     return -1;
1133   }
1134   return 0;
1135 }