1/* 2 * Error message information 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 */ 7 8#include "common.h" 9 10#include "mbedtls/error.h" 11 12#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) 13 14#if defined(MBEDTLS_ERROR_C) 15 16#include "mbedtls/platform.h" 17 18#include <stdio.h> 19#include <string.h> 20 21HEADER_INCLUDED 22 23const char *mbedtls_high_level_strerr(int error_code) 24{ 25 int high_level_error_code; 26 27 if (error_code < 0) { 28 error_code = -error_code; 29 } 30 31 /* Extract the high-level part from the error code. */ 32 high_level_error_code = error_code & 0xFF80; 33 34 switch (high_level_error_code) { 35 /* Begin Auto-Generated Code. */ 36 HIGH_LEVEL_CODE_CHECKS 37 /* End Auto-Generated Code. */ 38 39 default: 40 break; 41 } 42 43 return NULL; 44} 45 46const char *mbedtls_low_level_strerr(int error_code) 47{ 48 int low_level_error_code; 49 50 if (error_code < 0) { 51 error_code = -error_code; 52 } 53 54 /* Extract the low-level part from the error code. */ 55 low_level_error_code = error_code & ~0xFF80; 56 57 switch (low_level_error_code) { 58 /* Begin Auto-Generated Code. */ 59 LOW_LEVEL_CODE_CHECKS 60 /* End Auto-Generated Code. */ 61 62 default: 63 break; 64 } 65 66 return NULL; 67} 68 69void mbedtls_strerror(int ret, char *buf, size_t buflen) 70{ 71 size_t len; 72 int use_ret; 73 const char *high_level_error_description = NULL; 74 const char *low_level_error_description = NULL; 75 76 if (buflen == 0) { 77 return; 78 } 79 80 memset(buf, 0x00, buflen); 81 82 if (ret < 0) { 83 ret = -ret; 84 } 85 86 if (ret & 0xFF80) { 87 use_ret = ret & 0xFF80; 88 89 // Translate high level error code. 90 high_level_error_description = mbedtls_high_level_strerr(ret); 91 92 if (high_level_error_description == NULL) { 93 mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret); 94 } else { 95 mbedtls_snprintf(buf, buflen, "%s", high_level_error_description); 96 } 97 98#if defined(MBEDTLS_SSL_TLS_C) 99 // Early return in case of a fatal error - do not try to translate low 100 // level code. 101 if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { 102 return; 103 } 104#endif /* MBEDTLS_SSL_TLS_C */ 105 } 106 107 use_ret = ret & ~0xFF80; 108 109 if (use_ret == 0) { 110 return; 111 } 112 113 // If high level code is present, make a concatenation between both 114 // error strings. 115 // 116 len = strlen(buf); 117 118 if (len > 0) { 119 if (buflen - len < 5) { 120 return; 121 } 122 123 mbedtls_snprintf(buf + len, buflen - len, " : "); 124 125 buf += len + 3; 126 buflen -= len + 3; 127 } 128 129 // Translate low level error code. 130 low_level_error_description = mbedtls_low_level_strerr(ret); 131 132 if (low_level_error_description == NULL) { 133 mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret); 134 } else { 135 mbedtls_snprintf(buf, buflen, "%s", low_level_error_description); 136 } 137} 138 139#else /* MBEDTLS_ERROR_C */ 140 141/* 142 * Provide a dummy implementation when MBEDTLS_ERROR_C is not defined 143 */ 144void mbedtls_strerror(int ret, char *buf, size_t buflen) 145{ 146 ((void) ret); 147 148 if (buflen > 0) { 149 buf[0] = '\0'; 150 } 151} 152 153#endif /* MBEDTLS_ERROR_C */ 154 155#if defined(MBEDTLS_TEST_HOOKS) 156void (*mbedtls_test_hook_error_add)(int, int, const char *, int); 157#endif 158 159#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */ 160