/* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
- * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson
+ * Copyright (C) 2002-2013 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * along with this file; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include <assert.h>
+#ifndef MIN_GCRYPT_VERSION
+# define MIN_GCRYPT_VERSION "1.4.4"
+#endif
+
/* Initialization. */
Gc_rc
err = gcry_control (GCRYCTL_ANY_INITIALIZATION_P);
if (err == GPG_ERR_NO_ERROR)
{
- if (gcry_check_version (GCRYPT_VERSION) == NULL)
- return GC_INIT_ERROR;
+ if (gcry_control (GCRYCTL_DISABLE_SECMEM, NULL, 0))
+ return GC_INIT_ERROR;
+
+ if (gcry_check_version (MIN_GCRYPT_VERSION) == NULL)
+ return GC_INIT_ERROR;
err = gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
if (err != GPG_ERR_NO_ERROR)
- return GC_INIT_ERROR;
+ return GC_INIT_ERROR;
}
return GC_OK;
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)
{
gcry_set_allocation_handler (func_malloc, secure_malloc, secure_check,
- func_realloc, func_free);
+ func_realloc, func_free);
}
/* Ciphers. */
Gc_rc
gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
- gc_cipher_handle * outhandle)
+ gc_cipher_handle * outhandle)
{
int gcryalg, gcrymode;
gcry_error_t err;
}
err = gcry_cipher_open ((gcry_cipher_hd_t *) outhandle,
- gcryalg, gcrymode, 0);
+ gcryalg, gcrymode, 0);
if (gcry_err_code (err))
return GC_INVALID_CIPHER;
gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
{
if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
- data, len, NULL, len) != 0)
+ data, len, NULL, len) != 0)
return GC_INVALID_CIPHER;
return GC_OK;
gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
{
if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
- data, len, NULL, len) != 0)
+ data, len, NULL, len) != 0)
return GC_INVALID_CIPHER;
return GC_OK;
gcryalg = GCRY_MD_SHA512;
break;
+ case GC_SHA224:
+ gcryalg = GCRY_MD_SHA224;
+ break;
+
case GC_RMD160:
gcryalg = GCRY_MD_RMD160;
break;
{
err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
if (gcry_err_code (err))
- rc = GC_INVALID_HASH;
+ rc = GC_INVALID_HASH;
}
if (rc == GC_OK)
len = GC_SHA512_DIGEST_SIZE;
break;
+ case GC_SHA224:
+ len = GC_SHA224_DIGEST_SIZE;
+ break;
+
default:
return 0;
}
break;
#endif
+#ifdef GNULIB_GC_SHA224
+ case GC_SHA224:
+ gcryalg = GCRY_MD_SHA224;
+ break;
+#endif
+
#ifdef GNULIB_GC_RMD160
case GC_RMD160:
gcryalg = GCRY_MD_RMD160;
#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)
{
size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
gcry_md_hd_t mdh;
unsigned char *hash;
gpg_error_t err;
- assert (hlen == 16);
+ assert (hlen == GC_MD5_DIGEST_SIZE);
err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
if (err != GPG_ERR_NO_ERROR)
#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)
{
size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
gcry_md_hd_t mdh;
return GC_OK;
}
#endif
+
+#ifdef GNULIB_GC_HMAC_SHA256
+Gc_rc
+gc_hmac_sha256 (const void *key, size_t keylen,
+ const void *in, size_t inlen, char *resbuf)
+{
+ size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA256);
+ gcry_md_hd_t mdh;
+ unsigned char *hash;
+ gpg_error_t err;
+
+ assert (hlen == GC_SHA256_DIGEST_SIZE);
+
+ err = gcry_md_open (&mdh, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
+ if (err != GPG_ERR_NO_ERROR)
+ return GC_INVALID_HASH;
+
+ err = gcry_md_setkey (mdh, key, keylen);
+ if (err != GPG_ERR_NO_ERROR)
+ {
+ gcry_md_close (mdh);
+ return GC_INVALID_HASH;
+ }
+
+ gcry_md_write (mdh, in, inlen);
+
+ hash = gcry_md_read (mdh, GCRY_MD_SHA256);
+ if (hash == NULL)
+ {
+ gcry_md_close (mdh);
+ return GC_INVALID_HASH;
+ }
+
+ memcpy (resbuf, hash, hlen);
+
+ gcry_md_close (mdh);
+
+ return GC_OK;
+}
+#endif
+
+#ifdef GNULIB_GC_HMAC_SHA512
+Gc_rc
+gc_hmac_sha512 (const void *key, size_t keylen,
+ const void *in, size_t inlen, char *resbuf)
+{
+ size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_SHA512);
+ gcry_md_hd_t mdh;
+ unsigned char *hash;
+ gpg_error_t err;
+
+ assert (hlen == GC_SHA512_DIGEST_SIZE);
+
+ err = gcry_md_open (&mdh, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
+ if (err != GPG_ERR_NO_ERROR)
+ return GC_INVALID_HASH;
+
+ err = gcry_md_setkey (mdh, key, keylen);
+ if (err != GPG_ERR_NO_ERROR)
+ {
+ gcry_md_close (mdh);
+ return GC_INVALID_HASH;
+ }
+
+ gcry_md_write (mdh, in, inlen);
+
+ hash = gcry_md_read (mdh, GCRY_MD_SHA512);
+ if (hash == NULL)
+ {
+ gcry_md_close (mdh);
+ return GC_INVALID_HASH;
+ }
+
+ memcpy (resbuf, hash, hlen);
+
+ gcry_md_close (mdh);
+
+ return GC_OK;
+}
+#endif