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