// Copyright 2017 The Fuchsia 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 <lib/zircon-internal/debug.h>
#include <stddef.h>
#include <stdint.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <explicit-memory/bytes.h>
#include <fbl/alloc_checker.h>

// See note in //zircon/third_party/ulib/boringssl/BUILD.gn
#define BORINGSSL_NO_CXX
#include <openssl/digest.h>
#include <openssl/hmac.h>

#include "src/security/fcrypto/digest.h"
#include "src/security/fcrypto/error.h"
#include "src/security/fcrypto/hmac.h"

#define ZXDEBUG 0

namespace crypto {
namespace {

const uint16_t kAllFlags = HMAC::ALLOW_TRUNCATION | HMAC::ALLOW_WEAK_KEY;
}
// The previously opaque crypto implementation context.  Guaranteed to clean up on destruction.
struct HMAC::Context {
  Context() { HMAC_CTX_init(&impl); }

  ~Context() { HMAC_CTX_cleanup(&impl); }

  HMAC_CTX impl;
};

HMAC::HMAC() {}
HMAC::~HMAC() {}

zx_status_t HMAC::Create(digest::Algorithm digest, const Secret& key, const void* in, size_t in_len,
                         Bytes* out, uint16_t flags) {
  zx_status_t rc;

  HMAC hmac;
  if ((rc = hmac.Init(digest, key, flags)) != ZX_OK || (rc = hmac.Update(in, in_len)) != ZX_OK ||
      (rc = hmac.Final(out)) != ZX_OK) {
    return rc;
  }

  return ZX_OK;
}

zx_status_t HMAC::Verify(digest::Algorithm digest, const Secret& key, const void* in, size_t in_len,
                         const Bytes& hmac, uint16_t flags) {
  zx_status_t rc;

  Bytes tmp;
  if ((rc = HMAC::Create(digest, key, in, in_len, &tmp, flags)) != ZX_OK) {
    return rc;
  }

  size_t hmac_len = hmac.len();
  size_t tmp_len = tmp.len();
  if (hmac_len != tmp_len) {
    // According to RFC 2104, section 5, the digest can be truncated to half its original size.
    // We enforce a more stringent minimum than the RFC of 128 bits
    if ((flags & ALLOW_TRUNCATION) == 0 || hmac_len < tmp_len / 2 || hmac_len < 16) {
      xprintf("digest to verify is too short: %zu\n", hmac_len);
      return ZX_ERR_INVALID_ARGS;
    }
    if ((rc = tmp.Resize(hmac.len())) != ZX_OK) {
      return rc;
    }
  }

  if (tmp != hmac) {
    xprintf("HMAC verification failed\n");
    return ZX_ERR_IO_DATA_INTEGRITY;
  }

  return ZX_OK;
}

zx_status_t HMAC::Init(digest::Algorithm digest, const Secret& key, uint16_t flags) {
  zx_status_t rc;

  if ((flags & (~kAllFlags)) != 0) {
    xprintf("invalid flags: %04x\n", flags);
    return ZX_ERR_INVALID_ARGS;
  }

  fbl::AllocChecker ac;
  ctx_.reset(new (&ac) Context());
  if (!ac.check()) {
    xprintf("allocation failed: %zu bytes\n", sizeof(Context));
    return ZX_ERR_NO_MEMORY;
  }

  // Get the digest algorithm
  uintptr_t ptr;
  if ((rc = digest::GetDigest(digest, &ptr)) != ZX_OK) {
    return rc;
  }
  const EVP_MD* md = reinterpret_cast<const EVP_MD*>(ptr);

  // Check key length.  Keys less than digest length are invalid (RFC 2104, section 2).
  size_t key_len = key.len();
  if ((flags & ALLOW_WEAK_KEY) == 0 && key_len < EVP_MD_size(md)) {
    xprintf("weak key: %zu bytes\n", key_len);
    return ZX_ERR_INVALID_ARGS;
  }

  // Initialize the HMAC context
  if (HMAC_Init_ex(&ctx_->impl, key.get(), key_len, md, nullptr) != 1) {
    xprintf_crypto_errors(&rc);
    return rc;
  }

  return ZX_OK;
}

zx_status_t HMAC::Update(const void* in, size_t in_len) {
  zx_status_t rc;

  if (!ctx_) {
    xprintf("not initialized\n");
    return ZX_ERR_BAD_STATE;
  }

  if (in_len == 0) {
    return ZX_OK;
  }
  if (!in) {
    xprintf("input is null\n");
    return ZX_ERR_INVALID_ARGS;
  }

  if (HMAC_Update(&ctx_->impl, static_cast<const uint8_t*>(in), in_len) != 1) {
    xprintf_crypto_errors(&rc);
    return rc;
  }

  return ZX_OK;
}

zx_status_t HMAC::Final(Bytes* out) {
  zx_status_t rc;

  if (!out) {
    xprintf("null parameter: out\n");
    return ZX_ERR_INVALID_ARGS;
  }

  if (!ctx_) {
    xprintf("not initialized\n");
    return ZX_ERR_BAD_STATE;
  }

  Bytes tmp;
  if ((rc = tmp.Resize(EVP_MAX_MD_SIZE)) != ZX_OK) {
    return rc;
  }

  unsigned int out_len;
  if (HMAC_Final(&ctx_->impl, tmp.get(), &out_len) != 1) {
    xprintf_crypto_errors(&rc);
    return rc;
  }
  ctx_.reset();

  if ((rc = out->Resize(out_len)) != ZX_OK || (rc = out->Copy(tmp.get(), out_len)) != ZX_OK) {
    return rc;
  }

  return ZX_OK;
}

}  // namespace crypto
