summaryrefslogtreecommitdiff
path: root/lib/gc-libgcrypt.c
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2005-10-28 12:09:31 +0000
committerSimon Josefsson <simon@josefsson.org>2005-10-28 12:09:31 +0000
commitc5d8261e0e5c4675b6238af2f25cad968b94d8c8 (patch)
treed0e8fe75c5c4a7ffb72a1afb2c6b28d716286ba2 /lib/gc-libgcrypt.c
parent8df4dfe1cb7f07141fcaeccfc5a1fa93e0c76303 (diff)
downloadgnulib-c5d8261e0e5c4675b6238af2f25cad968b94d8c8.tar.gz
Add MD2 and hash fixes.
Diffstat (limited to 'lib/gc-libgcrypt.c')
-rw-r--r--lib/gc-libgcrypt.c137
1 files changed, 116 insertions, 21 deletions
diff --git a/lib/gc-libgcrypt.c b/lib/gc-libgcrypt.c
index 9272c19f41..bc0d12bbaf 100644
--- a/lib/gc-libgcrypt.c
+++ b/lib/gc-libgcrypt.c
@@ -27,8 +27,14 @@
/* Get prototype. */
#include "gc.h"
+#include <stdlib.h>
+#include <string.h>
+
/* Get libgcrypt API. */
#include <gcrypt.h>
+#ifdef GC_USE_MD2
+# include "md2.h"
+#endif
#include <assert.h>
@@ -218,14 +224,35 @@ gc_cipher_close (gc_cipher_handle handle)
/* Hashes. */
+typedef struct _gc_hash_ctx {
+ Gc_hash alg;
+ Gc_hash_mode mode;
+ gcry_md_hd_t gch;
+#ifdef GC_USE_MD2
+ char hash[GC_MD2_DIGEST_SIZE];
+ struct md2_ctx md2Context;
+#endif
+} _gc_hash_ctx;
+
Gc_rc
gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
{
+ _gc_hash_ctx *ctx;
int gcryalg, gcrymode;
gcry_error_t err;
+ Gc_rc rc = GC_OK;
+
+ ctx = calloc (sizeof (*ctx), 1);
+
+ ctx->alg = hash;
+ ctx->mode = mode;
switch (hash)
{
+ case GC_MD2:
+ gcryalg = GCRY_MD_NONE;
+ break;
+
case GC_MD4:
gcryalg = GCRY_MD_MD4;
break;
@@ -243,7 +270,7 @@ gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
break;
default:
- return GC_INVALID_HASH;
+ rc = GC_INVALID_HASH;
}
switch (mode)
@@ -257,24 +284,43 @@ gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
break;
default:
- return GC_INVALID_HASH;
+ rc = GC_INVALID_HASH;
}
- err = gcry_md_open ((gcry_md_hd_t *) outhandle, gcryalg, gcrymode);
- if (gcry_err_code (err))
- return GC_INVALID_HASH;
+ if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
+ {
+ err = gcry_md_open (&ctx->gch, gcryalg, gcrymode);
+ if (gcry_err_code (err))
+ rc = GC_INVALID_HASH;
+ }
- return GC_OK;
+ if (rc == GC_OK)
+ *outhandle = ctx;
+ else
+ free (ctx);
+
+ return rc;
}
Gc_rc
gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
{
+ _gc_hash_ctx *in = handle;
+ _gc_hash_ctx *out;
int err;
- err = gcry_md_copy ((gcry_md_hd_t *) outhandle, (gcry_md_hd_t) handle);
+ *outhandle = out = calloc (sizeof (*out), 1);
+ if (!out)
+ return GC_MALLOC_ERROR;
+
+ memcpy (out, in, sizeof (*out));
+
+ err = gcry_md_copy (&out->gch, in->gch);
if (err)
- return GC_INVALID_HASH;
+ {
+ free (out);
+ return GC_INVALID_HASH;
+ }
return GC_OK;
}
@@ -282,52 +328,78 @@ gc_hash_clone (gc_hash_handle handle, gc_hash_handle * outhandle)
size_t
gc_hash_digest_length (Gc_hash hash)
{
- int gcryalg;
+ size_t len;
switch (hash)
{
+ case GC_MD2:
+ len = GC_MD2_DIGEST_SIZE;
+ break;
+
case GC_MD4:
- gcryalg = GCRY_MD_MD4;
+ len = GC_MD4_DIGEST_SIZE;
break;
case GC_MD5:
- gcryalg = GCRY_MD_MD5;
+ len = GC_MD5_DIGEST_SIZE;
break;
- case GC_SHA1:
- gcryalg = GCRY_MD_SHA1;
+ case GC_RMD160:
+ len = GC_RMD160_DIGEST_SIZE;
break;
- case GC_RMD160:
- gcryalg = GCRY_MD_RMD160;
+ case GC_SHA1:
+ len = GC_SHA1_DIGEST_SIZE;
break;
default:
return 0;
}
- return gcry_md_get_algo_dlen (gcryalg);
+ return len;
}
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);
+ _gc_hash_ctx *ctx = handle;
+#ifdef GC_USE_MD2
+ if (ctx->alg != GC_MD2)
+#endif
+ gcry_md_setkey (ctx->gch, 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);
+ _gc_hash_ctx *ctx = handle;
+
+#ifdef GC_USE_MD2
+ if (ctx->alg == GC_MD2)
+ md2_process_bytes (data, len, &ctx->md2Context);
+ else
+#endif
+ gcry_md_write (ctx->gch, data, len);
}
const char *
gc_hash_read (gc_hash_handle handle)
{
+ _gc_hash_ctx *ctx = handle;
const char *digest;
- gcry_md_final ((gcry_md_hd_t) handle);
- digest = gcry_md_read ((gcry_md_hd_t) handle, 0);
+#ifdef GC_USE_MD2
+ if (ctx->alg == GC_MD2)
+ {
+ md2_finish_ctx (&ctx->md2Context, ctx->hash);
+ digest = ctx->hash;
+ }
+ else
+#endif
+ {
+ gcry_md_final (ctx->gch);
+ digest = gcry_md_read (ctx->gch, 0);
+ }
return digest;
}
@@ -335,7 +407,14 @@ gc_hash_read (gc_hash_handle handle)
void
gc_hash_close (gc_hash_handle handle)
{
- gcry_md_close ((gcry_md_hd_t) handle);
+ _gc_hash_ctx *ctx = handle;
+
+#ifdef GC_USE_MD2
+ if (ctx->alg != GC_MD2)
+#endif
+ gcry_md_close (ctx->gch);
+
+ free (ctx);
}
Gc_rc
@@ -345,6 +424,13 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
switch (hash)
{
+#ifdef GC_USE_MD2
+ case GC_MD2:
+ md2_buffer (in, inlen, resbuf);
+ return GC_OK;
+ break;
+#endif
+
#ifdef GC_USE_MD4
case GC_MD4:
gcryalg = GCRY_MD_MD4;
@@ -380,6 +466,15 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
/* One-call interface. */
+#ifdef GC_USE_MD2
+Gc_rc
+gc_md2 (const void *in, size_t inlen, void *resbuf)
+{
+ md2_buffer (in, inlen, resbuf);
+ return GC_OK;
+}
+#endif
+
#ifdef GC_USE_MD4
Gc_rc
gc_md4 (const void *in, size_t inlen, void *resbuf)