/* mac.c  -  message authentication code dispatcher
 * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
 *
 * This file is part of Libgcrypt.
 *
 * Libgcrypt 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 of
 * the License, or (at your option) any later version.
 *
 * Libgcrypt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "g10lib.h"
#include "mac-internal.h"


/* This is the list of the digest implementations included in
   libgcrypt.  */
static gcry_mac_spec_t *mac_list[] = {
#if USE_SHA1
  &_gcry_mac_type_spec_hmac_sha1,
#endif
#if USE_SHA256
  &_gcry_mac_type_spec_hmac_sha256,
  &_gcry_mac_type_spec_hmac_sha224,
#endif
#if USE_SHA512
  &_gcry_mac_type_spec_hmac_sha512,
  &_gcry_mac_type_spec_hmac_sha384,
#endif
#ifdef USE_GOST_R_3411_94
  &_gcry_mac_type_spec_hmac_gost3411_94,
#endif
#ifdef USE_GOST_R_3411_12
  &_gcry_mac_type_spec_hmac_stribog256,
  &_gcry_mac_type_spec_hmac_stribog512,
#endif
#if USE_WHIRLPOOL
  &_gcry_mac_type_spec_hmac_whirlpool,
#endif
#if USE_RMD160
  &_gcry_mac_type_spec_hmac_rmd160,
#endif
#if USE_TIGER
  &_gcry_mac_type_spec_hmac_tiger1,
#endif
#if USE_MD5
  &_gcry_mac_type_spec_hmac_md5,
#endif
#if USE_MD4
  &_gcry_mac_type_spec_hmac_md4,
#endif
#if USE_BLOWFISH
  &_gcry_mac_type_spec_cmac_blowfish,
#endif
#if USE_DES
  &_gcry_mac_type_spec_cmac_tripledes,
#endif
#if USE_CAST5
  &_gcry_mac_type_spec_cmac_cast5,
#endif
#if USE_AES
  &_gcry_mac_type_spec_cmac_aes,
  &_gcry_mac_type_spec_gmac_aes,
#endif
#if USE_TWOFISH
  &_gcry_mac_type_spec_cmac_twofish,
  &_gcry_mac_type_spec_gmac_twofish,
#endif
#if USE_SERPENT
  &_gcry_mac_type_spec_cmac_serpent,
  &_gcry_mac_type_spec_gmac_serpent,
#endif
#if USE_RFC2268
  &_gcry_mac_type_spec_cmac_rfc2268,
#endif
#if USE_SEED
  &_gcry_mac_type_spec_cmac_seed,
  &_gcry_mac_type_spec_gmac_seed,
#endif
#if USE_CAMELLIA
  &_gcry_mac_type_spec_cmac_camellia,
  &_gcry_mac_type_spec_gmac_camellia,
#endif
#ifdef USE_IDEA
  &_gcry_mac_type_spec_cmac_idea,
#endif
#if USE_GOST28147
  &_gcry_mac_type_spec_cmac_gost28147,
#endif
  NULL,
};



/* Return the spec structure for the MAC algorithm ALGO.  For an
   unknown algorithm NULL is returned.  */
static gcry_mac_spec_t *
spec_from_algo (int algo)
{
  gcry_mac_spec_t *spec;
  int idx;

  for (idx = 0; (spec = mac_list[idx]); idx++)
    if (algo == spec->algo)
      return spec;
  return NULL;
}


/* Lookup a mac's spec by its name.  */
static gcry_mac_spec_t *
spec_from_name (const char *name)
{
  gcry_mac_spec_t *spec;
  int idx;

  for (idx = 0; (spec = mac_list[idx]); idx++)
    if (!stricmp (name, spec->name))
      return spec;

  return NULL;
}


/****************
 * Map a string to the mac algo
 */
int
_gcry_mac_map_name (const char *string)
{
  gcry_mac_spec_t *spec;

  if (!string)
    return 0;

  /* Not found, search a matching mac name.  */
  spec = spec_from_name (string);
  if (spec)
    return spec->algo;

  return 0;
}


/****************
 * This function simply returns the name of the algorithm or some constant
 * string when there is no algo.  It will never return NULL.
 * Use the macro gcry_mac_test_algo() to check whether the algorithm
 * is valid.
 */
const char *
_gcry_mac_algo_name (int algorithm)
{
  gcry_mac_spec_t *spec;

  spec = spec_from_algo (algorithm);
  return spec ? spec->name : "?";
}


static gcry_err_code_t
check_mac_algo (int algorithm)
{
  gcry_mac_spec_t *spec;

  spec = spec_from_algo (algorithm);
  if (spec && !spec->flags.disabled)
    return 0;

  return GPG_ERR_MAC_ALGO;
}


/****************
 * Open a message digest handle for use with algorithm ALGO.
 */
static gcry_err_code_t
mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
{
  gcry_mac_spec_t *spec;
  gcry_err_code_t err;
  gcry_mac_hd_t h;

  spec = spec_from_algo (algo);
  if (!spec)
    return GPG_ERR_MAC_ALGO;
  else if (spec->flags.disabled)
    return GPG_ERR_MAC_ALGO;
  else if (!spec->ops)
    return GPG_ERR_MAC_ALGO;
  else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
           !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
    return GPG_ERR_MAC_ALGO;

  if (secure)
    h = xtrycalloc_secure (1, sizeof (*h));
  else
    h = xtrycalloc (1, sizeof (*h));

  if (!h)
    return gpg_err_code_from_syserror ();

  h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
  h->spec = spec;
  h->algo = algo;
  h->gcry_ctx = ctx;

  err = h->spec->ops->open (h);
  if (err)
    xfree (h);
  else
    *hd = h;

  return err;
}


