/* mac-gmac.c  -  GMAC glue for MAC API
 * 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 "cipher.h"
#include "./mac-internal.h"


static int
map_mac_algo_to_cipher (int mac_algo)
{
  switch (mac_algo)
    {
    default:
      return GCRY_CIPHER_NONE;
    case GCRY_MAC_GMAC_AES:
      return GCRY_CIPHER_AES;
    case GCRY_MAC_GMAC_CAMELLIA:
      return GCRY_CIPHER_CAMELLIA128;
    case GCRY_MAC_GMAC_TWOFISH:
      return GCRY_CIPHER_TWOFISH;
    case GCRY_MAC_GMAC_SERPENT:
      return GCRY_CIPHER_SERPENT128;
    case GCRY_MAC_GMAC_SEED:
      return GCRY_CIPHER_SEED;
    }
}


static gcry_err_code_t
gmac_open (gcry_mac_hd_t h)
{
  gcry_err_code_t err;
  gcry_cipher_hd_t hd;
  int secure = (h->magic == CTX_MAGIC_SECURE);
  int cipher_algo;
  unsigned int flags;

  cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
  flags = (secure ? GCRY_CIPHER_SECURE : 0);

  err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_GCM,
                                    flags);
  if (err)
    return err;

  h->u.gmac.cipher_algo = cipher_algo;
  h->u.gmac.ctx = hd;
  return 0;
}


static void
gmac_close (gcry_mac_hd_t h)
{
  _gcry_cipher_close (h->u.gmac.ctx);
  h->u.gmac.ctx = NULL;
}


static gcry_err_code_t
gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
{
  return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen);
}


static gcry_err_code_t
gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
{
  return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen);
}


static gcry_err_code_t
gmac_reset (gcry_mac_hd_t h)
{
  return _gcry_cipher_reset (h->u.gmac.ctx);
}


static gcry_err_code_t
gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
{
  return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen);
}


static gcry_err_code_t
gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
{
  if (*outlen > GCRY_GCM_BLOCK_LEN)
    *outlen = GCRY_GCM_BLOCK_LEN;
  return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen);
}


static gcry_err_code_t
gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
{
  return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen);
}


static unsigned int
gmac_get_maclen (int algo)
{
  (void)algo;
  return GCRY_GCM_BLOCK_LEN;
}


static unsigned int
gmac_get_keylen (int algo)
{
  return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
}


static gcry_mac_spec_ops_t gmac_ops = {
  gmac_open,
  gmac_close,
  gmac_setkey,
  gmac_setiv,
  gmac_reset,
  gmac_write,
  gmac_read,
  gmac_verify,
  gmac_get_maclen,
  gmac_get_keylen
};


#if USE_AES
gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = {
  GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES",
  &gmac_ops
};
#endif
#if USE_TWOFISH
gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish = {
  GCRY_MAC_GMAC_TWOFISH, {0, 0}, "GMAC_TWOFISH",
  &gmac_ops
};
#endif
#if USE_SERPENT
gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent = {
  GCRY_MAC_GMAC_SERPENT, {0, 0}, "GMAC_SERPENT",
  &gmac_ops
};
#endif
#if USE_SEED
gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed = {
  GCRY_MAC_GMAC_SEED, {0, 0}, "GMAC_SEED",
  &gmac_ops
};
#endif
#if USE_CAMELLIA
gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia = {
  GCRY_MAC_GMAC_CAMELLIA, {0, 0}, "GMAC_CAMELLIA",
  &gmac_ops
};
#endif
