// Copyright 2017 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/ctrdrbg.h>

#include <assert.h>

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

#include "../aes/internal.h"
#include "../service_indicator/internal.h"
#include "internal.h"


// Section references in this file refer to SP 800-90Ar1:
// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf

// Also see table 3.
constexpr uint64_t kMaxReseedCount = UINT64_C(1) << 48;

// Implements the BCC function as described in Section 10.3.3.
static void bcc(uint8_t out[AES_BLOCK_SIZE], const AES_KEY *aes_key,
                const uint8_t *data, size_t data_len) {
  // 1. chaining_value = 0^outlen.
  uint8_t *chaining_value = out;
  OPENSSL_memset(chaining_value, 0, AES_BLOCK_SIZE);

  // 2. n = len (data)/outlen.
  BSSL_CHECK(data_len % AES_BLOCK_SIZE == 0);
  const size_t n = data_len / AES_BLOCK_SIZE;

  for (size_t i = 0; i < n; i++) {
    const uint8_t *block = data + (i * AES_BLOCK_SIZE);
    uint8_t input_block[AES_BLOCK_SIZE];

    // 4.1: input_block = chaining_value ⊕ block_i.
    CRYPTO_xor16(input_block, chaining_value, block);

    // 4.2: chaining_value = Block_Encrypt (Key, input_block).
    BCM_aes_encrypt(input_block, chaining_value, aes_key);
  }

  // 5. output_block = chaining_value.
}

// Implements the derivation function as described in Section 10.3.2.
static int block_cipher_df(uint8_t *out, size_t out_len, const uint8_t *input,
                           size_t input_len) {
  // Constants for AES-256
  constexpr size_t kAESKeyLen = 32;
  constexpr size_t kAESOutLen = AES_BLOCK_SIZE;
  constexpr size_t kMaxNumBits = 512;

  if (out_len > kMaxNumBits / 8 || input_len > (1u << 30)) {
    return 0;
  }

  // 4. S = L || N || input_string || 0x80.
  const size_t s_rawlen = sizeof(uint32_t) + sizeof(uint32_t) + input_len + 1;
  // S is padded up to a block size.
  const size_t s_len = (s_rawlen + kAESOutLen - 1) & ~(kAESOutLen - 1);
  uint8_t iv_plus_s[/* space used below */ kAESOutLen + 4 + 4 +
                    CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_NONCE_LEN +
                    CTR_DRBG_SEED_LEN + 1 +
                    /* padding */ 7];
  if (kAESOutLen + s_len > sizeof(iv_plus_s)) {
    return 0;
  }
  OPENSSL_memset(iv_plus_s, 0, sizeof(iv_plus_s));
  uint8_t *s_ptr = iv_plus_s + kAESOutLen;
  // 2. L = len (input_string)/8.
  CRYPTO_store_u32_be(s_ptr, (uint32_t)input_len);
  s_ptr += sizeof(uint32_t);
  // 3. N = number_of_bits_to_return/8.
  CRYPTO_store_u32_be(s_ptr, (uint32_t)out_len);
  s_ptr += sizeof(uint32_t);
  OPENSSL_memcpy(s_ptr, input, input_len);
  s_ptr += input_len;
  *s_ptr = 0x80;

  uint8_t temp[kAESKeyLen + kAESOutLen];
  size_t temp_len = 0;

  // 8. K = leftmost (0x00010203...1D1E1F, keylen).
  static const uint8_t kInitialKey[kAESKeyLen] = {
      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
      0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
      0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
  AES_KEY aes_key;
  bcm_status status =
      BCM_aes_set_encrypt_key(kInitialKey, 8 * sizeof(kInitialKey), &aes_key);
  BSSL_CHECK(status != bcm_status::failure);

  // 7. i = 0.
  uint32_t i = 0;
  while (temp_len < sizeof(temp)) {
    // 9.1 IV = i || 0^(outlen - len(i)).
    CRYPTO_store_u32_be(iv_plus_s, i);

    // 9.2 temp = temp || BCC (K, (IV || S)).
    bcc(temp + temp_len, &aes_key, iv_plus_s, kAESOutLen + s_len);
    temp_len += kAESOutLen;

    // 9.3 i = i + 1.
    i++;
  }

  // 10. K = leftmost (temp, keylen).
  uint8_t *const k = temp;

  // 11. X = select (temp, keylen+1, keylen+outlen).
  uint8_t *const x = temp + kAESKeyLen;

  // 12. temp = the Null string.
  temp_len = 0;

  // Create an AES key schedule for the final encryption steps.
  status = BCM_aes_set_encrypt_key(k, kAESKeyLen * 8, &aes_key);
  BSSL_CHECK(status != bcm_status::failure);

  // 13. While len (temp) < number_of_bits_to_return, do:
  while (temp_len < out_len) {
    // 13.1 X = Block_Encrypt (K, X).
    BCM_aes_encrypt(x, x, &aes_key);

    // 13.2 temp = temp || X.
    size_t to_copy = std::min(kAESOutLen, out_len - temp_len);
    OPENSSL_memcpy(out + temp_len, x, to_copy);
    temp_len += to_copy;
  }

  return 1;
}

CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN],
                             const uint8_t *personalization,
                             size_t personalization_len) {
  CTR_DRBG_STATE *drbg = reinterpret_cast<CTR_DRBG_STATE *>(
      OPENSSL_malloc(sizeof(CTR_DRBG_STATE)));
  if (drbg == NULL ||
      !CTR_DRBG_init(drbg, /*df=*/false, entropy, CTR_DRBG_ENTROPY_LEN,
                     /*nonce=*/nullptr, personalization, personalization_len)) {
    CTR_DRBG_free(drbg);
    return NULL;
  }

  return drbg;
}

