#include "libpgp5.h"

/*-------------------------*/
/* hashes */
#include <md5.h>
#include <sha.h>

#ifdef RIPEMD
/* ripe-md - Note: there are symbol collisions */
#define BIGNUM XBIGNUMX
#include "ripemd.h"
#endif

#ifdef USEHAVAL
#include "haval.h"
#endif

void hashinit(int ha, void *ctx)
{
  switch (ha) {
  case 1:
    MD5_Init(ctx);
    break;
  case 2:
    SHA1_Init(ctx);
    break;
#ifdef RIPEMD
  case 3:
    ripemd160Initial(ctx);
    break;
#endif
#ifdef USEHAVAL
  case 4:
    haval_start(ctx);
    break;
#endif
  default:
    exit(-1);
  }
}

void hashupdate(int ha, void *ctx, unsigned char *buf, unsigned int len)
{
  switch (ha) {
  case 1:
    MD5_Update(ctx, buf, len);
    break;
  case 2:
    SHA1_Update(ctx, buf, len);
    break;
#ifdef RIPEMD
  case 3:
    ripemd160Update(ctx, buf, len);
    break;
#endif
#ifdef USEHAVAL
  case 4:
    haval_hash(ctx, buf, len);
    break;
#endif
  default:
    exit(-1);
  }
}

void hashfinal(int ha, unsigned char *buf, void *ctx)
{
  switch (ha) {
  case 1:
    MD5_Final(buf, ctx);
    break;
  case 2:
    SHA1_Final(buf, ctx);
    break;
#ifdef RIPEMD
  case 3:
    {
      RIPEMD160_INFO *ripctx = ctx;
      int i;

      ripemd160Final(ripctx);
      for (i = 0; i < 5; i++) {
        *buf++ = ripctx->digest[i];
        *buf++ = ripctx->digest[i] >> 8;
        *buf++ = ripctx->digest[i] >> 16;
        *buf++ = ripctx->digest[i] >> 24;
      }
    }
    break;
#endif
#ifdef USEHAVAL
  case 4:
    haval_end(ctx, buf);
    break;
#endif
  default:
    exit(-1);
  }
}

unsigned int hashlen[] =
{0, 16, 20, 20, 20};

unsigned int hashDERlen[] =
{0, 18, 15, 15, 0};

unsigned char hashDER[][64] =
{
  {0},
  {0x30, 0x20, 0x30, 12, 6, 8, 42,
   0x86, 0x48, 0x86, 0xF7, 0x0D, 2, 5, 5, 0, 4, 16},
  {0x30, 0x21, 0x30, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20},
  {0x30, 0x21, 0x30, 9, 6, 5, 43, 36, 3, 2, 1, 5, 0, 4, 20},
  /* HAVAL, totally made up - len above is zero */
  {0x30, 0x21, 0x30, 9, 6, 5, 43, 99, 3, 2, 1, 5, 0, 4, 20},
};
