// 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 <zircon/errors.h>
#include <zircon/types.h>

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

#include "error.h"

#define ZXDEBUG 0

namespace crypto {
namespace {

zx_status_t MapGlobalErrors(int reason) {
  switch (reason) {
    case ERR_R_MALLOC_FAILURE:
      return ZX_ERR_NO_MEMORY;

    case ERR_R_OVERFLOW:
      return ZX_ERR_OUT_OF_RANGE;

    default:
      return ZX_ERR_INTERNAL;
  }
}

zx_status_t MapCipherErrors(int reason) {
  switch (reason) {
    case CIPHER_R_CTRL_NOT_IMPLEMENTED:
    case CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED:
    case CIPHER_R_UNSUPPORTED_KEY_SIZE:
    case CIPHER_R_UNSUPPORTED_NONCE_SIZE:
      return ZX_ERR_NOT_SUPPORTED;

    case CIPHER_R_AES_KEY_SETUP_FAILED:
    case CIPHER_R_INITIALIZATION_ERROR:
      return ZX_ERR_NO_RESOURCES;

    case CIPHER_R_BAD_KEY_LENGTH:
    case CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
    case CIPHER_R_INVALID_NONCE:
    case CIPHER_R_INVALID_NONCE_SIZE:
    case CIPHER_R_INVALID_OPERATION:
    case CIPHER_R_INVALID_KEY_LENGTH:
    case CIPHER_R_INPUT_NOT_INITIALIZED:
    case CIPHER_R_OUTPUT_ALIASES_INPUT:
    case CIPHER_R_TAG_TOO_LARGE:
    case CIPHER_R_TOO_LARGE:
      return ZX_ERR_INVALID_ARGS;

    case CIPHER_R_NO_CIPHER_SET:
    case CIPHER_R_NO_DIRECTION_SET:
    case CIPHER_R_WRONG_FINAL_BLOCK_LENGTH:
      return ZX_ERR_BAD_STATE;

    case CIPHER_R_BUFFER_TOO_SMALL:
      return ZX_ERR_BUFFER_TOO_SMALL;

    case CIPHER_R_BAD_DECRYPT:
      return ZX_ERR_IO_DATA_INTEGRITY;

    default:
      return MapGlobalErrors(reason);
  }
}

zx_status_t MapDigestErrors(int reason) {
  switch (reason) {
    case DIGEST_R_INPUT_NOT_INITIALIZED:
      return ZX_ERR_INVALID_ARGS;

    default:
      return MapGlobalErrors(reason);
  }
}

zx_status_t MapHkdfErrors(int reason) {
  switch (reason) {
    case HKDF_R_OUTPUT_TOO_LARGE:
      return ZX_ERR_BUFFER_TOO_SMALL;

    default:
      return MapGlobalErrors(reason);
  }
}

// Callback to print BoringSSL's error stack
int xprintf_crypto_error(const char* str, size_t len, void* ctx) {
  xprintf("    %s\n", str);
  return 1;
}

}  // namespace

void xprintf_crypto_errors(zx_status_t* out) {
  uint32_t packed = ERR_peek_last_error();
  xprintf("BoringSSL error(s):\n");
  ERR_print_errors_cb(xprintf_crypto_error, nullptr);
  if (!out) {
    return;
  }
  int lib = ERR_GET_LIB(packed);
  int reason = ERR_GET_REASON(packed);
  switch (lib) {
    case ERR_R_CIPHER_LIB:
      *out = MapCipherErrors(reason);
      break;
    case ERR_R_DIGEST_LIB:
      *out = MapDigestErrors(reason);
      break;
    case ERR_R_HKDF_LIB:
      *out = MapHkdfErrors(reason);
      break;
    default:
      *out = MapGlobalErrors(reason);
      break;
  }
}

}  // namespace crypto