CTR_DRBG_STATE *CTR_DRBG_new_df(const uint8_t *entropy, size_t entropy_len,
                                const uint8_t nonce[CTR_DRBG_NONCE_LEN],
                                const uint8_t *personalization,
                                size_t personalization_len) {
  CTR_DRBG_STATE *drbg = reinterpret_cast<CTR_DRBG_STATE *>(
      OPENSSL_malloc(sizeof(CTR_DRBG_STATE)));
  if (drbg == NULL ||
      !CTR_DRBG_init(drbg, /*df=*/true, entropy, entropy_len, nonce,
                     personalization, personalization_len)) {
    CTR_DRBG_free(drbg);
    return NULL;
  }

  return drbg;
}

void CTR_DRBG_free(CTR_DRBG_STATE *state) { OPENSSL_free(state); }

int CTR_DRBG_init(CTR_DRBG_STATE *drbg, int df, const uint8_t *entropy,
                  size_t entropy_len, const uint8_t nonce[CTR_DRBG_NONCE_LEN],
                  const uint8_t *personalization, size_t personalization_len) {
  // Section 10.2.1.3.1 and 10.2.1.3.2
  if (personalization_len > CTR_DRBG_SEED_LEN ||
      (!df && entropy_len != CTR_DRBG_ENTROPY_LEN) ||
      (df && (entropy_len < CTR_DRBG_MIN_ENTROPY_LEN ||
              entropy_len > CTR_DRBG_MAX_ENTROPY_LEN)) ||  //
      (df != (nonce != nullptr))) {
    return 0;
  }

  uint8_t seed_material[CTR_DRBG_SEED_LEN];
  if (df) {
    uint8_t pre_seed_material[CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_NONCE_LEN +
                              CTR_DRBG_SEED_LEN];
    OPENSSL_memcpy(pre_seed_material, entropy, entropy_len);
    OPENSSL_memcpy(pre_seed_material + entropy_len, nonce, CTR_DRBG_NONCE_LEN);
    OPENSSL_memcpy(pre_seed_material + entropy_len + CTR_DRBG_NONCE_LEN,
                   personalization, personalization_len);
    const size_t pre_seed_material_length =
        entropy_len + CTR_DRBG_NONCE_LEN + personalization_len;

    if (!block_cipher_df(seed_material, sizeof(seed_material),
                         pre_seed_material, pre_seed_material_length)) {
      return 0;
    }
  } else {
    OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN);
    for (size_t i = 0; i < personalization_len; i++) {
      seed_material[i] ^= personalization[i];
    }
  }

  // Section 10.2.1.2

  // kInitMask is the result of encrypting blocks with big-endian value 1, 2
  // and 3 with the all-zero AES-256 key.
  static const uint8_t kInitMask[CTR_DRBG_SEED_LEN] = {
      0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1,
      0xc4, 0xcb, 0x73, 0x8b, 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
      0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, 0x72, 0x60, 0x03, 0xca,
      0x37, 0xa6, 0x2a, 0x74, 0xd1, 0xa2, 0xf5, 0x8e, 0x75, 0x06, 0x35, 0x8e,
  };

  for (size_t i = 0; i < sizeof(kInitMask); i++) {
    seed_material[i] ^= kInitMask[i];
  }

  drbg->df = df;
  drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32);
  OPENSSL_memcpy(drbg->counter, seed_material + 32, 16);
  drbg->reseed_counter = 1;

  return 1;
}

static_assert(CTR_DRBG_SEED_LEN % AES_BLOCK_SIZE == 0,
              "not a multiple of AES block size");

// ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a
// big-endian number.
static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) {
  uint32_t ctr = CRYPTO_load_u32_be(drbg->counter + 12);
  CRYPTO_store_u32_be(drbg->counter + 12, ctr + n);
}

static int ctr_drbg_update(CTR_DRBG_STATE *drbg,
                           const uint8_t data[CTR_DRBG_SEED_LEN]) {
  uint8_t temp[CTR_DRBG_SEED_LEN];
  for (size_t i = 0; i < CTR_DRBG_SEED_LEN; i += AES_BLOCK_SIZE) {
    ctr32_add(drbg, 1);
    drbg->block(drbg->counter, temp + i, &drbg->ks);
  }

  for (size_t i = 0; i < CTR_DRBG_SEED_LEN; i++) {
    temp[i] ^= data[i];
  }

  drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32);
  OPENSSL_memcpy(drbg->counter, temp + 32, 16);

  return 1;
}

