/* ghmac.h - data hashing functions
 *
 * Copyright (C) 2011  Collabora Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Stef Walter <stefw@collabora.co.uk>
 */

#include "config.h"

#include <string.h>

#include "ghmac.h"

#include "glib/galloca.h"
#include "gatomic.h"
#include "gmem.h"
#include "gstrfuncs.h"
#include "gtestutils.h"
#include "gtypes.h"
#include "glibintl.h"


/**
 * SECTION:hmac
 * @title: Secure HMAC Digests
 * @short_description: Computes the HMAC for data
 *
 * HMACs should be used when producing a cookie or hash based on data
 * and a key. Simple mechanisms for using SHA1 and other algorithms to
 * digest a key and data together are vulnerable to various security
 * issues. <ulink url="http://en.wikipedia.org/wiki/HMAC">HMAC</ulink>
 * uses algorithms like SHA1 in a secure way to produce a digest of a
 * key and data.
 *
 * Both the key and data are arbitrary byte arrays of bytes or characters.
 *
 * Support for HMAC Digests has been added in GLib 2.30.
 */

struct _GHmac
{
  int ref_count;
  GChecksumType digest_type;
  GChecksum *digesti;
  GChecksum *digesto;
};

/**
 * g_hmac_new:
 * @digest_type: the desired type of digest
 * @key: (array length=key_len): the key for the HMAC
 * @key_len: the length of the keys
 *
 * Creates a new #GHmac, using the digest algorithm @digest_type.
 * If the @digest_type is not known, %NULL is returned.
 * A #GHmac can be used to compute the HMAC of a key and an
 * arbitrary binary blob, using different hashing algorithms.
 *
 * A #GHmac works by feeding a binary blob through g_hmac_update()
 * until the data is complete; the digest can then be extracted
 * using g_hmac_get_string(), which will return the checksum as a
 * hexadecimal string; or g_hmac_get_digest(), which will return a
 * array of raw bytes. Once either g_hmac_get_string() or
 * g_hmac_get_digest() have been called on a #GHmac, the HMAC
 * will be closed and it won't be possible to call g_hmac_update()
 * on it anymore.
 *
 * Return value: the newly created #GHmac, or %NULL.
 *   Use g_hmac_unref() to free the memory allocated by it.
 *
 * Since: 2.30
 */
GHmac *
g_hmac_new (GChecksumType  digest_type,
            const guchar  *key,
            gsize          key_len)
{
  GChecksum *checksum;
  GHmac *hmac;
  guchar *buffer;
  guchar *pad;
  gsize i, len;
  gsize block_size;

  checksum = g_checksum_new (digest_type);
  g_return_val_if_fail (checksum != NULL, NULL);

  switch (digest_type)
    {
    case G_CHECKSUM_MD5:
    case G_CHECKSUM_SHA1:
      block_size = 64; /* RFC 2104 */
      break;
    case G_CHECKSUM_SHA256:
      block_size = 64; /* RFC draft-kelly-ipsec-ciph-sha2-01 */
      break;
    default:
      g_return_val_if_reached (NULL);
    }

  hmac = g_slice_new0 (GHmac);
  hmac->ref_count = 1;
  hmac->digest_type = digest_type;
  hmac->digesti = checksum;
  hmac->digesto = g_checksum_new (digest_type);

  buffer = g_alloca (block_size);
  pad = g_alloca (block_size);

  memset (buffer, 0, block_size);

  /* If the key is too long, hash it */
  if (key_len > block_size)
    {
      len = block_size;
      g_checksum_update (hmac->digesti, key, key_len);
      g_checksum_get_digest (hmac->digesti, buffer, &len);
      g_checksum_reset (hmac->digesti);
    }

  /* Otherwise pad it with zeros */
  else
    {
      memcpy (buffer, key, key_len);
    }

  /* First pad */
  for (i = 0; i < block_size; i++)
    pad[i] = 0x36 ^ buffer[i]; /* ipad value */
  g_checksum_update (hmac->digesti, pad, block_size);

  /* Second pad */
  for (i = 0; i < block_size; i++)
    pad[i] = 0x5c ^ buffer[i]; /* opad value */
  g_checksum_update (hmac->digesto, pad, block_size);

  return hmac;
}

/**
 * g_hmac_copy:
 * @hmac: the #GHmac to copy
 *
 * Copies a #GHmac. If @hmac has been closed, by calling
 * g_hmac_get_string() or g_hmac_get_digest(), the copied
 * HMAC will be closed as well.
 *
 * Return value: the copy of the passed #GHmac. Use g_hmac_unref()
 *   when finished using it.
 *
 * Since: 2.30
 */
GHmac *
g_hmac_copy (const GHmac *hmac)
{
  GHmac *copy;

  g_return_val_if_fail (hmac != NULL, NULL);

  copy = g_slice_new (GHmac);
  copy->digest_type = hmac->digest_type;
  copy->digesti = g_checksum_copy (hmac->digesti);
  copy->digesto = g_checksum_copy (hmac->digesto);

  return copy;
}

/**
 * g_hmac_ref:
 * @hmac: a valid #GHmac
 *
 * Atomically increments the reference count of @hmac by one.
 *
 * This function is MT-safe and may be called from any thread.
 *
 * Return value: the passed in #GHmac.
 *
 * Since: 2.30
 **/
GHmac *
g_hmac_ref (GHmac *hmac)
{
  g_return_val_if_fail (hmac != NULL, NULL);

  g_atomic_int_inc (&hmac->ref_count);

  return hmac;
}

