/* gc-gnulib.c --- Common gnulib internal crypto interface functions
- * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 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
#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
{
#ifdef GNULIB_GC_RANDOM
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
- if(g_hProv)
- CryptReleaseContext(g_hProv, 0);
- CryptAcquireContext(&g_hProv, NULL, NULL, PROV_RSA_FULL, 0);
+ 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
{
#ifdef GNULIB_GC_RANDOM
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
- if(g_hProv)
+ if (g_hProv)
{
- CryptReleaseContext(g_hProv, 0);
+ CryptReleaseContext (g_hProv, 0);
g_hProv = 0;
}
# endif
randomize (int level, char *data, size_t datalen)
{
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
- if(!g_hProv)
+ if (!g_hProv)
return GC_RANDOM_ERROR;
- CryptGenRandom(g_hProv, (DWORD)datalen, data);
+ CryptGenRandom (g_hProv, (DWORD) datalen, data);
#else
int fd;
const char *device;
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;
}
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
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;
#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
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
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
#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
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
#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
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
#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
#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
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
#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
#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
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
#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 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;
#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;