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