/**
 * g_hmac_unref:
 * @hmac: a #GHmac
 *
 * Atomically decrements the reference count of @hmac by one.
 *
 * If the reference count drops to 0, all keys and values will be
 * destroyed, and all memory allocated by the hash table is released.
 * This function is MT-safe and may be called from any thread.
 * Frees the memory allocated for @hmac.
 *
 * Since: 2.30
 */
void
g_hmac_unref (GHmac *hmac)
{
  g_return_if_fail (hmac != NULL);

  if (g_atomic_int_dec_and_test (&hmac->ref_count))
    {
      g_checksum_free (hmac->digesti);
      g_checksum_free (hmac->digesto);
      g_slice_free (GHmac, hmac);
    }
}

/**
 * g_hmac_update:
 * @hmac: a #GHmac
 * @data: (array length=length): buffer used to compute the checksum
 * @length: size of the buffer, or -1 if it is a nul-terminated string
 *
 * Feeds @data into an existing #GHmac.
 *
 * The HMAC must still be open, that is g_hmac_get_string() or
 * g_hmac_get_digest() must not have been called on @hmac.
 *
 * Since: 2.30
 */
void
g_hmac_update (GHmac        *hmac,
               const guchar *data,
               gssize        length)
{
  g_return_if_fail (hmac != NULL);
  g_return_if_fail (length == 0 || data != NULL);

  g_checksum_update (hmac->digesti, data, length);
}

/**
 * g_hmac_get_string:
 * @hmac: a #GHmac
 *
 * Gets the HMAC as an hexadecimal string.
 *
 * Once this function has been called the #GHmac can no longer be
 * updated with g_hmac_update().
 *
 * The hexadecimal characters will be lower case.
 *
 * Return value: the hexadecimal representation of the HMAC. The
 *   returned string is owned by the HMAC and should not be modified
 *   or freed.
 *
 * Since: 2.30
 */
const gchar *
g_hmac_get_string (GHmac *hmac)
{
  guint8 *buffer;
  gsize digest_len;

  g_return_val_if_fail (hmac != NULL, NULL);

  digest_len = g_checksum_type_get_length (hmac->digest_type);
  buffer = g_malloc (digest_len);

  g_hmac_get_digest (hmac, buffer, &digest_len);
  return g_checksum_get_string (hmac->digesto);
}

/**
 * g_hmac_get_digest:
 * @hmac: a #GHmac
 * @buffer: output buffer
 * @digest_len: an inout parameter. The caller initializes it to the
 *   size of @buffer. After the call it contains the length of the digest
 *
 * Gets the digest from @checksum as a raw binary array and places it
 * into @buffer. The size of the digest depends on the type of checksum.
 *
 * Once this function has been called, the #GHmac is closed and can
 * no longer be updated with g_checksum_update().
 *
 * Since: 2.30
 */
void
g_hmac_get_digest (GHmac  *hmac,
                   guint8 *buffer,
                   gsize  *digest_len)
{
  gsize len;

  g_return_if_fail (hmac != NULL);

  len = g_checksum_type_get_length (hmac->digest_type);
  g_return_if_fail (*digest_len >= len);

  /* Use the same buffer, because we can :) */
  g_checksum_get_digest (hmac->digesti, buffer, &len);
  g_checksum_update (hmac->digesto, buffer, len);
  g_checksum_get_digest (hmac->digesto, buffer, digest_len);
}

/**
 * g_compute_hmac_for_data:
 * @digest_type: a #GChecksumType to use for the HMAC
 * @key: (array length=key_len): the key to use in the HMAC
 * @key_len: the length of the key
 * @data: binary blob to compute the HMAC of
 * @length: length of @data
 *
 * Computes the HMAC for a binary @data of @length. This is a
 * convenience wrapper for g_hmac_new(), g_hmac_get_string()
 * and g_hmac_unref().
 *
 * The hexadecimal string returned will be in lower case.
 *
 * Return value: the HMAC of the binary data as a string in hexadecimal.
 *   The returned string should be freed with g_free() when done using it.
 *
 * Since: 2.30
 */
gchar *
g_compute_hmac_for_data (GChecksumType  digest_type,
                         const guchar  *key,
                         gsize          key_len,
                         const guchar  *data,
                         gsize          length)
{
  GHmac *hmac;
  gchar *retval;

  g_return_val_if_fail (length == 0 || data != NULL, NULL);

  hmac = g_hmac_new (digest_type, key, key_len);
  if (!hmac)
    return NULL;

  g_hmac_update (hmac, data, length);
  retval = g_strdup (g_hmac_get_string (hmac));
  g_hmac_unref (hmac);

  return retval;
}

/**
 * g_compute_hmac_for_string:
 * @digest_type: a #GChecksumType to use for the HMAC
 * @key: (array length=key_len): the key to use in the HMAC
 * @key_len: the length of the key
 * @str: the string to compute the HMAC for
 * @length: the length of the string, or -1 if the string is nul-terminated
 *
 * Computes the HMAC for a string.
 *
 * The hexadecimal string returned will be in lower case.
 *
 * Return value: the HMAC as a hexadecimal string.
 *     The returned string should be freed with g_free()
 *     when done using it.
 *
 * Since: 2.30
 */
gchar *
g_compute_hmac_for_string (GChecksumType  digest_type,
                           const guchar  *key,
                           gsize          key_len,
                           const gchar   *str,
                           gssize         length)
{
  g_return_val_if_fail (length == 0 || str != NULL, NULL);

  if (length < 0)
    length = strlen (str);

  return g_compute_hmac_for_data (digest_type, key, key_len,
                                  (const guchar *) str, length);
}
