X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fgc-gnulib.c;h=8aaa5c24853a2161a635b96fa7ffea82a59e4092;hb=86514ea5ebf71c35726c21ae077f2a3a10e196e2;hp=111c4a19e41836765dc7f09c7c31ba498af908dc;hpb=216c04af3d0ae20181e266391d1bdc09c120404c;p=gnulib.git diff --git a/lib/gc-gnulib.c b/lib/gc-gnulib.c index 111c4a19e..8aaa5c248 100644 --- a/lib/gc-gnulib.c +++ b/lib/gc-gnulib.c @@ -1,5 +1,5 @@ /* gc-gnulib.c --- Common gnulib internal crypto interface functions - * Copyright (C) 2002, 2003, 2004, 2005, 2006 Simon Josefsson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Simon Josefsson * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -20,9 +20,7 @@ /* Note: This file is only built if GC uses internal functions. */ -#ifdef HAVE_CONFIG_H -# include -#endif +#include /* Get prototype. */ #include "gc.h" @@ -31,7 +29,7 @@ #include /* For randomize. */ -#ifdef GC_USE_RANDOM +#ifdef GNULIB_GC_RANDOM # include # include # include @@ -40,55 +38,110 @@ #endif /* Hashes. */ -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 # include "md2.h" #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 # include "md4.h" #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 # include "md5.h" #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 # include "sha1.h" #endif -#ifdef GC_USE_HMAC_MD5 +#if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1) # include "hmac.h" #endif /* Ciphers. */ -#ifdef GC_USE_ARCFOUR +#ifdef GNULIB_GC_ARCFOUR # include "arcfour.h" #endif -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO # include "arctwo.h" #endif -#ifdef GC_USE_DES +#ifdef GNULIB_GC_DES # include "des.h" #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL # include "rijndael-api-fst.h" #endif +/* The results of open() in this file are not used with fchdir, + therefore save some unnecessary work in fchdir.c. */ +#undef open +#undef close + +#ifdef GNULIB_GC_RANDOM +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# include +# include +HCRYPTPROV g_hProv = 0; +# ifndef PROV_INTEL_SEC +# define PROV_INTEL_SEC 22 +# endif +# ifndef CRYPT_VERIFY_CONTEXT +# define CRYPT_VERIFY_CONTEXT 0xF0000000 +# endif +# endif +#endif + Gc_rc gc_init (void) { +#ifdef GNULIB_GC_RANDOM +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + if (g_hProv) + CryptReleaseContext (g_hProv, 0); + + /* There is no need to create a container for just random data, so + we can use CRYPT_VERIFY_CONTEXT (one call) see: + http://blogs.msdn.com/dangriff/archive/2003/11/19/51709.aspx */ + + /* We first try to use the Intel PIII RNG if drivers are present */ + if (!CryptAcquireContext (&g_hProv, NULL, NULL, + PROV_INTEL_SEC, CRYPT_VERIFY_CONTEXT)) + { + /* not a PIII or no drivers available, use default RSA CSP */ + if (!CryptAcquireContext (&g_hProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFY_CONTEXT)) + return GC_RANDOM_ERROR; + } +# endif +#endif + return GC_OK; } void gc_done (void) { +#ifdef GNULIB_GC_RANDOM +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + if (g_hProv) + { + CryptReleaseContext (g_hProv, 0); + g_hProv = 0; + } +# endif +#endif + return; } -#ifdef GC_USE_RANDOM +#ifdef GNULIB_GC_RANDOM /* Randomness. */ static Gc_rc randomize (int level, char *data, size_t datalen) { +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + if (!g_hProv) + return GC_RANDOM_ERROR; + CryptGenRandom (g_hProv, (DWORD) datalen, data); +#else int fd; const char *device; size_t len = 0; @@ -109,6 +162,9 @@ randomize (int level, char *data, size_t datalen) break; } + if (strcmp (device, "no") == 0) + return GC_RANDOM_ERROR; + fd = open (device, O_RDONLY); if (fd < 0) return GC_RANDOM_ERROR; @@ -134,6 +190,7 @@ randomize (int level, char *data, size_t datalen) rc = close (fd); if (rc < 0) return GC_RANDOM_ERROR; +#endif return GC_OK; } @@ -168,22 +225,24 @@ gc_set_allocators (gc_malloc_t func_malloc, { return; } + /* Ciphers. */ -typedef struct _gc_cipher_ctx { +typedef struct _gc_cipher_ctx +{ Gc_cipher alg; Gc_cipher_mode mode; -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO arctwo_context arctwoContext; char arctwoIV[ARCTWO_BLOCK_SIZE]; #endif -#ifdef GC_USE_ARCFOUR +#ifdef GNULIB_GC_ARCFOUR arcfour_context arcfourContext; #endif -#ifdef GC_USE_DES - des_ctx desContext; +#ifdef GNULIB_GC_DES + gl_des_ctx desContext; #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL rijndaelKeyInstance aesEncKey; rijndaelKeyInstance aesDecKey; rijndaelCipherInstance aesContext; @@ -206,7 +265,7 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, switch (alg) { -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: switch (mode) { @@ -220,7 +279,7 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, break; #endif -#ifdef GC_USE_ARCFOUR +#ifdef GNULIB_GC_ARCFOUR case GC_ARCFOUR128: case GC_ARCFOUR40: switch (mode) @@ -234,7 +293,7 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, break; #endif -#ifdef GC_USE_DES +#ifdef GNULIB_GC_DES case GC_DES: switch (mode) { @@ -247,7 +306,7 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, break; #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL case GC_AES128: case GC_AES192: case GC_AES256: @@ -282,28 +341,28 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) switch (ctx->alg) { -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: arctwo_setkey (&ctx->arctwoContext, keylen, key); break; #endif -#ifdef GC_USE_ARCFOUR +#ifdef GNULIB_GC_ARCFOUR case GC_ARCFOUR128: case GC_ARCFOUR40: arcfour_setkey (&ctx->arcfourContext, key, keylen); break; #endif -#ifdef GC_USE_DES +#ifdef GNULIB_GC_DES case GC_DES: if (keylen != 8) return GC_INVALID_CIPHER; - des_setkey (&ctx->desContext, key); + gl_des_setkey (&ctx->desContext, key); break; #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL case GC_AES128: case GC_AES192: case GC_AES256: @@ -313,7 +372,7 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; for (i = 0; i < keylen; i++) - sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF); + sprintf (&keyMaterial[2 * i], "%02x", key[i] & 0xFF); rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT, keylen * 8, keyMaterial); @@ -346,7 +405,7 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) switch (ctx->alg) { -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: if (ivlen != ARCTWO_BLOCK_SIZE) return GC_INVALID_CIPHER; @@ -354,7 +413,7 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) break; #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL case GC_AES128: case GC_AES192: case GC_AES256: @@ -371,7 +430,7 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1]; for (i = 0; i < ivlen; i++) - sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF); + sprintf (&ivMaterial[2 * i], "%02x", iv[i] & 0xFF); rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC, ivMaterial); @@ -400,7 +459,7 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) switch (ctx->alg) { -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: switch (ctx->mode) { @@ -410,7 +469,7 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) case GC_CBC: for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, - data += ARCTWO_BLOCK_SIZE) + data += ARCTWO_BLOCK_SIZE) { size_t i; for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) @@ -419,7 +478,7 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) ARCTWO_BLOCK_SIZE); memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE); } - break; + break; default: return GC_INVALID_CIPHER; @@ -427,21 +486,21 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) break; #endif -#ifdef GC_USE_ARCFOUR +#ifdef GNULIB_GC_ARCFOUR case GC_ARCFOUR128: case GC_ARCFOUR40: arcfour_stream (&ctx->arcfourContext, data, data, len); break; #endif -#ifdef GC_USE_DES +#ifdef GNULIB_GC_DES case GC_DES: for (; len >= 8; len -= 8, data += 8) - des_ecb_encrypt (&ctx->desContext, data, data); + gl_des_ecb_encrypt (&ctx->desContext, data, data); break; #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL case GC_AES128: case GC_AES192: case GC_AES256: @@ -470,7 +529,7 @@ gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) switch (ctx->alg) { -#ifdef GC_USE_ARCTWO +#ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: switch (ctx->mode) { @@ -480,7 +539,7 @@ gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) case GC_CBC: for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, - data += ARCTWO_BLOCK_SIZE) + data += ARCTWO_BLOCK_SIZE) { char tmpIV[ARCTWO_BLOCK_SIZE]; size_t i; @@ -499,21 +558,21 @@ gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) break; #endif -#ifdef GC_USE_ARCFOUR +#ifdef GNULIB_GC_ARCFOUR case GC_ARCFOUR128: case GC_ARCFOUR40: arcfour_stream (&ctx->arcfourContext, data, data, len); break; #endif -#ifdef GC_USE_DES +#ifdef GNULIB_GC_DES case GC_DES: for (; len >= 8; len -= 8, data += 8) - des_ecb_decrypt (&ctx->desContext, data, data); + gl_des_ecb_decrypt (&ctx->desContext, data, data); break; #endif -#ifdef GC_USE_RIJNDAEL +#ifdef GNULIB_GC_RIJNDAEL case GC_AES128: case GC_AES192: case GC_AES256: @@ -540,8 +599,7 @@ gc_cipher_close (gc_cipher_handle handle) { _gc_cipher_ctx *ctx = handle; - if (ctx) - free (ctx); + free (ctx); return GC_OK; } @@ -550,20 +608,21 @@ gc_cipher_close (gc_cipher_handle handle) #define MAX_DIGEST_SIZE 20 -typedef struct _gc_hash_ctx { +typedef struct _gc_hash_ctx +{ Gc_hash alg; Gc_hash_mode mode; char hash[MAX_DIGEST_SIZE]; -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 struct md2_ctx md2Context; #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 struct md4_ctx md4Context; #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 struct md5_ctx md5Context; #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 struct sha1_ctx sha1Context; #endif } _gc_hash_ctx; @@ -575,31 +634,33 @@ gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle) Gc_rc rc = GC_OK; ctx = calloc (sizeof (*ctx), 1); + if (!ctx) + return GC_MALLOC_ERROR; ctx->alg = hash; ctx->mode = mode; switch (hash) { -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 case GC_MD2: md2_init_ctx (&ctx->md2Context); break; #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 case GC_MD4: md4_init_ctx (&ctx->md4Context); break; #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 case GC_MD5: md5_init_ctx (&ctx->md5Context); break; #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 case GC_SHA1: sha1_init_ctx (&ctx->sha1Context); break; @@ -684,25 +745,25 @@ gc_hash_write (gc_hash_handle handle, size_t len, const char *data) switch (ctx->alg) { -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 case GC_MD2: md2_process_bytes (data, len, &ctx->md2Context); break; #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 case GC_MD4: md4_process_bytes (data, len, &ctx->md4Context); break; #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 case GC_MD5: md5_process_bytes (data, len, &ctx->md5Context); break; #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 case GC_SHA1: sha1_process_bytes (data, len, &ctx->sha1Context); break; @@ -721,28 +782,28 @@ gc_hash_read (gc_hash_handle handle) switch (ctx->alg) { -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 case GC_MD2: md2_finish_ctx (&ctx->md2Context, ctx->hash); ret = ctx->hash; break; #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 case GC_MD4: md4_finish_ctx (&ctx->md4Context, ctx->hash); ret = ctx->hash; break; #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 case GC_MD5: md5_finish_ctx (&ctx->md5Context, ctx->hash); ret = ctx->hash; break; #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 case GC_SHA1: sha1_finish_ctx (&ctx->sha1Context, ctx->hash); ret = ctx->hash; @@ -769,25 +830,25 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) { switch (hash) { -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 case GC_MD2: md2_buffer (in, inlen, resbuf); break; #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 case GC_MD4: md4_buffer (in, inlen, resbuf); break; #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 case GC_MD5: md5_buffer (in, inlen, resbuf); break; #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 case GC_SHA1: sha1_buffer (in, inlen, resbuf); break; @@ -800,7 +861,7 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf) return GC_OK; } -#ifdef GC_USE_MD2 +#ifdef GNULIB_GC_MD2 Gc_rc gc_md2 (const void *in, size_t inlen, void *resbuf) { @@ -809,7 +870,7 @@ gc_md2 (const void *in, size_t inlen, void *resbuf) } #endif -#ifdef GC_USE_MD4 +#ifdef GNULIB_GC_MD4 Gc_rc gc_md4 (const void *in, size_t inlen, void *resbuf) { @@ -818,7 +879,7 @@ gc_md4 (const void *in, size_t inlen, void *resbuf) } #endif -#ifdef GC_USE_MD5 +#ifdef GNULIB_GC_MD5 Gc_rc gc_md5 (const void *in, size_t inlen, void *resbuf) { @@ -827,7 +888,7 @@ gc_md5 (const void *in, size_t inlen, void *resbuf) } #endif -#ifdef GC_USE_SHA1 +#ifdef GNULIB_GC_SHA1 Gc_rc gc_sha1 (const void *in, size_t inlen, void *resbuf) { @@ -836,7 +897,7 @@ gc_sha1 (const void *in, size_t inlen, void *resbuf) } #endif -#ifdef GC_USE_HMAC_MD5 +#ifdef GNULIB_GC_HMAC_MD5 Gc_rc gc_hmac_md5 (const void *key, size_t keylen, const void *in, size_t inlen, char *resbuf) @@ -846,7 +907,7 @@ gc_hmac_md5 (const void *key, size_t keylen, } #endif -#ifdef GC_USE_HMAC_SHA1 +#ifdef GNULIB_GC_HMAC_SHA1 Gc_rc gc_hmac_sha1 (const void *key, size_t keylen, const void *in, size_t inlen, char *resbuf)