/*
 * AFsplitter - Anti forensic information splitter
 * Copyright 2004, Clemens Fruhwirth <clemens@endorphin.org>
 *
 * AFsplitter diffuses information over a large stripe of data,
 * therefor supporting secure data destruction.
 *
 *  This program is grub_free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the grub_free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License
 *  along with this program; if not, write to the grub_free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <grub/crypto.h>
#include <grub/mm.h>
#include <grub/misc.h>

gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
			  grub_uint8_t * dst, grub_size_t blocksize,
			  grub_size_t blocknumbers);

static void
diffuse (const gcry_md_spec_t * hash, grub_uint8_t * src,
	 grub_uint8_t * dst, grub_size_t size)
{
  grub_size_t i;
  grub_uint32_t IV;		/* host byte order independend hash IV */

  grub_size_t fullblocks = size / hash->mdlen;
  int padding = size % hash->mdlen;
  grub_uint8_t final[hash->mdlen];
  grub_uint8_t temp[sizeof (IV) + hash->mdlen];

  /* hash block the whole data set with different IVs to produce
   * more than just a single data block
   */
  for (i = 0; i < fullblocks; i++)
    {
      IV = grub_cpu_to_be32 (i);
      grub_memcpy (temp, &IV, sizeof (IV));
      grub_memcpy (temp + sizeof (IV), src + hash->mdlen * i, hash->mdlen);
      grub_crypto_hash (hash, dst + hash->mdlen * i, temp,
			sizeof (IV) + hash->mdlen);
    }

  if (padding)
    {
      IV = grub_cpu_to_be32 (i);
      grub_memcpy (temp, &IV, sizeof (IV));
      grub_memcpy (temp + sizeof (IV), src + hash->mdlen * i, padding);
      grub_crypto_hash (hash, final, temp, sizeof (IV) + padding);
      grub_memcpy (dst + hash->mdlen * i, final, padding);
    }
}

/**
 * Merges the splitted master key stored on disk into the original key
 */
gcry_err_code_t
AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_uint8_t * dst,
	  grub_size_t blocksize, grub_size_t blocknumbers)
{
  grub_size_t i;
  grub_uint8_t *bufblock;

  bufblock = grub_zalloc (blocksize);
  if (bufblock == NULL)
    return GPG_ERR_OUT_OF_MEMORY;

  grub_memset (bufblock, 0, blocksize);
  for (i = 0; i < blocknumbers - 1; i++)
    {
      grub_crypto_xor (bufblock, src + (blocksize * i), bufblock, blocksize);
      diffuse (hash, bufblock, bufblock, blocksize);
    }
  grub_crypto_xor (dst, src + (i * blocksize), bufblock, blocksize);

  grub_free (bufblock);
  return GPG_ERR_NO_ERROR;
}
