1 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
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, see <http://www.gnu.org/licenses/>.
19 /* Note: This file is only built if GC uses internal functions. */
30 #ifdef GNULIB_GC_RANDOM
32 # include <sys/types.h>
33 # include <sys/stat.h>
51 #if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1)
56 #ifdef GNULIB_GC_ARCFOUR
59 #ifdef GNULIB_GC_ARCTWO
65 #ifdef GNULIB_GC_RIJNDAEL
66 # include "rijndael-api-fst.h"
69 /* The results of open() in this file are not used with fchdir,
70 therefore save some unnecessary work in fchdir.c. */
74 #ifdef GNULIB_GC_RANDOM
75 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
77 # include <wincrypt.h>
78 HCRYPTPROV g_hProv = 0;
79 # ifndef PROV_INTEL_SEC
80 # define PROV_INTEL_SEC 22
82 # ifndef CRYPT_VERIFY_CONTEXT
83 # define CRYPT_VERIFY_CONTEXT 0xF0000000
91 #ifdef GNULIB_GC_RANDOM
92 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
94 CryptReleaseContext (g_hProv, 0);
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 */
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))
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;
118 #ifdef GNULIB_GC_RANDOM
119 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
122 CryptReleaseContext (g_hProv, 0);
131 #ifdef GNULIB_GC_RANDOM
136 randomize (int level, char *data, size_t datalen)
138 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
140 return GC_RANDOM_ERROR;
141 CryptGenRandom (g_hProv, (DWORD) datalen, data);
151 device = NAME_OF_NONCE_DEVICE;
155 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
159 device = NAME_OF_RANDOM_DEVICE;
163 if (strcmp (device, "no") == 0)
164 return GC_RANDOM_ERROR;
166 fd = open (device, O_RDONLY);
168 return GC_RANDOM_ERROR;
174 tmp = read (fd, data, datalen);
178 int save_errno = errno;
181 return GC_RANDOM_ERROR;
186 while (len < datalen);
190 return GC_RANDOM_ERROR;
197 gc_nonce (char *data, size_t datalen)
199 return randomize (0, data, datalen);
203 gc_pseudo_random (char *data, size_t datalen)
205 return randomize (1, data, datalen);
209 gc_random (char *data, size_t datalen)
211 return randomize (2, data, datalen);
216 /* Memory allocation. */
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)
229 typedef struct _gc_cipher_ctx
233 #ifdef GNULIB_GC_ARCTWO
234 arctwo_context arctwoContext;
235 char arctwoIV[ARCTWO_BLOCK_SIZE];
237 #ifdef GNULIB_GC_ARCFOUR
238 arcfour_context arcfourContext;
241 gl_des_ctx desContext;
243 #ifdef GNULIB_GC_RIJNDAEL
244 rijndaelKeyInstance aesEncKey;
245 rijndaelKeyInstance aesDecKey;
246 rijndaelCipherInstance aesContext;
251 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
252 gc_cipher_handle * outhandle)
257 ctx = calloc (sizeof (*ctx), 1);
259 return GC_MALLOC_ERROR;
266 #ifdef GNULIB_GC_ARCTWO
275 rc = GC_INVALID_CIPHER;
280 #ifdef GNULIB_GC_ARCFOUR
289 rc = GC_INVALID_CIPHER;
302 rc = GC_INVALID_CIPHER;
307 #ifdef GNULIB_GC_RIJNDAEL
318 rc = GC_INVALID_CIPHER;
324 rc = GC_INVALID_CIPHER;
336 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
338 _gc_cipher_ctx *ctx = handle;
342 #ifdef GNULIB_GC_ARCTWO
344 arctwo_setkey (&ctx->arctwoContext, keylen, key);
348 #ifdef GNULIB_GC_ARCFOUR
351 arcfour_setkey (&ctx->arcfourContext, key, keylen);
358 return GC_INVALID_CIPHER;
359 gl_des_setkey (&ctx->desContext, key);
363 #ifdef GNULIB_GC_RIJNDAEL
370 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
372 for (i = 0; i < keylen; i++)
373 sprintf (&keyMaterial[2 * i], "%02x", key[i] & 0xFF);
375 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
376 keylen * 8, keyMaterial);
378 return GC_INVALID_CIPHER;
380 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
381 keylen * 8, keyMaterial);
383 return GC_INVALID_CIPHER;
385 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
387 return GC_INVALID_CIPHER;
393 return GC_INVALID_CIPHER;
400 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
402 _gc_cipher_ctx *ctx = handle;
406 #ifdef GNULIB_GC_ARCTWO
408 if (ivlen != ARCTWO_BLOCK_SIZE)
409 return GC_INVALID_CIPHER;
410 memcpy (ctx->arctwoIV, iv, ivlen);
414 #ifdef GNULIB_GC_RIJNDAEL
421 /* Doesn't use IV. */
428 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
430 for (i = 0; i < ivlen; i++)
431 sprintf (&ivMaterial[2 * i], "%02x", iv[i] & 0xFF);
433 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
436 return GC_INVALID_CIPHER;
441 return GC_INVALID_CIPHER;
447 return GC_INVALID_CIPHER;
454 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
456 _gc_cipher_ctx *ctx = handle;
460 #ifdef GNULIB_GC_ARCTWO
465 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
469 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
470 data += ARCTWO_BLOCK_SIZE)
473 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
474 data[i] ^= ctx->arctwoIV[i];
475 arctwo_encrypt (&ctx->arctwoContext, data, data,
477 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
482 return GC_INVALID_CIPHER;
487 #ifdef GNULIB_GC_ARCFOUR
490 arcfour_stream (&ctx->arcfourContext, data, data, len);
496 for (; len >= 8; len -= 8, data += 8)
497 gl_des_ecb_encrypt (&ctx->desContext, data, data);
501 #ifdef GNULIB_GC_RIJNDAEL
508 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
509 data, 8 * len, data);
511 return GC_INVALID_CIPHER;
517 return GC_INVALID_CIPHER;
524 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
526 _gc_cipher_ctx *ctx = handle;
530 #ifdef GNULIB_GC_ARCTWO
535 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
539 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
540 data += ARCTWO_BLOCK_SIZE)
542 char tmpIV[ARCTWO_BLOCK_SIZE];
544 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
545 arctwo_decrypt (&ctx->arctwoContext, data, data,
547 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
548 data[i] ^= ctx->arctwoIV[i];
549 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
554 return GC_INVALID_CIPHER;
559 #ifdef GNULIB_GC_ARCFOUR
562 arcfour_stream (&ctx->arcfourContext, data, data, len);
568 for (; len >= 8; len -= 8, data += 8)
569 gl_des_ecb_decrypt (&ctx->desContext, data, data);
573 #ifdef GNULIB_GC_RIJNDAEL
580 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
581 data, 8 * len, data);
583 return GC_INVALID_CIPHER;
589 return GC_INVALID_CIPHER;
596 gc_cipher_close (gc_cipher_handle handle)
598 _gc_cipher_ctx *ctx = handle;
607 #define MAX_DIGEST_SIZE 20
609 typedef struct _gc_hash_ctx
613 char hash[MAX_DIGEST_SIZE];
615 struct md2_ctx md2Context;
618 struct md4_ctx md4Context;
621 struct md5_ctx md5Context;
623 #ifdef GNULIB_GC_SHA1
624 struct sha1_ctx sha1Context;
629 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
634 ctx = calloc (sizeof (*ctx), 1);
636 return GC_MALLOC_ERROR;
645 md2_init_ctx (&ctx->md2Context);
651 md4_init_ctx (&ctx->md4Context);
657 md5_init_ctx (&ctx->md5Context);
661 #ifdef GNULIB_GC_SHA1
663 sha1_init_ctx (&ctx->sha1Context);
668 rc = GC_INVALID_HASH;
678 rc = GC_INVALID_HASH;
691 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
693 _gc_hash_ctx *in = handle;
696 *outhandle = out = calloc (sizeof (*out), 1);
698 return GC_MALLOC_ERROR;
700 memcpy (out, in, sizeof (*out));
706 gc_hash_digest_length (Gc_hash hash)
713 len = GC_MD2_DIGEST_SIZE;
717 len = GC_MD4_DIGEST_SIZE;
721 len = GC_MD5_DIGEST_SIZE;
725 len = GC_RMD160_DIGEST_SIZE;
729 len = GC_SHA1_DIGEST_SIZE;
740 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
742 _gc_hash_ctx *ctx = handle;
748 md2_process_bytes (data, len, &ctx->md2Context);
754 md4_process_bytes (data, len, &ctx->md4Context);
760 md5_process_bytes (data, len, &ctx->md5Context);
764 #ifdef GNULIB_GC_SHA1
766 sha1_process_bytes (data, len, &ctx->sha1Context);
776 gc_hash_read (gc_hash_handle handle)
778 _gc_hash_ctx *ctx = handle;
779 const char *ret = NULL;
785 md2_finish_ctx (&ctx->md2Context, ctx->hash);
792 md4_finish_ctx (&ctx->md4Context, ctx->hash);
799 md5_finish_ctx (&ctx->md5Context, ctx->hash);
804 #ifdef GNULIB_GC_SHA1
806 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
819 gc_hash_close (gc_hash_handle handle)
821 _gc_hash_ctx *ctx = handle;
827 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
833 md2_buffer (in, inlen, resbuf);
839 md4_buffer (in, inlen, resbuf);
845 md5_buffer (in, inlen, resbuf);
849 #ifdef GNULIB_GC_SHA1
851 sha1_buffer (in, inlen, resbuf);
856 return GC_INVALID_HASH;
864 gc_md2 (const void *in, size_t inlen, void *resbuf)
866 md2_buffer (in, inlen, resbuf);
873 gc_md4 (const void *in, size_t inlen, void *resbuf)
875 md4_buffer (in, inlen, resbuf);
882 gc_md5 (const void *in, size_t inlen, void *resbuf)
884 md5_buffer (in, inlen, resbuf);
889 #ifdef GNULIB_GC_SHA1
891 gc_sha1 (const void *in, size_t inlen, void *resbuf)
893 sha1_buffer (in, inlen, resbuf);
898 #ifdef GNULIB_GC_HMAC_MD5
900 gc_hmac_md5 (const void *key, size_t keylen,
901 const void *in, size_t inlen, char *resbuf)
903 hmac_md5 (key, keylen, in, inlen, resbuf);
908 #ifdef GNULIB_GC_HMAC_SHA1
910 gc_hmac_sha1 (const void *key, size_t keylen,
911 const void *in, size_t inlen, char *resbuf)
913 hmac_sha1 (key, keylen, in, inlen, resbuf);