/* * Error message information * * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "common.h" #include "mbedtls/error.h" #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) #if defined(MBEDTLS_ERROR_C) #include "mbedtls/platform.h" #include #include HEADER_INCLUDED const char *mbedtls_high_level_strerr(int error_code) { int high_level_error_code; if (error_code < 0) { error_code = -error_code; } /* Extract the high-level part from the error code. */ high_level_error_code = error_code & 0xFF80; switch (high_level_error_code) { /* Begin Auto-Generated Code. */ HIGH_LEVEL_CODE_CHECKS /* End Auto-Generated Code. */ default: break; } return NULL; } const char *mbedtls_low_level_strerr(int error_code) { int low_level_error_code; if (error_code < 0) { error_code = -error_code; } /* Extract the low-level part from the error code. */ low_level_error_code = error_code & ~0xFF80; switch (low_level_error_code) { /* Begin Auto-Generated Code. */ LOW_LEVEL_CODE_CHECKS /* End Auto-Generated Code. */ default: break; } return NULL; } void mbedtls_strerror(int ret, char *buf, size_t buflen) { size_t len; int use_ret; const char *high_level_error_description = NULL; const char *low_level_error_description = NULL; if (buflen == 0) { return; } memset(buf, 0x00, buflen); if (ret < 0) { ret = -ret; } if (ret & 0xFF80) { use_ret = ret & 0xFF80; // Translate high level error code. high_level_error_description = mbedtls_high_level_strerr(ret); if (high_level_error_description == NULL) { mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret); } else { mbedtls_snprintf(buf, buflen, "%s", high_level_error_description); } #if defined(MBEDTLS_SSL_TLS_C) // Early return in case of a fatal error - do not try to translate low // level code. if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { return; } #endif /* MBEDTLS_SSL_TLS_C */ } use_ret = ret & ~0xFF80; if (use_ret == 0) { return; } // If high level code is present, make a concatenation between both // error strings. // len = strlen(buf); if (len > 0) { if (buflen - len < 5) { return; } mbedtls_snprintf(buf + len, buflen - len, " : "); buf += len + 3; buflen -= len + 3; } // Translate low level error code. low_level_error_description = mbedtls_low_level_strerr(ret); if (low_level_error_description == NULL) { mbedtls_snprintf(buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret); } else { mbedtls_snprintf(buf, buflen, "%s", low_level_error_description); } } #else /* MBEDTLS_ERROR_C */ /* * Provide a dummy implementation when MBEDTLS_ERROR_C is not defined */ void mbedtls_strerror(int ret, char *buf, size_t buflen) { ((void) ret); if (buflen > 0) { buf[0] = '\0'; } } #endif /* MBEDTLS_ERROR_C */ #if defined(MBEDTLS_TEST_HOOKS) void (*mbedtls_test_hook_error_add)(int, int, const char *, int); #endif #endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */