/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

// Adapted from the public domain, estream code by D. Bernstein.

#include <openssl/chacha.h>

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

#include "../internal.h"
#include "internal.h"


// sigma contains the ChaCha constants, which happen to be an ASCII string.
static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
                                   '2', '-', 'b', 'y', 't', 'e', ' ', 'k' };

// QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round.
#define QUARTERROUND(a, b, c, d)           \
  x[a] += x[b];                            \
  x[d] = CRYPTO_rotl_u32(x[d] ^ x[a], 16); \
  x[c] += x[d];                            \
  x[b] = CRYPTO_rotl_u32(x[b] ^ x[c], 12); \
  x[a] += x[b];                            \
  x[d] = CRYPTO_rotl_u32(x[d] ^ x[a], 8);  \
  x[c] += x[d];                            \
  x[b] = CRYPTO_rotl_u32(x[b] ^ x[c], 7);

void CRYPTO_hchacha20(uint8_t out[32], const uint8_t key[32],
                      const uint8_t nonce[16]) {
  uint32_t x[16];
  OPENSSL_memcpy(x, sigma, sizeof(sigma));
  OPENSSL_memcpy(&x[4], key, 32);
  OPENSSL_memcpy(&x[12], nonce, 16);

  for (size_t i = 0; i < 20; i += 2) {
    QUARTERROUND(0, 4, 8, 12)
    QUARTERROUND(1, 5, 9, 13)
    QUARTERROUND(2, 6, 10, 14)
    QUARTERROUND(3, 7, 11, 15)
    QUARTERROUND(0, 5, 10, 15)
    QUARTERROUND(1, 6, 11, 12)
    QUARTERROUND(2, 7, 8, 13)
    QUARTERROUND(3, 4, 9, 14)
  }

  OPENSSL_memcpy(out, &x[0], sizeof(uint32_t) * 4);
  OPENSSL_memcpy(&out[16], &x[12], sizeof(uint32_t) * 4);
}

#if defined(CHACHA20_ASM_NOHW)
static void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
                           const uint32_t key[8], const uint32_t counter[4]) {
#if defined(CHACHA20_ASM_NEON)
  if (ChaCha20_ctr32_neon_capable(in_len)) {
    ChaCha20_ctr32_neon(out, in, in_len, key, counter);
    return;
  }
#endif
#if defined(CHACHA20_ASM_AVX2)
  if (ChaCha20_ctr32_avx2_capable(in_len)) {
    ChaCha20_ctr32_avx2(out, in, in_len, key, counter);
    return;
  }
#endif
#if defined(CHACHA20_ASM_SSSE3_4X)
  if (ChaCha20_ctr32_ssse3_4x_capable(in_len)) {
    ChaCha20_ctr32_ssse3_4x(out, in, in_len, key, counter);
    return;
  }
#endif
#if defined(CHACHA20_ASM_SSSE3)
  if (ChaCha20_ctr32_ssse3_capable(in_len)) {
    ChaCha20_ctr32_ssse3(out, in, in_len, key, counter);
    return;
  }
#endif
  if (in_len > 0) {
    ChaCha20_ctr32_nohw(out, in, in_len, key, counter);
  }
}
#endif

#if defined(CHACHA20_ASM) || defined(CHACHA20_ASM_NOHW)

