/* scrypt.c - Scrypt password-based key derivation function.
 * Copyright (C) 2012 Simon Josefsson
 * Copyright (C) 2013 Christian Grothoff
 * Copyright (C) 2013 g10 Code GmbH
 *
 * 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/>.
 */

/* Adapted from the nettle, low-level cryptographics library for
 * libgcrypt by Christian Grothoff; original license:
 *
 * Copyright (C) 2012 Simon Josefsson
 *
 * The nettle library 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.
 *
 * The nettle 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 Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the nettle library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02111-1301, USA.
 */

#include <config.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "g10lib.h"
#include "kdf-internal.h"
#include "bufhelp.h"

/* We really need a 64 bit type for this code.  */
#ifdef HAVE_U64_TYPEDEF

#define SALSA20_INPUT_LENGTH 16

#define ROTL32(n,x) (((x)<<(n)) | ((x)>>(32-(n))))


/* Reads a 64-bit integer, in network, big-endian, byte order */
#define READ_UINT64(p) buf_get_be64(p)


/* And the other, little-endian, byteorder */
#define LE_READ_UINT64(p) buf_get_le64(p)

#define LE_SWAP32(v) le_bswap32(v)


#define QROUND(x0, x1, x2, x3) do { \
  x1 ^= ROTL32(7, x0 + x3);	    \
  x2 ^= ROTL32(9, x1 + x0);	    \
  x3 ^= ROTL32(13, x2 + x1);	    \
  x0 ^= ROTL32(18, x3 + x2);	    \
  } while(0)


static void
_salsa20_core(u32 *dst, const u32 *src, unsigned rounds)
{
  u32 x[SALSA20_INPUT_LENGTH];
  unsigned i;

  assert ( (rounds & 1) == 0);

  for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
    x[i] = LE_SWAP32(src[i]);

  for (i = 0; i < rounds;i += 2)
    {
      QROUND(x[0], x[4], x[8], x[12]);
      QROUND(x[5], x[9], x[13], x[1]);
      QROUND(x[10], x[14], x[2], x[6]);
      QROUND(x[15], x[3], x[7], x[11]);

      QROUND(x[0], x[1], x[2], x[3]);
      QROUND(x[5], x[6], x[7], x[4]);
      QROUND(x[10], x[11], x[8], x[9]);
      QROUND(x[15], x[12], x[13], x[14]);
    }

  for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
    {
      u32 t = x[i] + LE_SWAP32(src[i]);
      dst[i] = LE_SWAP32(t);
    }
}


static void
_scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2)
{
  u64 i;
  unsigned char *X = tmp2;
  unsigned char *Y = tmp2 + 64;

#if 0
  if (r == 1)
    {
      for (i = 0; i < 2 * r; i++)
        {
          size_t j;
          printf ("B[%d] = ", (int)i);
          for (j = 0; j < 64; j++)
            {
              if (j && !(j % 16))
                printf ("\n       ");
              printf (" %02x", B[i * 64 + j]);
            }
          putchar ('\n');
        }
    }
#endif

  /* X = B[2 * r - 1] */
  memcpy (X, &B[(2 * r - 1) * 64], 64);

  /* for i = 0 to 2 * r - 1 do */
  for (i = 0; i <= 2 * r - 1; i++)
    {
      /* T = X xor B[i] */
      buf_xor(X, X, &B[i * 64], 64);

      /* X = Salsa (T) */
      _salsa20_core ((u32*)X, (u32*)X, 8);

      /* Y[i] = X */
      memcpy (&Y[i * 64], X, 64);
    }

  for (i = 0; i < r; i++)
    {
      memcpy (&B[i * 64], &Y[2 * i * 64], 64);
      memcpy (&B[(r + i) * 64], &Y[(2 * i + 1) * 64], 64);
    }

#if 0
  if (r==1)
    {
      for (i = 0; i < 2 * r; i++)
        {
          size_t j;
          printf ("B'[%d] =", (int)i);
          for (j = 0; j < 64; j++)
            {
              if (j && !(j % 16))
                printf ("\n       ");
              printf (" %02x", B[i * 64 + j]);
            }
          putchar ('\n');
        }
    }
#endif
}

