X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fgc-gnulib.c;h=00eba174ad4d36991d23392df30afc3c31ab30e5;hb=c8068b3df116650efbf0fbf2d790c706577ae972;hp=94e08806c5b780e1f47d6a3225452c6009dd74f7;hpb=a3379e2f78900d6e7186ca49f395d7e0ea6ec1ca;p=gnulib.git diff --git a/lib/gc-gnulib.c b/lib/gc-gnulib.c index 94e08806c..00eba174a 100644 --- a/lib/gc-gnulib.c +++ b/lib/gc-gnulib.c @@ -1,5 +1,6 @@ /* gc-gnulib.c --- Common gnulib internal crypto interface functions - * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free + * Software Foundation, Inc. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -73,15 +74,60 @@ #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; } @@ -92,6 +138,11 @@ gc_done (void) 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; @@ -126,12 +177,12 @@ randomize (int level, char *data, size_t datalen) tmp = read (fd, data, datalen); if (tmp < 0) - { - int save_errno = errno; - close (fd); - errno = save_errno; - return GC_RANDOM_ERROR; - } + { + int save_errno = errno; + close (fd); + errno = save_errno; + return GC_RANDOM_ERROR; + } len += tmp; } @@ -140,6 +191,7 @@ randomize (int level, char *data, size_t datalen) rc = close (fd); if (rc < 0) return GC_RANDOM_ERROR; +#endif return GC_OK; } @@ -168,15 +220,17 @@ gc_random (char *data, size_t datalen) void gc_set_allocators (gc_malloc_t func_malloc, - gc_malloc_t secure_malloc, - gc_secure_check_t secure_check, - gc_realloc_t func_realloc, gc_free_t func_free) + gc_malloc_t secure_malloc, + gc_secure_check_t secure_check, + gc_realloc_t func_realloc, gc_free_t func_free) { return; } + /* Ciphers. */ -typedef struct _gc_cipher_ctx { +typedef struct _gc_cipher_ctx +{ Gc_cipher alg; Gc_cipher_mode mode; #ifdef GNULIB_GC_ARCTWO @@ -198,7 +252,7 @@ typedef struct _gc_cipher_ctx { Gc_rc gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, - gc_cipher_handle * outhandle) + gc_cipher_handle * outhandle) { _gc_cipher_ctx *ctx; Gc_rc rc = GC_OK; @@ -215,14 +269,14 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, #ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: switch (mode) - { - case GC_ECB: - case GC_CBC: - break; + { + case GC_ECB: + case GC_CBC: + break; - default: - rc = GC_INVALID_CIPHER; - } + default: + rc = GC_INVALID_CIPHER; + } break; #endif @@ -230,26 +284,26 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, case GC_ARCFOUR128: case GC_ARCFOUR40: switch (mode) - { - case GC_STREAM: - break; + { + case GC_STREAM: + break; - default: - rc = GC_INVALID_CIPHER; - } + default: + rc = GC_INVALID_CIPHER; + } break; #endif #ifdef GNULIB_GC_DES case GC_DES: switch (mode) - { - case GC_ECB: - break; + { + case GC_ECB: + break; - default: - rc = GC_INVALID_CIPHER; - } + default: + rc = GC_INVALID_CIPHER; + } break; #endif @@ -258,14 +312,14 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode, case GC_AES192: case GC_AES256: switch (mode) - { - case GC_ECB: - case GC_CBC: - break; + { + case GC_ECB: + case GC_CBC: + break; - default: - rc = GC_INVALID_CIPHER; - } + default: + rc = GC_INVALID_CIPHER; + } break; #endif @@ -304,7 +358,7 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) #ifdef GNULIB_GC_DES case GC_DES: if (keylen != 8) - return GC_INVALID_CIPHER; + return GC_INVALID_CIPHER; gl_des_setkey (&ctx->desContext, key); break; #endif @@ -314,26 +368,26 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key) case GC_AES192: case GC_AES256: { - rijndael_rc rc; - size_t i; - char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; - - for (i = 0; i < keylen; i++) - sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF); - - rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT, - keylen * 8, keyMaterial); - if (rc < 0) - return GC_INVALID_CIPHER; - - rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT, - keylen * 8, keyMaterial); - if (rc < 0) - return GC_INVALID_CIPHER; - - rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL); - if (rc < 0) - return GC_INVALID_CIPHER; + rijndael_rc rc; + size_t i; + char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1]; + + for (i = 0; i < keylen; i++) + sprintf (&keyMaterial[2 * i], "%02x", key[i] & 0xFF); + + rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT, + keylen * 8, keyMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + + rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT, + keylen * 8, keyMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + + rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL); + if (rc < 0) + return GC_INVALID_CIPHER; } break; #endif @@ -355,7 +409,7 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) #ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: if (ivlen != ARCTWO_BLOCK_SIZE) - return GC_INVALID_CIPHER; + return GC_INVALID_CIPHER; memcpy (ctx->arctwoIV, iv, ivlen); break; #endif @@ -365,30 +419,30 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv) case GC_AES192: case GC_AES256: switch (ctx->mode) - { - case GC_ECB: - /* Doesn't use IV. */ - break; + { + case GC_ECB: + /* Doesn't use IV. */ + break; - case GC_CBC: - { - rijndael_rc rc; - size_t i; - char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1]; + case GC_CBC: + { + rijndael_rc rc; + size_t i; + char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1]; - for (i = 0; i < ivlen; i++) - sprintf (&ivMaterial[2*i], "%02x", iv[i] & 0xFF); + for (i = 0; i < ivlen; i++) + sprintf (&ivMaterial[2 * i], "%02x", iv[i] & 0xFF); - rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC, - ivMaterial); - if (rc < 0) - return GC_INVALID_CIPHER; - } - break; + rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC, + ivMaterial); + if (rc < 0) + return GC_INVALID_CIPHER; + } + break; - default: - return GC_INVALID_CIPHER; - } + default: + return GC_INVALID_CIPHER; + } break; #endif @@ -409,27 +463,27 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) #ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: switch (ctx->mode) - { - case GC_ECB: - arctwo_encrypt (&ctx->arctwoContext, data, data, len); - break; - - case GC_CBC: - for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, - data += ARCTWO_BLOCK_SIZE) - { - size_t i; - for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) - data[i] ^= ctx->arctwoIV[i]; - arctwo_encrypt (&ctx->arctwoContext, data, data, - ARCTWO_BLOCK_SIZE); - memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE); - } - break; - - default: - return GC_INVALID_CIPHER; - } + { + case GC_ECB: + arctwo_encrypt (&ctx->arctwoContext, data, data, len); + break; + + case GC_CBC: + for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, + data += ARCTWO_BLOCK_SIZE) + { + size_t i; + for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) + data[i] ^= ctx->arctwoIV[i]; + arctwo_encrypt (&ctx->arctwoContext, data, data, + ARCTWO_BLOCK_SIZE); + memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE); + } + break; + + default: + return GC_INVALID_CIPHER; + } break; #endif @@ -443,7 +497,7 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) #ifdef GNULIB_GC_DES case GC_DES: for (; len >= 8; len -= 8, data += 8) - gl_des_ecb_encrypt (&ctx->desContext, data, data); + gl_des_ecb_encrypt (&ctx->desContext, data, data); break; #endif @@ -452,12 +506,12 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data) case GC_AES192: case GC_AES256: { - int nblocks; + int nblocks; - nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey, - data, 8 * len, data); - if (nblocks < 0) - return GC_INVALID_CIPHER; + nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey, + data, 8 * len, data); + if (nblocks < 0) + return GC_INVALID_CIPHER; } break; #endif @@ -479,29 +533,29 @@ gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) #ifdef GNULIB_GC_ARCTWO case GC_ARCTWO40: switch (ctx->mode) - { - case GC_ECB: - arctwo_decrypt (&ctx->arctwoContext, data, data, len); - break; - - case GC_CBC: - for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, - data += ARCTWO_BLOCK_SIZE) - { - char tmpIV[ARCTWO_BLOCK_SIZE]; - size_t i; - memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE); - arctwo_decrypt (&ctx->arctwoContext, data, data, - ARCTWO_BLOCK_SIZE); - for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) - data[i] ^= ctx->arctwoIV[i]; - memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE); - } - break; - - default: - return GC_INVALID_CIPHER; - } + { + case GC_ECB: + arctwo_decrypt (&ctx->arctwoContext, data, data, len); + break; + + case GC_CBC: + for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE, + data += ARCTWO_BLOCK_SIZE) + { + char tmpIV[ARCTWO_BLOCK_SIZE]; + size_t i; + memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE); + arctwo_decrypt (&ctx->arctwoContext, data, data, + ARCTWO_BLOCK_SIZE); + for (i = 0; i < ARCTWO_BLOCK_SIZE; i++) + data[i] ^= ctx->arctwoIV[i]; + memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE); + } + break; + + default: + return GC_INVALID_CIPHER; + } break; #endif @@ -515,7 +569,7 @@ gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) #ifdef GNULIB_GC_DES case GC_DES: for (; len >= 8; len -= 8, data += 8) - gl_des_ecb_decrypt (&ctx->desContext, data, data); + gl_des_ecb_decrypt (&ctx->desContext, data, data); break; #endif @@ -524,12 +578,12 @@ gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data) case GC_AES192: case GC_AES256: { - int nblocks; + int nblocks; - nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey, - data, 8 * len, data); - if (nblocks < 0) - return GC_INVALID_CIPHER; + nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey, + data, 8 * len, data); + if (nblocks < 0) + return GC_INVALID_CIPHER; } break; #endif @@ -546,8 +600,7 @@ gc_cipher_close (gc_cipher_handle handle) { _gc_cipher_ctx *ctx = handle; - if (ctx) - free (ctx); + free (ctx); return GC_OK; } @@ -556,7 +609,8 @@ 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]; @@ -847,7 +901,7 @@ gc_sha1 (const void *in, size_t inlen, void *resbuf) #ifdef GNULIB_GC_HMAC_MD5 Gc_rc gc_hmac_md5 (const void *key, size_t keylen, - const void *in, size_t inlen, char *resbuf) + const void *in, size_t inlen, char *resbuf) { hmac_md5 (key, keylen, in, inlen, resbuf); return GC_OK; @@ -857,7 +911,7 @@ gc_hmac_md5 (const void *key, size_t keylen, #ifdef GNULIB_GC_HMAC_SHA1 Gc_rc gc_hmac_sha1 (const void *key, size_t keylen, - const void *in, size_t inlen, char *resbuf) + const void *in, size_t inlen, char *resbuf) { hmac_sha1 (key, keylen, in, inlen, resbuf); return GC_OK;