void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
                      const uint8_t key[32], const uint8_t nonce[12],
                      uint32_t counter) {
  assert(!buffers_alias(out, in_len, in, in_len) || in == out);

  uint32_t counter_nonce[4];
  counter_nonce[0] = counter;
  counter_nonce[1] = CRYPTO_load_u32_le(nonce + 0);
  counter_nonce[2] = CRYPTO_load_u32_le(nonce + 4);
  counter_nonce[3] = CRYPTO_load_u32_le(nonce + 8);

  const uint32_t *key_ptr = (const uint32_t *)key;
#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64)
  // The assembly expects the key to be four-byte aligned.
  uint32_t key_u32[8];
  if ((((uintptr_t)key) & 3) != 0) {
    key_u32[0] = CRYPTO_load_u32_le(key + 0);
    key_u32[1] = CRYPTO_load_u32_le(key + 4);
    key_u32[2] = CRYPTO_load_u32_le(key + 8);
    key_u32[3] = CRYPTO_load_u32_le(key + 12);
    key_u32[4] = CRYPTO_load_u32_le(key + 16);
    key_u32[5] = CRYPTO_load_u32_le(key + 20);
    key_u32[6] = CRYPTO_load_u32_le(key + 24);
    key_u32[7] = CRYPTO_load_u32_le(key + 28);

    key_ptr = key_u32;
  }
#endif

  while (in_len > 0) {
    // The assembly functions do not have defined overflow behavior. While
    // overflow is almost always a bug in the caller, we prefer our functions to
    // behave the same across platforms, so divide into multiple calls to avoid
    // this case.
    uint64_t todo = 64 * ((UINT64_C(1) << 32) - counter_nonce[0]);
    if (todo > in_len) {
      todo = in_len;
    }

    ChaCha20_ctr32(out, in, (size_t)todo, key_ptr, counter_nonce);
    in += todo;
    out += todo;
    in_len -= todo;

    // We're either done and will next break out of the loop, or we stopped at
    // the wraparound point and the counter should continue at zero.
    counter_nonce[0] = 0;
  }
}

#else

// chacha_core performs 20 rounds of ChaCha on the input words in
// |input| and writes the 64 output bytes to |output|.
static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
  uint32_t x[16];
  int i;

  OPENSSL_memcpy(x, input, sizeof(uint32_t) * 16);
  for (i = 20; i > 0; i -= 2) {
    QUARTERROUND(0, 4, 8, 12)
    QUARTERROUND(1, 5, 9, 13)
    QUARTERROUND(2, 6, 10, 14)
    QUARTERROUND(3, 7, 11, 15)
    QUARTERROUND(0, 5, 10, 15)
    QUARTERROUND(1, 6, 11, 12)
    QUARTERROUND(2, 7, 8, 13)
    QUARTERROUND(3, 4, 9, 14)
  }

  for (i = 0; i < 16; ++i) {
    x[i] += input[i];
  }
  for (i = 0; i < 16; ++i) {
    CRYPTO_store_u32_le(output + 4 * i, x[i]);
  }
}

void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
                      const uint8_t key[32], const uint8_t nonce[12],
                      uint32_t counter) {
  assert(!buffers_alias(out, in_len, in, in_len) || in == out);

  uint32_t input[16];
  uint8_t buf[64];
  size_t todo, i;

  input[0] = CRYPTO_load_u32_le(sigma + 0);
  input[1] = CRYPTO_load_u32_le(sigma + 4);
  input[2] = CRYPTO_load_u32_le(sigma + 8);
  input[3] = CRYPTO_load_u32_le(sigma + 12);

  input[4] = CRYPTO_load_u32_le(key + 0);
  input[5] = CRYPTO_load_u32_le(key + 4);
  input[6] = CRYPTO_load_u32_le(key + 8);
  input[7] = CRYPTO_load_u32_le(key + 12);

  input[8] = CRYPTO_load_u32_le(key + 16);
  input[9] = CRYPTO_load_u32_le(key + 20);
  input[10] = CRYPTO_load_u32_le(key + 24);
  input[11] = CRYPTO_load_u32_le(key + 28);

  input[12] = counter;
  input[13] = CRYPTO_load_u32_le(nonce + 0);
  input[14] = CRYPTO_load_u32_le(nonce + 4);
  input[15] = CRYPTO_load_u32_le(nonce + 8);

  while (in_len > 0) {
    todo = sizeof(buf);
    if (in_len < todo) {
      todo = in_len;
    }

    chacha_core(buf, input);
    for (i = 0; i < todo; i++) {
      out[i] = in[i] ^ buf[i];
    }

    out += todo;
    in += todo;
    in_len -= todo;

    input[12]++;
  }
}

#endif
