1 | /* gc-gnulib.c --- Common gnulib internal crypto interface functions |
2 | * Copyright (C) 2002-2012 Free Software Foundation, Inc. |
3 | * |
4 | * This file is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU Lesser General Public License as published |
6 | * by the Free Software Foundation; either version 2.1, or (at your |
7 | * option) any later version. |
8 | * |
9 | * This file is distributed in the hope that it will be useful, but |
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public License |
15 | * along with this file; if not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | */ |
18 | |
19 | /* Note: This file is only built if GC uses internal functions. */ |
20 | |
21 | #include <config.h> |
22 | |
23 | /* Get prototype. */ |
24 | #include "gc.h" |
25 | |
26 | #include <stdlib.h> |
27 | #include <string.h> |
28 | |
29 | /* For randomize. */ |
30 | #ifdef GNULIB_GC_RANDOM |
31 | # include <unistd.h> |
32 | # include <sys/types.h> |
33 | # include <sys/stat.h> |
34 | # include <fcntl.h> |
35 | # include <errno.h> |
36 | #endif |
37 | |
38 | /* Hashes. */ |
39 | #ifdef GNULIB_GC_MD2 |
40 | # include "md2.h" |
41 | #endif |
42 | #ifdef GNULIB_GC_MD4 |
43 | # include "md4.h" |
44 | #endif |
45 | #ifdef GNULIB_GC_MD5 |
46 | # include "md5.h" |
47 | #endif |
48 | #ifdef GNULIB_GC_SHA1 |
49 | # include "sha1.h" |
50 | #endif |
51 | #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1) |
52 | # include "hmac.h" |
53 | #endif |
54 | |
55 | /* Ciphers. */ |
56 | #ifdef GNULIB_GC_ARCFOUR |
57 | # include "arcfour.h" |
58 | #endif |
59 | #ifdef GNULIB_GC_ARCTWO |
60 | # include "arctwo.h" |
61 | #endif |
62 | #ifdef GNULIB_GC_DES |
63 | # include "des.h" |
64 | #endif |
65 | #ifdef GNULIB_GC_RIJNDAEL |
66 | # include "rijndael-api-fst.h" |
67 | #endif |
68 | |
69 | /* The results of open() in this file are not used with fchdir, |
70 | therefore save some unnecessary work in fchdir.c. */ |
71 | #undef open |
72 | #undef close |
73 | |
74 | #ifdef GNULIB_GC_RANDOM |
75 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
76 | # include <windows.h> |
77 | # include <wincrypt.h> |
78 | HCRYPTPROV g_hProv = 0; |
79 | # ifndef PROV_INTEL_SEC |
80 | # define PROV_INTEL_SEC 22 |
81 | # endif |
82 | # ifndef CRYPT_VERIFY_CONTEXT |
83 | # define CRYPT_VERIFY_CONTEXT 0xF0000000 |
84 | # endif |
85 | # endif |
86 | #endif |
87 | |
88 | Gc_rc |
89 | gc_init (void) |
90 | { |
91 | #ifdef GNULIB_GC_RANDOM |
92 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
93 | if (g_hProv) |
94 | CryptReleaseContext (g_hProv, 0); |
95 | |
96 | /* There is no need to create a container for just random data, so |
97 | we can use CRYPT_VERIFY_CONTEXT (one call) see: |
98 | http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */ |
99 | |
100 | /* We first try to use the Intel PIII RNG if drivers are present */ |
101 | if (!CryptAcquireContext (&g_hProv, NULL, NULL, |
102 | PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT)) |
103 | { |
104 | /* not a PIII or no drivers available, use default RSA CSP */ |
105 | if (!CryptAcquireContext (&g_hProv, NULL, NULL, |
106 | PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT)) |
107 | return GC_RANDOM_ERROR; |
108 | } |
109 | # endif |
110 | #endif |
111 | |
112 | return GC_OK; |
113 | } |
114 | |
115 | void |
116 | gc_done (void) |
117 | { |
118 | #ifdef GNULIB_GC_RANDOM |
119 | # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
120 | if (g_hProv) |
121 | { |
122 | CryptReleaseContext (g_hProv, 0); |
123 | g_hProv = 0; |
124 | } |
125 | # endif |
126 | #endif |
127 | |
128 | return; |
129 | } |
130 | |
131 | #ifdef GNULIB_GC_RANDOM |
132 | |
133 | /* Randomness. */ |
134 | |
135 | static Gc_rc |
136 | randomize (int level, char *data, size_t datalen) |
137 | { |
138 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
139 | if (!g_hProv) |
140 | return GC_RANDOM_ERROR; |
141 | CryptGenRandom (g_hProv, (DWORD) datalen, data); |
142 | #else |
143 | int fd; |
144 | const char *device; |
145 | size_t len = 0; |
146 | int rc; |
147 | |
148 | switch (level) |
149 | { |
150 | case 0: |
151 | device = NAME_OF_NONCE_DEVICE; |
152 | break; |
153 | |
154 | case 1: |
155 | device = NAME_OF_PSEUDO_RANDOM_DEVICE; |
156 | break; |
157 | |
158 | default: |
159 | device = NAME_OF_RANDOM_DEVICE; |
160 | break; |
161 | } |
162 | |
163 | if (strcmp (device, "no" ) == 0) |
164 | return GC_RANDOM_ERROR; |
165 | |
166 | fd = open (device, O_RDONLY); |
167 | if (fd < 0) |
168 | return GC_RANDOM_ERROR; |
169 | |
170 | do |
171 | { |
172 | ssize_t tmp; |
173 | |
174 | tmp = read (fd, data, datalen); |
175 | |
176 | if (tmp < 0) |
177 | { |
178 | int save_errno = errno; |
179 | close (fd); |
180 | errno = save_errno; |
181 | return GC_RANDOM_ERROR; |
182 | } |
183 | |
184 | len += tmp; |
185 | } |
186 | while (len < datalen); |
187 | |
188 | rc = close (fd); |
189 | if (rc < 0) |
190 | return GC_RANDOM_ERROR; |
191 | #endif |
192 | |
193 | return GC_OK; |
194 | } |
195 | |
196 | Gc_rc |
197 | gc_nonce (char *data, size_t datalen) |
198 | { |
199 | return randomize (0, data, datalen); |
200 | } |
201 | |
202 | Gc_rc |
203 | gc_pseudo_random (char *data, size_t datalen) |
204 | { |
205 | return randomize (1, data, datalen); |
206 | } |
207 | |
208 | Gc_rc |
209 | gc_random (char *data, size_t datalen) |
210 | { |
211 | return randomize (2, data, datalen); |
212 | } |
213 | |
214 | #endif |
215 | |
216 | /* Memory allocation. */ |
217 | |
218 | void |
219 | gc_set_allocators (gc_malloc_t func_malloc, |
220 | gc_malloc_t secure_malloc, |
221 | gc_secure_check_t secure_check, |
222 | gc_realloc_t func_realloc, gc_free_t func_free) |
223 | { |
224 | return; |
225 | } |
226 | |
227 | /* Ciphers. */ |
228 | |
229 | typedef struct _gc_cipher_ctx |
230 | { |
231 | Gc_cipher alg; |
232 | Gc_cipher_mode mode; |
233 | #ifdef GNULIB_GC_ARCTWO |
234 | arctwo_context arctwoContext; |
235 | char arctwoIV[ARCTWO_BLOCK_SIZE]; |
236 | #endif |
237 | #ifdef GNULIB_GC_ARCFOUR |
238 | arcfour_context arcfourContext; |
239 | #endif |
240 | #ifdef GNULIB_GC_DES |
241 | gl_des_ctx desContext; |
242 | #endif |
243 | #ifdef GNULIB_GC_RIJNDAEL |
244 | rijndaelKeyInstance aesEncKey; |
245 | rijndaelKeyInstance aesDecKey; |
246 | rijndaelCipherInstance aesContext; |
247 | #endif |
248 | } _gc_cipher_ctx; |
249 | |
250 | Gc_rc |
251 | gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, |
252 | gc_cipher_handle * outhandle) |
253 | { |
254 | _gc_cipher_ctx *ctx; |
255 | Gc_rc rc = GC_OK; |
256 | |
257 | ctx = calloc (sizeof (*ctx), 1); |
258 | if (!ctx) |
259 | return GC_MALLOC_ERROR; |
260 | |
261 | ctx->alg = alg; |
262 | ctx->mode = mode; |
263 | |
264 | switch (alg) |
265 | { |
266 | #ifdef GNULIB_GC_ARCTWO |
267 | case GC_ARCTWO40: |
268 | switch (mode) |
269 | { |
270 | case GC_ECB: |
271 | case GC_CBC: |
272 | break; |
273 | |
274 | default: |
275 | rc = GC_INVALID_CIPHER; |
276 | } |
277 | break; |
278 | #endif |
279 | |
280 | #ifdef GNULIB_GC_ARCFOUR |
281 | case GC_ARCFOUR128: |
282 | case GC_ARCFOUR40: |
283 | switch (mode) |
284 | { |
285 | case GC_STREAM: |
286 | break; |
287 | |
288 | default: |
289 | rc = GC_INVALID_CIPHER; |
290 | } |
291 | break; |
292 | #endif |
293 | |
294 | #ifdef GNULIB_GC_DES |
295 | case GC_DES: |
296 | switch (mode) |
297 | { |
298 | case GC_ECB: |
299 | break; |
300 | |
301 | default: |
302 | rc = GC_INVALID_CIPHER; |
303 | } |
304 | break; |
305 | #endif |
306 | |
307 | #ifdef GNULIB_GC_RIJNDAEL |
308 | case GC_AES128: |
309 | case GC_AES192: |
310 | case GC_AES256: |
311 | switch (mode) |
312 | { |
313 | case GC_ECB: |
314 | case GC_CBC: |
315 | break; |
316 | |
317 | default: |
318 | rc = GC_INVALID_CIPHER; |
319 | } |
320 | break; |
321 | #endif |
322 | |
323 | default: |
324 | rc = GC_INVALID_CIPHER; |
325 | } |
326 | |
327 | if (rc == GC_OK) |
328 | *outhandle = ctx; |
329 | else |
330 | free (ctx); |
331 | |
332 | return rc; |
333 | } |
334 | |
335 | Gc_rc |
336 | gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) |
337 | { |
338 | _gc_cipher_ctx *ctx = handle; |
339 | |
340 | switch (ctx->alg) |
341 | { |
342 | #ifdef GNULIB_GC_ARCTWO |
343 | case GC_ARCTWO40: |
344 | arctwo_setkey (&ctx->arctwoContext, keylen, key); |
345 | break; |
346 | #endif |
347 | |
348 | #ifdef GNULIB_GC_ARCFOUR |
349 | case GC_ARCFOUR128: |
350 | case GC_ARCFOUR40: |
351 | arcfour_setkey (&ctx->arcfourContext, key, keylen); |
352 | break; |
353 | #endif |
354 | |
355 | #ifdef GNULIB_GC_DES |
356 | case GC_DES: |
357 | if (keylen != 8) |
358 | return GC_INVALID_CIPHER; |
359 | gl_des_setkey (&ctx->desContext, key); |
360 | break; |
361 | #endif |
362 | |
363 | #ifdef GNULIB_GC_RIJNDAEL |
364 | case GC_AES128: |
365 | case GC_AES192: |
366 | case GC_AES256: |
367 | { |
368 | rijndael_rc rc; |
369 | size_t i; |
370 | char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; |
371 | |
372 | for (i = 0; i < keylen; i++) |
373 | sprintf (&keyMaterial[2 * i], "%02x" , key[i] & 0xFF); |
374 | |
375 | rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT, |
376 | keylen * 8, keyMaterial); |
377 | if (rc < 0) |
378 | return GC_INVALID_CIPHER; |
379 | |
380 | rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT, |
381 | keylen * 8, keyMaterial); |
382 | if (rc < 0) |
383 | return GC_INVALID_CIPHER; |
384 | |
385 | rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL); |
386 | if (rc < 0) |
387 | return GC_INVALID_CIPHER; |
388 | } |
389 | break; |
390 | #endif |
391 | |
392 | default: |
393 | return GC_INVALID_CIPHER; |
394 | } |
395 | |
396 | return GC_OK; |
397 | } |
398 | |
399 | Gc_rc |
400 | gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) |
401 | { |
402 | _gc_cipher_ctx *ctx = handle; |
403 | |
404 | switch (ctx->alg) |
405 | { |
406 | #ifdef GNULIB_GC_ARCTWO |
407 | case GC_ARCTWO40: |
408 | if (ivlen != ARCTWO_BLOCK_SIZE) |
409 | return GC_INVALID_CIPHER; |
410 | memcpy (ctx->arctwoIV, iv, ivlen); |
411 | break; |
412 | #endif |
413 | |
414 | #ifdef GNULIB_GC_RIJNDAEL |
415 | case GC_AES128: |
416 | case GC_AES192: |
417 | case GC_AES256: |
418 | switch (ctx->mode) |
419 | { |
420 | case GC_ECB: |
421 | /* Doesn't use IV. */ |
422 | break; |
423 | |
424 | case GC_CBC: |
425 | { |
426 | rijndael_rc rc; |
427 | size_t i; |
428 | char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1]; |
429 | |
430 | for (i = 0; i < ivlen; i++) |
431 | sprintf (&ivMaterial[2 * i], "%02x" , iv[i] & 0xFF); |
432 | |
433 | rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC, |
434 | ivMaterial); |
435 | if (rc < 0) |
436 | return GC_INVALID_CIPHER; |
437 | } |
438 | break; |
439 | |
440 | default: |
441 | return GC_INVALID_CIPHER; |
442 | } |
443 | break; |
444 | #endif |
445 | |
446 | default: |
447 | return GC_INVALID_CIPHER; |
448 | } |
449 | |
450 | return GC_OK; |
451 | } |
452 | |
453 | Gc_rc |
454 | gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) |
455 | { |
456 | _gc_cipher_ctx *ctx = handle; |
457 | |
458 | switch (ctx->alg) |
459 | { |
460 | #ifdef GNULIB_GC_ARCTWO |
461 | case GC_ARCTWO40: |
462 | switch (ctx->mode) |
463 | { |
464 | case GC_ECB: |
465 | arctwo_encrypt (&ctx->arctwoContext, data, data, len); |
466 | break; |
467 | |
468 | case GC_CBC: |
469 | for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, |
470 | data += ARCTWO_BLOCK_SIZE) |
471 | { |
472 | size_t i; |
473 | for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) |
474 | data[i] ^= ctx->arctwoIV[i]; |
475 | arctwo_encrypt (&ctx->arctwoContext, data, data, |
476 | ARCTWO_BLOCK_SIZE); |
477 | memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE); |
478 | } |
479 | break; |
480 | |
481 | default: |
482 | return GC_INVALID_CIPHER; |
483 | } |
484 | break; |
485 | #endif |
486 | |
487 | #ifdef GNULIB_GC_ARCFOUR |
488 | case GC_ARCFOUR128: |
489 | case GC_ARCFOUR40: |
490 | arcfour_stream (&ctx->arcfourContext, data, data, len); |
491 | break; |
492 | #endif |
493 | |
494 | #ifdef GNULIB_GC_DES |
495 | case GC_DES: |
496 | for (; len >= 8; len -= 8, data += 8) |
497 | gl_des_ecb_encrypt (&ctx->desContext, data, data); |
498 | break; |
499 | #endif |
500 | |
501 | #ifdef GNULIB_GC_RIJNDAEL |
502 | case GC_AES128: |
503 | case GC_AES192: |
504 | case GC_AES256: |
505 | { |
506 | int nblocks; |
507 | |
508 | nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey, |
509 | data, 8 * len, data); |
510 | if (nblocks < 0) |
511 | return GC_INVALID_CIPHER; |
512 | } |
513 | break; |
514 | #endif |
515 | |
516 | default: |
517 | return GC_INVALID_CIPHER; |
518 | } |
519 | |
520 | return GC_OK; |
521 | } |
522 | |
523 | Gc_rc |
524 | gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) |
525 | { |
526 | _gc_cipher_ctx *ctx = handle; |
527 | |
528 | switch (ctx->alg) |
529 | { |
530 | #ifdef GNULIB_GC_ARCTWO |
531 | case GC_ARCTWO40: |
532 | switch (ctx->mode) |
533 | { |
534 | case GC_ECB: |
535 | arctwo_decrypt (&ctx->arctwoContext, data, data, len); |
536 | break; |
537 | |
538 | case GC_CBC: |
539 | for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, |
540 | data += ARCTWO_BLOCK_SIZE) |
541 | { |
542 | char tmpIV[ARCTWO_BLOCK_SIZE]; |
543 | size_t i; |
544 | memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE); |
545 | arctwo_decrypt (&ctx->arctwoContext, data, data, |
546 | ARCTWO_BLOCK_SIZE); |
547 | for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) |
548 | data[i] ^= ctx->arctwoIV[i]; |
549 | memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE); |
550 | } |
551 | break; |
552 | |
553 | default: |
554 | return GC_INVALID_CIPHER; |
555 | } |
556 | break; |
557 | #endif |
558 | |
559 | #ifdef GNULIB_GC_ARCFOUR |
560 | case GC_ARCFOUR128: |
561 | case GC_ARCFOUR40: |
562 | arcfour_stream (&ctx->arcfourContext, data, data, len); |
563 | break; |
564 | #endif |
565 | |
566 | #ifdef GNULIB_GC_DES |
567 | case GC_DES: |
568 | for (; len >= 8; len -= 8, data += 8) |
569 | gl_des_ecb_decrypt (&ctx->desContext, data, data); |
570 | break; |
571 | #endif |
572 | |
573 | #ifdef GNULIB_GC_RIJNDAEL |
574 | case GC_AES128: |
575 | case GC_AES192: |
576 | case GC_AES256: |
577 | { |
578 | int nblocks; |
579 | |
580 | nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey, |
581 | data, 8 * len, data); |
582 | if (nblocks < 0) |
583 | return GC_INVALID_CIPHER; |
584 | } |
585 | break; |
586 | #endif |
587 | |
588 | default: |
589 | return GC_INVALID_CIPHER; |
590 | } |
591 | |
592 | return GC_OK; |
593 | } |
594 | |
595 | Gc_rc |
596 | gc_cipher_close (gc_cipher_handle handle) |
597 | { |
598 | _gc_cipher_ctx *ctx = handle; |
599 | |
600 | free (ctx); |
601 | |
602 | return GC_OK; |
603 | } |
604 | |
605 | /* Hashes. */ |
606 | |
607 | #define MAX_DIGEST_SIZE 20 |
608 | |
609 | typedef struct _gc_hash_ctx |
610 | { |
611 | Gc_hash alg; |
612 | Gc_hash_mode mode; |
613 | char hash[MAX_DIGEST_SIZE]; |
614 | #ifdef GNULIB_GC_MD2 |
615 | struct md2_ctx md2Context; |
616 | #endif |
617 | #ifdef GNULIB_GC_MD4 |
618 | struct md4_ctx md4Context; |
619 | #endif |
620 | #ifdef GNULIB_GC_MD5 |
621 | struct md5_ctx md5Context; |
622 | #endif |
623 | #ifdef GNULIB_GC_SHA1 |
624 | struct sha1_ctx sha1Context; |
625 | #endif |
626 | } _gc_hash_ctx; |
627 | |
628 | Gc_rc |
629 | gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) |
630 | { |
631 | _gc_hash_ctx *ctx; |
632 | Gc_rc rc = GC_OK; |
633 | |
634 | ctx = calloc (sizeof (*ctx), 1); |
635 | if (!ctx) |
636 | return GC_MALLOC_ERROR; |
637 | |
638 | ctx->alg = hash; |
639 | ctx->mode = mode; |
640 | |
641 | switch (hash) |
642 | { |
643 | #ifdef GNULIB_GC_MD2 |
644 | case GC_MD2: |
645 | md2_init_ctx (&ctx->md2Context); |
646 | break; |
647 | #endif |
648 | |
649 | #ifdef GNULIB_GC_MD4 |
650 | case GC_MD4: |
651 | md4_init_ctx (&ctx->md4Context); |
652 | break; |
653 | #endif |
654 | |
655 | #ifdef GNULIB_GC_MD5 |
656 | case GC_MD5: |
657 | md5_init_ctx (&ctx->md5Context); |
658 | break; |
659 | #endif |
660 | |
661 | #ifdef GNULIB_GC_SHA1 |
662 | case GC_SHA1: |
663 | sha1_init_ctx (&ctx->sha1Context); |
664 | break; |
665 | #endif |
666 | |
667 | default: |
668 | rc = GC_INVALID_HASH; |
669 | break; |
670 | } |
671 | |
672 | switch (mode) |
673 | { |
674 | case 0: |
675 | break; |
676 | |
677 | default: |
678 | rc = GC_INVALID_HASH; |
679 | break; |
680 | } |
681 | |
682 | if (rc == GC_OK) |
683 | *outhandle = ctx; |
684 | else |
685 | free (ctx); |
686 | |
687 | return rc; |
688 | } |
689 | |
690 | Gc_rc |
691 | gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle) |
692 | { |
693 | _gc_hash_ctx *in = handle; |
694 | _gc_hash_ctx *out; |
695 | |
696 | *outhandle = out = calloc (sizeof (*out), 1); |
697 | if (!out) |
698 | return GC_MALLOC_ERROR; |
699 | |
700 | memcpy (out, in, sizeof (*out)); |
701 | |
702 | return GC_OK; |
703 | } |
704 | |
705 | size_t |
706 | gc_hash_digest_length (Gc_hash hash) |
707 | { |
708 | size_t len; |
709 | |
710 | switch (hash) |
711 | { |
712 | case GC_MD2: |
713 | len = GC_MD2_DIGEST_SIZE; |
714 | break; |
715 | |
716 | case GC_MD4: |
717 | len = GC_MD4_DIGEST_SIZE; |
718 | break; |
719 | |
720 | case GC_MD5: |
721 | len = GC_MD5_DIGEST_SIZE; |
722 | break; |
723 | |
724 | case GC_RMD160: |
725 | len = GC_RMD160_DIGEST_SIZE; |
726 | break; |
727 | |
728 | case GC_SHA1: |
729 | len = GC_SHA1_DIGEST_SIZE; |
730 | break; |
731 | |
732 | default: |
733 | return 0; |
734 | } |
735 | |
736 | return len; |
737 | } |
738 | |
739 | void |
740 | gc_hash_write (gc_hash_handle handle, size_t len, const char *data) |
741 | { |
742 | _gc_hash_ctx *ctx = handle; |
743 | |
744 | switch (ctx->alg) |
745 | { |
746 | #ifdef GNULIB_GC_MD2 |
747 | case GC_MD2: |
748 | md2_process_bytes (data, len, &ctx->md2Context); |
749 | break; |
750 | #endif |
751 | |
752 | #ifdef GNULIB_GC_MD4 |
753 | case GC_MD4: |
754 | md4_process_bytes (data, len, &ctx->md4Context); |
755 | break; |
756 | #endif |
757 | |
758 | #ifdef GNULIB_GC_MD5 |
759 | case GC_MD5: |
760 | md5_process_bytes (data, len, &ctx->md5Context); |
761 | break; |
762 | #endif |
763 | |
764 | #ifdef GNULIB_GC_SHA1 |
765 | case GC_SHA1: |
766 | sha1_process_bytes (data, len, &ctx->sha1Context); |
767 | break; |
768 | #endif |
769 | |
770 | default: |
771 | break; |
772 | } |
773 | } |
774 | |
775 | const char * |
776 | gc_hash_read (gc_hash_handle handle) |
777 | { |
778 | _gc_hash_ctx *ctx = handle; |
779 | const char *ret = NULL; |
780 | |
781 | switch (ctx->alg) |
782 | { |
783 | #ifdef GNULIB_GC_MD2 |
784 | case GC_MD2: |
785 | md2_finish_ctx (&ctx->md2Context, ctx->hash); |
786 | ret = ctx->hash; |
787 | break; |
788 | #endif |
789 | |
790 | #ifdef GNULIB_GC_MD4 |
791 | case GC_MD4: |
792 | md4_finish_ctx (&ctx->md4Context, ctx->hash); |
793 | ret = ctx->hash; |
794 | break; |
795 | #endif |
796 | |
797 | #ifdef GNULIB_GC_MD5 |
798 | case GC_MD5: |
799 | md5_finish_ctx (&ctx->md5Context, ctx->hash); |
800 | ret = ctx->hash; |
801 | break; |
802 | #endif |
803 | |
804 | #ifdef GNULIB_GC_SHA1 |
805 | case GC_SHA1: |
806 | sha1_finish_ctx (&ctx->sha1Context, ctx->hash); |
807 | ret = ctx->hash; |
808 | break; |
809 | #endif |
810 | |
811 | default: |
812 | return NULL; |
813 | } |
814 | |
815 | return ret; |
816 | } |
817 | |
818 | void |
819 | gc_hash_close (gc_hash_handle handle) |
820 | { |
821 | _gc_hash_ctx *ctx = handle; |
822 | |
823 | free (ctx); |
824 | } |
825 | |
826 | Gc_rc |
827 | gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) |
828 | { |
829 | switch (hash) |
830 | { |
831 | #ifdef GNULIB_GC_MD2 |
832 | case GC_MD2: |
833 | md2_buffer (in, inlen, resbuf); |
834 | break; |
835 | #endif |
836 | |
837 | #ifdef GNULIB_GC_MD4 |
838 | case GC_MD4: |
839 | md4_buffer (in, inlen, resbuf); |
840 | break; |
841 | #endif |
842 | |
843 | #ifdef GNULIB_GC_MD5 |
844 | case GC_MD5: |
845 | md5_buffer (in, inlen, resbuf); |
846 | break; |
847 | #endif |
848 | |
849 | #ifdef GNULIB_GC_SHA1 |
850 | case GC_SHA1: |
851 | sha1_buffer (in, inlen, resbuf); |
852 | break; |
853 | #endif |
854 | |
855 | default: |
856 | return GC_INVALID_HASH; |
857 | } |
858 | |
859 | return GC_OK; |
860 | } |
861 | |
862 | #ifdef GNULIB_GC_MD2 |
863 | Gc_rc |
864 | gc_md2 (const void *in, size_t inlen, void *resbuf) |
865 | { |
866 | md2_buffer (in, inlen, resbuf); |
867 | return GC_OK; |
868 | } |
869 | #endif |
870 | |
871 | #ifdef GNULIB_GC_MD4 |
872 | Gc_rc |
873 | gc_md4 (const void *in, size_t inlen, void *resbuf) |
874 | { |
875 | md4_buffer (in, inlen, resbuf); |
876 | return GC_OK; |
877 | } |
878 | #endif |
879 | |
880 | #ifdef GNULIB_GC_MD5 |
881 | Gc_rc |
882 | gc_md5 (const void *in, size_t inlen, void *resbuf) |
883 | { |
884 | md5_buffer (in, inlen, resbuf); |
885 | return GC_OK; |
886 | } |
887 | #endif |
888 | |
889 | #ifdef GNULIB_GC_SHA1 |
890 | Gc_rc |
891 | gc_sha1 (const void *in, size_t inlen, void *resbuf) |
892 | { |
893 | sha1_buffer (in, inlen, resbuf); |
894 | return GC_OK; |
895 | } |
896 | #endif |
897 | |
898 | #ifdef GNULIB_GC_HMAC_MD5 |
899 | Gc_rc |
900 | gc_hmac_md5 (const void *key, size_t keylen, |
901 | const void *in, size_t inlen, char *resbuf) |
902 | { |
903 | hmac_md5 (key, keylen, in, inlen, resbuf); |
904 | return GC_OK; |
905 | } |
906 | #endif |
907 | |
908 | #ifdef GNULIB_GC_HMAC_SHA1 |
909 | Gc_rc |
910 | gc_hmac_sha1 (const void *key, size_t keylen, |
911 | const void *in, size_t inlen, char *resbuf) |
912 | { |
913 | hmac_sha1 (key, keylen, in, inlen, resbuf); |
914 | return GC_OK; |
915 | } |
916 | #endif |
917 | |