// Copyright (c) 2013 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 "crypto/hkdf.h"

#include <stddef.h>
#include <stdint.h>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "crypto/hmac.h"

namespace crypto {

const size_t kSHA256HashLength = 32;

HKDF::HKDF(const base::StringPiece& secret,
           const base::StringPiece& salt,
           const base::StringPiece& info,
           size_t key_bytes_to_generate,
           size_t iv_bytes_to_generate,
           size_t subkey_secret_bytes_to_generate) {
  // https://tools.ietf.org/html/rfc5869#section-2.2
  base::StringPiece actual_salt = salt;
  char zeros[kSHA256HashLength];
  if (actual_salt.empty()) {
    // If salt is not given, HashLength zeros are used.
    memset(zeros, 0, sizeof(zeros));
    actual_salt.set(zeros, sizeof(zeros));
  }

  // Perform the Extract step to transform the input key and
  // salt into the pseudorandom key (PRK) used for Expand.
  HMAC prk_hmac(HMAC::SHA256);
  bool result = prk_hmac.Init(actual_salt);
  DCHECK(result);

  // |prk| is a pseudorandom key (of kSHA256HashLength octets).
  uint8_t prk[kSHA256HashLength];
  DCHECK_EQ(sizeof(prk), prk_hmac.DigestLength());
  result = prk_hmac.Sign(secret, prk, sizeof(prk));
  DCHECK(result);

  // https://tools.ietf.org/html/rfc5869#section-2.3
  // Perform the Expand phase to turn the pseudorandom key
  // and info into the output keying material.
  const size_t material_length = 2 * key_bytes_to_generate +
                                 2 * iv_bytes_to_generate +
                                 subkey_secret_bytes_to_generate;
  const size_t n = (material_length + kSHA256HashLength-1) /
                   kSHA256HashLength;
  DCHECK_LT(n, 256u);

  output_.resize(n * kSHA256HashLength);
  base::StringPiece previous;

  scoped_ptr<char[]> buf(new char[kSHA256HashLength + info.size() + 1]);
  uint8_t digest[kSHA256HashLength];

  HMAC hmac(HMAC::SHA256);
  result = hmac.Init(prk, sizeof(prk));
  DCHECK(result);

  for (size_t i = 0; i < n; i++) {
    memcpy(buf.get(), previous.data(), previous.size());
    size_t j = previous.size();
    memcpy(buf.get() + j, info.data(), info.size());
    j += info.size();
    buf[j++] = static_cast<char>(i + 1);

    result = hmac.Sign(base::StringPiece(buf.get(), j), digest, sizeof(digest));
    DCHECK(result);

    memcpy(&output_[i*sizeof(digest)], digest, sizeof(digest));
    previous = base::StringPiece(reinterpret_cast<char*>(digest),
                                 sizeof(digest));
  }

  size_t j = 0;
  // 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 (key_bytes_to_generate) {
    client_write_key_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
                                          key_bytes_to_generate);
    j += key_bytes_to_generate;
    server_write_key_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
                                          key_bytes_to_generate);
    j += key_bytes_to_generate;
  }

  if (iv_bytes_to_generate) {
    client_write_iv_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
                                         iv_bytes_to_generate);
    j += iv_bytes_to_generate;
    server_write_iv_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
                                         iv_bytes_to_generate);
    j += iv_bytes_to_generate;
  }
  if (subkey_secret_bytes_to_generate) {
    subkey_secret_ = base::StringPiece(reinterpret_cast<char*>(&output_[j]),
                                       subkey_secret_bytes_to_generate);
  }
}

HKDF::~HKDF() {
}

}  // namespace crypto
