/*
 * 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 <openssl/type_check.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;

OPENSSL_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.
  OPENSSL_STATIC_ASSERT(UINT64_MAX >= ((size_t)-1), "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 = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t));
  if (B == NULL) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
    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;
}
