// Copyright (c) 2012 The Chromium OS 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 <cstring>  // memcpy

#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>

#include "brillo/secure_blob.h"

namespace brillo {

namespace {

bool ConvertHexToBytes(char c, uint8_t* v) {
  if (c >= '0' && c <= '9')
    *v = c - '0';
  else if (c >= 'a' && c <= 'f')
    *v = c - 'a' + 10;
  else if (c >= 'A' && c <= 'F')
    *v = c - 'A' + 10;
  else
    return false;

  return true;
}

}  // namespace

std::string BlobToString(const Blob& blob) {
  return std::string(blob.begin(), blob.end());
}

Blob BlobFromString(const std::string& bytes) {
  return Blob(bytes.begin(), bytes.end());
}

Blob CombineBlobs(const std::initializer_list<Blob>& blobs) {
  size_t total_size = 0;
  for (const auto& blob : blobs)
    total_size += blob.size();
  Blob concatenation;
  concatenation.reserve(total_size);
  for (const auto& blob : blobs)
    concatenation.insert(concatenation.end(), blob.begin(), blob.end());
  return concatenation;
}

SecureBlob::SecureBlob(const Blob& blob)
    : SecureBlob(blob.begin(), blob.end()) {}

SecureBlob::SecureBlob(const std::string& data)
    : SecureBlob(data.begin(), data.end()) {}

SecureBlob::~SecureBlob() {
  SecureVector::clear();
}

void SecureBlob::resize(size_type count) {
  if (count < size()) {
    SecureMemset(data() + count, 0, capacity() - count);
  }
  SecureVector::resize(count);
}

void SecureBlob::resize(size_type count, const value_type& value) {
  if (count < size()) {
    SecureMemset(data() + count, 0, capacity() - count);
  }
  SecureVector::resize(count, value);
}

void SecureBlob::clear() {
  SecureVector::clear();
}

std::string SecureBlob::to_string() const {
  return std::string(data(), data() + size());
}

SecureBlob SecureBlob::Combine(const SecureBlob& blob1,
                               const SecureBlob& blob2) {
  SecureBlob result;
  result.reserve(blob1.size() + blob2.size());
  result.insert(result.end(), blob1.begin(), blob1.end());
  result.insert(result.end(), blob2.begin(), blob2.end());
  return result;
}

bool SecureBlob::HexStringToSecureBlob(const std::string& input,
                                       SecureBlob* output) {
  // TODO(jorgelo,crbug.com/728047): Consider not using an intermediate
  // std::vector here at all.
  std::vector<uint8_t> temp;
  if (!base::HexStringToBytes(input, &temp)) {
    output->clear();
    return false;
  }
  output->assign(temp.begin(), temp.end());
  SecureMemset(temp.data(), 0, temp.capacity());
  return true;
}

BRILLO_DISABLE_ASAN void* SecureMemset(void* v, int c, size_t n) {
  volatile uint8_t* p = reinterpret_cast<volatile uint8_t*>(v);
  while (n--)
    *p++ = c;
  return v;
}

int SecureMemcmp(const void* s1, const void* s2, size_t n) {
  const uint8_t* us1 = reinterpret_cast<const uint8_t*>(s1);
  const uint8_t* us2 = reinterpret_cast<const uint8_t*>(s2);
  int result = 0;

  if (0 == n)
    return 1;

  /* Code snippet without data-dependent branch due to
   * Nate Lawson (nate@root.org) of Root Labs. */
  while (n--)
    result |= *us1++ ^ *us2++;

  return result != 0;
}

// base::HexEncode and base::HexStringToBytes use strings, which may leak
// contents. These functions are alternatives that keep all contents
// within secured memory.
SecureBlob SecureBlobToSecureHex(const SecureBlob& blob) {
  std::string kHexChars("0123456789ABCDEF");
  SecureBlob hex(blob.size() * 2, 0);
  const char* blob_char_data = blob.char_data();

  // Each input byte creates two output hex characters.
  for (size_t i = 0; i < blob.size(); ++i) {
    hex[(i * 2)] = kHexChars[(blob_char_data[i] >> 4) & 0xf];
    hex[(i * 2) + 1] = kHexChars[blob_char_data[i] & 0xf];
  }
  return hex;
}

SecureBlob SecureHexToSecureBlob(const SecureBlob& hex) {
  SecureBlob blob(hex.size() / 2, 0);

  if (hex.size() == 0 || hex.size() % 2)
    return SecureBlob();

  for (size_t i = 0; i < hex.size(); i++) {
    uint8_t v;
    // Check for invalid characters.
    if (!ConvertHexToBytes(hex[i], &v))
      return SecureBlob();

    blob[i / 2] = (blob[i / 2] << 4) | (v & 0xf);
  }

  return blob;
}

}  // namespace brillo
