text
[RRG-proxmark3.git] / common / mbedtls / debug.c
blob0af8c085c3ffdc9c00993c5acc5aaa6cc0daf332
1 /*
2 * Debugging routines
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "common.h"
22 #if defined(MBEDTLS_DEBUG_C)
24 #if defined(MBEDTLS_PLATFORM_C)
25 #include "mbedtls/platform.h"
26 #else
27 #include <stdlib.h>
28 #define mbedtls_calloc calloc
29 #define mbedtls_free free
30 #define mbedtls_time_t time_t
31 #define mbedtls_snprintf snprintf
32 #define mbedtls_vsnprintf vsnprintf
33 #endif
35 #include "mbedtls/debug.h"
36 #include "mbedtls/error.h"
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <string.h>
42 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
43 !defined(inline) && !defined(__cplusplus)
44 #define inline __inline
45 #endif
47 #define DEBUG_BUF_SIZE 512
49 static int debug_threshold = 0;
51 void mbedtls_debug_set_threshold(int threshold) {
52 debug_threshold = threshold;
56 * All calls to f_dbg must be made via this function
58 static inline void debug_send_line(const mbedtls_ssl_context *ssl, int level,
59 const char *file, int line,
60 const char *str) {
62 * If in a threaded environment, we need a thread identifier.
63 * Since there is no portable way to get one, use the address of the ssl
64 * context instead, as it shouldn't be shared between threads.
66 #if defined(MBEDTLS_THREADING_C)
67 char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
68 mbedtls_snprintf(idstr, sizeof(idstr), "%p: %s", (void *)ssl, str);
69 ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, idstr);
70 #else
71 ssl->conf->f_dbg(ssl->conf->p_dbg, level, file, line, str);
72 #endif
75 MBEDTLS_PRINTF_ATTRIBUTE(5, 6)
76 void mbedtls_debug_print_msg(const mbedtls_ssl_context *ssl, int level,
77 const char *file, int line,
78 const char *format, ...) {
79 va_list argp;
80 char str[DEBUG_BUF_SIZE];
81 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
83 if (NULL == ssl ||
84 NULL == ssl->conf ||
85 NULL == ssl->conf->f_dbg ||
86 level > debug_threshold) {
87 return;
90 va_start(argp, format);
91 ret = mbedtls_vsnprintf(str, DEBUG_BUF_SIZE, format, argp);
92 va_end(argp);
94 if (ret >= 0 && ret < DEBUG_BUF_SIZE - 1) {
95 str[ret] = '\n';
96 str[ret + 1] = '\0';
99 debug_send_line(ssl, level, file, line, str);
102 void mbedtls_debug_print_ret(const mbedtls_ssl_context *ssl, int level,
103 const char *file, int line,
104 const char *text, int ret) {
105 char str[DEBUG_BUF_SIZE];
107 if (NULL == ssl ||
108 NULL == ssl->conf ||
109 NULL == ssl->conf->f_dbg ||
110 level > debug_threshold) {
111 return;
115 * With non-blocking I/O and examples that just retry immediately,
116 * the logs would be quickly flooded with WANT_READ, so ignore that.
117 * Don't ignore WANT_WRITE however, since is is usually rare.
119 if (ret == MBEDTLS_ERR_SSL_WANT_READ)
120 return;
122 mbedtls_snprintf(str, sizeof(str), "%s() returned %d (-0x%04x)\n",
123 text, ret, (unsigned int) - ret);
125 debug_send_line(ssl, level, file, line, str);
128 void mbedtls_debug_print_buf(const mbedtls_ssl_context *ssl, int level,
129 const char *file, int line, const char *text,
130 const unsigned char *buf, size_t len) {
131 char str[DEBUG_BUF_SIZE];
132 char txt[17];
133 size_t i, idx = 0;
135 if (NULL == ssl ||
136 NULL == ssl->conf ||
137 NULL == ssl->conf->f_dbg ||
138 level > debug_threshold) {
139 return;
142 mbedtls_snprintf(str + idx, sizeof(str) - idx, "dumping '%s' (%u bytes)\n",
143 text, (unsigned int) len);
145 debug_send_line(ssl, level, file, line, str);
147 idx = 0;
148 memset(txt, 0, sizeof(txt));
149 for (i = 0; i < len; i++) {
150 if (i >= 4096)
151 break;
153 if (i % 16 == 0) {
154 if (i > 0) {
155 mbedtls_snprintf(str + idx, sizeof(str) - idx, " %s\n", txt);
156 debug_send_line(ssl, level, file, line, str);
158 idx = 0;
159 memset(txt, 0, sizeof(txt));
162 idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, "%04x: ",
163 (unsigned int) i);
167 idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x",
168 (unsigned int) buf[i]);
169 txt[i % 16] = (buf[i] > 31 && buf[i] < 127) ? buf[i] : '.' ;
172 if (len > 0) {
173 for (/* i = i */; i % 16 != 0; i++)
174 idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " ");
176 mbedtls_snprintf(str + idx, sizeof(str) - idx, " %s\n", txt);
177 debug_send_line(ssl, level, file, line, str);
181 #if defined(MBEDTLS_ECP_C)
182 void mbedtls_debug_print_ecp(const mbedtls_ssl_context *ssl, int level,
183 const char *file, int line,
184 const char *text, const mbedtls_ecp_point *X) {
185 char str[DEBUG_BUF_SIZE];
187 if (NULL == ssl ||
188 NULL == ssl->conf ||
189 NULL == ssl->conf->f_dbg ||
190 level > debug_threshold) {
191 return;
194 mbedtls_snprintf(str, sizeof(str), "%s(X)", text);
195 mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->X);
197 mbedtls_snprintf(str, sizeof(str), "%s(Y)", text);
198 mbedtls_debug_print_mpi(ssl, level, file, line, str, &X->Y);
200 #endif /* MBEDTLS_ECP_C */
202 #if defined(MBEDTLS_BIGNUM_C)
203 void mbedtls_debug_print_mpi(const mbedtls_ssl_context *ssl, int level,
204 const char *file, int line,
205 const char *text, const mbedtls_mpi *X) {
206 char str[DEBUG_BUF_SIZE];
207 int j, k, zeros = 1;
208 size_t i, n, idx = 0;
210 if (NULL == ssl ||
211 NULL == ssl->conf ||
212 NULL == ssl->conf->f_dbg ||
213 NULL == X ||
214 level > debug_threshold) {
215 return;
218 for (n = X->n - 1; n > 0; n--)
219 if (X->p[n] != 0)
220 break;
222 for (j = (sizeof(mbedtls_mpi_uint) << 3) - 1; j >= 0; j--)
223 if (((X->p[n] >> j) & 1) != 0)
224 break;
226 mbedtls_snprintf(str + idx, sizeof(str) - idx, "value of '%s' (%d bits) is:\n",
227 text, (int)((n * (sizeof(mbedtls_mpi_uint) << 3)) + j + 1));
229 debug_send_line(ssl, level, file, line, str);
231 idx = 0;
232 for (i = n + 1, j = 0; i > 0; i--) {
233 if (zeros && X->p[i - 1] == 0)
234 continue;
236 for (k = sizeof(mbedtls_mpi_uint) - 1; k >= 0; k--) {
237 if (zeros && ((X->p[i - 1] >> (k << 3)) & 0xFF) == 0)
238 continue;
239 else
240 zeros = 0;
242 if (j % 16 == 0) {
243 if (j > 0) {
244 mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
245 debug_send_line(ssl, level, file, line, str);
246 idx = 0;
250 idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " %02x", (unsigned int)
251 (X->p[i - 1] >> (k << 3)) & 0xFF);
253 j++;
258 if (zeros == 1)
259 idx += mbedtls_snprintf(str + idx, sizeof(str) - idx, " 00");
261 mbedtls_snprintf(str + idx, sizeof(str) - idx, "\n");
262 debug_send_line(ssl, level, file, line, str);
264 #endif /* MBEDTLS_BIGNUM_C */
266 #if defined(MBEDTLS_X509_CRT_PARSE_C)
267 static void debug_print_pk(const mbedtls_ssl_context *ssl, int level,
268 const char *file, int line,
269 const char *text, const mbedtls_pk_context *pk) {
270 size_t i;
271 mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS];
272 char name[16];
274 memset(items, 0, sizeof(items));
276 if (mbedtls_pk_debug(pk, items) != 0) {
277 debug_send_line(ssl, level, file, line,
278 "invalid PK context\n");
279 return;
282 for (i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++) {
283 if (items[i].type == MBEDTLS_PK_DEBUG_NONE)
284 return;
286 mbedtls_snprintf(name, sizeof(name), "%s%s", text, items[i].name);
287 name[sizeof(name) - 1] = '\0';
289 if (items[i].type == MBEDTLS_PK_DEBUG_MPI)
290 mbedtls_debug_print_mpi(ssl, level, file, line, name, items[i].value);
291 else
292 #if defined(MBEDTLS_ECP_C)
293 if (items[i].type == MBEDTLS_PK_DEBUG_ECP)
294 mbedtls_debug_print_ecp(ssl, level, file, line, name, items[i].value);
295 else
296 #endif
297 debug_send_line(ssl, level, file, line,
298 "should not happen\n");
302 static void debug_print_line_by_line(const mbedtls_ssl_context *ssl, int level,
303 const char *file, int line, const char *text) {
304 char str[DEBUG_BUF_SIZE];
305 const char *start, *cur;
307 start = text;
308 for (cur = text; *cur != '\0'; cur++) {
309 if (*cur == '\n') {
310 size_t len = cur - start + 1;
311 if (len > DEBUG_BUF_SIZE - 1)
312 len = DEBUG_BUF_SIZE - 1;
314 memcpy(str, start, len);
315 str[len] = '\0';
317 debug_send_line(ssl, level, file, line, str);
319 start = cur + 1;
324 void mbedtls_debug_print_crt(const mbedtls_ssl_context *ssl, int level,
325 const char *file, int line,
326 const char *text, const mbedtls_x509_crt *crt) {
327 char str[DEBUG_BUF_SIZE];
328 int i = 0;
330 if (NULL == ssl ||
331 NULL == ssl->conf ||
332 NULL == ssl->conf->f_dbg ||
333 NULL == crt ||
334 level > debug_threshold) {
335 return;
338 while (crt != NULL) {
339 char buf[1024];
341 mbedtls_snprintf(str, sizeof(str), "%s #%d:\n", text, ++i);
342 debug_send_line(ssl, level, file, line, str);
344 mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
345 debug_print_line_by_line(ssl, level, file, line, buf);
347 debug_print_pk(ssl, level, file, line, "crt->", &crt->pk);
349 crt = crt->next;
352 #endif /* MBEDTLS_X509_CRT_PARSE_C */
354 #if defined(MBEDTLS_ECDH_C)
355 static void mbedtls_debug_printf_ecdh_internal(const mbedtls_ssl_context *ssl,
356 int level, const char *file,
357 int line,
358 const mbedtls_ecdh_context *ecdh,
359 mbedtls_debug_ecdh_attr attr) {
360 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
361 const mbedtls_ecdh_context *ctx = ecdh;
362 #else
363 const mbedtls_ecdh_context_mbed *ctx = &ecdh->ctx.mbed_ecdh;
364 #endif
366 switch (attr) {
367 case MBEDTLS_DEBUG_ECDH_Q:
368 mbedtls_debug_print_ecp(ssl, level, file, line, "ECDH: Q",
369 &ctx->Q);
370 break;
371 case MBEDTLS_DEBUG_ECDH_QP:
372 mbedtls_debug_print_ecp(ssl, level, file, line, "ECDH: Qp",
373 &ctx->Qp);
374 break;
375 case MBEDTLS_DEBUG_ECDH_Z:
376 mbedtls_debug_print_mpi(ssl, level, file, line, "ECDH: z",
377 &ctx->z);
378 break;
379 default:
380 break;
384 void mbedtls_debug_printf_ecdh(const mbedtls_ssl_context *ssl, int level,
385 const char *file, int line,
386 const mbedtls_ecdh_context *ecdh,
387 mbedtls_debug_ecdh_attr attr) {
388 #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
389 mbedtls_debug_printf_ecdh_internal(ssl, level, file, line, ecdh, attr);
390 #else
391 switch (ecdh->var) {
392 default:
393 mbedtls_debug_printf_ecdh_internal(ssl, level, file, line, ecdh,
394 attr);
396 #endif
398 #endif /* MBEDTLS_ECDH_C */
400 #endif /* MBEDTLS_DEBUG_C */