// 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 <stddef.h>

#include <lib/zircon-internal/debug.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
