1/* 2 * Error message information 3 * 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * This file is part of mbed TLS (https://tls.mbed.org) 20 */ 21 22#if !defined(MBEDTLS_CONFIG_FILE) 23#include "mbedtls/config.h" 24#else 25#include MBEDTLS_CONFIG_FILE 26#endif 27 28#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) 29#include "mbedtls/error.h" 30#include <string.h> 31#endif 32 33#if defined(MBEDTLS_PLATFORM_C) 34#include "mbedtls/platform.h" 35#else 36#define mbedtls_snprintf snprintf 37#define mbedtls_time_t time_t 38#endif 39 40#if defined(MBEDTLS_ERROR_C) 41 42#include <stdio.h> 43 44HEADER_INCLUDED 45 46// Error code table type 47struct ssl_errs { 48 int16_t errnum; 49 const char *errstr; 50}; 51 52// Table of high level error codes 53static const struct ssl_errs mbedtls_high_level_error_tab[] = { 54// BEGIN generated code 55HIGH_LEVEL_CODE_CHECKS 56// END generated code 57}; 58 59static const struct ssl_errs mbedtls_low_level_error_tab[] = { 60// Low level error codes 61// 62// BEGIN generated code 63LOW_LEVEL_CODE_CHECKS 64// END generated code 65}; 66 67static const char *mbedtls_err_prefix = "MBEDTLS_ERR_"; 68#define MBEDTLS_ERR_PREFIX_LEN ( sizeof("MBEDTLS_ERR_")-1 ) 69 70// copy error text into buffer, ensure null termination, return strlen of result 71static size_t mbedtls_err_to_str(int err, const struct ssl_errs tab[], int tab_len, char *buf, size_t buflen) { 72 if (buflen == 0) return 0; 73 74 // prefix for all error names 75 strncpy(buf, mbedtls_err_prefix, buflen); 76 if (buflen <= MBEDTLS_ERR_PREFIX_LEN+1) { 77 buf[buflen-1] = 0; 78 return buflen-1; 79 } 80 81 // append error name from table 82 for (int i = 0; i < tab_len; i++) { 83 if (tab[i].errnum == err) { 84 strncpy(buf+MBEDTLS_ERR_PREFIX_LEN, tab[i].errstr, buflen-MBEDTLS_ERR_PREFIX_LEN); 85 buf[buflen-1] = 0; 86 return strlen(buf); 87 } 88 } 89 90 mbedtls_snprintf(buf+MBEDTLS_ERR_PREFIX_LEN, buflen-MBEDTLS_ERR_PREFIX_LEN, "UNKNOWN (0x%04X)", 91 err); 92 return strlen(buf); 93} 94 95#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 96 97void mbedtls_strerror(int ret, char *buf, size_t buflen) { 98 int use_ret; 99 100 if (buflen == 0) return; 101 102 buf[buflen-1] = 0; 103 104 if (ret < 0) ret = -ret; 105 106 // 107 // High-level error codes 108 // 109 uint8_t got_hl = (ret & 0xFF80) != 0; 110 if (got_hl) { 111 use_ret = ret & 0xFF80; 112 113 // special case 114#if defined(MBEDTLS_SSL_TLS_C) 115 if (use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE)) { 116 strncpy(buf, "MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE", buflen); 117 buf[buflen-1] = 0; 118 return; 119 } 120#endif 121 122 size_t len = mbedtls_err_to_str(use_ret, mbedtls_high_level_error_tab, 123 ARRAY_SIZE(mbedtls_high_level_error_tab), buf, buflen); 124 125 buf += len; 126 buflen -= len; 127 if (buflen == 0) return; 128 } 129 130 // 131 // Low-level error codes 132 // 133 use_ret = ret & ~0xFF80; 134 135 if (use_ret == 0) return; 136 137 // If high level code is present, make a concatenation between both error strings. 138 if (got_hl) { 139 if (buflen < 2) return; 140 *buf++ = '+'; 141 buflen--; 142 } 143 144 mbedtls_err_to_str(use_ret, mbedtls_low_level_error_tab, 145 ARRAY_SIZE(mbedtls_low_level_error_tab), buf, buflen); 146} 147 148#else /* MBEDTLS_ERROR_C */ 149 150#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) 151 152/* 153 * Provide an non-function in case MBEDTLS_ERROR_C is not defined 154 */ 155void mbedtls_strerror( int ret, char *buf, size_t buflen ) 156{ 157 ((void) ret); 158 159 if( buflen > 0 ) 160 buf[0] = '\0'; 161} 162 163#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ 164 165#endif /* MBEDTLS_ERROR_C */ 166