/*
 * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/evp.h>

#include <assert.h>

#include <openssl/err.h>
#include <openssl/mem.h>

#include "../internal.h"


// This file implements scrypt, described in RFC 7914.
//
// Note scrypt refers to both "blocks" and a "block size" parameter, r. These
// are two different notions of blocks. A Salsa20 block is 64 bytes long,
// represented in this implementation by 16 |uint32_t|s. |r| determines the
// number of 64-byte Salsa20 blocks in a scryptBlockMix block, which is 2 * |r|
// Salsa20 blocks. This implementation refers to them as Salsa20 blocks and
// scrypt blocks, respectively.

// A block_t is a Salsa20 block.
typedef struct {
  uint32_t words[16];
} block_t;

static_assert(sizeof(block_t) == 64, "block_t has padding");

// salsa208_word_specification implements the Salsa20/8 core function, also
// described in RFC 7914, section 3. It modifies the block at |inout|
// in-place.
static void salsa208_word_specification(block_t *inout) {
  block_t x;
  OPENSSL_memcpy(&x, inout, sizeof(x));

  for (int i = 8; i > 0; i -= 2) {
    x.words[4] ^= CRYPTO_rotl_u32(x.words[0] + x.words[12], 7);
    x.words[8] ^= CRYPTO_rotl_u32(x.words[4] + x.words[0], 9);
    x.words[12] ^= CRYPTO_rotl_u32(x.words[8] + x.words[4], 13);
    x.words[0] ^= CRYPTO_rotl_u32(x.words[12] + x.words[8], 18);
    x.words[9] ^= CRYPTO_rotl_u32(x.words[5] + x.words[1], 7);
    x.words[13] ^= CRYPTO_rotl_u32(x.words[9] + x.words[5], 9);
    x.words[1] ^= CRYPTO_rotl_u32(x.words[13] + x.words[9], 13);
    x.words[5] ^= CRYPTO_rotl_u32(x.words[1] + x.words[13], 18);
    x.words[14] ^= CRYPTO_rotl_u32(x.words[10] + x.words[6], 7);
    x.words[2] ^= CRYPTO_rotl_u32(x.words[14] + x.words[10], 9);
    x.words[6] ^= CRYPTO_rotl_u32(x.words[2] + x.words[14], 13);
    x.words[10] ^= CRYPTO_rotl_u32(x.words[6] + x.words[2], 18);
    x.words[3] ^= CRYPTO_rotl_u32(x.words[15] + x.words[11], 7);
    x.words[7] ^= CRYPTO_rotl_u32(x.words[3] + x.words[15], 9);
    x.words[11] ^= CRYPTO_rotl_u32(x.words[7] + x.words[3], 13);
    x.words[15] ^= CRYPTO_rotl_u32(x.words[11] + x.words[7], 18);
    x.words[1] ^= CRYPTO_rotl_u32(x.words[0] + x.words[3], 7);
    x.words[2] ^= CRYPTO_rotl_u32(x.words[1] + x.words[0], 9);
    x.words[3] ^= CRYPTO_rotl_u32(x.words[2] + x.words[1], 13);
    x.words[0] ^= CRYPTO_rotl_u32(x.words[3] + x.words[2], 18);
    x.words[6] ^= CRYPTO_rotl_u32(x.words[5] + x.words[4], 7);
    x.words[7] ^= CRYPTO_rotl_u32(x.words[6] + x.words[5], 9);
    x.words[4] ^= CRYPTO_rotl_u32(x.words[7] + x.words[6], 13);
    x.words[5] ^= CRYPTO_rotl_u32(x.words[4] + x.words[7], 18);
    x.words[11] ^= CRYPTO_rotl_u32(x.words[10] + x.words[9], 7);
    x.words[8] ^= CRYPTO_rotl_u32(x.words[11] + x.words[10], 9);
    x.words[9] ^= CRYPTO_rotl_u32(x.words[8] + x.words[11], 13);
    x.words[10] ^= CRYPTO_rotl_u32(x.words[9] + x.words[8], 18);
    x.words[12] ^= CRYPTO_rotl_u32(x.words[15] + x.words[14], 7);
    x.words[13] ^= CRYPTO_rotl_u32(x.words[12] + x.words[15], 9);
    x.words[14] ^= CRYPTO_rotl_u32(x.words[13] + x.words[12], 13);
    x.words[15] ^= CRYPTO_rotl_u32(x.words[14] + x.words[13], 18);
  }

  for (int i = 0; i < 16; ++i) {
    inout->words[i] += x.words[i];
  }
}

// xor_block sets |*out| to be |*a| XOR |*b|.
static void xor_block(block_t *out, const block_t *a, const block_t *b) {
  for (size_t i = 0; i < 16; i++) {
    out->words[i] = a->words[i] ^ b->words[i];
  }
}

// scryptBlockMix implements the function described in RFC 7914, section 4. B'
// is written to |out|. |out| and |B| may not alias and must be each one scrypt
// block (2 * |r| Salsa20 blocks) long.
static void scryptBlockMix(block_t *out, const block_t *B, uint64_t r) {
  assert(out != B);

  block_t X;
  OPENSSL_memcpy(&X, &B[r * 2 - 1], sizeof(X));
  for (uint64_t i = 0; i < r * 2; i++) {
    xor_block(&X, &X, &B[i]);
    salsa208_word_specification(&X);

    // This implements the permutation in step 3.
    OPENSSL_memcpy(&out[i / 2 + (i & 1) * r], &X, sizeof(X));
  }
}

// scryptROMix implements the function described in RFC 7914, section 5.  |B| is
// an scrypt block (2 * |r| Salsa20 blocks) and is modified in-place. |T| and
// |V| are scratch space allocated by the caller. |T| must have space for one
// scrypt block (2 * |r| Salsa20 blocks). |V| must have space for |N| scrypt
// blocks (2 * |r| * |N| Salsa20 blocks).
static void scryptROMix(block_t *B, uint64_t r, uint64_t N, block_t *T,
                        block_t *V) {
  // Steps 1 and 2.
  OPENSSL_memcpy(V, B, 2 * r * sizeof(block_t));
  for (uint64_t i = 1; i < N; i++) {
    scryptBlockMix(&V[2 * r * i /* scrypt block i */],
                   &V[2 * r * (i - 1) /* scrypt block i-1 */], r);
  }
  scryptBlockMix(B, &V[2 * r * (N - 1) /* scrypt block N-1 */], r);

  // Step 3.
  for (uint64_t i = 0; i < N; i++) {
    // Note this assumes |N| <= 2^32 and is a power of 2.
    uint32_t j = B[2 * r - 1].words[0] & (N - 1);
    for (size_t k = 0; k < 2 * r; k++) {
      xor_block(&T[k], &B[k], &V[2 * r * j + k]);
    }
    scryptBlockMix(B, T, r);
  }
}

