/* * Error message information * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * 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. * * This file is part of mbed TLS (https://tls.mbed.org) */ #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif #if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) #include "mbedtls/error.h" #include #endif #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else #define mbedtls_snprintf snprintf #define mbedtls_time_t time_t #endif #if defined(MBEDTLS_ERROR_C) #include HEADER_INCLUDED // Error code table type struct ssl_errs { int16_t errnum; const char *errstr; }; // Table of high level error codes static const struct ssl_errs mbedtls_high_level_error_tab[] = { // BEGIN generated code HIGH_LEVEL_CODE_CHECKS // END generated code }; static const struct ssl_errs mbedtls_low_level_error_tab[] = { // Low level error codes // // BEGIN generated code LOW_LEVEL_CODE_CHECKS // END generated code }; static const char *mbedtls_err_prefix = "MBEDTLS_ERR_"; #define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 ) // copy error text into buffer, ensure null termination, return strlen of result static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) { if (buflen == 0) return 0; // prefix for all error names strncpy(buf, mbedtls_err_prefix, buflen); if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) { buf[buflen-1] = 0; return buflen-1; } // append error name from table for (int i = 0; i < tab_len; i++) { if (tab[i].errnum == err) { strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN); buf[buflen-1] = 0; return strlen(buf); } } mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)", err); return strlen(buf); } #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) void mbedtls_strerror(int ret, char *buf, size_t buflen) { int use_ret; if (buflen == 0) return; buf[buflen-1] = 0; if (ret < 0) ret = -ret; // // High-level error codes // uint8_t got_hl = (ret & 0xFF80) != 0; if (got_hl) { use_ret = ret & 0xFF80; // special case, don't try to translate low level code #if defined(MBEDTLS_SSL_TLS_C) if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen); buf[buflen-1] = 0; return; } #endif size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab, ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen); buf += len; buflen -= len; if (buflen == 0) return; } // // Low-level error codes // use_ret = ret & ~0xFF80; if (use_ret == 0) return; // If high level code is present, make a concatenation between both error strings. if (got_hl) { if (buflen < 2) return; *buf++ = '+'; buflen--; } mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab, ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen); } #else /* MBEDTLS_ERROR_C */ #if defined(MBEDTLS_ERROR_STRERROR_DUMMY) /* * Provide an non-function in case 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_STRERROR_DUMMY */ #endif /* MBEDTLS_ERROR_C */