See ChangeLog: Tue Oct 26 14:10:21 CEST 1999 Werner Koch
[libgcrypt.git] / cipher / md.c
1 /* md.c  -  message digest dispatcher
2  *      Copyright (C) 1998,1999 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * 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 "util.h"
30 #include "cipher.h"
31 #include "errors.h"
32 #include "dynload.h"
33 #include "rmd.h"
34
35
36 struct md_digest_list_s;
37
38 /* this structure is put right after the GCRY_MD_HD buffer, so that
39  * only one memory block is needed. */
40 struct gcry_md_context {
41     int  magic;
42     int  secure;
43     FILE  *debug;
44     int finalized;
45     struct md_digest_list_s *list;
46 };
47 #define CTX_MAGIC_NORMAL 0x11071961
48 #define CTX_MAGIC_SECURE 0x16917011
49
50 static const char * digest_algo_to_string( int algo );
51 static int check_digest_algo( int algo );
52 static GCRY_MD_HD md_open( int algo, int secure );
53 static int  md_enable( GCRY_MD_HD hd, int algo );
54 static GCRY_MD_HD md_copy( GCRY_MD_HD a );
55 static void md_close(GCRY_MD_HD a);
56 static void md_write( GCRY_MD_HD a, byte *inbuf, size_t inlen);
57 static void md_final(GCRY_MD_HD a);
58 static byte *md_read( GCRY_MD_HD a, int algo );
59 static int md_get_algo( GCRY_MD_HD a );
60 static int md_digest_length( int algo );
61 static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
62 static void md_start_debug( GCRY_MD_HD a, const char *suffix );
63 static void md_stop_debug( GCRY_MD_HD a );
64
65 /****************
66  * This structure is used for the list of available algorithms
67  * and for the list of algorithms in GCRY_MD_HD.
68  */
69 struct md_digest_list_s {
70     struct md_digest_list_s *next;
71     const char *name;
72     int algo;
73     byte *asnoid;
74     int asnlen;
75     int mdlen;
76     void (*init)( void *c );
77     void (*write)( void *c, byte *buf, size_t nbytes );
78     void (*final)( void *c );
79     byte *(*read)( void *c );
80     size_t contextsize; /* allocate this amount of context */
81     PROPERLY_ALIGNED_TYPE context;
82 };
83
84 static struct md_digest_list_s *digest_list;
85
86
87 static struct md_digest_list_s *
88 new_list_item( int algo,
89                const char *(*get_info)( int, size_t*,byte**, int*, int*,
90                                        void (**)(void*),
91                                        void (**)(void*,byte*,size_t),
92                                        void (**)(void*),byte *(**)(void*)) )
93 {
94     struct md_digest_list_s *r;
95
96     r = m_alloc_clear( sizeof *r );
97     r->algo = algo,
98     r->name = (*get_info)( algo, &r->contextsize,
99                            &r->asnoid, &r->asnlen, &r->mdlen,
100                            &r->init, &r->write, &r->final, &r->read );
101     if( !r->name ) {
102         m_free(r);
103         r = NULL;
104     }
105     return r;
106 }
107
108
109
110 /****************
111  * Try to load the modules with the requeste algorithm
112  * and return true if new modules are available
113  * If req_alog is -1 try to load all digest algorithms.
114  */
115 static int
116 load_digest_module( int req_algo )
117 {
118     static int initialized = 0;
119     static u32 checked_algos[256/32];
120     static int checked_all = 0;
121     struct md_digest_list_s *r;
122     void *context = NULL;
123     int algo;
124     int any = 0;
125     const char *(*get_info)( int, size_t*,byte**, int*, int*,
126                             void (**)(void*),
127                             void (**)(void*,byte*,size_t),
128                             void (**)(void*),byte *(**)(void*));
129
130     if( !initialized ) {
131         cipher_modules_constructor();
132         initialized = 1;
133     }
134     algo = req_algo;
135     if( algo > 255 || !algo )
136         return 0; /* algorithm number too high (does not fit into out bitmap)*/
137     if( checked_all )
138         return 0; /* already called with -1 */
139     if( algo < 0 )
140         checked_all = 1;
141     else if( (checked_algos[algo/32] & (1 << (algo%32))) )
142         return 0; /* already checked and not found */
143     else
144         checked_algos[algo/32] |= (1 << (algo%32));
145
146     while( enum_gnupgext_digests( &context, &algo, &get_info ) ) {
147         if( req_algo != -1 && algo != req_algo )
148             continue;
149         for(r=digest_list; r; r = r->next )
150             if( r->algo == algo )
151                 break;
152         if( r ) {
153             log_info("skipping digest %d: already loaded\n", algo );
154             continue;
155         }
156         r = new_list_item( algo, get_info );
157         if( ! r ) {
158             log_info("skipping digest %d: no name\n", algo );
159             continue;
160         }
161         /* put it into the list */
162         if( g10_opt_verbose > 1 )
163             log_info("loaded digest %d\n", algo);
164         r->next = digest_list;
165         digest_list = r;
166         any = 1;
167         if( req_algo != -1 )
168             break;
169     }
170     enum_gnupgext_digests( &context, NULL, NULL );
171     return any;
172 }
173
174
175
176 /****************
177  * Map a string to the digest algo
178  */
179 int
180 gcry_md_map_name( const char *string )
181 {
182     struct md_digest_list_s *r;
183
184     do {
185         for(r = digest_list; r; r = r->next )
186             if( !stricmp( r->name, string ) )
187                 return r->algo;
188     } while( !r && load_digest_module(-1) );
189     return 0;
190 }
191
192
193 /****************
194  * Map a digest algo to a string
195  */
196 static const char *
197 digest_algo_to_string( int algo )
198 {
199     struct md_digest_list_s *r;
200
201     do {
202         for(r = digest_list; r; r = r->next )
203             if( r->algo == algo )
204                 return r->name;
205     } while( !r && load_digest_module( algo ) );
206     return NULL;
207 }
208
209 /****************
210  * This function simply returns the name of the algorithm or some constant
211  * string when there is no algo.  It will never return NULL.
212  * Use  the macro gcry_md_test_algo() to check whether the algorithm
213  * is valid.
214  */
215 const char *
216 gcry_md_algo_name( int algo )
217 {
218     const char *s = digest_algo_to_string( algo );
219     return s? s: "?";
220 }
221
222
223 static int
224 check_digest_algo( int algo )
225 {
226     struct md_digest_list_s *r;
227
228     do {
229         for(r = digest_list; r; r = r->next )
230             if( r->algo == algo )
231                 return 0;
232     } while( !r && load_digest_module(algo) );
233     return G10ERR_DIGEST_ALGO;
234 }
235
236
237
238 /****************
239  * Open a message digest handle for use with algorithm ALGO.
240  * More algorithms may be added by md_enable(). The initial algorithm
241  * may be 0.
242  */
243 static GCRY_MD_HD
244 md_open( int algo, int secure )
245 {
246     GCRY_MD_HD hd;
247     struct gcry_md_context *ctx;
248     int bufsize = secure? 512 : 1024;
249     size_t n;
250
251     /* Allocate a memory area to hold the caller visible buffer with it's
252      * control information and the data required by this module. Set the
253      * context pointer at the beginning to this area.
254      * We have to use this strange scheme because we want to hide the
255      * internal data but have a variable sized buffer.
256      *
257      *  +---+------+---........------+-------------+
258      *  !ctx! bctl !  buffer         ! private     !
259      *  +---+------+---........------+-------------+
260      *    !                           ^
261      *    !---------------------------!
262      *
263      * We have to make sture that private is well aligned.
264      */
265     n = sizeof( struct gcry_md_handle ) + bufsize;
266     n = ((n + sizeof(PROPERLY_ALIGNED_TYPE)-1)
267          / sizeof(PROPERLY_ALIGNED_TYPE) ) * sizeof(PROPERLY_ALIGNED_TYPE);
268
269     /* allocate and set the Context pointer to the private data */
270     hd = secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) )
271                 : m_alloc(        n + sizeof( struct gcry_md_context ) );
272     hd->ctx = ctx = (struct gcry_md_context*)( (char*)hd + n );
273     /* setup the globally visible data (bctl in the diagram)*/
274     hd->bufsize = n - sizeof( struct gcry_md_handle ) + 1;
275     hd->bufpos = 0;
276     /* initialize the private data */
277     memset( hd->ctx, 0, sizeof *hd->ctx );
278     ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
279     ctx->secure = secure;
280     fast_random_poll(); /* FIXME: should we really do that? */
281     if( algo && md_enable( hd, algo ) ) {
282         md_close( hd );
283         return NULL;
284     }
285     return hd;
286 }
287
288
289 GCRY_MD_HD
290 gcry_md_open( int algo, unsigned int flags )
291 {
292     GCRY_MD_HD hd;
293     /* fixme: check that algo is available and that only valid
294      * flag values are used */
295     hd = md_open( algo, (flags & GCRY_MD_FLAG_SECURE) );
296     return hd;
297 }
298
299
300
301 static int
302 md_enable( GCRY_MD_HD hd, int algo )
303 {
304     struct gcry_md_context *h = hd->ctx;
305     struct md_digest_list_s *r, *ac;
306
307     for( ac=h->list; ac; ac = ac->next )
308         if( ac->algo == algo )
309             return 0; /* already enabled */
310     /* find the algorithm */
311     do {
312         for(r = digest_list; r; r = r->next )
313             if( r->algo == algo )
314                 break;
315     } while( !r && load_digest_module( algo ) );
316     if( !r ) {
317         log_debug("md_enable: algorithm %d not available\n", algo );
318         return set_lasterr( GCRYERR_INV_ALGO );
319     }
320     /* and allocate a new list entry */
321     ac = h->secure? m_alloc_secure( sizeof *ac + r->contextsize
322                                                - sizeof(r->context) )
323                   : m_alloc( sizeof *ac + r->contextsize
324                                                - sizeof(r->context) );
325     *ac = *r;
326     ac->next = h->list;
327     h->list = ac;
328     /* and init this instance */
329     (*ac->init)( &ac->context.c );
330     return 0;
331 }
332
333
334 int
335 gcry_md_enable( GCRY_MD_HD hd, int algo )
336 {
337     return md_enable( hd, algo );
338 }
339
340 static GCRY_MD_HD
341 md_copy( GCRY_MD_HD ahd )
342 {
343     struct gcry_md_context *a = ahd->ctx;
344     struct gcry_md_context *b;
345     GCRY_MD_HD bhd;
346     struct md_digest_list_s *ar, *br;
347     size_t n;
348
349     if( ahd->bufpos )
350         md_write( ahd, NULL, 0 );
351
352     n = (char*)ahd->ctx - (char*)ahd;
353     bhd = a->secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) )
354                     : m_alloc(        n + sizeof( struct gcry_md_context ) );
355     bhd->ctx = b = (struct gcry_md_context*)( (char*)bhd + n );
356     /* no need to copy the buffer due to the write above */
357     assert( ahd->bufsize == (n - sizeof( struct gcry_md_handle ) + 1) );
358     bhd->bufsize = ahd->bufsize;
359     bhd->bufpos = 0;  assert( !ahd->bufpos );
360     memcpy( b, a, sizeof *a );
361     b->list = NULL;
362     b->debug = NULL;
363     /* and now copy the complete list of algorithms */
364     /* I know that the copied list is reversed, but that doesn't matter */
365     for( ar=a->list; ar; ar = ar->next ) {
366         br = a->secure ? m_alloc_secure( sizeof *br + ar->contextsize
367                                                - sizeof(ar->context) )
368                        : m_alloc( sizeof *br + ar->contextsize
369                                                - sizeof(ar->context) );
370         memcpy( br, ar, sizeof(*br) + ar->contextsize
371                                     - sizeof(ar->context) );
372         br->next = b->list;
373         b->list = br;
374     }
375
376     if( a->debug )
377         md_start_debug( bhd, "unknown" );
378     return bhd;
379 }
380
381 GCRY_MD_HD
382 gcry_md_copy( GCRY_MD_HD hd )
383 {
384     return md_copy( hd );
385 }
386
387 /****************
388  * Reset all contexts and discard any buffered stuff.  This may be used
389  * instead of a md_close(); md_open().
390  */
391 void
392 gcry_md_reset( GCRY_MD_HD a )
393 {
394     struct md_digest_list_s *r;
395
396     a->bufpos = a->ctx->finalized = 0;
397     for( r=a->ctx->list; r; r = r->next ) {
398         memset( r->context.c, 0, r->contextsize );
399         (*r->init)( &r->context.c );
400     }
401 }
402
403
404 static void
405 md_close(GCRY_MD_HD a)
406 {
407     struct md_digest_list_s *r, *r2;
408
409     if( !a )
410         return;
411     if( a->ctx->debug )
412         md_stop_debug(a);
413     for(r=a->ctx->list; r; r = r2 ) {
414         r2 = r->next;
415         m_free(r);
416     }
417     m_free(a);
418 }
419
420
421 void
422 gcry_md_close( GCRY_MD_HD hd )
423 {
424     md_close( hd );
425 }
426
427
428 static void
429 md_write( GCRY_MD_HD a, byte *inbuf, size_t inlen)
430 {
431     struct md_digest_list_s *r;
432
433     if( a->ctx->debug ) {
434         if( a->bufpos && fwrite(a->buf, a->bufpos, 1, a->ctx->debug ) != 1 )
435             BUG();
436         if( inlen && fwrite(inbuf, inlen, 1, a->ctx->debug ) != 1 )
437             BUG();
438     }
439     for(r=a->ctx->list; r; r = r->next ) {
440         if( a->bufpos )
441             (*r->write)( &r->context.c, a->buf, a->bufpos );
442         (*r->write)( &r->context.c, inbuf, inlen );
443     }
444     a->bufpos = 0;
445 }
446
447
448 void
449 gcry_md_write( GCRY_MD_HD hd, const byte *inbuf, size_t inlen)
450 {
451     md_write( hd, (byte*)inbuf, inlen );
452 }
453
454
455
456 static void
457 md_final(GCRY_MD_HD a)
458 {
459     struct md_digest_list_s *r;
460
461     if( a->ctx->finalized )
462         return;
463
464     if( a->bufpos )
465         md_write( a, NULL, 0 );
466
467     for(r=a->ctx->list; r; r = r->next ) {
468         (*r->final)( &r->context.c );
469     }
470     a->ctx->finalized = 1;
471 }
472
473
474 int
475 gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
476 {
477     if( cmd == GCRYCTL_FINALIZE )
478         md_final( hd );
479     else
480         return GCRYERR_INV_OP;
481     return 0;
482 }
483
484
485 /****************
486  * if ALGO is null get the digest for the used algo (which should be only one)
487  */
488 static byte *
489 md_read( GCRY_MD_HD a, int algo )
490 {
491     struct md_digest_list_s *r;
492
493     if( !algo ) {  /* return the first algorithm */
494         if( (r=a->ctx->list) ) {
495             if( r->next )
496                 log_debug("more than algorithm in md_read(0)\n");
497             return (*r->read)( &r->context.c );
498         }
499     }
500     else {
501         for(r=a->ctx->list; r; r = r->next )
502             if( r->algo == algo )
503                 return (*r->read)( &r->context.c );
504     }
505     BUG();
506     return NULL;
507 }
508
509 /****************
510  * Read out the complete digest, this function implictly finalizes
511  * the hash.
512  */
513 byte *
514 gcry_md_read( GCRY_MD_HD hd, int algo )
515 {
516     gcry_md_ctl( hd, GCRYCTL_FINALIZE, NULL, 0 );
517     return md_read( hd, algo);
518 }
519
520
521 /****************
522  * This function combines md_final and md_read but keeps the context
523  * intact.  This function can be used to calculate intermediate
524  * digests.  The digest is copied into buffer and the digestlength is
525  * returned.  If buffer is NULL only the needed size for buffer is returned.
526  * buflen gives the max size of buffer. If the buffer is too shourt to
527  * hold the complete digest, the buffer is filled with as many bytes are
528  * possible and this value is returned.
529  */
530 #if 0
531 static int
532 md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen )
533 {
534     struct md_digest_list_s *r = NULL;
535     char *context;
536     char *digest;
537
538     if( a->bufpos )
539         md_write( a, NULL, 0 );
540
541     if( !algo ) {  /* return digest for the first algorithm */
542         if( (r=a->ctx->list) && r->next )
543             log_debug("more than algorithm in md_digest(0)\n");
544     }
545     else {
546         for(r=a->ctx->list; r; r = r->next )
547             if( r->algo == algo )
548                 break;
549     }
550     if( !r )
551         BUG();
552
553     if( !buffer )
554         return r->mdlen;
555
556     /* I don't want to change the interface, so I simply work on a copy
557      * of the context (extra overhead - should be fixed)*/
558     context = a->ctx->secure ? m_alloc_secure( r->contextsize )
559                              : m_alloc( r->contextsize );
560     memcpy( context, r->context.c, r->contextsize );
561     (*r->final)( context );
562     digest = (*r->read)( context );
563
564     if( buflen > r->mdlen )
565         buflen = r->mdlen;
566     memcpy( buffer, digest, buflen );
567
568     m_free(context);
569     return buflen;
570 }
571 #endif
572
573 /****************
574  * Read out an intermediate digest.
575  */
576 int
577 gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen )
578 {
579     /*md_digest ... */
580     return GCRYERR_INTERNAL;
581 }
582
583
584
585 static int
586 md_get_algo( GCRY_MD_HD a )
587 {
588     struct md_digest_list_s *r;
589
590     if( (r=a->ctx->list) ) {
591         if( r->next )
592             log_error("WARNING: more than algorithm in md_get_algo()\n");
593         return r->algo;
594     }
595     return 0;
596 }
597
598
599 int
600 gcry_md_get_algo( GCRY_MD_HD hd )
601 {
602     return md_get_algo( hd ); /* fixme: we need error handling */
603 }
604
605
606 /****************
607  * Return the length of the digest
608  */
609 static int
610 md_digest_length( int algo )
611 {
612     struct md_digest_list_s *r;
613
614     do {
615         for(r = digest_list; r; r = r->next ) {
616             if( r->algo == algo )
617                 return r->mdlen;
618         }
619     } while( !r && load_digest_module( algo ) );
620     return 0;
621 }
622
623 /****************
624  * Return the length of the digest in bytes.
625  * This function will return 0 in case of errors.
626  */
627 unsigned int
628 gcry_md_get_algo_dlen( int algo )
629 {
630     /* we do some very quick checks here */
631     switch( algo )
632     {
633       case GCRY_MD_MD5: return 16;
634       case GCRY_MD_SHA1:
635       case GCRY_MD_RMD160: return 20;
636       default: {
637             int len = md_digest_length( algo );
638             if( !len )
639                 set_lasterr( GCRYERR_INV_ALGO );
640             return 0;
641         }
642     }
643 }
644
645
646 /* Hmmm: add a mode to enumerate the OIDs
647  *      to make g10/sig-check.c more portable */
648 static const byte *
649 md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
650 {
651     struct md_digest_list_s *r;
652
653     do {
654         for(r = digest_list; r; r = r->next ) {
655             if( r->algo == algo ) {
656                 if( asnlen )
657                     *asnlen = r->asnlen;
658                 if( mdlen )
659                     *mdlen = r->mdlen;
660                 return r->asnoid;
661             }
662         }
663     } while( !r && load_digest_module( algo ) );
664     log_bug("no asn for md algo %d\n", algo);
665     return NULL;
666 }
667
668
669
670 /****************
671  * Return information about the given cipher algorithm
672  * WHAT select the kind of information returned:
673  *  GCRYCTL_TEST_ALGO:
674  *      Returns 0 when the specified algorithm is available for use.
675  *      buffer and nbytes must be zero.
676  *  GCRYCTL_GET_ASNOID:
677  *      Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
678  *      the required length is returned.
679  *
680  * On error the value -1 is returned and the error reason may be
681  * retrieved by gcry_errno().
682  * Note:  Because this function is in most caes used to return an
683  * integer value, we can make it easier for the caller to just look at
684  * the return value.  The caller will in all cases consult the value
685  * and thereby detecting whether a error occured or not (i.e. while checking
686  * the block size)
687  */
688 int
689 gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes)
690 {
691     switch( what ) {
692       case GCRYCTL_TEST_ALGO:
693         if( buffer || nbytes ) {
694             set_lasterr( GCRYERR_INV_ARG );
695             return -1;
696         }
697         if( check_digest_algo( algo ) ) {
698             set_lasterr( GCRYERR_INV_ALGO );
699             return -1;
700         }
701         break;
702
703       case GCRYCTL_GET_ASNOID: {
704             size_t asnlen;
705             const char *asn = md_asn_oid( algo, &asnlen, NULL );
706             if( buffer && *nbytes >= asnlen ) {
707                 memcpy( buffer, asn, asnlen );
708                 *nbytes = asnlen;
709                 return 0;
710             }
711             if( !buffer && nbytes ) {
712                 *nbytes = asnlen;
713                 return 0;
714             }
715             set_lasterr( buffer ? GCRYERR_TOO_SHORT : GCRYERR_INV_ARG );
716             return -1;
717         }
718         break;
719
720       default:
721         set_lasterr( GCRYERR_INV_OP );
722         return -1;
723     }
724     return 0;
725 }
726
727
728
729
730 void
731 md_start_debug( GCRY_MD_HD md, const char *suffix )
732 {
733     static int idx=0;
734     char buf[25];
735
736     if( md->ctx->debug ) {
737         log_debug("Oops: md debug already started\n");
738         return;
739     }
740     idx++;
741     sprintf(buf, "dbgmd-%05d.%.10s", idx, suffix );
742     md->ctx->debug = fopen(buf, "w");
743     if( !md->ctx->debug )
744         log_debug("md debug: can't open %s\n", buf );
745 }
746
747 void
748 md_stop_debug( GCRY_MD_HD md )
749 {
750     if( md->ctx->debug ) {
751         if( md->bufpos )
752             md_write( md, NULL, 0 );
753         fclose(md->ctx->debug);
754         md->ctx->debug = NULL;
755     }
756   #ifdef HAVE_U64_TYPEDEF
757     {  /* a kludge to pull in the __muldi3 for Solaris */
758        volatile u32 a = (u32)(ulong)md;
759        volatile u64 b = 42;
760        volatile u64 c;
761        c = a * b;
762     }
763   #endif
764 }
765
766
767
768 /****************
769  * Return information about the digest handle.
770  *  GCRYCTL_IS_SECURE:
771  *      Returns 1 when the handle works on secured memory
772  *      otherwise 0 is returned.  There is no error return.
773  */
774 int
775 gcry_md_info( GCRY_MD_HD h, int cmd, void *buffer, size_t *nbytes)
776 {
777     switch( cmd ) {
778       case GCRYCTL_IS_SECURE:
779         return h->ctx->secure;
780
781       default:
782         set_lasterr( GCRYERR_INV_OP );
783         return -1;
784     }
785     return 0;
786 }
787