int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg,
                    const uint8_t entropy[CTR_DRBG_ENTROPY_LEN],
                    const uint8_t *additional_data,
                    size_t additional_data_len) {
  return CTR_DRBG_reseed_ex(drbg, entropy, CTR_DRBG_ENTROPY_LEN,
                            additional_data, additional_data_len);
}

int CTR_DRBG_reseed_ex(CTR_DRBG_STATE *drbg, const uint8_t *entropy,
                       size_t entropy_len, const uint8_t *additional_data,
                       size_t additional_data_len) {
  if (additional_data_len > CTR_DRBG_SEED_LEN ||
      (drbg->df && (entropy_len > CTR_DRBG_MAX_ENTROPY_LEN ||
                    entropy_len < CTR_DRBG_MIN_ENTROPY_LEN)) ||
      (!drbg->df && entropy_len != CTR_DRBG_ENTROPY_LEN)) {
    return 0;
  }

  uint8_t seed_material[CTR_DRBG_SEED_LEN];
  if (drbg->df) {
    // Section 10.2.1.4.2
    uint8_t pre_seed_material[CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_SEED_LEN];
    static_assert(CTR_DRBG_MAX_ENTROPY_LEN <= sizeof(pre_seed_material));
    OPENSSL_memcpy(pre_seed_material, entropy, entropy_len);
    OPENSSL_memcpy(pre_seed_material + entropy_len, additional_data,
                   additional_data_len);
    const size_t pre_seed_material_len = entropy_len + additional_data_len;

    if (!block_cipher_df(seed_material, sizeof(seed_material),
                         pre_seed_material, pre_seed_material_len)) {
      return 0;
    }
  } else {
    // Section 10.2.1.4
    static_assert(CTR_DRBG_ENTROPY_LEN == sizeof(seed_material));
    OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN);
    if (additional_data_len > 0) {
      for (size_t i = 0; i < additional_data_len; i++) {
        seed_material[i] ^= additional_data[i];
      }
    }
  }

  if (!ctr_drbg_update(drbg, seed_material)) {
    return 0;
  }

  drbg->reseed_counter = 1;

  return 1;
}

int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len,
                      const uint8_t *additional_data,
                      size_t additional_data_len) {
  // See 9.3.1
  if (out_len > CTR_DRBG_MAX_GENERATE_LENGTH) {
    return 0;
  }

  // See 10.2.1.5.1
  if (drbg->reseed_counter > kMaxReseedCount) {
    return 0;
  }

  uint8_t processed_additional_data[CTR_DRBG_SEED_LEN];
  OPENSSL_memset(processed_additional_data, 0,
                 sizeof(processed_additional_data));
  if (additional_data_len != 0) {
    if (drbg->df) {
      if (!block_cipher_df(processed_additional_data,
                           sizeof(processed_additional_data), additional_data,
                           additional_data_len)) {
        return 0;
      }
    } else {
      if (additional_data_len > sizeof(processed_additional_data)) {
        return 0;
      }
      OPENSSL_memcpy(processed_additional_data, additional_data,
                     additional_data_len);
    }
    if (!ctr_drbg_update(drbg, processed_additional_data)) {
      return 0;
    }
  }

  // kChunkSize is used to interact better with the cache. Since the AES-CTR
  // code assumes that it's encrypting rather than just writing keystream, the
  // buffer has to be zeroed first. Without chunking, large reads would zero
  // the whole buffer, flushing the L1 cache, and then do another pass (missing
  // the cache every time) to “encrypt” it. The code can avoid this by
  // chunking.
  constexpr size_t kChunkSize = 8 * 1024;

  while (out_len >= AES_BLOCK_SIZE) {
    size_t todo = kChunkSize;
    if (todo > out_len) {
      todo = out_len;
    }

    todo &= ~(AES_BLOCK_SIZE - 1);
    const size_t num_blocks = todo / AES_BLOCK_SIZE;

    OPENSSL_memset(out, 0, todo);
    ctr32_add(drbg, 1);
    drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter);
    ctr32_add(drbg, (uint32_t)(num_blocks - 1));

    out += todo;
    out_len -= todo;
  }

  if (out_len > 0) {
    uint8_t block[AES_BLOCK_SIZE];
    ctr32_add(drbg, 1);
    drbg->block(drbg->counter, block, &drbg->ks);

    OPENSSL_memcpy(out, block, out_len);
  }

  if (!ctr_drbg_update(drbg, processed_additional_data)) {
    return 0;
  }

  drbg->reseed_counter++;
  FIPS_service_indicator_update_state();
  return 1;
}

void CTR_DRBG_clear(CTR_DRBG_STATE *drbg) {
  OPENSSL_cleanse(drbg, sizeof(CTR_DRBG_STATE));
}