static gcry_error_t
mac_reset (gcry_mac_hd_t hd)
{
  if (hd->spec->ops->reset)
    return hd->spec->ops->reset (hd);

  return 0;
}


static void
mac_close (gcry_mac_hd_t hd)
{
  if (hd->spec->ops->close)
    hd->spec->ops->close (hd);

  wipememory (hd, sizeof (*hd));

  xfree (hd);
}


static gcry_error_t
mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
{
  if (!hd->spec->ops->setkey)
    return GPG_ERR_INV_ARG;
  if (keylen > 0 && !key)
    return GPG_ERR_INV_ARG;

  return hd->spec->ops->setkey (hd, key, keylen);
}


static gcry_error_t
mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
{
  if (!hd->spec->ops->setiv)
    return GPG_ERR_INV_ARG;
  if (ivlen > 0 && !iv)
    return GPG_ERR_INV_ARG;

  return hd->spec->ops->setiv (hd, iv, ivlen);
}


static gcry_error_t
mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
{
  if (!hd->spec->ops->write)
    return GPG_ERR_INV_ARG;
  if (inlen > 0 && !inbuf)
    return GPG_ERR_INV_ARG;

  return hd->spec->ops->write (hd, inbuf, inlen);
}


static gcry_error_t
mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
{
  if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
    return GPG_ERR_INV_ARG;

  return hd->spec->ops->read (hd, outbuf, outlen);
}


static gcry_error_t
mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
{
  if (!buf || buflen == 0 || !hd->spec->ops->verify)
    return GPG_ERR_INV_ARG;

  return hd->spec->ops->verify (hd, buf, buflen);
}


/* Create a MAC object for algorithm ALGO.  FLAGS may be
   given as an bitwise OR of the gcry_mac_flags values.
   H is guaranteed to be a valid handle or NULL on error.  */
gpg_err_code_t
_gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
                gcry_ctx_t ctx)
{
  gcry_err_code_t rc;
  gcry_mac_hd_t hd = NULL;

  if ((flags & ~GCRY_MAC_FLAG_SECURE))
    rc = GPG_ERR_INV_ARG;
  else
    rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);

  *h = rc ? NULL : hd;
  return rc;
}


void
_gcry_mac_close (gcry_mac_hd_t hd)
{
  mac_close (hd);
}


gcry_err_code_t
_gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
{
  return mac_setkey (hd, key, keylen);
}


gcry_err_code_t
_gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
{
  return mac_setiv (hd, iv, ivlen);
}


gcry_err_code_t
_gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
{
  return mac_write (hd, inbuf, inlen);
}


gcry_err_code_t
_gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
{
  return mac_read (hd, outbuf, outlen);
}


gcry_err_code_t
_gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
{
  return mac_verify (hd, buf, buflen);
}


unsigned int
_gcry_mac_get_algo_maclen (int algo)
{
  gcry_mac_spec_t *spec;

  spec = spec_from_algo (algo);
  if (!spec || !spec->ops || !spec->ops->get_maclen)
    return 0;

  return spec->ops->get_maclen (algo);
}


unsigned int
_gcry_mac_get_algo_keylen (int algo)
{
  gcry_mac_spec_t *spec;

  spec = spec_from_algo (algo);
  if (!spec || !spec->ops || !spec->ops->get_keylen)
    return 0;

  return spec->ops->get_keylen (algo);
}


gcry_err_code_t
_gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
{
  gcry_err_code_t rc;

  /* Currently not used.  */
  (void) hd;
  (void) buffer;
  (void) buflen;

  switch (cmd)
    {
    case GCRYCTL_RESET:
      rc = mac_reset (hd);
      break;
    default:
      rc = GPG_ERR_INV_OP;
    }
  return rc;
}


/* Return information about the given MAC algorithm ALGO.

    GCRYCTL_TEST_ALGO:
        Returns 0 if the specified algorithm ALGO is available for use.
        BUFFER and NBYTES must be zero.

   Note: Because this function is in most cases used to return an
   integer value, we can make it easier for the caller to just look at
   the return value.  The caller will in all cases consult the value
   and thereby detecting whether a error occurred or not (i.e. while
   checking the block size)
 */
gcry_err_code_t
_gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
{
  gcry_err_code_t rc = 0;
  unsigned int ui;

  switch (what)
    {
    case GCRYCTL_GET_KEYLEN:
      if (buffer || (!nbytes))
        rc = GPG_ERR_INV_ARG;
      else
        {
          ui = _gcry_mac_get_algo_keylen (algo);
          if (ui > 0)
            *nbytes = (size_t) ui;
          else
            /* The only reason for an error is an invalid algo.  */
            rc = GPG_ERR_MAC_ALGO;
        }
      break;
    case GCRYCTL_TEST_ALGO:
      if (buffer || nbytes)
        rc = GPG_ERR_INV_ARG;
      else
        rc = check_mac_algo (algo);
      break;

    default:
      rc = GPG_ERR_INV_OP;
    }

  return rc;
}
