// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/core/crypto/quic_hkdf.h"

#include <memory>

#include "third_party/boringssl/src/include/openssl/digest.h"
#include "third_party/boringssl/src/include/openssl/hkdf.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"

namespace quic {

const size_t kSHA256HashLength = 32;
const size_t kMaxKeyMaterialSize = kSHA256HashLength * 256;

QuicHKDF::QuicHKDF(QuicStringPiece secret,
                   QuicStringPiece salt,
                   QuicStringPiece info,
                   size_t key_bytes_to_generate,
                   size_t iv_bytes_to_generate,
                   size_t subkey_secret_bytes_to_generate)
    : QuicHKDF(secret,
               salt,
               info,
               key_bytes_to_generate,
               key_bytes_to_generate,
               iv_bytes_to_generate,
               iv_bytes_to_generate,
               subkey_secret_bytes_to_generate) {}

QuicHKDF::QuicHKDF(QuicStringPiece secret,
                   QuicStringPiece salt,
                   QuicStringPiece info,
                   size_t client_key_bytes_to_generate,
                   size_t server_key_bytes_to_generate,
                   size_t client_iv_bytes_to_generate,
                   size_t server_iv_bytes_to_generate,
                   size_t subkey_secret_bytes_to_generate) {
  const size_t material_length =
      2 * client_key_bytes_to_generate + client_iv_bytes_to_generate +
      2 * server_key_bytes_to_generate + server_iv_bytes_to_generate +
      subkey_secret_bytes_to_generate;
  DCHECK_LT(material_length, kMaxKeyMaterialSize);

  output_.resize(material_length);
  // On Windows, when the size of output_ is zero, dereference of 0'th element
  // results in a crash. C++11 solves this problem by adding a data() getter
  // method to std::vector.
  if (output_.empty()) {
    return;
  }

  ::HKDF(&output_[0], output_.size(), ::EVP_sha256(),
         reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
         reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
         reinterpret_cast<const uint8_t*>(info.data()), info.size());

  size_t j = 0;
  if (client_key_bytes_to_generate) {
    client_write_key_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                        client_key_bytes_to_generate);
    j += client_key_bytes_to_generate;
  }

  if (server_key_bytes_to_generate) {
    server_write_key_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                        server_key_bytes_to_generate);
    j += server_key_bytes_to_generate;
  }

  if (client_iv_bytes_to_generate) {
    client_write_iv_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                       client_iv_bytes_to_generate);
    j += client_iv_bytes_to_generate;
  }

  if (server_iv_bytes_to_generate) {
    server_write_iv_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                       server_iv_bytes_to_generate);
    j += server_iv_bytes_to_generate;
  }

  if (subkey_secret_bytes_to_generate) {
    subkey_secret_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                     subkey_secret_bytes_to_generate);
    j += subkey_secret_bytes_to_generate;
  }
  // Repeat client and server key bytes for header protection keys.
  if (client_key_bytes_to_generate) {
    client_hp_key_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                     client_key_bytes_to_generate);
    j += client_key_bytes_to_generate;
  }

  if (server_key_bytes_to_generate) {
    server_hp_key_ = QuicStringPiece(reinterpret_cast<char*>(&output_[j]),
                                     server_key_bytes_to_generate);
    j += server_key_bytes_to_generate;
  }
}

QuicHKDF::~QuicHKDF() {}

}  // namespace quic
