1 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free
3 * Software Foundation, Inc.
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published
7 * by the Free Software Foundation; either version 2, or (at your
8 * option) any later version.
10 * This file is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this file; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 /* Note: This file is only built if GC uses internal functions. */
33 #ifdef GNULIB_GC_RANDOM
35 # include <sys/types.h>
36 # include <sys/stat.h>
54 #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1)
59 #ifdef GNULIB_GC_ARCFOUR
62 #ifdef GNULIB_GC_ARCTWO
68 #ifdef GNULIB_GC_RIJNDAEL
69 # include "rijndael-api-fst.h"
72 /* The results of open() in this file are not used with fchdir,
73 therefore save some unnecessary work in fchdir.c. */
77 #ifdef GNULIB_GC_RANDOM
78 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
80 # include <wincrypt.h>
81 HCRYPTPROV g_hProv = 0;
82 # ifndef PROV_INTEL_SEC
83 # define PROV_INTEL_SEC 22
85 # ifndef CRYPT_VERIFY_CONTEXT
86 # define CRYPT_VERIFY_CONTEXT 0xF0000000
94 #ifdef GNULIB_GC_RANDOM
95 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
97 CryptReleaseContext (g_hProv, 0);
99 /* There is no need to create a container for just random data, so
100 we can use CRYPT_VERIFY_CONTEXT (one call) see:
101 http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */
103 /* We first try to use the Intel PIII RNG if drivers are present */
104 if (!CryptAcquireContext (&g_hProv, NULL, NULL,
105 PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT))
107 /* not a PIII or no drivers available, use default RSA CSP */
108 if (!CryptAcquireContext (&g_hProv, NULL, NULL,
109 PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT))
110 return GC_RANDOM_ERROR;
121 #ifdef GNULIB_GC_RANDOM
122 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
125 CryptReleaseContext (g_hProv, 0);
134 #ifdef GNULIB_GC_RANDOM
139 randomize (int level, char *data, size_t datalen)
141 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
143 return GC_RANDOM_ERROR;
144 CryptGenRandom (g_hProv, (DWORD) datalen, data);
154 device = NAME_OF_NONCE_DEVICE;
158 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
162 device = NAME_OF_RANDOM_DEVICE;
166 if (strcmp (device, "no") == 0)
167 return GC_RANDOM_ERROR;
169 fd = open (device, O_RDONLY);
171 return GC_RANDOM_ERROR;
177 tmp = read (fd, data, datalen);
181 int save_errno = errno;
184 return GC_RANDOM_ERROR;
189 while (len < datalen);
193 return GC_RANDOM_ERROR;
200 gc_nonce (char *data, size_t datalen)
202 return randomize (0, data, datalen);
206 gc_pseudo_random (char *data, size_t datalen)
208 return randomize (1, data, datalen);
212 gc_random (char *data, size_t datalen)
214 return randomize (2, data, datalen);
219 /* Memory allocation. */
222 gc_set_allocators (gc_malloc_t func_malloc,
223 gc_malloc_t secure_malloc,
224 gc_secure_check_t secure_check,
225 gc_realloc_t func_realloc, gc_free_t func_free)
232 typedef struct _gc_cipher_ctx
236 #ifdef GNULIB_GC_ARCTWO
237 arctwo_context arctwoContext;
238 char arctwoIV[ARCTWO_BLOCK_SIZE];
240 #ifdef GNULIB_GC_ARCFOUR
241 arcfour_context arcfourContext;
244 gl_des_ctx desContext;
246 #ifdef GNULIB_GC_RIJNDAEL
247 rijndaelKeyInstance aesEncKey;
248 rijndaelKeyInstance aesDecKey;
249 rijndaelCipherInstance aesContext;
254 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
255 gc_cipher_handle * outhandle)
260 ctx = calloc (sizeof (*ctx), 1);
262 return GC_MALLOC_ERROR;
269 #ifdef GNULIB_GC_ARCTWO
278 rc = GC_INVALID_CIPHER;
283 #ifdef GNULIB_GC_ARCFOUR
292 rc = GC_INVALID_CIPHER;
305 rc = GC_INVALID_CIPHER;
310 #ifdef GNULIB_GC_RIJNDAEL
321 rc = GC_INVALID_CIPHER;
327 rc = GC_INVALID_CIPHER;
339 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
341 _gc_cipher_ctx *ctx = handle;
345 #ifdef GNULIB_GC_ARCTWO
347 arctwo_setkey (&ctx->arctwoContext, keylen, key);
351 #ifdef GNULIB_GC_ARCFOUR
354 arcfour_setkey (&ctx->arcfourContext, key, keylen);
361 return GC_INVALID_CIPHER;
362 gl_des_setkey (&ctx->desContext, key);
366 #ifdef GNULIB_GC_RIJNDAEL
373 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
375 for (i = 0; i < keylen; i++)
376 sprintf (&keyMaterial[2 * i], "%02x", key[i] & 0xFF);
378 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
379 keylen * 8, keyMaterial);
381 return GC_INVALID_CIPHER;
383 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
384 keylen * 8, keyMaterial);
386 return GC_INVALID_CIPHER;
388 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
390 return GC_INVALID_CIPHER;
396 return GC_INVALID_CIPHER;
403 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
405 _gc_cipher_ctx *ctx = handle;
409 #ifdef GNULIB_GC_ARCTWO
411 if (ivlen != ARCTWO_BLOCK_SIZE)
412 return GC_INVALID_CIPHER;
413 memcpy (ctx->arctwoIV, iv, ivlen);
417 #ifdef GNULIB_GC_RIJNDAEL
424 /* Doesn't use IV. */
431 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
433 for (i = 0; i < ivlen; i++)
434 sprintf (&ivMaterial[2 * i], "%02x", iv[i] & 0xFF);
436 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
439 return GC_INVALID_CIPHER;
444 return GC_INVALID_CIPHER;
450 return GC_INVALID_CIPHER;
457 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
459 _gc_cipher_ctx *ctx = handle;
463 #ifdef GNULIB_GC_ARCTWO
468 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
472 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
473 data += ARCTWO_BLOCK_SIZE)
476 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
477 data[i] ^= ctx->arctwoIV[i];
478 arctwo_encrypt (&ctx->arctwoContext, data, data,
480 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
485 return GC_INVALID_CIPHER;
490 #ifdef GNULIB_GC_ARCFOUR
493 arcfour_stream (&ctx->arcfourContext, data, data, len);
499 for (; len >= 8; len -= 8, data += 8)
500 gl_des_ecb_encrypt (&ctx->desContext, data, data);
504 #ifdef GNULIB_GC_RIJNDAEL
511 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
512 data, 8 * len, data);
514 return GC_INVALID_CIPHER;
520 return GC_INVALID_CIPHER;
527 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
529 _gc_cipher_ctx *ctx = handle;
533 #ifdef GNULIB_GC_ARCTWO
538 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
542 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
543 data += ARCTWO_BLOCK_SIZE)
545 char tmpIV[ARCTWO_BLOCK_SIZE];
547 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
548 arctwo_decrypt (&ctx->arctwoContext, data, data,
550 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
551 data[i] ^= ctx->arctwoIV[i];
552 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
557 return GC_INVALID_CIPHER;
562 #ifdef GNULIB_GC_ARCFOUR
565 arcfour_stream (&ctx->arcfourContext, data, data, len);
571 for (; len >= 8; len -= 8, data += 8)
572 gl_des_ecb_decrypt (&ctx->desContext, data, data);
576 #ifdef GNULIB_GC_RIJNDAEL
583 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
584 data, 8 * len, data);
586 return GC_INVALID_CIPHER;
592 return GC_INVALID_CIPHER;
599 gc_cipher_close (gc_cipher_handle handle)
601 _gc_cipher_ctx *ctx = handle;
610 #define MAX_DIGEST_SIZE 20
612 typedef struct _gc_hash_ctx
616 char hash[MAX_DIGEST_SIZE];
618 struct md2_ctx md2Context;
621 struct md4_ctx md4Context;
624 struct md5_ctx md5Context;
626 #ifdef GNULIB_GC_SHA1
627 struct sha1_ctx sha1Context;
632 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
637 ctx = calloc (sizeof (*ctx), 1);
639 return GC_MALLOC_ERROR;
648 md2_init_ctx (&ctx->md2Context);
654 md4_init_ctx (&ctx->md4Context);
660 md5_init_ctx (&ctx->md5Context);
664 #ifdef GNULIB_GC_SHA1
666 sha1_init_ctx (&ctx->sha1Context);
671 rc = GC_INVALID_HASH;
681 rc = GC_INVALID_HASH;
694 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
696 _gc_hash_ctx *in = handle;
699 *outhandle = out = calloc (sizeof (*out), 1);
701 return GC_MALLOC_ERROR;
703 memcpy (out, in, sizeof (*out));
709 gc_hash_digest_length (Gc_hash hash)
716 len = GC_MD2_DIGEST_SIZE;
720 len = GC_MD4_DIGEST_SIZE;
724 len = GC_MD5_DIGEST_SIZE;
728 len = GC_RMD160_DIGEST_SIZE;
732 len = GC_SHA1_DIGEST_SIZE;
743 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
745 _gc_hash_ctx *ctx = handle;
751 md2_process_bytes (data, len, &ctx->md2Context);
757 md4_process_bytes (data, len, &ctx->md4Context);
763 md5_process_bytes (data, len, &ctx->md5Context);
767 #ifdef GNULIB_GC_SHA1
769 sha1_process_bytes (data, len, &ctx->sha1Context);
779 gc_hash_read (gc_hash_handle handle)
781 _gc_hash_ctx *ctx = handle;
782 const char *ret = NULL;
788 md2_finish_ctx (&ctx->md2Context, ctx->hash);
795 md4_finish_ctx (&ctx->md4Context, ctx->hash);
802 md5_finish_ctx (&ctx->md5Context, ctx->hash);
807 #ifdef GNULIB_GC_SHA1
809 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
822 gc_hash_close (gc_hash_handle handle)
824 _gc_hash_ctx *ctx = handle;
830 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
836 md2_buffer (in, inlen, resbuf);
842 md4_buffer (in, inlen, resbuf);
848 md5_buffer (in, inlen, resbuf);
852 #ifdef GNULIB_GC_SHA1
854 sha1_buffer (in, inlen, resbuf);
859 return GC_INVALID_HASH;
867 gc_md2 (const void *in, size_t inlen, void *resbuf)
869 md2_buffer (in, inlen, resbuf);
876 gc_md4 (const void *in, size_t inlen, void *resbuf)
878 md4_buffer (in, inlen, resbuf);
885 gc_md5 (const void *in, size_t inlen, void *resbuf)
887 md5_buffer (in, inlen, resbuf);
892 #ifdef GNULIB_GC_SHA1
894 gc_sha1 (const void *in, size_t inlen, void *resbuf)
896 sha1_buffer (in, inlen, resbuf);
901 #ifdef GNULIB_GC_HMAC_MD5
903 gc_hmac_md5 (const void *key, size_t keylen,
904 const void *in, size_t inlen, char *resbuf)
906 hmac_md5 (key, keylen, in, inlen, resbuf);
911 #ifdef GNULIB_GC_HMAC_SHA1
913 gc_hmac_sha1 (const void *key, size_t keylen,
914 const void *in, size_t inlen, char *resbuf)
916 hmac_sha1 (key, keylen, in, inlen, resbuf);