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