1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <stddef.h> 6 7 #include <lib/fdio/debug.h> 8 #include <zircon/errors.h> 9 #include <zircon/types.h> 10 11 // See note in //zircon/third_party/ulib/uboringssl/rules.mk 12 #define BORINGSSL_NO_CXX 13 #include <openssl/cipher.h> 14 #include <openssl/digest.h> 15 #include <openssl/err.h> 16 #include <openssl/hkdf.h> 17 18 #include "error.h" 19 20 #define ZXDEBUG 0 21 22 namespace crypto { 23 namespace { 24 MapGlobalErrors(int reason)25zx_status_t MapGlobalErrors(int reason) { 26 switch (reason) { 27 28 case ERR_R_MALLOC_FAILURE: 29 return ZX_ERR_NO_MEMORY; 30 31 case ERR_R_OVERFLOW: 32 return ZX_ERR_OUT_OF_RANGE; 33 34 default: 35 return ZX_ERR_INTERNAL; 36 } 37 } 38 MapCipherErrors(int reason)39zx_status_t MapCipherErrors(int reason) { 40 switch (reason) { 41 42 case CIPHER_R_CTRL_NOT_IMPLEMENTED: 43 case CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED: 44 case CIPHER_R_UNSUPPORTED_KEY_SIZE: 45 case CIPHER_R_UNSUPPORTED_NONCE_SIZE: 46 return ZX_ERR_NOT_SUPPORTED; 47 48 case CIPHER_R_AES_KEY_SETUP_FAILED: 49 case CIPHER_R_INITIALIZATION_ERROR: 50 return ZX_ERR_NO_RESOURCES; 51 52 case CIPHER_R_BAD_KEY_LENGTH: 53 case CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH: 54 case CIPHER_R_INVALID_NONCE: 55 case CIPHER_R_INVALID_NONCE_SIZE: 56 case CIPHER_R_INVALID_OPERATION: 57 case CIPHER_R_INVALID_KEY_LENGTH: 58 case CIPHER_R_INPUT_NOT_INITIALIZED: 59 case CIPHER_R_OUTPUT_ALIASES_INPUT: 60 case CIPHER_R_TAG_TOO_LARGE: 61 case CIPHER_R_TOO_LARGE: 62 return ZX_ERR_INVALID_ARGS; 63 64 case CIPHER_R_NO_CIPHER_SET: 65 case CIPHER_R_NO_DIRECTION_SET: 66 case CIPHER_R_WRONG_FINAL_BLOCK_LENGTH: 67 return ZX_ERR_BAD_STATE; 68 69 case CIPHER_R_BUFFER_TOO_SMALL: 70 return ZX_ERR_BUFFER_TOO_SMALL; 71 72 case CIPHER_R_BAD_DECRYPT: 73 return ZX_ERR_IO_DATA_INTEGRITY; 74 75 default: 76 return MapGlobalErrors(reason); 77 } 78 } 79 MapDigestErrors(int reason)80zx_status_t MapDigestErrors(int reason) { 81 switch (reason) { 82 83 case DIGEST_R_INPUT_NOT_INITIALIZED: 84 return ZX_ERR_INVALID_ARGS; 85 86 default: 87 return MapGlobalErrors(reason); 88 } 89 } 90 MapHkdfErrors(int reason)91zx_status_t MapHkdfErrors(int reason) { 92 switch (reason) { 93 94 case HKDF_R_OUTPUT_TOO_LARGE: 95 return ZX_ERR_BUFFER_TOO_SMALL; 96 97 default: 98 return MapGlobalErrors(reason); 99 } 100 } 101 102 // Callback to print BoringSSL's error stack xprintf_crypto_error(const char * str,size_t len,void * ctx)103int xprintf_crypto_error(const char* str, size_t len, void* ctx) { 104 xprintf(" %s\n", str); 105 return 1; 106 } 107 108 } // namespace 109 xprintf_crypto_errors(zx_status_t * out)110void xprintf_crypto_errors(zx_status_t* out) { 111 uint32_t packed = ERR_peek_last_error(); 112 xprintf("BoringSSL error(s):\n"); 113 ERR_print_errors_cb(xprintf_crypto_error, nullptr); 114 if (!out) { 115 return; 116 } 117 int lib = ERR_GET_LIB(packed); 118 int reason = ERR_GET_REASON(packed); 119 switch (lib) { 120 case ERR_R_CIPHER_LIB: 121 *out = MapCipherErrors(reason); 122 break; 123 case ERR_R_DIGEST_LIB: 124 *out = MapDigestErrors(reason); 125 break; 126 case ERR_R_HKDF_LIB: 127 *out = MapHkdfErrors(reason); 128 break; 129 default: 130 *out = MapGlobalErrors(reason); 131 break; 132 } 133 } 134 135 } // namespace crypto 136