summaryrefslogtreecommitdiff
path: root/gl/gc-gnulib.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/gc-gnulib.c')
-rw-r--r--gl/gc-gnulib.c270
1 files changed, 232 insertions, 38 deletions
diff --git a/gl/gc-gnulib.c b/gl/gc-gnulib.c
index a6f51dd20d..217d71d0d4 100644
--- a/gl/gc-gnulib.c
+++ b/gl/gc-gnulib.c
@@ -2,8 +2,8 @@
* Copyright (C) 2002, 2003, 2004, 2005 Simon Josefsson
*
* This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1, or (at your
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
* option) any later version.
*
* This file is distributed in the hope that it will be useful, but
@@ -11,7 +11,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public License
+ * 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.
@@ -53,6 +53,8 @@
# include "rijndael-api-fst.h"
#endif
+#include <gcrypt.h>
+
Gc_rc
gc_init (void)
{
@@ -149,7 +151,7 @@ gc_set_allocators (gc_malloc_t func_malloc,
}
/* Ciphers. */
-typedef struct {
+typedef struct _gc_cipher_ctx {
Gc_cipher alg;
Gc_cipher_mode mode;
rijndaelKeyInstance aesEncKey;
@@ -162,10 +164,9 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
gc_cipher_handle * outhandle)
{
_gc_cipher_ctx *ctx;
- puts("copen");
- *outhandle = ctx = malloc (sizeof (_gc_cipher_ctx));
- if (*!outhandle)
- return GC_MALLOC_ERROR;
+ Gc_rc rc = GC_OK;
+
+ ctx = calloc (sizeof (*ctx), 1);
ctx->alg = alg;
ctx->mode = mode;
@@ -173,35 +174,36 @@ gc_cipher_open (Gc_cipher alg, Gc_cipher_mode mode,
switch (alg)
{
case GC_AES128:
- break;
-
case GC_AES192:
- break;
-
case GC_AES256:
- break;
-
- default:
- return GC_INVALID_CIPHER;
- }
+ switch (mode)
+ {
+ case GC_ECB:
+ case GC_CBC:
+ break;
- switch (mode)
- {
- case GC_CBC:
+ default:
+ rc = GC_INVALID_CIPHER;
+ }
break;
default:
- return GC_INVALID_CIPHER;
+ rc = GC_INVALID_CIPHER;
}
- return GC_OK;
+ if (rc == GC_OK)
+ *outhandle = ctx;
+ else
+ free (ctx);
+
+ return rc;
}
Gc_rc
gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
{
_gc_cipher_ctx *ctx = handle;
- puts("setkey");
+
switch (ctx->alg)
{
case GC_AES128:
@@ -213,12 +215,21 @@ 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]);
+ sprintf (&keyMaterial[2*i], "%02x", key[i] & 0xFF);
- rc = rijndaelMakeKey (&ctx->aesKey, RIJNDAEL_DIR_ENCRYPT,
+ 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;
@@ -232,12 +243,43 @@ gc_cipher_setkey (gc_cipher_handle handle, size_t keylen, const char *key)
Gc_rc
gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
{
- gcry_error_t err;
+ _gc_cipher_ctx *ctx = handle;
- puts("setiv");
- err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
- if (gcry_err_code (err))
- return GC_INVALID_CIPHER;
+ switch (ctx->alg)
+ {
+ case GC_AES128:
+ case GC_AES192:
+ case GC_AES256:
+ switch (ctx->mode)
+ {
+ 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];
+
+ 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;
+
+ default:
+ return GC_INVALID_CIPHER;
+ }
+ break;
+
+ default:
+ return GC_INVALID_CIPHER;
+ }
return GC_OK;
}
@@ -245,10 +287,26 @@ gc_cipher_setiv (gc_cipher_handle handle, size_t ivlen, const char *iv)
Gc_rc
gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
{
- puts("encrypt");
- if (gcry_cipher_encrypt ((gcry_cipher_hd_t) handle,
- data, len, NULL, len) != 0)
- return GC_INVALID_CIPHER;
+ _gc_cipher_ctx *ctx = handle;
+
+ switch (ctx->alg)
+ {
+ case GC_AES128:
+ case GC_AES192:
+ case GC_AES256:
+ {
+ int nblocks;
+
+ nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
+ data, 8 * len, data);
+ if (nblocks < 0)
+ return GC_INVALID_CIPHER;
+ }
+ break;
+
+ default:
+ return GC_INVALID_CIPHER;
+ }
return GC_OK;
}
@@ -256,10 +314,26 @@ gc_cipher_encrypt_inline (gc_cipher_handle handle, size_t len, char *data)
Gc_rc
gc_cipher_decrypt_inline (gc_cipher_handle handle, size_t len, char *data)
{
- puts("decrypt");
- if (gcry_cipher_decrypt ((gcry_cipher_hd_t) handle,
- data, len, NULL, len) != 0)
- return GC_INVALID_CIPHER;
+ _gc_cipher_ctx *ctx = handle;
+
+ switch (ctx->alg)
+ {
+ case GC_AES128:
+ case GC_AES192:
+ case GC_AES256:
+ {
+ int nblocks;
+
+ nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
+ data, 8 * len, data);
+ if (nblocks < 0)
+ return GC_INVALID_CIPHER;
+ }
+ break;
+
+ default:
+ return GC_INVALID_CIPHER;
+ }
return GC_OK;
}
@@ -353,3 +427,123 @@ gc_hmac_sha1 (const void *key, size_t keylen,
return GC_OK;
}
#endif
+
+Gc_rc
+gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
+{
+ int gcryalg, gcrymode;
+ gcry_error_t err;
+
+ switch (hash)
+ {
+ case GC_MD4:
+ gcryalg = GCRY_MD_MD4;
+ break;
+
+ case GC_MD5:
+ gcryalg = GCRY_MD_MD5;
+ break;
+
+ case GC_SHA1:
+ gcryalg = GCRY_MD_SHA1;
+ break;
+
+ case GC_RMD160:
+ gcryalg = GCRY_MD_RMD160;
+ break;
+
+ default:
+ return GC_INVALID_HASH;
+ }
+
+ switch (mode)
+ {
+ case 0:
+ gcrymode = 0;
+ break;
+
+ case GC_HMAC:
+ gcrymode = GCRY_MD_FLAG_HMAC;
+ break;
+
+ default:
+ return GC_INVALID_HASH;
+ }
+
+ err = gcry_md_open ((gcry_md_hd_t *) outhandle, gcryalg, gcrymode);
+ if (gcry_err_code (err))
+ return GC_INVALID_HASH;
+
+ return GC_OK;
+}
+
+Gc_rc
+gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
+{
+ int err;
+
+ err = gcry_md_copy ((gcry_md_hd_t *) outhandle, (gcry_md_hd_t) handle);
+ if (err)
+ return GC_INVALID_HASH;
+
+ return GC_OK;
+}
+
+size_t
+gc_hash_digest_length (Gc_hash hash)
+{
+ int gcryalg;
+
+ switch (hash)
+ {
+ case GC_MD4:
+ gcryalg = GCRY_MD_MD4;
+ break;
+
+ case GC_MD5:
+ gcryalg = GCRY_MD_MD5;
+ break;
+
+ case GC_SHA1:
+ gcryalg = GCRY_MD_SHA1;
+ break;
+
+ case GC_RMD160:
+ gcryalg = GCRY_MD_RMD160;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return gcry_md_get_algo_dlen (gcryalg);
+}
+
+void
+gc_hash_hmac_setkey (gc_hash_handle handle, size_t len, const char *key)
+{
+ gcry_md_setkey ((gcry_md_hd_t) handle, key, len);
+}
+
+void
+gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
+{
+ gcry_md_write ((gcry_md_hd_t) handle, data, len);
+}
+
+const char *
+gc_hash_read (gc_hash_handle handle)
+{
+ const char *digest;
+
+ gcry_md_final ((gcry_md_hd_t) handle);
+ digest = gcry_md_read ((gcry_md_hd_t) handle, 0);
+
+ return digest;
+}
+
+void
+gc_hash_close (gc_hash_handle handle)
+{
+ gcry_md_close ((gcry_md_hd_t) handle);
+}