1 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Simon Josefsson
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2, or (at your
7 * option) any later version.
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 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 /* Note: This file is only built if GC uses internal functions. */
32 #ifdef GNULIB_GC_RANDOM
34 # include <sys/types.h>
35 # include <sys/stat.h>
53 #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1)
58 #ifdef GNULIB_GC_ARCFOUR
61 #ifdef GNULIB_GC_ARCTWO
67 #ifdef GNULIB_GC_RIJNDAEL
68 # include "rijndael-api-fst.h"
71 /* The results of open() in this file are not used with fchdir,
72 therefore save some unnecessary work in fchdir.c. */
76 #ifdef GNULIB_GC_RANDOM
77 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
79 # include <wincrypt.h>
80 HCRYPTPROV g_hProv = 0;
87 #ifdef GNULIB_GC_RANDOM
88 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
90 CryptReleaseContext(g_hProv, 0);
91 CryptAcquireContext(&g_hProv, NULL, NULL, PROV_RSA_FULL, 0);
101 #ifdef GNULIB_GC_RANDOM
102 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
105 CryptReleaseContext(g_hProv, 0);
114 #ifdef GNULIB_GC_RANDOM
119 randomize (int level, char *data, size_t datalen)
121 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
123 return GC_RANDOM_ERROR;
124 CryptGenRandom(g_hProv, (DWORD)datalen, data);
134 device = NAME_OF_NONCE_DEVICE;
138 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
142 device = NAME_OF_RANDOM_DEVICE;
146 if (strcmp (device, "no") == 0)
147 return GC_RANDOM_ERROR;
149 fd = open (device, O_RDONLY);
151 return GC_RANDOM_ERROR;
157 tmp = read (fd, data, datalen);
161 int save_errno = errno;
164 return GC_RANDOM_ERROR;
169 while (len < datalen);
173 return GC_RANDOM_ERROR;
180 gc_nonce (char *data, size_t datalen)
182 return randomize (0, data, datalen);
186 gc_pseudo_random (char *data, size_t datalen)
188 return randomize (1, data, datalen);
192 gc_random (char *data, size_t datalen)
194 return randomize (2, data, datalen);
199 /* Memory allocation. */
202 gc_set_allocators (gc_malloc_t func_malloc,
203 gc_malloc_t secure_malloc,
204 gc_secure_check_t secure_check,
205 gc_realloc_t func_realloc, gc_free_t func_free)
211 typedef struct _gc_cipher_ctx {
214 #ifdef GNULIB_GC_ARCTWO
215 arctwo_context arctwoContext;
216 char arctwoIV[ARCTWO_BLOCK_SIZE];
218 #ifdef GNULIB_GC_ARCFOUR
219 arcfour_context arcfourContext;
222 gl_des_ctx desContext;
224 #ifdef GNULIB_GC_RIJNDAEL
225 rijndaelKeyInstance aesEncKey;
226 rijndaelKeyInstance aesDecKey;
227 rijndaelCipherInstance aesContext;
232 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
233 gc_cipher_handle * outhandle)
238 ctx = calloc (sizeof (*ctx), 1);
240 return GC_MALLOC_ERROR;
247 #ifdef GNULIB_GC_ARCTWO
256 rc = GC_INVALID_CIPHER;
261 #ifdef GNULIB_GC_ARCFOUR
270 rc = GC_INVALID_CIPHER;
283 rc = GC_INVALID_CIPHER;
288 #ifdef GNULIB_GC_RIJNDAEL
299 rc = GC_INVALID_CIPHER;
305 rc = GC_INVALID_CIPHER;
317 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
319 _gc_cipher_ctx *ctx = handle;
323 #ifdef GNULIB_GC_ARCTWO
325 arctwo_setkey (&ctx->arctwoContext, keylen, key);
329 #ifdef GNULIB_GC_ARCFOUR
332 arcfour_setkey (&ctx->arcfourContext, key, keylen);
339 return GC_INVALID_CIPHER;
340 gl_des_setkey (&ctx->desContext, key);
344 #ifdef GNULIB_GC_RIJNDAEL
351 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
353 for (i = 0; i < keylen; i++)
354 sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
356 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
357 keylen * 8, keyMaterial);
359 return GC_INVALID_CIPHER;
361 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
362 keylen * 8, keyMaterial);
364 return GC_INVALID_CIPHER;
366 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
368 return GC_INVALID_CIPHER;
374 return GC_INVALID_CIPHER;
381 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
383 _gc_cipher_ctx *ctx = handle;
387 #ifdef GNULIB_GC_ARCTWO
389 if (ivlen != ARCTWO_BLOCK_SIZE)
390 return GC_INVALID_CIPHER;
391 memcpy (ctx->arctwoIV, iv, ivlen);
395 #ifdef GNULIB_GC_RIJNDAEL
402 /* Doesn't use IV. */
409 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
411 for (i = 0; i < ivlen; i++)
412 sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
414 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
417 return GC_INVALID_CIPHER;
422 return GC_INVALID_CIPHER;
428 return GC_INVALID_CIPHER;
435 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
437 _gc_cipher_ctx *ctx = handle;
441 #ifdef GNULIB_GC_ARCTWO
446 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
450 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
451 data += ARCTWO_BLOCK_SIZE)
454 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
455 data[i] ^= ctx->arctwoIV[i];
456 arctwo_encrypt (&ctx->arctwoContext, data, data,
458 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
463 return GC_INVALID_CIPHER;
468 #ifdef GNULIB_GC_ARCFOUR
471 arcfour_stream (&ctx->arcfourContext, data, data, len);
477 for (; len >= 8; len -= 8, data += 8)
478 gl_des_ecb_encrypt (&ctx->desContext, data, data);
482 #ifdef GNULIB_GC_RIJNDAEL
489 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
490 data, 8 * len, data);
492 return GC_INVALID_CIPHER;
498 return GC_INVALID_CIPHER;
505 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
507 _gc_cipher_ctx *ctx = handle;
511 #ifdef GNULIB_GC_ARCTWO
516 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
520 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
521 data += ARCTWO_BLOCK_SIZE)
523 char tmpIV[ARCTWO_BLOCK_SIZE];
525 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
526 arctwo_decrypt (&ctx->arctwoContext, data, data,
528 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
529 data[i] ^= ctx->arctwoIV[i];
530 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
535 return GC_INVALID_CIPHER;
540 #ifdef GNULIB_GC_ARCFOUR
543 arcfour_stream (&ctx->arcfourContext, data, data, len);
549 for (; len >= 8; len -= 8, data += 8)
550 gl_des_ecb_decrypt (&ctx->desContext, data, data);
554 #ifdef GNULIB_GC_RIJNDAEL
561 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
562 data, 8 * len, data);
564 return GC_INVALID_CIPHER;
570 return GC_INVALID_CIPHER;
577 gc_cipher_close (gc_cipher_handle handle)
579 _gc_cipher_ctx *ctx = handle;
588 #define MAX_DIGEST_SIZE 20
590 typedef struct _gc_hash_ctx {
593 char hash[MAX_DIGEST_SIZE];
595 struct md2_ctx md2Context;
598 struct md4_ctx md4Context;
601 struct md5_ctx md5Context;
603 #ifdef GNULIB_GC_SHA1
604 struct sha1_ctx sha1Context;
609 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
614 ctx = calloc (sizeof (*ctx), 1);
616 return GC_MALLOC_ERROR;
625 md2_init_ctx (&ctx->md2Context);
631 md4_init_ctx (&ctx->md4Context);
637 md5_init_ctx (&ctx->md5Context);
641 #ifdef GNULIB_GC_SHA1
643 sha1_init_ctx (&ctx->sha1Context);
648 rc = GC_INVALID_HASH;
658 rc = GC_INVALID_HASH;
671 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
673 _gc_hash_ctx *in = handle;
676 *outhandle = out = calloc (sizeof (*out), 1);
678 return GC_MALLOC_ERROR;
680 memcpy (out, in, sizeof (*out));
686 gc_hash_digest_length (Gc_hash hash)
693 len = GC_MD2_DIGEST_SIZE;
697 len = GC_MD4_DIGEST_SIZE;
701 len = GC_MD5_DIGEST_SIZE;
705 len = GC_RMD160_DIGEST_SIZE;
709 len = GC_SHA1_DIGEST_SIZE;
720 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
722 _gc_hash_ctx *ctx = handle;
728 md2_process_bytes (data, len, &ctx->md2Context);
734 md4_process_bytes (data, len, &ctx->md4Context);
740 md5_process_bytes (data, len, &ctx->md5Context);
744 #ifdef GNULIB_GC_SHA1
746 sha1_process_bytes (data, len, &ctx->sha1Context);
756 gc_hash_read (gc_hash_handle handle)
758 _gc_hash_ctx *ctx = handle;
759 const char *ret = NULL;
765 md2_finish_ctx (&ctx->md2Context, ctx->hash);
772 md4_finish_ctx (&ctx->md4Context, ctx->hash);
779 md5_finish_ctx (&ctx->md5Context, ctx->hash);
784 #ifdef GNULIB_GC_SHA1
786 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
799 gc_hash_close (gc_hash_handle handle)
801 _gc_hash_ctx *ctx = handle;
807 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
813 md2_buffer (in, inlen, resbuf);
819 md4_buffer (in, inlen, resbuf);
825 md5_buffer (in, inlen, resbuf);
829 #ifdef GNULIB_GC_SHA1
831 sha1_buffer (in, inlen, resbuf);
836 return GC_INVALID_HASH;
844 gc_md2 (const void *in, size_t inlen, void *resbuf)
846 md2_buffer (in, inlen, resbuf);
853 gc_md4 (const void *in, size_t inlen, void *resbuf)
855 md4_buffer (in, inlen, resbuf);
862 gc_md5 (const void *in, size_t inlen, void *resbuf)
864 md5_buffer (in, inlen, resbuf);
869 #ifdef GNULIB_GC_SHA1
871 gc_sha1 (const void *in, size_t inlen, void *resbuf)
873 sha1_buffer (in, inlen, resbuf);
878 #ifdef GNULIB_GC_HMAC_MD5
880 gc_hmac_md5 (const void *key, size_t keylen,
881 const void *in, size_t inlen, char *resbuf)
883 hmac_md5 (key, keylen, in, inlen, resbuf);
888 #ifdef GNULIB_GC_HMAC_SHA1
890 gc_hmac_sha1 (const void *key, size_t keylen,
891 const void *in, size_t inlen, char *resbuf)
893 hmac_sha1 (key, keylen, in, inlen, resbuf);