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