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;
81 # ifndef PROV_INTEL_SEC
82 # define PROV_INTEL_SEC 22
84 # ifndef CRYPT_VERIFY_CONTEXT
85 # define CRYPT_VERIFY_CONTEXT 0xF0000000
93 #ifdef GNULIB_GC_RANDOM
94 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
96 CryptReleaseContext(g_hProv, 0);
97 if(!CryptAcquireContext(&g_hProv, NULL, NULL, PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT))
98 if(!CryptAcquireContext(&g_hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT))
99 return GC_RANDOM_ERROR;
109 #ifdef GNULIB_GC_RANDOM
110 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
113 CryptReleaseContext(g_hProv, 0);
122 #ifdef GNULIB_GC_RANDOM
127 randomize (int level, char *data, size_t datalen)
129 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
131 return GC_RANDOM_ERROR;
132 CryptGenRandom(g_hProv, (DWORD)datalen, data);
142 device = NAME_OF_NONCE_DEVICE;
146 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
150 device = NAME_OF_RANDOM_DEVICE;
154 if (strcmp (device, "no") == 0)
155 return GC_RANDOM_ERROR;
157 fd = open (device, O_RDONLY);
159 return GC_RANDOM_ERROR;
165 tmp = read (fd, data, datalen);
169 int save_errno = errno;
172 return GC_RANDOM_ERROR;
177 while (len < datalen);
181 return GC_RANDOM_ERROR;
188 gc_nonce (char *data, size_t datalen)
190 return randomize (0, data, datalen);
194 gc_pseudo_random (char *data, size_t datalen)
196 return randomize (1, data, datalen);
200 gc_random (char *data, size_t datalen)
202 return randomize (2, data, datalen);
207 /* Memory allocation. */
210 gc_set_allocators (gc_malloc_t func_malloc,
211 gc_malloc_t secure_malloc,
212 gc_secure_check_t secure_check,
213 gc_realloc_t func_realloc, gc_free_t func_free)
219 typedef struct _gc_cipher_ctx {
222 #ifdef GNULIB_GC_ARCTWO
223 arctwo_context arctwoContext;
224 char arctwoIV[ARCTWO_BLOCK_SIZE];
226 #ifdef GNULIB_GC_ARCFOUR
227 arcfour_context arcfourContext;
230 gl_des_ctx desContext;
232 #ifdef GNULIB_GC_RIJNDAEL
233 rijndaelKeyInstance aesEncKey;
234 rijndaelKeyInstance aesDecKey;
235 rijndaelCipherInstance aesContext;
240 gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
241 gc_cipher_handle * outhandle)
246 ctx = calloc (sizeof (*ctx), 1);
248 return GC_MALLOC_ERROR;
255 #ifdef GNULIB_GC_ARCTWO
264 rc = GC_INVALID_CIPHER;
269 #ifdef GNULIB_GC_ARCFOUR
278 rc = GC_INVALID_CIPHER;
291 rc = GC_INVALID_CIPHER;
296 #ifdef GNULIB_GC_RIJNDAEL
307 rc = GC_INVALID_CIPHER;
313 rc = GC_INVALID_CIPHER;
325 gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
327 _gc_cipher_ctx *ctx = handle;
331 #ifdef GNULIB_GC_ARCTWO
333 arctwo_setkey (&ctx->arctwoContext, keylen, key);
337 #ifdef GNULIB_GC_ARCFOUR
340 arcfour_setkey (&ctx->arcfourContext, key, keylen);
347 return GC_INVALID_CIPHER;
348 gl_des_setkey (&ctx->desContext, key);
352 #ifdef GNULIB_GC_RIJNDAEL
359 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
361 for (i = 0; i < keylen; i++)
362 sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
364 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
365 keylen * 8, keyMaterial);
367 return GC_INVALID_CIPHER;
369 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
370 keylen * 8, keyMaterial);
372 return GC_INVALID_CIPHER;
374 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
376 return GC_INVALID_CIPHER;
382 return GC_INVALID_CIPHER;
389 gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
391 _gc_cipher_ctx *ctx = handle;
395 #ifdef GNULIB_GC_ARCTWO
397 if (ivlen != ARCTWO_BLOCK_SIZE)
398 return GC_INVALID_CIPHER;
399 memcpy (ctx->arctwoIV, iv, ivlen);
403 #ifdef GNULIB_GC_RIJNDAEL
410 /* Doesn't use IV. */
417 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
419 for (i = 0; i < ivlen; i++)
420 sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF);
422 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
425 return GC_INVALID_CIPHER;
430 return GC_INVALID_CIPHER;
436 return GC_INVALID_CIPHER;
443 gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
445 _gc_cipher_ctx *ctx = handle;
449 #ifdef GNULIB_GC_ARCTWO
454 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
458 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
459 data += ARCTWO_BLOCK_SIZE)
462 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
463 data[i] ^= ctx->arctwoIV[i];
464 arctwo_encrypt (&ctx->arctwoContext, data, data,
466 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
471 return GC_INVALID_CIPHER;
476 #ifdef GNULIB_GC_ARCFOUR
479 arcfour_stream (&ctx->arcfourContext, data, data, len);
485 for (; len >= 8; len -= 8, data += 8)
486 gl_des_ecb_encrypt (&ctx->desContext, data, data);
490 #ifdef GNULIB_GC_RIJNDAEL
497 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
498 data, 8 * len, data);
500 return GC_INVALID_CIPHER;
506 return GC_INVALID_CIPHER;
513 gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
515 _gc_cipher_ctx *ctx = handle;
519 #ifdef GNULIB_GC_ARCTWO
524 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
528 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
529 data += ARCTWO_BLOCK_SIZE)
531 char tmpIV[ARCTWO_BLOCK_SIZE];
533 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
534 arctwo_decrypt (&ctx->arctwoContext, data, data,
536 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
537 data[i] ^= ctx->arctwoIV[i];
538 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
543 return GC_INVALID_CIPHER;
548 #ifdef GNULIB_GC_ARCFOUR
551 arcfour_stream (&ctx->arcfourContext, data, data, len);
557 for (; len >= 8; len -= 8, data += 8)
558 gl_des_ecb_decrypt (&ctx->desContext, data, data);
562 #ifdef GNULIB_GC_RIJNDAEL
569 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
570 data, 8 * len, data);
572 return GC_INVALID_CIPHER;
578 return GC_INVALID_CIPHER;
585 gc_cipher_close (gc_cipher_handle handle)
587 _gc_cipher_ctx *ctx = handle;
596 #define MAX_DIGEST_SIZE 20
598 typedef struct _gc_hash_ctx {
601 char hash[MAX_DIGEST_SIZE];
603 struct md2_ctx md2Context;
606 struct md4_ctx md4Context;
609 struct md5_ctx md5Context;
611 #ifdef GNULIB_GC_SHA1
612 struct sha1_ctx sha1Context;
617 gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
622 ctx = calloc (sizeof (*ctx), 1);
624 return GC_MALLOC_ERROR;
633 md2_init_ctx (&ctx->md2Context);
639 md4_init_ctx (&ctx->md4Context);
645 md5_init_ctx (&ctx->md5Context);
649 #ifdef GNULIB_GC_SHA1
651 sha1_init_ctx (&ctx->sha1Context);
656 rc = GC_INVALID_HASH;
666 rc = GC_INVALID_HASH;
679 gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
681 _gc_hash_ctx *in = handle;
684 *outhandle = out = calloc (sizeof (*out), 1);
686 return GC_MALLOC_ERROR;
688 memcpy (out, in, sizeof (*out));
694 gc_hash_digest_length (Gc_hash hash)
701 len = GC_MD2_DIGEST_SIZE;
705 len = GC_MD4_DIGEST_SIZE;
709 len = GC_MD5_DIGEST_SIZE;
713 len = GC_RMD160_DIGEST_SIZE;
717 len = GC_SHA1_DIGEST_SIZE;
728 gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
730 _gc_hash_ctx *ctx = handle;
736 md2_process_bytes (data, len, &ctx->md2Context);
742 md4_process_bytes (data, len, &ctx->md4Context);
748 md5_process_bytes (data, len, &ctx->md5Context);
752 #ifdef GNULIB_GC_SHA1
754 sha1_process_bytes (data, len, &ctx->sha1Context);
764 gc_hash_read (gc_hash_handle handle)
766 _gc_hash_ctx *ctx = handle;
767 const char *ret = NULL;
773 md2_finish_ctx (&ctx->md2Context, ctx->hash);
780 md4_finish_ctx (&ctx->md4Context, ctx->hash);
787 md5_finish_ctx (&ctx->md5Context, ctx->hash);
792 #ifdef GNULIB_GC_SHA1
794 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
807 gc_hash_close (gc_hash_handle handle)
809 _gc_hash_ctx *ctx = handle;
815 gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
821 md2_buffer (in, inlen, resbuf);
827 md4_buffer (in, inlen, resbuf);
833 md5_buffer (in, inlen, resbuf);
837 #ifdef GNULIB_GC_SHA1
839 sha1_buffer (in, inlen, resbuf);
844 return GC_INVALID_HASH;
852 gc_md2 (const void *in, size_t inlen, void *resbuf)
854 md2_buffer (in, inlen, resbuf);
861 gc_md4 (const void *in, size_t inlen, void *resbuf)
863 md4_buffer (in, inlen, resbuf);
870 gc_md5 (const void *in, size_t inlen, void *resbuf)
872 md5_buffer (in, inlen, resbuf);
877 #ifdef GNULIB_GC_SHA1
879 gc_sha1 (const void *in, size_t inlen, void *resbuf)
881 sha1_buffer (in, inlen, resbuf);
886 #ifdef GNULIB_GC_HMAC_MD5
888 gc_hmac_md5 (const void *key, size_t keylen,
889 const void *in, size_t inlen, char *resbuf)
891 hmac_md5 (key, keylen, in, inlen, resbuf);
896 #ifdef GNULIB_GC_HMAC_SHA1
898 gc_hmac_sha1 (const void *key, size_t keylen,
899 const void *in, size_t inlen, char *resbuf)
901 hmac_sha1 (key, keylen, in, inlen, resbuf);