/*
 * Cryptographic API.
 *
 * MD5 Message Digest Algorithm (RFC1321).
 *
 * Derived from cryptoapi implementation, originally based on the
 * public domain implementation written by Colin Plumb in 1993.
 *
 * Copyright (c) Cryptoapi developers.
 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 */
#include <crypto/internal/hash.h>
#include <crypto/md5.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/cryptohash.h>
#include <asm/byteorder.h>

/* XXX: this stuff can be optimized */
static inline void le32_to_cpu_array(u32* buf, unsigned int words) {
  while (words--) {
    __le32_to_cpus(buf);
    buf++;
  }
}

static inline void cpu_to_le32_array(u32* buf, unsigned int words) {
  while (words--) {
    __cpu_to_le32s(buf);
    buf++;
  }
}

static inline void md5_transform_helper(struct md5_state* ctx) {
  le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
  md5_transform(ctx->hash, ctx->block);
}

static int md5_init(struct shash_desc* desc) {
  struct md5_state* mctx = shash_desc_ctx(desc);

  mctx->hash[0] = 0x67452301;
  mctx->hash[1] = 0xefcdab89;
  mctx->hash[2] = 0x98badcfe;
  mctx->hash[3] = 0x10325476;
  mctx->byte_count = 0;

  return 0;
}

static int md5_update(struct shash_desc* desc,
                      const u8* data,
                      unsigned int len) {
  struct md5_state* mctx = shash_desc_ctx(desc);
  const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);

  mctx->byte_count += len;

  if (avail > len) {
    memcpy((char*)mctx->block + (sizeof(mctx->block) - avail), data, len);
    return 0;
  }

  memcpy((char*)mctx->block + (sizeof(mctx->block) - avail), data, avail);

  md5_transform_helper(mctx);
  data += avail;
  len -= avail;

  while (len >= sizeof(mctx->block)) {
    memcpy(mctx->block, data, sizeof(mctx->block));
    md5_transform_helper(mctx);
    data += sizeof(mctx->block);
    len -= sizeof(mctx->block);
  }

  memcpy(mctx->block, data, len);

  return 0;
}

static int md5_final(struct shash_desc* desc, u8* out) {
  struct md5_state* mctx = shash_desc_ctx(desc);
  const unsigned int offset = mctx->byte_count & 0x3f;
  char* p = (char*)mctx->block + offset;
  int padding = 56 - (offset + 1);

  *p++ = 0x80;
  if (padding < 0) {
    memset(p, 0x00, padding + sizeof(u64));
    md5_transform_helper(mctx);
    p = (char*)mctx->block;
    padding = 56;
  }

  memset(p, 0, padding);
  mctx->block[14] = mctx->byte_count << 3;
  mctx->block[15] = mctx->byte_count >> 29;
  le32_to_cpu_array(mctx->block,
                    (sizeof(mctx->block) - sizeof(u64)) / sizeof(u32));
  md5_transform(mctx->hash, mctx->block);
  cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
  memcpy(out, mctx->hash, sizeof(mctx->hash));
  memset(mctx, 0, sizeof(*mctx));

  return 0;
}

static int md5_export(struct shash_desc* desc, void* out) {
  struct md5_state* ctx = shash_desc_ctx(desc);

  memcpy(out, ctx, sizeof(*ctx));
  return 0;
}

static int md5_import(struct shash_desc* desc, const void* in) {
  struct md5_state* ctx = shash_desc_ctx(desc);

  memcpy(ctx, in, sizeof(*ctx));
  return 0;
}

static struct shash_alg alg = {.digestsize = MD5_DIGEST_SIZE,
                               .init = md5_init,
                               .update = md5_update,
                               .final = md5_final,
                               .export = md5_export,
                               .import = md5_import,
                               .descsize = sizeof(struct md5_state),
                               .statesize = sizeof(struct md5_state),
                               .base = {
                                   .cra_name = "md5",
                                   .cra_flags = CRYPTO_ALG_TYPE_SHASH,
                                   .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
                                   .cra_module = NULL,
                               }};

static int __init md5_mod_init(void) {
  return crypto_register_shash(&alg);
}

static void __exit md5_mod_fini(void) {
  crypto_unregister_shash(&alg);
}

module_init(md5_mod_init);
module_exit(md5_mod_fini);
