extensions are now working and fixed a lot of bugs
[libgcrypt.git] / cipher / md.c
1 /* md.c  -  message digest dispatcher
2  *      Copyright (C) 1998 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 "util.h"
27 #include "cipher.h"
28 #include "errors.h"
29
30
31
32 /* Note: the first string is the one used by ascii armor */
33 static struct { const char *name; int algo;} digest_names[] = {
34     { "MD5",           DIGEST_ALGO_MD5    },
35     { "SHA1",          DIGEST_ALGO_SHA1   },
36     { "SHA-1",         DIGEST_ALGO_SHA1   },
37     { "RIPEMD160",     DIGEST_ALGO_RMD160 },
38     { "RMD160",        DIGEST_ALGO_RMD160 },
39     { "RMD-160",       DIGEST_ALGO_RMD160 },
40     { "RIPE-MD-160",   DIGEST_ALGO_RMD160 },
41     {NULL} };
42
43
44
45
46 /****************
47  * Map a string to the digest algo
48  */
49 int
50 string_to_digest_algo( const char *string )
51 {
52     int i;
53     const char *s;
54
55     for(i=0; (s=digest_names[i].name); i++ )
56         if( !stricmp( s, string ) )
57             return digest_names[i].algo;
58     return 0;
59 }
60
61
62 /****************
63  * Map a digest algo to a string
64  */
65 const char *
66 digest_algo_to_string( int algo )
67 {
68     int i;
69
70     for(i=0; digest_names[i].name; i++ )
71         if( digest_names[i].algo == algo )
72             return digest_names[i].name;
73     return NULL;
74 }
75
76
77 int
78 check_digest_algo( int algo )
79 {
80     switch( algo ) {
81       case DIGEST_ALGO_MD5:
82       case DIGEST_ALGO_RMD160:
83       case DIGEST_ALGO_SHA1:
84         return 0;
85       default:
86         return G10ERR_DIGEST_ALGO;
87     }
88 }
89
90
91
92
93
94
95
96 /****************
97  * Open a message digest handle for use with algorithm ALGO.
98  * More algorithms may be added by md_enable(). The initial algorithm
99  * may be 0.
100  */
101 MD_HANDLE
102 md_open( int algo, int secure )
103 {
104     MD_HANDLE hd;
105
106     hd = secure ? m_alloc_secure_clear( sizeof *hd )
107                 : m_alloc_clear( sizeof *hd );
108     hd->secure = secure;
109     if( algo )
110         md_enable( hd, algo );
111     fast_random_poll();
112     return hd;
113 }
114
115 void
116 md_enable( MD_HANDLE h, int algo )
117 {
118     if( algo == DIGEST_ALGO_MD5 ) {
119         if( !h->use_md5 )
120             md5_init( &h->md5 );
121         h->use_md5 = 1;
122     }
123     else if( algo == DIGEST_ALGO_RMD160 ) {
124         if( !h->use_rmd160 )
125             rmd160_init( &h->rmd160 );
126         h->use_rmd160 = 1;
127     }
128     else if( algo == DIGEST_ALGO_SHA1 ) {
129         if( !h->use_sha1 )
130             sha1_init( &h->sha1 );
131         h->use_sha1 = 1;
132     }
133     else
134         log_bug("md_enable(%d)", algo );
135 }
136
137
138 MD_HANDLE
139 md_copy( MD_HANDLE a )
140 {
141     MD_HANDLE b;
142
143     b = a->secure ? m_alloc_secure( sizeof *b )
144                   : m_alloc( sizeof *b );
145     memcpy( b, a, sizeof *a );
146     return b;
147 }
148
149
150 void
151 md_close(MD_HANDLE a)
152 {
153     if( !a )
154         return;
155     if( a->debug )
156         md_stop_debug(a);
157     m_free(a);
158 }
159
160
161 void
162 md_write( MD_HANDLE a, byte *inbuf, size_t inlen)
163 {
164     if( a->debug ) {
165         if( a->bufcount && fwrite(a->buffer, a->bufcount, 1, a->debug ) != 1 )
166             BUG();
167         if( inlen && fwrite(inbuf, inlen, 1, a->debug ) != 1 )
168             BUG();
169     }
170     if( a->use_rmd160 ) {
171         rmd160_write( &a->rmd160, a->buffer, a->bufcount );
172         rmd160_write( &a->rmd160, inbuf, inlen  );
173     }
174     if( a->use_sha1 ) {
175         sha1_write( &a->sha1, a->buffer, a->bufcount );
176         sha1_write( &a->sha1, inbuf, inlen  );
177     }
178     if( a->use_md5 ) {
179         md5_write( &a->md5, a->buffer, a->bufcount );
180         md5_write( &a->md5, inbuf, inlen  );
181     }
182     a->bufcount = 0;
183 }
184
185
186
187 void
188 md_final(MD_HANDLE a)
189 {
190     if( a->bufcount )
191         md_write( a, NULL, 0 );
192     if( a->use_rmd160 )
193         rmd160_final( &a->rmd160 );
194     if( a->use_sha1 )
195         sha1_final( &a->sha1 );
196     if( a->use_md5 )
197         md5_final( &a->md5 );
198 }
199
200
201 /****************
202  * if ALGO is null get the digest for the used algo (which should be only one)
203  */
204 byte *
205 md_read( MD_HANDLE a, int algo )
206 {
207     if( !algo ) {
208         if( a->use_rmd160 )
209             return rmd160_read( &a->rmd160 );
210         if( a->use_sha1 )
211             return sha1_read( &a->sha1 );
212         if( a->use_md5 )
213             return md5_read( &a->md5 );
214     }
215     else {
216         if( algo == DIGEST_ALGO_RMD160 )
217             return rmd160_read( &a->rmd160 );
218         if( algo == DIGEST_ALGO_SHA1 )
219             return sha1_read( &a->sha1 );
220         if( algo == DIGEST_ALGO_MD5 )
221             return md5_read( &a->md5 );
222     }
223     BUG();
224 }
225
226 int
227 md_get_algo( MD_HANDLE a )
228 {
229     if( a->use_rmd160 )
230         return DIGEST_ALGO_RMD160;
231     if( a->use_sha1 )
232         return DIGEST_ALGO_SHA1;
233     if( a->use_md5 )
234         return DIGEST_ALGO_MD5;
235     return 0;
236 }
237
238 /****************
239  * Return the length of the digest
240  */
241 int
242 md_digest_length( int algo )
243 {
244     switch( algo ) {
245       case DIGEST_ALGO_RMD160:
246       case DIGEST_ALGO_SHA1:
247         return 20;
248       default:
249         return 16;
250     }
251 }
252
253
254 /* fixme: put the oids in a table and add a mode to enumerate the OIDs
255  * to make g10/sig-check.c more portable */
256 const byte *
257 md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
258 {
259     size_t alen;
260     byte *p;
261
262     if( algo == DIGEST_ALGO_MD5 ) {
263         static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
264                     { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
265                       0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
266         alen = DIM(asn); p = asn;
267     }
268     else if( algo == DIGEST_ALGO_RMD160 ) {
269         static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
270           { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
271             0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
272         alen = DIM(asn); p = asn;
273     }
274     else if( algo == DIGEST_ALGO_TIGER ) {
275         /* 40: SEQUENCE {
276          * 12:   SEQUENCE {
277          *  8:     OCTET STRING   :54 49 47 45 52 31 39 32
278          *  0:     NULL
279          *   :     }
280          * 24:   OCTET STRING
281          *   :   }
282          *
283          * By replacing the 5th byte (0x04) with 0x16 we would have;
284          *        8:     IA5String 'TIGER192'
285          */
286         static byte asn[18] =
287                     { 0x30, 0x28, 0x30, 0x0c, 0x04, 0x08, 0x54, 0x49, 0x47,
288                       0x45, 0x52, 0x31, 0x39, 0x32, 0x05, 0x00, 0x04, 0x18 };
289         alen = DIM(asn); p = asn;
290     }
291     else if( algo == DIGEST_ALGO_SHA1 ) {
292         static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */
293                     { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
294                       0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
295         alen = DIM(asn); p = asn;
296     }
297     else
298         log_bug("md_asn_oid(%d)", algo );
299
300     if( asnlen )
301         *asnlen = alen;
302     if( mdlen )
303         *mdlen = p[alen-1];
304     return p;
305 }
306
307
308 void
309 md_start_debug( MD_HANDLE md, const char *suffix )
310 {
311     static int index=0;
312     char buf[25];
313
314     if( md->debug ) {
315         log_debug("Oops: md debug already started\n");
316         return;
317     }
318     index++;
319     sprintf(buf, "dbgmd-%05d.%.10s", index, suffix );
320     md->debug = fopen(buf, "w");
321     if( !md->debug )
322         log_debug("md debug: can't open %s\n", buf );
323 }
324
325 void
326 md_stop_debug( MD_HANDLE md )
327 {
328     if( md->debug ) {
329         fclose(md->debug);
330         md->debug = NULL;
331     }
332 }
333