static void
_scryptROMix (u32 r, unsigned char *B, u64 N,
	      unsigned char *tmp1, unsigned char *tmp2)
{
  unsigned char *X = B, *T = B;
  u64 i;

#if 0
  if (r == 1)
    {
      printf ("B = ");
      for (i = 0; i < 128 * r; i++)
        {
          if (i && !(i % 16))
            printf ("\n    ");
          printf (" %02x", B[i]);
        }
      putchar ('\n');
    }
#endif

  /* for i = 0 to N - 1 do */
  for (i = 0; i <= N - 1; i++)
    {
      /* V[i] = X */
      memcpy (&tmp1[i * 128 * r], X, 128 * r);

      /* X =  ScryptBlockMix (X) */
      _scryptBlockMix (r, X, tmp2);
    }

  /* for i = 0 to N - 1 do */
  for (i = 0; i <= N - 1; i++)
    {
      u64 j;

      /* j = Integerify (X) mod N */
      j = LE_READ_UINT64 (&X[128 * r - 64]) % N;

      /* T = X xor V[j] */
      buf_xor (T, T, &tmp1[j * 128 * r], 128 * r);

      /* X = scryptBlockMix (T) */
      _scryptBlockMix (r, T, tmp2);
    }

#if 0
  if (r == 1)
    {
      printf ("B' =");
      for (i = 0; i < 128 * r; i++)
        {
          if (i && !(i % 16))
            printf ("\n    ");
          printf (" %02x", B[i]);
        }
      putchar ('\n');
    }
#endif
}

/**
 */
gcry_err_code_t
_gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
                  int algo, int subalgo,
                  const unsigned char *salt, size_t saltlen,
                  unsigned long iterations,
                  size_t dkLen, unsigned char *DK)
{
  u64 N = subalgo;    /* CPU/memory cost paramter.  */
  u32 r;              /* Block size.  */
  u32 p = iterations; /* Parallelization parameter.  */

  gpg_err_code_t ec;
  u32 i;
  unsigned char *B = NULL;
  unsigned char *tmp1 = NULL;
  unsigned char *tmp2 = NULL;
  size_t r128;
  size_t nbytes;

  if (subalgo < 1 || !iterations)
    return GPG_ERR_INV_VALUE;

  if (algo == GCRY_KDF_SCRYPT)
    r = 8;
  else if (algo == 41) /* Hack to allow the use of all test vectors.  */
    r = 1;
  else
    return GPG_ERR_UNKNOWN_ALGORITHM;

  r128 = r * 128;
  if (r128 / 128 != r)
    return GPG_ERR_ENOMEM;

  nbytes = p * r128;
  if (r128 && nbytes / r128 != p)
    return GPG_ERR_ENOMEM;

  nbytes = N * r128;
  if (r128 && nbytes / r128 != N)
    return GPG_ERR_ENOMEM;

  nbytes = 64 + r128;
  if (nbytes < r128)
    return GPG_ERR_ENOMEM;

  B = xtrymalloc (p * r128);
  if (!B)
    {
      ec = gpg_err_code_from_syserror ();
      goto leave;
    }

  tmp1 = xtrymalloc (N * r128);
  if (!tmp1)
    {
      ec = gpg_err_code_from_syserror ();
      goto leave;
    }

  tmp2 = xtrymalloc (64 + r128);
  if (!tmp2)
    {
      ec = gpg_err_code_from_syserror ();
      goto leave;
    }

  ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, salt, saltlen,
                        1 /* iterations */, p * r128, B);

  for (i = 0; !ec && i < p; i++)
    _scryptROMix (r, &B[i * r128], N, tmp1, tmp2);

  for (i = 0; !ec && i < p; i++)
    ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, B, p * r128,
                          1 /* iterations */, dkLen, DK);

 leave:
  xfree (tmp2);
  xfree (tmp1);
  xfree (B);

  return ec;
}


#endif /* HAVE_U64_TYPEDEF */
