From b910016049910544899c677f8da5c99855788d85 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 09:46:03 +0000 Subject: [PATCH] Add MPS trace module implementation This commit adds an implementation of the MPS trace module based on `printf()`. The enabling macro MBEDTLS_MPS_TRACE remains unset by default because MPS tracing is very verbose and consumes unnecessary space in the CI. Signed-off-by: Hanno Becker --- library/CMakeLists.txt | 1 + library/Makefile | 1 + library/mps/reader.c | 4 ++ library/mps/trace.c | 122 ++++++++++++++++++++++++++++++++++++ library/mps/trace.h | 139 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 library/mps/trace.c diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 67074d6d1..2c1bccb29 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -48,6 +48,7 @@ set(src_crypto md5.c memory_buffer_alloc.c mps/reader.c + mps/trace.o nist_kw.c oid.c padlock.c diff --git a/library/Makefile b/library/Makefile index a67160c46..0fb6eeb56 100644 --- a/library/Makefile +++ b/library/Makefile @@ -105,6 +105,7 @@ OBJS_CRYPTO= \ md5.o \ memory_buffer_alloc.o \ mps/reader.o \ + mps/trace.o \ nist_kw.o \ oid.o \ padlock.o \ diff --git a/library/mps/reader.c b/library/mps/reader.c index 5c75c47a3..791b8bd72 100644 --- a/library/mps/reader.c +++ b/library/mps/reader.c @@ -30,6 +30,10 @@ #define inline __inline #endif +#if defined(MBEDTLS_MPS_TRACE) +static int trace_id = TRACE_BIT_READER; +#endif /* MBEDTLS_MPS_TRACE */ + /* * GENERAL NOTE ON CODING STYLE * diff --git a/library/mps/trace.c b/library/mps/trace.c new file mode 100644 index 000000000..61965dca1 --- /dev/null +++ b/library/mps/trace.c @@ -0,0 +1,122 @@ +/* + * Message Processing Stack, Trace module + * + * 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. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#include "common.h" + +#if defined(MBEDTLS_MPS_TRACE) + +#include "trace.h" +#include + +static int trace_depth_ = 0; + +#define color_default "\x1B[0m" +#define color_red "\x1B[1;31m" +#define color_green "\x1B[1;32m" +#define color_yellow "\x1B[1;33m" +#define color_blue "\x1B[1;34m" +#define color_magenta "\x1B[1;35m" +#define color_cyan "\x1B[1;36m" +#define color_white "\x1B[1;37m" + +static char const * colors[] = +{ + color_default, + color_green, + color_yellow, + color_magenta, + color_cyan, + color_blue, + color_white +}; + +#define MPS_TRACE_BUF_SIZE 100 + +void trace_print_msg( int id, int line, const char *format, ... ) +{ + int ret; + char str[MPS_TRACE_BUF_SIZE]; + va_list argp; + va_start( argp, format ); + ret = mbedtls_vsnprintf( str, MPS_TRACE_BUF_SIZE, format, argp ); + va_end( argp ); + + if( ret >= 0 && ret < MPS_TRACE_BUF_SIZE ) + { + str[ret] = '\0'; + mbedtls_printf( "[%d|L%d]: %s\n", id, line, str ); + } +} + +int trace_get_depth() +{ + return trace_depth_; +} +void trace_dec_depth() +{ + trace_depth_--; +} +void trace_inc_depth() +{ + trace_depth_++; +} + +void trace_color( int id ) +{ + if( id > (int) ( sizeof( colors ) / sizeof( *colors ) ) ) + return; + printf( "%s", colors[ id ] ); +} + +void trace_indent( int level, trace_type ty ) +{ + if( level > 0 ) + { + while( --level ) + printf( "| " ); + + printf( "| " ); + } + + switch( ty ) + { + case trace_comment: + mbedtls_printf( "@ " ); + break; + + case trace_call: + mbedtls_printf( "+--> " ); + break; + + case trace_error: + mbedtls_printf( "E " ); + break; + + case trace_return: + mbedtls_printf( "< " ); + break; + + default: + break; + } +} + +#endif /* MBEDTLS_MPS_TRACE */ diff --git a/library/mps/trace.h b/library/mps/trace.h index 1ce079de8..b1da7ede2 100644 --- a/library/mps/trace.h +++ b/library/mps/trace.h @@ -28,15 +28,146 @@ #include "common.h" +#include "../common.h" + +#include "trace.h" +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#define mbedtls_vsnprintf vsnprintf +#endif /* MBEDTLS_PLATFORM_C */ + #if defined(MBEDTLS_MPS_TRACE) -#error "MPS tracing module not yet implemented" +/* + * Adapt this to enable/disable tracing output + * from the various layers of the MPS. + */ + +#define TRACE_ENABLE_LAYER_1 +#define TRACE_ENABLE_LAYER_2 +#define TRACE_ENABLE_LAYER_3 +#define TRACE_ENABLE_LAYER_4 +#define TRACE_ENABLE_READER +#define TRACE_ENABLE_WRITER + +/* + * To use the existing trace module, only change + * TRACE_ENABLE_XXX above, but don't modify the + * rest of this file. + */ + +typedef enum +{ + trace_comment, + trace_call, + trace_error, + trace_return +} trace_type; + +#define TRACE_BIT_LAYER_1 1 +#define TRACE_BIT_LAYER_2 2 +#define TRACE_BIT_LAYER_3 3 +#define TRACE_BIT_LAYER_4 4 +#define TRACE_BIT_WRITER 5 +#define TRACE_BIT_READER 6 + +#if defined(TRACE_ENABLE_LAYER_1) +#define TRACE_MASK_LAYER_1 (1u << TRACE_BIT_LAYER_1 ) +#else +#define TRACE_MASK_LAYER_1 0 +#endif + +#if defined(TRACE_ENABLE_LAYER_2) +#define TRACE_MASK_LAYER_2 (1u << TRACE_BIT_LAYER_2 ) +#else +#define TRACE_MASK_LAYER_2 0 +#endif + +#if defined(TRACE_ENABLE_LAYER_3) +#define TRACE_MASK_LAYER_3 (1u << TRACE_BIT_LAYER_3 ) +#else +#define TRACE_MASK_LAYER_3 0 +#endif + +#if defined(TRACE_ENABLE_LAYER_4) +#define TRACE_MASK_LAYER_4 (1u << TRACE_BIT_LAYER_4 ) +#else +#define TRACE_MASK_LAYER_4 0 +#endif + +#if defined(TRACE_ENABLE_READER) +#define TRACE_MASK_READER (1u << TRACE_BIT_READER ) +#else +#define TRACE_MASK_READER 0 +#endif + +#if defined(TRACE_ENABLE_WRITER) +#define TRACE_MASK_WRITER (1u << TRACE_BIT_WRITER ) +#else +#define TRACE_MASK_WRITER 0 +#endif + +#define TRACE_MASK ( TRACE_MASK_LAYER_1 | \ + TRACE_MASK_LAYER_2 | \ + TRACE_MASK_LAYER_3 | \ + TRACE_MASK_LAYER_4 | \ + TRACE_MASK_READER | \ + TRACE_MASK_WRITER ) + +/* We have to avoid globals because E-ACSL chokes on them... + * Wrap everything in stub functions. */ +int trace_get_depth( void ); +void trace_inc_depth( void ); +void trace_dec_depth( void ); + +void trace_color( int id ); +void trace_indent( int level, trace_type ty ); + +void trace_print_msg( int id, int line, const char *format, ... ); + +#define TRACE( type, ... ) \ + do { \ + if( ! ( TRACE_MASK & ( 1u << trace_id ) ) ) \ + break; \ + trace_indent( trace_get_depth(), type ); \ + trace_color( trace_id ); \ + trace_print_msg( trace_id, __LINE__, __VA_ARGS__ ); \ + trace_color( 0 ); \ + } while( 0 ) + +#define TRACE_INIT( ... ) \ + do { \ + if( ! ( TRACE_MASK & ( 1u << trace_id ) ) ) \ + break; \ + TRACE( trace_call, __VA_ARGS__ ); \ + trace_inc_depth(); \ + } while( 0 ) + +#define TRACE_END( val ) \ + do { \ + if( ! ( TRACE_MASK & ( 1u << trace_id ) ) ) \ + break; \ + TRACE( trace_return, "%d (-%#04x)", \ + (int) (val), -((unsigned)(val)) ); \ + trace_dec_depth(); \ + } while( 0 ) + +#define RETURN( val ) \ + do { \ + /* Breaks tail recursion. */ \ + int ret__ = val; \ + TRACE_END( ret__ ); \ + return( ret__ ); \ + } while( 0 ) #else /* MBEDTLS_MPS_TRACE */ -#define TRACE( type, fmt, ... ) do { } while( 0 ) -#define TRACE_INIT( fmt, ... ) do { } while( 0 ) -#define TRACE_END do { } while( 0 ) +#define TRACE( type, ... ) do { } while( 0 ) +#define TRACE_INIT( ... ) do { } while( 0 ) +#define TRACE_END do { } while( 0 ) #define RETURN( val ) return( val );