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