// SCRYPT_PR_MAX is the maximum value of p * r. This is equivalent to the
// bounds on p in section 6:
//
//   p <= ((2^32-1) * hLen) / MFLen iff
//   p <= ((2^32-1) * 32) / (128 * r) iff
//   p * r <= (2^30-1)
#define SCRYPT_PR_MAX ((1 << 30) - 1)

// SCRYPT_MAX_MEM is the default maximum memory that may be allocated by
// |EVP_PBE_scrypt|.
#define SCRYPT_MAX_MEM (1024 * 1024 * 32)

int EVP_PBE_scrypt(const char *password, size_t password_len,
                   const uint8_t *salt, size_t salt_len, uint64_t N, uint64_t r,
                   uint64_t p, size_t max_mem, uint8_t *out_key,
                   size_t key_len) {
  if (r == 0 || p == 0 || p > SCRYPT_PR_MAX / r ||
      // |N| must be a power of two.
      N < 2 || (N & (N - 1)) ||
      // We only support |N| <= 2^32 in |scryptROMix|.
      N > UINT64_C(1) << 32 ||
      // Check that |N| < 2^(128×r / 8).
      (16 * r <= 63 && N >= UINT64_C(1) << (16 * r))) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PARAMETERS);
    return 0;
  }

  // Determine the amount of memory needed. B, T, and V are |p|, 1, and |N|
  // scrypt blocks, respectively. Each scrypt block is 2*|r| |block_t|s.
  if (max_mem == 0) {
    max_mem = SCRYPT_MAX_MEM;
  }

  size_t max_scrypt_blocks = max_mem / (2 * r * sizeof(block_t));
  if (max_scrypt_blocks < p + 1 || max_scrypt_blocks - p - 1 < N) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_MEMORY_LIMIT_EXCEEDED);
    return 0;
  }

  // Allocate and divide up the scratch space. |max_mem| fits in a size_t, which
  // is no bigger than uint64_t, so none of these operations may overflow.
  static_assert(UINT64_MAX >= SIZE_MAX, "size_t exceeds uint64_t");
  size_t B_blocks = p * 2 * r;
  size_t B_bytes = B_blocks * sizeof(block_t);
  size_t T_blocks = 2 * r;
  size_t V_blocks = N * 2 * r;
  block_t *B = reinterpret_cast<block_t *>(
      OPENSSL_calloc(B_blocks + T_blocks + V_blocks, sizeof(block_t)));
  if (B == NULL) {
    return 0;
  }

  int ret = 0;
  block_t *T = B + B_blocks;
  block_t *V = T + T_blocks;

  // NOTE: PKCS5_PBKDF2_HMAC can only fail due to allocation failure
  // or |iterations| of 0 (we pass 1 here). This is consistent with
  // the documented failure conditions of EVP_PBE_scrypt.
  if (!PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, 1,
                         EVP_sha256(), B_bytes, (uint8_t *)B)) {
    goto err;
  }

  for (uint64_t i = 0; i < p; i++) {
    scryptROMix(B + 2 * r * i, r, N, T, V);
  }

  if (!PKCS5_PBKDF2_HMAC(password, password_len, (const uint8_t *)B, B_bytes, 1,
                         EVP_sha256(), key_len, out_key)) {
    goto err;
  }

  ret = 1;

err:
  OPENSSL_free(B);
  return ret;
}
