/* 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 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
# 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 <windows.h>
+# include <wincrypt.h>
+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;
}
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;
rc = close (fd);
if (rc < 0)
return GC_RANDOM_ERROR;
+#endif
return GC_OK;
}
{
return;
}
+
/* Ciphers. */
-typedef struct _gc_cipher_ctx {
+typedef struct _gc_cipher_ctx
+{
Gc_cipher alg;
Gc_cipher_mode mode;
#ifdef GNULIB_GC_ARCTWO
arcfour_context arcfourContext;
#endif
#ifdef GNULIB_GC_DES
- des_ctx desContext;
+ gl_des_ctx desContext;
#endif
#ifdef GNULIB_GC_RIJNDAEL
rijndaelKeyInstance aesEncKey;
case GC_DES:
if (keylen != 8)
return GC_INVALID_CIPHER;
- des_setkey (&ctx->desContext, key);
+ gl_des_setkey (&ctx->desContext, key);
break;
#endif
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);
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);
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++)
ARCTWO_BLOCK_SIZE);
memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
}
- break;
+ break;
default:
return GC_INVALID_CIPHER;
#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
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;
#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
{
_gc_cipher_ctx *ctx = handle;
- if (ctx)
- free (ctx);
+ free (ctx);
return GC_OK;
}
#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];
Gc_rc rc = GC_OK;
ctx = calloc (sizeof (*ctx), 1);
+ if (!ctx)
+ return GC_MALLOC_ERROR;
ctx->alg = hash;
ctx->mode = mode;