Add MD2 and hash fixes.
[pspp] / lib / gc-gnulib.c
index 0b70ccebc0a822e1494fc8577df955060d7c3fb9..61143b0de28a286508278285bf9931215e2fb1a2 100644 (file)
@@ -38,6 +38,9 @@
 #include <errno.h>
 
 /* Hashes. */
+#ifdef GC_USE_MD2
+# include "md2.h"
+#endif
 #ifdef GC_USE_MD4
 # include "md4.h"
 #endif
@@ -537,11 +540,233 @@ gc_cipher_close (gc_cipher_handle handle)
 
 /* Hashes. */
 
+#define MAX_DIGEST_SIZE 20
+
+typedef struct _gc_hash_ctx {
+  Gc_hash alg;
+  Gc_hash_mode mode;
+  char hash[MAX_DIGEST_SIZE];
+#ifdef GC_USE_MD2
+  struct md2_ctx md2Context;
+#endif
+#ifdef GC_USE_MD4
+  struct md4_ctx md4Context;
+#endif
+#ifdef GC_USE_MD5
+  struct md5_ctx md5Context;
+#endif
+#ifdef GC_USE_SHA1
+  struct sha1_ctx sha1Context;
+#endif
+} _gc_hash_ctx;
+
+Gc_rc
+gc_hash_open (Gc_hash hash, Gc_hash_mode mode, gc_hash_handle * outhandle)
+{
+  _gc_hash_ctx *ctx;
+  Gc_rc rc = GC_OK;
+
+  ctx = calloc (sizeof (*ctx), 1);
+
+  ctx->alg = hash;
+  ctx->mode = mode;
+
+  switch (hash)
+    {
+#ifdef GC_USE_MD2
+    case GC_MD2:
+      md2_init_ctx (&ctx->md2Context);
+      break;
+#endif
+
+#ifdef GC_USE_MD4
+    case GC_MD4:
+      md4_init_ctx (&ctx->md4Context);
+      break;
+#endif
+
+#ifdef GC_USE_MD5
+    case GC_MD5:
+      md5_init_ctx (&ctx->md5Context);
+      break;
+#endif
+
+#ifdef GC_USE_SHA1
+    case GC_SHA1:
+      sha1_init_ctx (&ctx->sha1Context);
+      break;
+#endif
+
+    default:
+      rc = GC_INVALID_HASH;
+      break;
+    }
+
+  switch (mode)
+    {
+    case 0:
+      break;
+
+    default:
+      rc = GC_INVALID_HASH;
+      break;
+    }
+
+  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;
+
+  *outhandle = out = calloc (sizeof (*out), 1);
+  if (!out)
+    return GC_MALLOC_ERROR;
+
+  memcpy (out, in, sizeof (*out));
+
+  return GC_OK;
+}
+
+size_t
+gc_hash_digest_length (Gc_hash hash)
+{
+  size_t len;
+
+  switch (hash)
+    {
+    case GC_MD2:
+      len = GC_MD2_DIGEST_SIZE;
+      break;
+
+    case GC_MD4:
+      len = GC_MD4_DIGEST_SIZE;
+      break;
+
+    case GC_MD5:
+      len = GC_MD5_DIGEST_SIZE;
+      break;
+
+    case GC_RMD160:
+      len = GC_RMD160_DIGEST_SIZE;
+      break;
+
+    case GC_SHA1:
+      len = GC_SHA1_DIGEST_SIZE;
+      break;
+
+    default:
+      return 0;
+    }
+
+  return len;
+}
+
+void
+gc_hash_write (gc_hash_handle handle, size_t len, const char *data)
+{
+  _gc_hash_ctx *ctx = handle;
+
+  switch (ctx->alg)
+    {
+#ifdef GC_USE_MD2
+    case GC_MD2:
+      md2_process_bytes (data, len, &ctx->md2Context);
+      break;
+#endif
+
+#ifdef GC_USE_MD4
+    case GC_MD4:
+      md4_process_bytes (data, len, &ctx->md4Context);
+      break;
+#endif
+
+#ifdef GC_USE_MD5
+    case GC_MD5:
+      md5_process_bytes (data, len, &ctx->md5Context);
+      break;
+#endif
+
+#ifdef GC_USE_SHA1
+    case GC_SHA1:
+      sha1_process_bytes (data, len, &ctx->sha1Context);
+      break;
+#endif
+
+    default:
+      break;
+    }
+}
+
+const char *
+gc_hash_read (gc_hash_handle handle)
+{
+  _gc_hash_ctx *ctx = handle;
+  const char *ret = NULL;
+
+  switch (ctx->alg)
+    {
+#ifdef GC_USE_MD2
+    case GC_MD2:
+      md2_finish_ctx (&ctx->md2Context, ctx->hash);
+      ret = ctx->hash;
+      break;
+#endif
+
+#ifdef GC_USE_MD4
+    case GC_MD4:
+      md4_finish_ctx (&ctx->md4Context, ctx->hash);
+      ret = ctx->hash;
+      break;
+#endif
+
+#ifdef GC_USE_MD5
+    case GC_MD5:
+      md5_finish_ctx (&ctx->md5Context, ctx->hash);
+      ret = ctx->hash;
+      break;
+#endif
+
+#ifdef GC_USE_SHA1
+    case GC_SHA1:
+      sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
+      ret = ctx->hash;
+      break;
+#endif
+
+    default:
+      return NULL;
+    }
+
+  return ret;
+}
+
+void
+gc_hash_close (gc_hash_handle handle)
+{
+  _gc_hash_ctx *ctx = handle;
+
+  free (ctx);
+}
+
 Gc_rc
 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);
+      break;
+#endif
+
 #ifdef GC_USE_MD4
     case GC_MD4:
       md4_buffer (in, inlen, resbuf);
@@ -567,6 +792,15 @@ gc_hash_buffer (Gc_hash hash, const void *in, size_t inlen, char *resbuf)
   return GC_OK;
 }
 
+#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)