blob: 0f6a0a7c0172536a8d5ea9126ad4e24f97f0ad43 [file] [log] [blame]
// 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/uboringssl/rules.mk
#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