Line data Source code
1 : /* md.c - message digest dispatcher
2 : * Copyright (C) 1998, 1999, 2002, 2003, 2006,
3 : * 2008 Free Software Foundation, Inc.
4 : * Copyright (C) 2013, 2014 g10 Code GmbH
5 : *
6 : * This file is part of Libgcrypt.
7 : *
8 : * Libgcrypt is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU Lesser general Public License as
10 : * published by the Free Software Foundation; either version 2.1 of
11 : * the License, or (at your option) any later version.
12 : *
13 : * Libgcrypt is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU Lesser General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU Lesser General Public
19 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include <config.h>
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <errno.h>
27 :
28 : #include "g10lib.h"
29 : #include "cipher.h"
30 :
31 :
32 : /* This is the list of the digest implementations included in
33 : libgcrypt. */
34 : static gcry_md_spec_t *digest_list[] =
35 : {
36 : #if USE_CRC
37 : &_gcry_digest_spec_crc32,
38 : &_gcry_digest_spec_crc32_rfc1510,
39 : &_gcry_digest_spec_crc24_rfc2440,
40 : #endif
41 : #if USE_SHA1
42 : &_gcry_digest_spec_sha1,
43 : #endif
44 : #if USE_SHA256
45 : &_gcry_digest_spec_sha256,
46 : &_gcry_digest_spec_sha224,
47 : #endif
48 : #if USE_SHA512
49 : &_gcry_digest_spec_sha512,
50 : &_gcry_digest_spec_sha384,
51 : #endif
52 : #if USE_SHA3
53 : &_gcry_digest_spec_sha3_224,
54 : &_gcry_digest_spec_sha3_256,
55 : &_gcry_digest_spec_sha3_384,
56 : &_gcry_digest_spec_sha3_512,
57 : &_gcry_digest_spec_shake128,
58 : &_gcry_digest_spec_shake256,
59 : #endif
60 : #if USE_GOST_R_3411_94
61 : &_gcry_digest_spec_gost3411_94,
62 : &_gcry_digest_spec_gost3411_cp,
63 : #endif
64 : #if USE_GOST_R_3411_12
65 : &_gcry_digest_spec_stribog_256,
66 : &_gcry_digest_spec_stribog_512,
67 : #endif
68 : #if USE_WHIRLPOOL
69 : &_gcry_digest_spec_whirlpool,
70 : #endif
71 : #if USE_RMD160
72 : &_gcry_digest_spec_rmd160,
73 : #endif
74 : #if USE_TIGER
75 : &_gcry_digest_spec_tiger,
76 : &_gcry_digest_spec_tiger1,
77 : &_gcry_digest_spec_tiger2,
78 : #endif
79 : #if USE_MD5
80 : &_gcry_digest_spec_md5,
81 : #endif
82 : #if USE_MD4
83 : &_gcry_digest_spec_md4,
84 : #endif
85 : #if USE_MD2
86 : &_gcry_digest_spec_md2,
87 : #endif
88 : #if USE_BLAKE2
89 : &_gcry_digest_spec_blake2b_512,
90 : &_gcry_digest_spec_blake2b_384,
91 : &_gcry_digest_spec_blake2b_256,
92 : &_gcry_digest_spec_blake2b_160,
93 : &_gcry_digest_spec_blake2s_256,
94 : &_gcry_digest_spec_blake2s_224,
95 : &_gcry_digest_spec_blake2s_160,
96 : &_gcry_digest_spec_blake2s_128,
97 : #endif
98 : NULL
99 : };
100 :
101 :
102 : typedef struct gcry_md_list
103 : {
104 : gcry_md_spec_t *spec;
105 : struct gcry_md_list *next;
106 : size_t actual_struct_size; /* Allocated size of this structure. */
107 : PROPERLY_ALIGNED_TYPE context;
108 : } GcryDigestEntry;
109 :
110 : /* This structure is put right after the gcry_md_hd_t buffer, so that
111 : * only one memory block is needed. */
112 : struct gcry_md_context
113 : {
114 : int magic;
115 : size_t actual_handle_size; /* Allocated size of this handle. */
116 : FILE *debug;
117 : struct {
118 : unsigned int secure: 1;
119 : unsigned int finalized:1;
120 : unsigned int bugemu1:1;
121 : unsigned int hmac:1;
122 : } flags;
123 : GcryDigestEntry *list;
124 : };
125 :
126 :
127 : #define CTX_MAGIC_NORMAL 0x11071961
128 : #define CTX_MAGIC_SECURE 0x16917011
129 :
130 : static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
131 : static void md_close (gcry_md_hd_t a);
132 : static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
133 : static byte *md_read( gcry_md_hd_t a, int algo );
134 : static int md_get_algo( gcry_md_hd_t a );
135 : static int md_digest_length( int algo );
136 : static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
137 : static void md_stop_debug ( gcry_md_hd_t a );
138 :
139 :
140 :
141 : static int
142 144809 : map_algo (int algo)
143 : {
144 144809 : return algo;
145 : }
146 :
147 :
148 : /* Return the spec structure for the hash algorithm ALGO. For an
149 : unknown algorithm NULL is returned. */
150 : static gcry_md_spec_t *
151 144809 : spec_from_algo (int algo)
152 : {
153 : int idx;
154 : gcry_md_spec_t *spec;
155 :
156 144809 : algo = map_algo (algo);
157 :
158 1486065 : for (idx = 0; (spec = digest_list[idx]); idx++)
159 1484595 : if (algo == spec->algo)
160 143339 : return spec;
161 1470 : return NULL;
162 : }
163 :
164 :
165 : /* Lookup a hash's spec by its name. */
166 : static gcry_md_spec_t *
167 127 : spec_from_name (const char *name)
168 : {
169 : gcry_md_spec_t *spec;
170 : int idx;
171 :
172 1797 : for (idx=0; (spec = digest_list[idx]); idx++)
173 : {
174 1773 : if (!stricmp (name, spec->name))
175 103 : return spec;
176 : }
177 :
178 24 : return NULL;
179 : }
180 :
181 :
182 : /* Lookup a hash's spec by its OID. */
183 : static gcry_md_spec_t *
184 175 : spec_from_oid (const char *oid)
185 : {
186 : gcry_md_spec_t *spec;
187 : gcry_md_oid_spec_t *oid_specs;
188 : int idx, j;
189 :
190 4510 : for (idx=0; (spec = digest_list[idx]); idx++)
191 : {
192 4383 : oid_specs = spec->oids;
193 4383 : if (oid_specs)
194 : {
195 9082 : for (j = 0; oid_specs[j].oidstring; j++)
196 5780 : if (!stricmp (oid, oid_specs[j].oidstring))
197 48 : return spec;
198 : }
199 : }
200 :
201 127 : return NULL;
202 : }
203 :
204 :
205 : static gcry_md_spec_t *
206 175 : search_oid (const char *oid, gcry_md_oid_spec_t *oid_spec)
207 : {
208 : gcry_md_spec_t *spec;
209 : int i;
210 :
211 175 : if (!oid)
212 0 : return NULL;
213 :
214 175 : if (!strncmp (oid, "oid.", 4) || !strncmp (oid, "OID.", 4))
215 48 : oid += 4;
216 :
217 175 : spec = spec_from_oid (oid);
218 175 : if (spec && spec->oids)
219 : {
220 192 : for (i = 0; spec->oids[i].oidstring; i++)
221 192 : if (!stricmp (oid, spec->oids[i].oidstring))
222 : {
223 48 : if (oid_spec)
224 0 : *oid_spec = spec->oids[i];
225 48 : return spec;
226 : }
227 : }
228 :
229 127 : return NULL;
230 : }
231 :
232 :
233 : /****************
234 : * Map a string to the digest algo
235 : */
236 : int
237 175 : _gcry_md_map_name (const char *string)
238 : {
239 : gcry_md_spec_t *spec;
240 :
241 175 : if (!string)
242 0 : return 0;
243 :
244 : /* If the string starts with a digit (optionally prefixed with
245 : either "OID." or "oid."), we first look into our table of ASN.1
246 : object identifiers to figure out the algorithm */
247 175 : spec = search_oid (string, NULL);
248 175 : if (spec)
249 48 : return spec->algo;
250 :
251 : /* Not found, search a matching digest name. */
252 127 : spec = spec_from_name (string);
253 127 : if (spec)
254 103 : return spec->algo;
255 :
256 24 : return 0;
257 : }
258 :
259 :
260 : /****************
261 : * This function simply returns the name of the algorithm or some constant
262 : * string when there is no algo. It will never return NULL.
263 : * Use the macro gcry_md_test_algo() to check whether the algorithm
264 : * is valid.
265 : */
266 : const char *
267 126 : _gcry_md_algo_name (int algorithm)
268 : {
269 : gcry_md_spec_t *spec;
270 :
271 126 : spec = spec_from_algo (algorithm);
272 126 : return spec ? spec->name : "?";
273 : }
274 :
275 :
276 : static gcry_err_code_t
277 9500 : check_digest_algo (int algorithm)
278 : {
279 : gcry_md_spec_t *spec;
280 :
281 9500 : spec = spec_from_algo (algorithm);
282 9500 : if (spec && !spec->flags.disabled)
283 8030 : return 0;
284 :
285 1470 : return GPG_ERR_DIGEST_ALGO;
286 :
287 : }
288 :
289 :
290 : /****************
291 : * Open a message digest handle for use with algorithm ALGO.
292 : * More algorithms may be added by md_enable(). The initial algorithm
293 : * may be 0.
294 : */
295 : static gcry_err_code_t
296 59232 : md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
297 : {
298 59232 : gcry_err_code_t err = 0;
299 59232 : int secure = !!(flags & GCRY_MD_FLAG_SECURE);
300 59232 : int hmac = !!(flags & GCRY_MD_FLAG_HMAC);
301 59232 : int bufsize = secure ? 512 : 1024;
302 : struct gcry_md_context *ctx;
303 : gcry_md_hd_t hd;
304 : size_t n;
305 :
306 : /* Allocate a memory area to hold the caller visible buffer with it's
307 : * control information and the data required by this module. Set the
308 : * context pointer at the beginning to this area.
309 : * We have to use this strange scheme because we want to hide the
310 : * internal data but have a variable sized buffer.
311 : *
312 : * +---+------+---........------+-------------+
313 : * !ctx! bctl ! buffer ! private !
314 : * +---+------+---........------+-------------+
315 : * ! ^
316 : * !---------------------------!
317 : *
318 : * We have to make sure that private is well aligned.
319 : */
320 59232 : n = sizeof (struct gcry_md_handle) + bufsize;
321 59232 : n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
322 : / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
323 :
324 : /* Allocate and set the Context pointer to the private data */
325 59232 : if (secure)
326 76 : hd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
327 : else
328 59156 : hd = xtrymalloc (n + sizeof (struct gcry_md_context));
329 :
330 59232 : if (! hd)
331 0 : err = gpg_err_code_from_errno (errno);
332 :
333 59232 : if (! err)
334 : {
335 59232 : hd->ctx = ctx = (void *) ((char *) hd + n);
336 : /* Setup the globally visible data (bctl in the diagram).*/
337 59232 : hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
338 59232 : hd->bufpos = 0;
339 :
340 : /* Initialize the private data. */
341 59232 : memset (hd->ctx, 0, sizeof *hd->ctx);
342 59232 : ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
343 59232 : ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
344 59232 : ctx->flags.secure = secure;
345 59232 : ctx->flags.hmac = hmac;
346 59232 : ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
347 : }
348 :
349 59232 : if (! err)
350 : {
351 : /* Hmmm, should we really do that? - yes [-wk] */
352 59232 : _gcry_fast_random_poll ();
353 :
354 59232 : if (algo)
355 : {
356 59232 : err = md_enable (hd, algo);
357 59232 : if (err)
358 0 : md_close (hd);
359 : }
360 : }
361 :
362 59232 : if (! err)
363 59232 : *h = hd;
364 :
365 59232 : return err;
366 : }
367 :
368 : /* Create a message digest object for algorithm ALGO. FLAGS may be
369 : given as an bitwise OR of the gcry_md_flags values. ALGO may be
370 : given as 0 if the algorithms to be used are later set using
371 : gcry_md_enable. H is guaranteed to be a valid handle or NULL on
372 : error. */
373 : gcry_err_code_t
374 12459 : _gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
375 : {
376 : gcry_err_code_t rc;
377 : gcry_md_hd_t hd;
378 :
379 12459 : if ((flags & ~(GCRY_MD_FLAG_SECURE
380 : | GCRY_MD_FLAG_HMAC
381 : | GCRY_MD_FLAG_BUGEMU1)))
382 0 : rc = GPG_ERR_INV_ARG;
383 : else
384 12459 : rc = md_open (&hd, algo, flags);
385 :
386 12459 : *h = rc? NULL : hd;
387 12459 : return rc;
388 : }
389 :
390 :
391 :
392 : static gcry_err_code_t
393 59232 : md_enable (gcry_md_hd_t hd, int algorithm)
394 : {
395 59232 : struct gcry_md_context *h = hd->ctx;
396 : gcry_md_spec_t *spec;
397 : GcryDigestEntry *entry;
398 59232 : gcry_err_code_t err = 0;
399 :
400 59232 : for (entry = h->list; entry; entry = entry->next)
401 0 : if (entry->spec->algo == algorithm)
402 0 : return 0; /* Already enabled */
403 :
404 59232 : spec = spec_from_algo (algorithm);
405 59232 : if (!spec)
406 : {
407 0 : log_debug ("md_enable: algorithm %d not available\n", algorithm);
408 0 : err = GPG_ERR_DIGEST_ALGO;
409 : }
410 :
411 :
412 59232 : if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
413 : {
414 0 : _gcry_inactivate_fips_mode ("MD5 used");
415 0 : if (_gcry_enforced_fips_mode () )
416 : {
417 : /* We should never get to here because we do not register
418 : MD5 in enforced fips mode. But better throw an error. */
419 0 : err = GPG_ERR_DIGEST_ALGO;
420 : }
421 : }
422 :
423 59232 : if (!err && h->flags.hmac && spec->read == NULL)
424 : {
425 : /* Expandable output function cannot act as part of HMAC. */
426 0 : err = GPG_ERR_DIGEST_ALGO;
427 : }
428 :
429 59232 : if (!err)
430 : {
431 59232 : size_t size = (sizeof (*entry)
432 59232 : + spec->contextsize * (h->flags.hmac? 3 : 1)
433 : - sizeof (entry->context));
434 :
435 : /* And allocate a new list entry. */
436 59232 : if (h->flags.secure)
437 76 : entry = xtrymalloc_secure (size);
438 : else
439 59156 : entry = xtrymalloc (size);
440 :
441 59232 : if (! entry)
442 0 : err = gpg_err_code_from_errno (errno);
443 : else
444 : {
445 59232 : entry->spec = spec;
446 59232 : entry->next = h->list;
447 59232 : entry->actual_struct_size = size;
448 59232 : h->list = entry;
449 :
450 : /* And init this instance. */
451 118464 : entry->spec->init (&entry->context.c,
452 59232 : h->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
453 : }
454 : }
455 :
456 59232 : return err;
457 : }
458 :
459 :
460 : gcry_err_code_t
461 0 : _gcry_md_enable (gcry_md_hd_t hd, int algorithm)
462 : {
463 0 : return md_enable (hd, algorithm);
464 : }
465 :
466 :
467 : static gcry_err_code_t
468 3496 : md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
469 : {
470 3496 : gcry_err_code_t err = 0;
471 3496 : struct gcry_md_context *a = ahd->ctx;
472 : struct gcry_md_context *b;
473 : GcryDigestEntry *ar, *br;
474 : gcry_md_hd_t bhd;
475 : size_t n;
476 :
477 3496 : if (ahd->bufpos)
478 0 : md_write (ahd, NULL, 0);
479 :
480 3496 : n = (char *) ahd->ctx - (char *) ahd;
481 3496 : if (a->flags.secure)
482 0 : bhd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
483 : else
484 3496 : bhd = xtrymalloc (n + sizeof (struct gcry_md_context));
485 :
486 3496 : if (!bhd)
487 : {
488 0 : err = gpg_err_code_from_syserror ();
489 0 : goto leave;
490 : }
491 :
492 3496 : bhd->ctx = b = (void *) ((char *) bhd + n);
493 : /* No need to copy the buffer due to the write above. */
494 3496 : gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
495 3496 : bhd->bufsize = ahd->bufsize;
496 3496 : bhd->bufpos = 0;
497 3496 : gcry_assert (! ahd->bufpos);
498 3496 : memcpy (b, a, sizeof *a);
499 3496 : b->list = NULL;
500 3496 : b->debug = NULL;
501 :
502 : /* Copy the complete list of algorithms. The copied list is
503 : reversed, but that doesn't matter. */
504 6992 : for (ar = a->list; ar; ar = ar->next)
505 : {
506 3496 : if (a->flags.secure)
507 0 : br = xtrymalloc_secure (ar->actual_struct_size);
508 : else
509 3496 : br = xtrymalloc (ar->actual_struct_size);
510 3496 : if (!br)
511 : {
512 0 : err = gpg_err_code_from_syserror ();
513 0 : md_close (bhd);
514 0 : goto leave;
515 : }
516 :
517 3496 : memcpy (br, ar, ar->actual_struct_size);
518 3496 : br->next = b->list;
519 3496 : b->list = br;
520 : }
521 :
522 3496 : if (a->debug)
523 0 : md_start_debug (bhd, "unknown");
524 :
525 3496 : *b_hd = bhd;
526 :
527 : leave:
528 3496 : return err;
529 : }
530 :
531 :
532 : gcry_err_code_t
533 3496 : _gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
534 : {
535 : gcry_err_code_t rc;
536 :
537 3496 : rc = md_copy (hd, handle);
538 3496 : if (rc)
539 0 : *handle = NULL;
540 3496 : return rc;
541 : }
542 :
543 :
544 : /*
545 : * Reset all contexts and discard any buffered stuff. This may be used
546 : * instead of a md_close(); md_open().
547 : */
548 : void
549 331816 : _gcry_md_reset (gcry_md_hd_t a)
550 : {
551 : GcryDigestEntry *r;
552 :
553 : /* Note: We allow this even in fips non operational mode. */
554 :
555 331816 : a->bufpos = a->ctx->flags.finalized = 0;
556 :
557 331816 : if (a->ctx->flags.hmac)
558 590930 : for (r = a->ctx->list; r; r = r->next)
559 : {
560 295465 : memcpy (r->context.c, r->context.c + r->spec->contextsize,
561 295465 : r->spec->contextsize);
562 : }
563 : else
564 72702 : for (r = a->ctx->list; r; r = r->next)
565 : {
566 36351 : memset (r->context.c, 0, r->spec->contextsize);
567 72702 : (*r->spec->init) (&r->context.c,
568 36351 : a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
569 : }
570 331816 : }
571 :
572 :
573 : static void
574 62726 : md_close (gcry_md_hd_t a)
575 : {
576 : GcryDigestEntry *r, *r2;
577 :
578 62726 : if (! a)
579 0 : return;
580 62726 : if (a->ctx->debug)
581 0 : md_stop_debug (a);
582 125452 : for (r = a->ctx->list; r; r = r2)
583 : {
584 62726 : r2 = r->next;
585 62726 : wipememory (r, r->actual_struct_size);
586 62726 : xfree (r);
587 : }
588 :
589 62726 : wipememory (a, a->ctx->actual_handle_size);
590 62726 : xfree(a);
591 : }
592 :
593 :
594 : void
595 15953 : _gcry_md_close (gcry_md_hd_t hd)
596 : {
597 : /* Note: We allow this even in fips non operational mode. */
598 15953 : md_close (hd);
599 15953 : }
600 :
601 :
602 : static void
603 35961922 : md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
604 : {
605 : GcryDigestEntry *r;
606 :
607 35961922 : if (a->ctx->debug)
608 : {
609 0 : if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
610 0 : BUG();
611 0 : if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
612 0 : BUG();
613 : }
614 :
615 71923844 : for (r = a->ctx->list; r; r = r->next)
616 : {
617 35961922 : if (a->bufpos)
618 32186 : (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
619 35961922 : (*r->spec->write) (&r->context.c, inbuf, inlen);
620 : }
621 35961922 : a->bufpos = 0;
622 35961922 : }
623 :
624 :
625 : /* Note that this function may be used after finalize and read to keep
626 : on writing to the transform function so to mitigate timing
627 : attacks. */
628 : void
629 35902546 : _gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
630 : {
631 35902546 : md_write (hd, inbuf, inlen);
632 35902546 : }
633 :
634 :
635 : static void
636 393902 : md_final (gcry_md_hd_t a)
637 : {
638 : GcryDigestEntry *r;
639 :
640 393902 : if (a->ctx->flags.finalized)
641 18199 : return;
642 :
643 375703 : if (a->bufpos)
644 0 : md_write (a, NULL, 0);
645 :
646 751406 : for (r = a->ctx->list; r; r = r->next)
647 375703 : (*r->spec->final) (&r->context.c);
648 :
649 375703 : a->ctx->flags.finalized = 1;
650 :
651 375703 : if (!a->ctx->flags.hmac)
652 87692 : return;
653 :
654 576022 : for (r = a->ctx->list; r; r = r->next)
655 : {
656 : byte *p;
657 288011 : size_t dlen = r->spec->mdlen;
658 : byte *hash;
659 : gcry_err_code_t err;
660 :
661 288011 : if (r->spec->read == NULL)
662 0 : continue;
663 :
664 288011 : p = r->spec->read (&r->context.c);
665 :
666 288011 : if (a->ctx->flags.secure)
667 478 : hash = xtrymalloc_secure (dlen);
668 : else
669 287533 : hash = xtrymalloc (dlen);
670 288011 : if (!hash)
671 : {
672 0 : err = gpg_err_code_from_errno (errno);
673 0 : _gcry_fatal_error (err, NULL);
674 : }
675 :
676 288011 : memcpy (hash, p, dlen);
677 288011 : memcpy (r->context.c, r->context.c + r->spec->contextsize * 2,
678 288011 : r->spec->contextsize);
679 288011 : (*r->spec->write) (&r->context.c, hash, dlen);
680 288011 : (*r->spec->final) (&r->context.c);
681 288011 : xfree (hash);
682 : }
683 : }
684 :
685 :
686 : static gcry_err_code_t
687 50 : md_setkey (gcry_md_hd_t h, const unsigned char *key, size_t keylen)
688 : {
689 50 : gcry_err_code_t rc = 0;
690 : GcryDigestEntry *r;
691 50 : int algo_had_setkey = 0;
692 :
693 50 : if (!h->ctx->list)
694 0 : return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
695 :
696 50 : if (h->ctx->flags.hmac)
697 0 : return GPG_ERR_DIGEST_ALGO; /* Tried md_setkey for HMAC md. */
698 :
699 100 : for (r = h->ctx->list; r; r = r->next)
700 : {
701 50 : switch (r->spec->algo)
702 : {
703 : /* TODO? add spec->init_with_key? */
704 : case GCRY_MD_BLAKE2B_512:
705 : case GCRY_MD_BLAKE2B_384:
706 : case GCRY_MD_BLAKE2B_256:
707 : case GCRY_MD_BLAKE2B_160:
708 : case GCRY_MD_BLAKE2S_256:
709 : case GCRY_MD_BLAKE2S_224:
710 : case GCRY_MD_BLAKE2S_160:
711 : case GCRY_MD_BLAKE2S_128:
712 50 : algo_had_setkey = 1;
713 50 : memset (r->context.c, 0, r->spec->contextsize);
714 100 : rc = _gcry_blake2_init_with_key (r->context.c,
715 50 : h->ctx->flags.bugemu1
716 50 : ? GCRY_MD_FLAG_BUGEMU1:0,
717 50 : key, keylen, r->spec->algo);
718 50 : break;
719 : default:
720 0 : rc = GPG_ERR_DIGEST_ALGO;
721 0 : break;
722 : }
723 :
724 50 : if (rc)
725 0 : break;
726 : }
727 :
728 50 : if (rc && !algo_had_setkey)
729 : {
730 : /* None of algorithms had setkey implementation, so contexts were not
731 : * modified. Just return error. */
732 0 : return rc;
733 : }
734 50 : else if (rc && algo_had_setkey)
735 : {
736 : /* Some of the contexts have been modified, but got error. Reset
737 : * all contexts. */
738 0 : _gcry_md_reset (h);
739 0 : return rc;
740 : }
741 :
742 : /* Successful md_setkey implies reset. */
743 50 : h->bufpos = h->ctx->flags.finalized = 0;
744 :
745 50 : return 0;
746 : }
747 :
748 :
749 : static gcry_err_code_t
750 8282 : prepare_macpads (gcry_md_hd_t a, const unsigned char *key, size_t keylen)
751 : {
752 : GcryDigestEntry *r;
753 :
754 8282 : if (!a->ctx->list)
755 0 : return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
756 :
757 8282 : if (!a->ctx->flags.hmac)
758 0 : return GPG_ERR_DIGEST_ALGO; /* Tried prepare_macpads for non-HMAC md. */
759 :
760 16564 : for (r = a->ctx->list; r; r = r->next)
761 : {
762 : const unsigned char *k;
763 : size_t k_len;
764 8282 : unsigned char *key_allocated = NULL;
765 : int macpad_Bsize;
766 : int i;
767 :
768 8282 : switch (r->spec->algo)
769 : {
770 : /* TODO: add spec->blocksize */
771 : case GCRY_MD_SHA3_224:
772 296 : macpad_Bsize = 1152 / 8;
773 296 : break;
774 : case GCRY_MD_SHA3_256:
775 296 : macpad_Bsize = 1088 / 8;
776 296 : break;
777 : case GCRY_MD_SHA3_384:
778 292 : macpad_Bsize = 832 / 8;
779 292 : break;
780 : case GCRY_MD_SHA3_512:
781 296 : macpad_Bsize = 576 / 8;
782 296 : break;
783 : case GCRY_MD_SHA384:
784 : case GCRY_MD_SHA512:
785 : case GCRY_MD_BLAKE2B_512:
786 : case GCRY_MD_BLAKE2B_384:
787 : case GCRY_MD_BLAKE2B_256:
788 : case GCRY_MD_BLAKE2B_160:
789 1694 : macpad_Bsize = 128;
790 1694 : break;
791 : case GCRY_MD_GOSTR3411_94:
792 : case GCRY_MD_GOSTR3411_CP:
793 559 : macpad_Bsize = 32;
794 559 : break;
795 : default:
796 4849 : macpad_Bsize = 64;
797 4849 : break;
798 : }
799 :
800 8282 : if ( keylen > macpad_Bsize )
801 : {
802 111 : k = key_allocated = xtrymalloc_secure (r->spec->mdlen);
803 111 : if (!k)
804 0 : return gpg_err_code_from_errno (errno);
805 111 : _gcry_md_hash_buffer (r->spec->algo, key_allocated, key, keylen);
806 111 : k_len = r->spec->mdlen;
807 111 : gcry_assert ( k_len <= macpad_Bsize );
808 : }
809 : else
810 : {
811 8171 : k = key;
812 8171 : k_len = keylen;
813 : }
814 :
815 16564 : (*r->spec->init) (&r->context.c,
816 8282 : a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
817 8282 : a->bufpos = 0;
818 81588 : for (i=0; i < k_len; i++ )
819 73306 : _gcry_md_putc (a, k[i] ^ 0x36);
820 614592 : for (; i < macpad_Bsize; i++ )
821 606310 : _gcry_md_putc (a, 0x36);
822 8282 : (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
823 8282 : memcpy (r->context.c + r->spec->contextsize, r->context.c,
824 8282 : r->spec->contextsize);
825 :
826 16564 : (*r->spec->init) (&r->context.c,
827 8282 : a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
828 8282 : a->bufpos = 0;
829 81588 : for (i=0; i < k_len; i++ )
830 73306 : _gcry_md_putc (a, k[i] ^ 0x5c);
831 614592 : for (; i < macpad_Bsize; i++ )
832 606310 : _gcry_md_putc (a, 0x5c);
833 8282 : (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
834 8282 : memcpy (r->context.c + r->spec->contextsize*2, r->context.c,
835 8282 : r->spec->contextsize);
836 :
837 8282 : xfree (key_allocated);
838 : }
839 :
840 8282 : a->bufpos = 0;
841 8282 : return 0;
842 : }
843 :
844 :
845 : gcry_err_code_t
846 347129 : _gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
847 : {
848 347129 : gcry_err_code_t rc = 0;
849 :
850 : (void)buflen; /* Currently not used. */
851 :
852 347129 : switch (cmd)
853 : {
854 : case GCRYCTL_FINALIZE:
855 347129 : md_final (hd);
856 347129 : break;
857 : case GCRYCTL_START_DUMP:
858 0 : md_start_debug (hd, buffer);
859 0 : break;
860 : case GCRYCTL_STOP_DUMP:
861 0 : md_stop_debug ( hd );
862 0 : break;
863 : default:
864 0 : rc = GPG_ERR_INV_OP;
865 : }
866 347129 : return rc;
867 : }
868 :
869 :
870 : gcry_err_code_t
871 8332 : _gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
872 : {
873 : gcry_err_code_t rc;
874 :
875 8332 : if (hd->ctx->flags.hmac)
876 : {
877 8282 : rc = prepare_macpads (hd, key, keylen);
878 8282 : if (!rc)
879 8282 : _gcry_md_reset (hd);
880 : }
881 : else
882 : {
883 50 : rc = md_setkey (hd, key, keylen);
884 : }
885 :
886 8332 : return rc;
887 : }
888 :
889 :
890 : /* The new debug interface. If SUFFIX is a string it creates an debug
891 : file for the context HD. IF suffix is NULL, the file is closed and
892 : debugging is stopped. */
893 : void
894 0 : _gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
895 : {
896 0 : if (suffix)
897 0 : md_start_debug (hd, suffix);
898 : else
899 0 : md_stop_debug (hd);
900 0 : }
901 :
902 :
903 : /****************
904 : * If ALGO is null get the digest for the used algo (which should be
905 : * only one)
906 : */
907 : static byte *
908 342616 : md_read( gcry_md_hd_t a, int algo )
909 : {
910 342616 : GcryDigestEntry *r = a->ctx->list;
911 :
912 342616 : if (! algo)
913 : {
914 : /* Return the first algorithm */
915 281339 : if (r)
916 : {
917 281339 : if (r->next)
918 0 : log_debug ("more than one algorithm in md_read(0)\n");
919 281339 : if (r->spec->read)
920 281339 : return r->spec->read (&r->context.c);
921 : }
922 : }
923 : else
924 : {
925 61277 : for (r = a->ctx->list; r; r = r->next)
926 61277 : if (r->spec->algo == algo)
927 : {
928 61277 : if (r->spec->read)
929 61277 : return r->spec->read (&r->context.c);
930 0 : break;
931 : }
932 : }
933 :
934 0 : if (r && !r->spec->read)
935 0 : _gcry_fatal_error (GPG_ERR_DIGEST_ALGO,
936 : "requested algo has no fixed digest length");
937 : else
938 0 : _gcry_fatal_error (GPG_ERR_DIGEST_ALGO, "requested algo not in md context");
939 : return NULL;
940 : }
941 :
942 :
943 : /*
944 : * Read out the complete digest, this function implictly finalizes
945 : * the hash.
946 : */
947 : byte *
948 295843 : _gcry_md_read (gcry_md_hd_t hd, int algo)
949 : {
950 : /* This function is expected to always return a digest, thus we
951 : can't return an error which we actually should do in
952 : non-operational state. */
953 295843 : _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
954 295843 : return md_read (hd, algo);
955 : }
956 :
957 :
958 : /****************
959 : * If ALGO is null get the digest for the used algo (which should be
960 : * only one)
961 : */
962 : static gcry_err_code_t
963 17878 : md_extract(gcry_md_hd_t a, int algo, void *out, size_t outlen)
964 : {
965 17878 : GcryDigestEntry *r = a->ctx->list;
966 :
967 17878 : if (!algo)
968 : {
969 : /* Return the first algorithm */
970 0 : if (r && r->spec->extract)
971 : {
972 0 : if (r->next)
973 0 : log_debug ("more than one algorithm in md_extract(0)\n");
974 0 : r->spec->extract (&r->context.c, out, outlen);
975 0 : return 0;
976 : }
977 : }
978 : else
979 : {
980 17878 : for (r = a->ctx->list; r; r = r->next)
981 17878 : if (r->spec->algo == algo && r->spec->extract)
982 : {
983 17878 : r->spec->extract (&r->context.c, out, outlen);
984 17878 : return 0;
985 : }
986 : }
987 :
988 0 : return GPG_ERR_DIGEST_ALGO;
989 : }
990 :
991 :
992 : /*
993 : * Expand the output from XOF class digest, this function implictly finalizes
994 : * the hash.
995 : */
996 : gcry_err_code_t
997 17878 : _gcry_md_extract (gcry_md_hd_t hd, int algo, void *out, size_t outlen)
998 : {
999 17878 : _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
1000 17878 : return md_extract (hd, algo, out, outlen);
1001 : }
1002 :
1003 :
1004 : /*
1005 : * Read out an intermediate digest. Not yet functional.
1006 : */
1007 : gcry_err_code_t
1008 0 : _gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
1009 : {
1010 : (void)hd;
1011 : (void)algo;
1012 : (void)buffer;
1013 : (void)buflen;
1014 :
1015 : /*md_digest ... */
1016 0 : fips_signal_error ("unimplemented function called");
1017 0 : return GPG_ERR_INTERNAL;
1018 : }
1019 :
1020 :
1021 : /*
1022 : * Shortcut function to hash a buffer with a given algo. The only
1023 : * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
1024 : * supplied digest buffer must be large enough to store the resulting
1025 : * hash. No error is returned, the function will abort on an invalid
1026 : * algo. DISABLED_ALGOS are ignored here. */
1027 : void
1028 63589 : _gcry_md_hash_buffer (int algo, void *digest,
1029 : const void *buffer, size_t length)
1030 : {
1031 63589 : if (algo == GCRY_MD_SHA1)
1032 24132 : _gcry_sha1_hash_buffer (digest, buffer, length);
1033 39457 : else if (algo == GCRY_MD_RMD160 && !fips_mode () )
1034 100 : _gcry_rmd160_hash_buffer (digest, buffer, length);
1035 : else
1036 : {
1037 : /* For the others we do not have a fast function, so we use the
1038 : normal functions. */
1039 : gcry_md_hd_t h;
1040 : gpg_err_code_t err;
1041 :
1042 39357 : if (algo == GCRY_MD_MD5 && fips_mode ())
1043 : {
1044 0 : _gcry_inactivate_fips_mode ("MD5 used");
1045 0 : if (_gcry_enforced_fips_mode () )
1046 : {
1047 : /* We should never get to here because we do not register
1048 : MD5 in enforced fips mode. */
1049 0 : _gcry_fips_noreturn ();
1050 : }
1051 : }
1052 :
1053 39357 : err = md_open (&h, algo, 0);
1054 39357 : if (err)
1055 0 : log_bug ("gcry_md_open failed for algo %d: %s",
1056 : algo, gpg_strerror (gcry_error(err)));
1057 39357 : md_write (h, (byte *) buffer, length);
1058 39357 : md_final (h);
1059 39357 : memcpy (digest, md_read (h, algo), md_digest_length (algo));
1060 39357 : md_close (h);
1061 : }
1062 63589 : }
1063 :
1064 :
1065 : /* Shortcut function to hash multiple buffers with a given algo. In
1066 : contrast to gcry_md_hash_buffer, this function returns an error on
1067 : invalid arguments or on other problems; disabled algorithms are
1068 : _not_ ignored but flagged as an error.
1069 :
1070 : The data to sign is taken from the array IOV which has IOVCNT items.
1071 :
1072 : The only supported flag in FLAGS is GCRY_MD_FLAG_HMAC which turns
1073 : this function into a HMAC function; the first item in IOV is then
1074 : used as the key.
1075 :
1076 : On success 0 is returned and resulting hash or HMAC is stored at
1077 : DIGEST which must have been provided by the caller with an
1078 : appropriate length. */
1079 : gpg_err_code_t
1080 7422 : _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
1081 : const gcry_buffer_t *iov, int iovcnt)
1082 : {
1083 : int hmac;
1084 :
1085 7422 : if (!iov || iovcnt < 0)
1086 0 : return GPG_ERR_INV_ARG;
1087 7422 : if (flags & ~(GCRY_MD_FLAG_HMAC))
1088 0 : return GPG_ERR_INV_ARG;
1089 :
1090 7422 : hmac = !!(flags & GCRY_MD_FLAG_HMAC);
1091 7422 : if (hmac && iovcnt < 1)
1092 0 : return GPG_ERR_INV_ARG;
1093 :
1094 7422 : if (algo == GCRY_MD_SHA1 && !hmac)
1095 6 : _gcry_sha1_hash_buffers (digest, iov, iovcnt);
1096 : else
1097 : {
1098 : /* For the others we do not have a fast function, so we use the
1099 : normal functions. */
1100 : gcry_md_hd_t h;
1101 : gpg_err_code_t rc;
1102 : int dlen;
1103 :
1104 7416 : if (algo == GCRY_MD_MD5 && fips_mode ())
1105 : {
1106 0 : _gcry_inactivate_fips_mode ("MD5 used");
1107 0 : if (_gcry_enforced_fips_mode () )
1108 : {
1109 : /* We should never get to here because we do not register
1110 : MD5 in enforced fips mode. */
1111 0 : _gcry_fips_noreturn ();
1112 : }
1113 : }
1114 :
1115 : /* Detect SHAKE128 like algorithms which we can't use because
1116 : * our API does not allow for a variable length digest. */
1117 7416 : dlen = md_digest_length (algo);
1118 7416 : if (!dlen)
1119 0 : return GPG_ERR_DIGEST_ALGO;
1120 :
1121 7416 : rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0));
1122 7416 : if (rc)
1123 0 : return rc;
1124 :
1125 7416 : if (hmac)
1126 : {
1127 2 : rc = _gcry_md_setkey (h,
1128 1 : (const char*)iov[0].data + iov[0].off,
1129 : iov[0].len);
1130 1 : if (rc)
1131 : {
1132 0 : md_close (h);
1133 0 : return rc;
1134 : }
1135 1 : iov++; iovcnt--;
1136 : }
1137 27435 : for (;iovcnt; iov++, iovcnt--)
1138 20019 : md_write (h, (const char*)iov[0].data + iov[0].off, iov[0].len);
1139 7416 : md_final (h);
1140 7416 : memcpy (digest, md_read (h, algo), dlen);
1141 7416 : md_close (h);
1142 : }
1143 :
1144 7422 : return 0;
1145 : }
1146 :
1147 :
1148 : static int
1149 0 : md_get_algo (gcry_md_hd_t a)
1150 : {
1151 0 : GcryDigestEntry *r = a->ctx->list;
1152 :
1153 0 : if (r && r->next)
1154 : {
1155 0 : fips_signal_error ("possible usage error");
1156 0 : log_error ("WARNING: more than one algorithm in md_get_algo()\n");
1157 : }
1158 0 : return r ? r->spec->algo : 0;
1159 : }
1160 :
1161 :
1162 : int
1163 0 : _gcry_md_get_algo (gcry_md_hd_t hd)
1164 : {
1165 0 : return md_get_algo (hd);
1166 : }
1167 :
1168 :
1169 : /****************
1170 : * Return the length of the digest
1171 : */
1172 : static int
1173 75002 : md_digest_length (int algorithm)
1174 : {
1175 : gcry_md_spec_t *spec;
1176 :
1177 75002 : spec = spec_from_algo (algorithm);
1178 75002 : return spec? spec->mdlen : 0;
1179 : }
1180 :
1181 :
1182 : /****************
1183 : * Return the length of the digest in bytes.
1184 : * This function will return 0 in case of errors.
1185 : */
1186 : unsigned int
1187 28229 : _gcry_md_get_algo_dlen (int algorithm)
1188 : {
1189 28229 : return md_digest_length (algorithm);
1190 : }
1191 :
1192 :
1193 : /* Hmmm: add a mode to enumerate the OIDs
1194 : * to make g10/sig-check.c more portable */
1195 : static const byte *
1196 906 : md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
1197 : {
1198 : gcry_md_spec_t *spec;
1199 906 : const byte *asnoid = NULL;
1200 :
1201 906 : spec = spec_from_algo (algorithm);
1202 906 : if (spec)
1203 : {
1204 906 : if (asnlen)
1205 906 : *asnlen = spec->asnlen;
1206 906 : if (mdlen)
1207 0 : *mdlen = spec->mdlen;
1208 906 : asnoid = spec->asnoid;
1209 : }
1210 : else
1211 0 : log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
1212 :
1213 906 : return asnoid;
1214 : }
1215 :
1216 :
1217 : /****************
1218 : * Return information about the given cipher algorithm
1219 : * WHAT select the kind of information returned:
1220 : * GCRYCTL_TEST_ALGO:
1221 : * Returns 0 when the specified algorithm is available for use.
1222 : * buffer and nbytes must be zero.
1223 : * GCRYCTL_GET_ASNOID:
1224 : * Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
1225 : * the required length is returned.
1226 : * GCRYCTL_SELFTEST
1227 : * Helper for the regression tests - shall not be used by applications.
1228 : *
1229 : * Note: Because this function is in most cases used to return an
1230 : * integer value, we can make it easier for the caller to just look at
1231 : * the return value. The caller will in all cases consult the value
1232 : * and thereby detecting whether a error occurred or not (i.e. while checking
1233 : * the block size)
1234 : */
1235 : gcry_err_code_t
1236 9533 : _gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
1237 : {
1238 : gcry_err_code_t rc;
1239 :
1240 9533 : switch (what)
1241 : {
1242 : case GCRYCTL_TEST_ALGO:
1243 8594 : if (buffer || nbytes)
1244 0 : rc = GPG_ERR_INV_ARG;
1245 : else
1246 8594 : rc = check_digest_algo (algo);
1247 8594 : break;
1248 :
1249 : case GCRYCTL_GET_ASNOID:
1250 : /* We need to check that the algo is available because
1251 : md_asn_oid would otherwise raise an assertion. */
1252 906 : rc = check_digest_algo (algo);
1253 906 : if (!rc)
1254 : {
1255 : const char unsigned *asn;
1256 : size_t asnlen;
1257 :
1258 906 : asn = md_asn_oid (algo, &asnlen, NULL);
1259 906 : if (buffer && (*nbytes >= asnlen))
1260 : {
1261 906 : memcpy (buffer, asn, asnlen);
1262 906 : *nbytes = asnlen;
1263 : }
1264 0 : else if (!buffer && nbytes)
1265 0 : *nbytes = asnlen;
1266 : else
1267 : {
1268 0 : if (buffer)
1269 0 : rc = GPG_ERR_TOO_SHORT;
1270 : else
1271 0 : rc = GPG_ERR_INV_ARG;
1272 : }
1273 : }
1274 906 : break;
1275 :
1276 : case GCRYCTL_SELFTEST:
1277 : /* Helper function for the regression tests. */
1278 33 : rc = gpg_err_code (_gcry_md_selftest (algo, nbytes? (int)*nbytes : 0,
1279 : NULL));
1280 33 : break;
1281 :
1282 : default:
1283 0 : rc = GPG_ERR_INV_OP;
1284 0 : break;
1285 : }
1286 :
1287 9533 : return rc;
1288 : }
1289 :
1290 :
1291 : static void
1292 0 : md_start_debug ( gcry_md_hd_t md, const char *suffix )
1293 : {
1294 : static int idx=0;
1295 : char buf[50];
1296 :
1297 0 : if (fips_mode ())
1298 0 : return;
1299 :
1300 0 : if ( md->ctx->debug )
1301 : {
1302 0 : log_debug("Oops: md debug already started\n");
1303 0 : return;
1304 : }
1305 0 : idx++;
1306 0 : snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
1307 0 : md->ctx->debug = fopen(buf, "w");
1308 0 : if ( !md->ctx->debug )
1309 0 : log_debug("md debug: can't open %s\n", buf );
1310 : }
1311 :
1312 :
1313 : static void
1314 0 : md_stop_debug( gcry_md_hd_t md )
1315 : {
1316 0 : if ( md->ctx->debug )
1317 : {
1318 0 : if ( md->bufpos )
1319 0 : md_write ( md, NULL, 0 );
1320 0 : fclose (md->ctx->debug);
1321 0 : md->ctx->debug = NULL;
1322 : }
1323 :
1324 : { /* a kludge to pull in the __muldi3 for Solaris */
1325 0 : volatile u32 a = (u32)(uintptr_t)md;
1326 0 : volatile u64 b = 42;
1327 : volatile u64 c;
1328 0 : c = a * b;
1329 0 : (void)c;
1330 : }
1331 0 : }
1332 :
1333 :
1334 :
1335 : /*
1336 : * Return information about the digest handle.
1337 : * GCRYCTL_IS_SECURE:
1338 : * Returns 1 when the handle works on secured memory
1339 : * otherwise 0 is returned. There is no error return.
1340 : * GCRYCTL_IS_ALGO_ENABLED:
1341 : * Returns 1 if the algo is enabled for that handle.
1342 : * The algo must be passed as the address of an int.
1343 : */
1344 : gcry_err_code_t
1345 0 : _gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
1346 : {
1347 0 : gcry_err_code_t rc = 0;
1348 :
1349 0 : switch (cmd)
1350 : {
1351 : case GCRYCTL_IS_SECURE:
1352 0 : *nbytes = h->ctx->flags.secure;
1353 0 : break;
1354 :
1355 : case GCRYCTL_IS_ALGO_ENABLED:
1356 : {
1357 : GcryDigestEntry *r;
1358 : int algo;
1359 :
1360 0 : if ( !buffer || !nbytes || *nbytes != sizeof (int))
1361 0 : rc = GPG_ERR_INV_ARG;
1362 : else
1363 : {
1364 0 : algo = *(int*)buffer;
1365 :
1366 0 : *nbytes = 0;
1367 0 : for(r=h->ctx->list; r; r = r->next ) {
1368 0 : if (r->spec->algo == algo)
1369 : {
1370 0 : *nbytes = 1;
1371 0 : break;
1372 : }
1373 : }
1374 : }
1375 0 : break;
1376 : }
1377 :
1378 : default:
1379 0 : rc = GPG_ERR_INV_OP;
1380 : }
1381 :
1382 0 : return rc;
1383 : }
1384 :
1385 :
1386 : /* Explicitly initialize this module. */
1387 : gcry_err_code_t
1388 34 : _gcry_md_init (void)
1389 : {
1390 34 : if (fips_mode())
1391 : {
1392 : /* disable algorithms that are disallowed in fips */
1393 : int idx;
1394 : gcry_md_spec_t *spec;
1395 :
1396 0 : for (idx = 0; (spec = digest_list[idx]); idx++)
1397 0 : if (!spec->flags.fips)
1398 0 : spec->flags.disabled = 1;
1399 : }
1400 :
1401 34 : return 0;
1402 : }
1403 :
1404 :
1405 : int
1406 0 : _gcry_md_is_secure (gcry_md_hd_t a)
1407 : {
1408 : size_t value;
1409 :
1410 0 : if (_gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
1411 0 : value = 1; /* It seems to be better to assume secure memory on
1412 : error. */
1413 0 : return value;
1414 : }
1415 :
1416 :
1417 : int
1418 0 : _gcry_md_is_enabled (gcry_md_hd_t a, int algo)
1419 : {
1420 : size_t value;
1421 :
1422 0 : value = sizeof algo;
1423 0 : if (_gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
1424 0 : value = 0;
1425 0 : return value;
1426 : }
1427 :
1428 :
1429 : /* Run the selftests for digest algorithm ALGO with optional reporting
1430 : function REPORT. */
1431 : gpg_error_t
1432 43 : _gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
1433 : {
1434 43 : gcry_err_code_t ec = 0;
1435 : gcry_md_spec_t *spec;
1436 :
1437 43 : spec = spec_from_algo (algo);
1438 43 : if (spec && !spec->flags.disabled && spec->selftest)
1439 29 : ec = spec->selftest (algo, extended, report);
1440 : else
1441 : {
1442 28 : ec = (spec && spec->selftest) ? GPG_ERR_DIGEST_ALGO
1443 14 : /* */ : GPG_ERR_NOT_IMPLEMENTED;
1444 14 : if (report)
1445 0 : report ("digest", algo, "module",
1446 0 : (spec && !spec->flags.disabled)?
1447 : "no selftest available" :
1448 0 : spec? "algorithm disabled" : "algorithm not found");
1449 : }
1450 :
1451 43 : return gpg_error (ec);
1452 : }
|