From 108fc84b04a305e760fdbcfe725e6df67199e793 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 06:39:43 +0000 Subject: [PATCH 01/68] Add MPS configuration header This commit introduces the internal MPS header `mps/common.h` which will subsequently be populated with MPS-specific compile-time options and helper macros. For now, it's a stub. Signed-off-by: Hanno Becker --- library/mps/common.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 library/mps/common.h diff --git a/library/mps/common.h b/library/mps/common.h new file mode 100644 index 000000000..397c500db --- /dev/null +++ b/library/mps/common.h @@ -0,0 +1,31 @@ +/* + * 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) + */ + +/** + * \file common.h + * + * \brief Common functions and macros used by MPS + */ + +#ifndef MBEDTLS_MPS_COMMON_H +#define MBEDTLS_MPS_COMMON_H + +/* To be populated */ + +#endif /* MBEDTLS_MPS_COMMON_H */ From 6ed183cf0022fdc65b0bfcd883dd3a9c4e231a19 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 06:42:16 +0000 Subject: [PATCH 02/68] Add MPS compile time option for enabling/disabling assertions This commit adds the compile-time option MBEDTLS_MPS_ENABLE_ASSERTIONS which controls the presence of runtime assertions in MPS code. See the documentation in the header for more information. Signed-off-by: Hanno Becker --- library/mps/common.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/library/mps/common.h b/library/mps/common.h index 397c500db..7e994634f 100644 --- a/library/mps/common.h +++ b/library/mps/common.h @@ -26,6 +26,27 @@ #ifndef MBEDTLS_MPS_COMMON_H #define MBEDTLS_MPS_COMMON_H -/* To be populated */ +/** + * \name SECTION: MPS Configuration + * + * \{ + */ + +/*! This flag enables/disables assertions on the internal state of MPS. + * + * Assertions are sanity checks that should never trigger when MPS + * is used within the bounds of its API and preconditions. + * + * Enabling this increases security by limiting the scope of + * potential bugs, but comes at the cost of increased code size. + * + * Note: So far, there is no guiding principle as to what + * expected conditions merit an assertion, and which don't. + * + * Comment this to disable assertions. + */ +#define MBEDTLS_MPS_ENABLE_ASSERTIONS + +/* \} name SECTION: MPS Configuration */ #endif /* MBEDTLS_MPS_COMMON_H */ From 1ae9f756bacd4d54555fb2d828a6e50f4186b0fb Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 06:43:17 +0000 Subject: [PATCH 03/68] Add MPS compile-time option for enabling/disabling tracing This commit adds an MPS-specific compile-time option `MBEDTLS_MPS_TRACE` to the internal MPS header `mps/common.h`. So far -- this may need revisiting -- MPS comes with its own internal tracing module which allows to track the operation of MPS' various layers for the purpose of understanding of it workings as well as for debugging. The reasons for the introduction of a module separate from SSL debug are the following: 1) The SSL debug module requires an SSL context to function because debug callbacks are part of the runtime configuration of the SSL module. The MPS tracing module, in contrast, is not supposed to be used in production environments, and there is no need for a runtime configuration. Instead, a compile-time defined tracing callback is used. 2) In the interest of modularity, MPS' tracing module shouldn't require having an SSL context around. 3) Purely visually, MPS' tracing module adds support for indentation according to call-depth and coloring according to which module is being used, which makes it very useful for what's going on; however, those features aren't available in the SSL debug module (and they shouldn't be). Signed-off-by: Hanno Becker --- library/mps/common.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/mps/common.h b/library/mps/common.h index 7e994634f..becd1778d 100644 --- a/library/mps/common.h +++ b/library/mps/common.h @@ -47,6 +47,9 @@ */ #define MBEDTLS_MPS_ENABLE_ASSERTIONS +/*! This flag controls whether tracing for MPS should be enabled. */ +#define MBEDTLS_MPS_TRACE + /* \} name SECTION: MPS Configuration */ #endif /* MBEDTLS_MPS_COMMON_H */ From c809ff6ef6fa82a0790688dfdf7c2b1ba75bd933 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 06:54:04 +0000 Subject: [PATCH 04/68] Add stub implementation for MPS tracing API MPS' tracing module uses four macros: 1) TRACE( type, fmt, ... ) This acts like `printf( fmt, ... )` but also allows the specification of a type of trace output (comment, warning, error, ...) 2) TRACE_INIT This acts like TRACE() but increases the level of indentation. It will be used at the beginning of function calls. 3) RETURN( val ) Equivalent to `return( val )` plus a decrement in the level of indentation. This should be used at the end of functions that have been started with TRACE_INIT. 4) TRACE_END This combines a trace output with a decrement of the level of indentation. It's necessary prior to leaving functions which have been started with TRACE_INIT but which don't have a return value. This commit defines those macros as no-op dummies in `library/mps/trace.h` for now. Signed-off-by: Hanno Becker --- library/mps/common.h | 2 +- library/mps/trace.h | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 library/mps/trace.h diff --git a/library/mps/common.h b/library/mps/common.h index becd1778d..84c584105 100644 --- a/library/mps/common.h +++ b/library/mps/common.h @@ -48,7 +48,7 @@ #define MBEDTLS_MPS_ENABLE_ASSERTIONS /*! This flag controls whether tracing for MPS should be enabled. */ -#define MBEDTLS_MPS_TRACE +//#define MBEDTLS_MPS_TRACE /* \} name SECTION: MPS Configuration */ diff --git a/library/mps/trace.h b/library/mps/trace.h new file mode 100644 index 000000000..1ce079de8 --- /dev/null +++ b/library/mps/trace.h @@ -0,0 +1,45 @@ +/* + * 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) + */ + +/** + * \file trace.h + * + * \brief Tracing module for MPS + */ + +#ifndef MBEDTLS_MPS_TRACE_H +#define MBEDTLS_MPS_TRACE_H + +#include "common.h" + +#if defined(MBEDTLS_MPS_TRACE) + +#error "MPS tracing module not yet implemented" + +#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 RETURN( val ) return( val ); + +#endif /* MBEDTLS_MPS_TRACE */ + +#endif /* MBEDTLS_MPS_TRACE_H */ From 1c0cd10ea8e097ea7429e0cc5c58b21511da50f4 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:01:23 +0000 Subject: [PATCH 05/68] Add header and documentation for MPS reader This commit adds the interface fo the MPS reader component as `library/mps/reader.h`. Please see the file itself for extensive documentation. Signed-off-by: Hanno Becker --- library/mps/reader.h | 349 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 library/mps/reader.h diff --git a/library/mps/reader.h b/library/mps/reader.h new file mode 100644 index 000000000..5801e1c87 --- /dev/null +++ b/library/mps/reader.h @@ -0,0 +1,349 @@ +/* + * 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) + */ + +/** + * \file reader.h + * + * \brief This file defines reader objects, which together with their + * sibling writer objects form the basis for the communication + * between the various layers of the Mbed TLS messaging stack, + * as well as the communication between the messaging stack and + * the (D)TLS handshake protocol implementation. + * + * Readers provide a means of transferring incoming data from + * a 'producer' providing it in chunks of arbitrary size, to + * a 'consumer' which fetches and processes it in chunks of + * again arbitrary, and potentially different, size. + * + * Readers can be seen as datagram-to-stream converters, + * and they abstract away the following two tasks from the user: + * 1. The pointer arithmetic of stepping through a producer- + * provided chunk in smaller chunks. + * 2. The merging of incoming data chunks in case the + * consumer requests data in larger chunks than what the + * producer provides. + * + * The basic abstract flow of operation is the following: + * - Initially, the reader is in 'producing mode'. + * - The producer hands an incoming data buffer to the reader, + * moving it from 'producing' to 'consuming' mode. + * - The consumer subsequently fetches and processes the buffer + * content. Once that's done -- or partially done and a consumer's + * requests can't be fulfilled -- the producer revokes the reader's + * access to the incoming data buffer, putting the reader back to + * producing mode. + * - The producer subsequently gathers more incoming data and hands + * it to reader until the latter switches back to consuming mode + * if enough data is available for the last consumer request to + * be satisfiable. + * - Repeat the above. + * + * From the perspective of the consumer, the state of the + * reader is a potentially empty list of input buffers that + * the reader has provided to the consumer. + * New buffers can be requested through calls to mbedtls_reader_get(), + * while previously obtained input buffers can be marked processed + * through calls to mbedtls_reader_consume(), emptying the list of + * input buffers and invalidating them from the consumer's perspective. + * The consumer need not be aware of the distinction between consumer + * and producer mode, because he only interfaces with the reader + * when the latter is in consuming mode. + * + * From the perspective of the producer, the state of the reader + * is one of the following: + * - Attached: An incoming data buffer is currently + * being managed by the reader, and + * - Unset: No incoming data buffer is currently + * managed by the reader, and all previously + * handed incoming data buffers have been + * fully processed. + * - Accumulating: No incoming data buffer is currently + * managed by the reader, but some data + * from the previous incoming data buffer + * hasn't been processed yet and is internally + * held back. + * The Unset and Accumulating states belong to producing mode, + * while the Attached state belongs to consuming mode. + * + * Transitioning from Unset or Accumulating to Attached is + * done via calls to mbedtls_reader_feed(), while transitioning + * from Consuming to either Unset or Accumulating (depending + * on what has been processed) is done via mbedtls_reader_reclaim(). + * + * The following diagram depicts the producer-state progression: + * + * +------------------+ reclaim + * | Unset +<-------------------------------------+ get + * +--------|---------+ | +------+ + * | | | | + * | | | | + * | feed +---------+---+--+ | + * +--------------------------------------> Attached <---+ + * | / | + * +--------------------------------------> Consuming <---+ + * | feed, enough data available +---------+---+--+ | + * | to serve previous consumer request | | | + * | | | | + * +--------+---------+ | +------+ + * +----> Accumulating |<-------------------------------------+ commit + * | +---+--------------+ reclaim, previous read request + * | | couldn't be fulfilled + * | | + * +--------+ + * feed, need more data to serve + * previous consumer request + * + */ + +#ifndef MBEDTLS_READER_H +#define MBEDTLS_READER_H + +#include + +#include "common.h" +#include "error.h" + +struct mbedtls_reader; +typedef struct mbedtls_reader mbedtls_reader; + +/* + * Structure definitions + */ + +struct mbedtls_reader +{ + unsigned char *frag; /*!< The fragment of incoming data managed by + * the reader; it is provided to the reader + * through mbedtls_reader_feed(). The reader + * does not own the fragment and does not + * perform any allocation operations on it, + * but does have read and write access to it. */ + mbedtls_mps_stored_size_t frag_len; + /*!< The length of the current fragment. + * Must be 0 if \c frag == \c NULL. */ + mbedtls_mps_stored_size_t commit; + /*!< The offset of the last commit, relative + * to the first byte in the accumulator. + * This is only used when the reader is in + * consuming mode, i.e. frag != NULL; + * otherwise, its value is \c 0. */ + mbedtls_mps_stored_size_t end; + /*!< The offset of the end of the last chunk + * passed to the user through a call to + * mbedtls_reader_get(), relative to the first + * byte in the accumulator. + * This is only used when the reader is in + * consuming mode, i.e. \c frag != \c NULL; + * otherwise, its value is \c 0. */ + mbedtls_mps_stored_size_t pending; + /*!< The amount of incoming data missing on the + * last call to mbedtls_reader_get(). + * In particular, it is \c 0 if the last call + * was successful. + * If a reader is reclaimed after an + * unsuccessful call to mbedtls_reader_get(), + * this variable is used to have the reader + * remember how much data should be accumulated + * before the reader can be passed back to + * the user again. + * This is only used when the reader is in + * consuming mode, i.e. \c frag != \c NULL; + * otherwise, its value is \c 0. */ + + /* The accumulator is only needed if we need to be able to pause + * the reader. A few bytes could be saved by moving this to a + * separate struct and using a pointer here. */ + + unsigned char *acc; /*!< The accumulator is used to gather incoming + * data if a read-request via mbedtls_reader_get() + * cannot be served from the current fragment. */ + mbedtls_mps_stored_size_t acc_len; + /*!< The total size of the accumulator. */ + mbedtls_mps_stored_size_t acc_avail; + /*!< The number of bytes currently gathered in + * the accumulator. This is both used in + * producing and in consuming mode: + * While producing, it is increased until + * it reaches the value of \c acc_remaining below. + * While consuming, it is used to judge if a + * read request can be served from the + * accumulator or not. + * Must not be larger than acc_len. */ + union + { + mbedtls_mps_stored_size_t acc_remaining; + /*!< This indicates the amount of data still + * to be gathered in the accumulator. It is + * only used in producing mode. + * Must be at most acc_len - acc_available. */ + mbedtls_mps_stored_size_t frag_offset; + /*!< This indicates the offset of the current + * fragment from the beginning of the + * accumulator. + * It is only used in consuming mode. + * Must not be larger than \c acc_avail. */ + } acc_share; +}; + +/* + * API organization: + * A reader object is usually prepared and maintained + * by some lower layer and passed for usage to an upper + * layer, and the API naturally splits according to which + * layer is supposed to use the respective functions. + */ + +/* + * Maintenance API (Lower layer) + */ + +/** + * \brief Initialize a reader object + * + * \param reader The reader to be initialized. + * \param acc The buffer to be used as a temporary accumulator + * in case read requests through mbedtls_reader_get() + * exceed the buffer provided by mbedtls_reader_feed(). + * This buffer is owned by the caller and exclusive use + * for reading and writing is given to the reade for the + * duration of the reader's lifetime. It is thus the caller's + * responsibility to maintain (and not touch) the buffer for + * the lifetime of the reader, and to properly zeroize and + * free the memory after the reader has been destroyed. + * \param acc_len The size in Bytes of \p acc. + * + * \return \c 0 on success. + * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. + */ +int mbedtls_reader_init( mbedtls_reader *reader, + unsigned char *acc, + mbedtls_mps_size_t acc_len ); + +/** + * \brief Free a reader object + * + * \param reader The reader to be freed. + * + * \return \c 0 on success. + * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. + */ +int mbedtls_reader_free( mbedtls_reader *reader ); + +/** + * \brief Pass chunk of data for the reader to manage. + * + * \param reader The reader context to use. The reader must be + * in producing state. + * \param buf The buffer to be managed by the reader. + * \param buflen The size in Bytes of \p buffer. + * + * \return \c 0 on success. In this case, the reader will be + * moved to consuming state, and ownership of \p buf + * will be passed to the reader until mbedtls_reader_reclaim() + * is called. + * \return \c MBEDTLS_ERR_READER_NEED_MORE if more input data is + * required to fulfill a previous request to mbedtls_reader_get(). + * In this case, the reader remains in producing state and + * takes no ownership of the provided buffer (an internal copy + * is made instead). + * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on + * different kinds of failures. + */ +int mbedtls_reader_feed( mbedtls_reader *reader, + unsigned char *buf, + mbedtls_mps_size_t buflen ); + +/** + * \brief Reclaim reader's access to the current input buffer. + * + * \param reader The reader context to use. The reader must be + * in producing state. + * \param paused If not \c NULL, the intger at address \p paused will be + * modified to indicate whether the reader has been paused + * (value \c 1) or not (value \c 0). Pausing happens if there + * is uncommitted data and a previous request to + * mbedtls_reader_get() has exceeded the bounds of the + * input buffer. + * + * \return \c 0 on success. + * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. + */ +int mbedtls_reader_reclaim( mbedtls_reader *reader, + mbedtls_mps_size_t *paused ); + +/* + * Usage API (Upper layer) + */ + +/** + * \brief Request data from the reader. + * + * \param reader The reader context to use. The reader must + * in consuming state. + * \param desired The desired amount of data to be read, in Bytes. + * \param buffer The address to store the buffer pointer in. + * This must not be \c NULL. + * \param buflen The address to store the actual buffer + * length in, or \c NULL. + * + * \return \c 0 on success. In this case, \c *buf holds the + * address of a buffer of size \c *buflen + * (if \c buflen != \c NULL) or \c desired + * (if \c buflen == \c NULL). The user hass ownership + * of the buffer until the next call to mbedtls_reader_commit(). + * or mbedtls_reader_reclaim(). + * \return #MBEDTLS_ERR_READER_OUT_OF_DATA if there is not enough + * data available to serve the read request. In this case, + * the reader remains intact, and additional data can be + * provided by reclaiming the current input buffer via + * mbedtls_reader_reclaim() and feeding a new one via + * mbedtls_reader_feed(). + * \return Another negative \c MBEDTLS_ERR_READER_XXX error + * code for different kinds of failure. + * + * \note Passing \c NULL as \p buflen is a convenient way to + * indicate that fragmentation is not tolerated. + * It's functionally equivalent to passing a valid + * address as buflen and checking \c *buflen == \c desired + * afterwards. + */ +int mbedtls_reader_get( mbedtls_reader *reader, + mbedtls_mps_size_t desired, + unsigned char **buffer, + mbedtls_mps_size_t *buflen ); + +/** + * \brief Signal that all input buffers previously obtained + * from mbedtls_writer_get() are fully processed. + * + * This function marks the previously fetched data as fully + * processed and invalidates their respective buffers. + * + * \param reader The reader context to use. + * + * \return \c 0 on success. + * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. + * + * \warning Once this function is called, you must not use the + * pointers corresponding to the committed data anymore. + * + */ +int mbedtls_reader_commit( mbedtls_reader *reader ); + +#endif /* MBEDTLS_READER_H */ From 13cd7846a057974bcb8a5ce941efc31743383b6d Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:08:33 +0000 Subject: [PATCH 06/68] Add MPS reader implementation Signed-off-by: Hanno Becker --- library/mps/reader.c | 509 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 library/mps/reader.c diff --git a/library/mps/reader.c b/library/mps/reader.c new file mode 100644 index 000000000..5c75c47a3 --- /dev/null +++ b/library/mps/reader.c @@ -0,0 +1,509 @@ +/* + * Message Processing Stack, Reader implementation + * + * 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 "reader.h" +#include "common.h" +#include "trace.h" + +#include + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/* + * GENERAL NOTE ON CODING STYLE + * + * The following code intentionally separates memory loads + * and stores from other operations (arithmetic or branches). + * This leads to the introduction of many local variables + * and significantly increases the C-code line count, but + * should not increase the size of generated assembly. + * + * This reason for this is twofold: + * (1) It will ease verification efforts using the VST + * whose program logic cannot directly reason + * about instructions containing a load or store in + * addition to other operations (e.g. *p = *q or + * tmp = *p + 42). + * (2) Operating on local variables and writing the results + * back to the target contexts on success only + * allows to maintain structure invariants even + * on failure - this in turn has two benefits: + * (2.a) If for some reason an error code is not caught + * and operation continues, functions are nonetheless + * called with sane contexts, reducing the risk + * of dangerous behavior. + * (2.b) Randomized testing is easier if structures + * remain intact even in the face of failing + * and/or non-sensical calls. + * Moreover, it might even reduce code-size because + * the compiler need not write back temporary results + * to memory in case of failure. + * + */ + +static inline void mps_reader_zero( mbedtls_reader *rd ) +{ + /* A plain memset() would likely be more efficient, + * but the current way of zeroing makes it harder + * to overlook fields which should not be zero-initialized. + * It's also more suitable for VF efforts since it + * doesn't require reasoning about structs being + * interpreted as unstructured binary blobs. */ + static mbedtls_reader const zero = + { .frag = NULL, + .frag_len = 0, + .commit = 0, + .end = 0, + .pending = 0, + .acc = NULL, + .acc_len = 0, + .acc_avail = 0, + .acc_share = { .acc_remaining = 0 } + }; + *rd = zero; +} + +int mbedtls_reader_init( mbedtls_reader *rd, + unsigned char *acc, + mbedtls_mps_size_t acc_len ) +{ + TRACE_INIT( "reader_init, acc len %u", (unsigned) acc_len ); + mps_reader_zero( rd ); + rd->acc = acc; + rd->acc_len = acc_len; + RETURN( 0 ); +} + +int mbedtls_reader_free( mbedtls_reader *rd ) +{ + TRACE_INIT( "reader_free" ); + mps_reader_zero( rd ); + RETURN( 0 ); +} + +int mbedtls_reader_feed( mbedtls_reader *rd, + unsigned char *new_frag, + mbedtls_mps_size_t new_frag_len ) +{ + unsigned char *acc; + mbedtls_mps_size_t copy_to_acc; + TRACE_INIT( "reader_feed, frag %p, len %u", + (void*) new_frag, (unsigned) new_frag_len ); + + if( new_frag == NULL ) + RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG ); + + MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag == NULL, + "mbedtls_reader_feed() requires reader to be in producing mode" ); + + acc = rd->acc; + if( acc != NULL ) + { + mbedtls_mps_size_t aa, ar; + + ar = rd->acc_share.acc_remaining; + aa = rd->acc_avail; + + copy_to_acc = ar; + if( copy_to_acc > new_frag_len ) + copy_to_acc = new_frag_len; + + acc += aa; + + if( copy_to_acc > 0 ) + memcpy( acc, new_frag, copy_to_acc ); + + TRACE( trace_comment, "Copy new data of size %u of %u into accumulator at offset %u", + (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) aa ); + + /* Check if, with the new fragment, we have enough data. */ + ar -= copy_to_acc; + if( ar > 0 ) + { + /* Need more data */ + aa += copy_to_acc; + rd->acc_share.acc_remaining = ar; + rd->acc_avail = aa; + RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE ); + } + + TRACE( trace_comment, "Enough data available to serve user request" ); + + rd->acc_share.frag_offset = aa; + aa += copy_to_acc; + rd->acc_avail = aa; + } + else + { + rd->acc_share.frag_offset = 0; + } + + rd->frag = new_frag; + rd->frag_len = new_frag_len; + rd->commit = 0; + rd->end = 0; + RETURN( 0 ); +} + + +int mbedtls_reader_get( mbedtls_reader *rd, + mbedtls_mps_size_t desired, + unsigned char **buffer, + mbedtls_mps_size_t *buflen ) +{ + unsigned char *frag, *acc; + mbedtls_mps_size_t end, fo, fl, frag_fetched, frag_remaining; + TRACE_INIT( "reader_get %p, desired %u", (void*) rd, (unsigned) desired ); + + frag = rd->frag; + MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, + "mbedtls_reader_get() requires reader to be in consuming mode" ); + + /* The fragment offset indicates the offset of the fragment + * from the accmulator, if the latter is present. Use a offset + * of \c 0 if no accumulator is used. */ + acc = rd->acc; + if( acc == NULL ) + fo = 0; + else + fo = rd->acc_share.frag_offset; + + TRACE( trace_comment, "frag_off %u, end %u, acc_avail %d", + (unsigned) fo, (unsigned) rd->end, + acc == NULL ? -1 : (int) rd->acc_avail ); + + /* Check if we're still serving from the accumulator. */ + end = rd->end; + if( end < fo ) + { + TRACE( trace_comment, "Serve the request from the accumulator" ); + if( fo - end < desired ) + { + /* Illustration of supported and unsupported cases: + * + * - Allowed #1 + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end+desired + * | | + * +-----v-------v-------------+ + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_avail + * + * - Allowed #2 + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end+desired + * | | + * +----------v----------------v + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_avail + * + * - Not allowed #1 (could be served, but we don't actually use it): + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end+desired + * | | + * +------v-------------v------+ + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_avail + * + * + * - Not allowed #2 (can't be served with a contiguous buffer): + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end + desired + * | | + * +------v--------------------+ v + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_avail + * + * In case of Allowed #1 and #2 we're switching to serve from + * `frag` starting from the next call to mbedtls_reader_get(). + */ + + mbedtls_mps_size_t aa; + aa = rd->acc_avail; + if( aa - end != desired ) + { + /* It might be possible to serve some of these situations by + * making additional space in the accumulator, removing those + * parts that have already been committed. + * On the other hand, this brings additional complexity and + * enlarges the code size, while there doesn't seem to be a use + * case where we don't attempt exactly the same `get` calls when + * resuming on a reader than what we tried before pausing it. + * If we believe we adhere to this restricted usage throughout + * the library, this check is a good opportunity to + * validate this. */ + RETURN( MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); + } + } + + acc += end; + *buffer = acc; + if( buflen != NULL ) + *buflen = desired; + + end += desired; + rd->end = end; + rd->pending = 0; + + RETURN( 0 ); + } + + /* Attempt to serve the request from the current fragment */ + TRACE( trace_comment, "Serve the request from the current fragment." ); + + fl = rd->frag_len; + frag_fetched = end - fo; /* The amount of data from the current fragment + * that has already been passed to the user. */ + frag += frag_fetched; + frag_remaining = fl - frag_fetched; /* Remaining data in fragment */ + + /* Check if we can serve the read request from the fragment. */ + if( frag_remaining < desired ) + { + TRACE( trace_comment, "There's not enough data in the current fragment to serve the request." ); + /* There's not enough data in the current fragment, + * so either just RETURN what we have or fail. */ + if( buflen == NULL ) + { + if( frag_remaining > 0 ) + { + rd->pending = desired - frag_remaining; + TRACE( trace_comment, "Remember to collect %u bytes before re-opening", + (unsigned) rd->pending ); + } + RETURN( MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + } + + desired = frag_remaining; + } + + /* There's enough data in the current fragment to serve the + * (potentially modified) read request. */ + *buffer = frag; + if( buflen != NULL ) + *buflen = desired; + + end += desired; + rd->end = end; + rd->pending = 0; + RETURN( 0 ); +} + +int mbedtls_reader_commit( mbedtls_reader *rd ) +{ + unsigned char *acc; + mbedtls_mps_size_t aa, end, fo, shift; + TRACE_INIT( "reader_commit" ); + + MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag != NULL, + "mbedtls_reader_commit() requires reader to be in consuming mode" ); + + acc = rd->acc; + end = rd->end; + + if( acc == NULL ) + { + TRACE( trace_comment, "No accumulator, just shift end" ); + rd->commit = end; + RETURN( 0 ); + } + + fo = rd->acc_share.frag_offset; + if( end >= fo ) + { + TRACE( trace_comment, "Started to serve fragment, get rid of accumulator" ); + shift = fo; + aa = 0; + } + else + { + TRACE( trace_comment, "Still serving from accumulator" ); + aa = rd->acc_avail; + shift = end; + memmove( acc, acc + shift, aa - shift ); + aa -= shift; + } + + end -= shift; + fo -= shift; + + rd->acc_share.frag_offset = fo; + rd->acc_avail = aa; + rd->commit = end; + rd->end = end; + + TRACE( trace_comment, "Final state: (end=commit,fo,avail) = (%u,%u,%u)", + (unsigned) end, (unsigned) fo, (unsigned) aa ); + RETURN( 0 ); +} + +int mbedtls_reader_reclaim( mbedtls_reader *rd, + mbedtls_mps_size_t *paused ) +{ + unsigned char *frag, *acc; + mbedtls_mps_size_t pending, commit; + mbedtls_mps_size_t al, fo, fl; + TRACE_INIT( "reader_reclaim" ); + + if( paused != NULL ) + *paused = 0; + + frag = rd->frag; + MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, + "mbedtls_reader_reclaim() requires reader to be in consuming mode" ); + + acc = rd->acc; + pending = rd->pending; + commit = rd->commit; + fl = rd->frag_len; + + if( acc == NULL ) + fo = 0; + else + fo = rd->acc_share.frag_offset; + + if( pending == 0 ) + { + TRACE( trace_comment, "No unsatisfied read-request has been logged." ); + /* Check if there's data left to be consumed. */ + if( commit < fo || commit - fo < fl ) + { + TRACE( trace_comment, "There is data left to be consumed." ); + rd->end = commit; + RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT ); + } + TRACE( trace_comment, "The fragment has been completely processed and committed." ); + } + else + { + mbedtls_mps_size_t frag_backup_offset; + mbedtls_mps_size_t frag_backup_len; + TRACE( trace_comment, "There has been an unsatisfied read-request with %u bytes overhead.", + (unsigned) pending ); + + if( acc == NULL ) + { + TRACE( trace_comment, "No accumulator present" ); + RETURN( MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR ); + } + al = rd->acc_len; + + /* Check if the upper layer has already fetched + * and committed the contents of the accumulator. */ + if( commit < fo ) + { + /* No, accumulator is still being processed. */ + int overflow; + TRACE( trace_comment, "Still processing data from the accumulator" ); + + overflow = + ( fo + fl < fo ) || ( fo + fl + pending < fo + fl ); + if( overflow || al < fo + fl + pending ) + { + rd->end = commit; + rd->pending = 0; + TRACE( trace_error, "The accumulator is too small to handle the backup." ); + TRACE( trace_error, "* Remaining size: %u", (unsigned) al ); + TRACE( trace_error, "* Needed: %u (%u + %u + %u)", + (unsigned) ( fo + fl + pending ), + (unsigned) fo, (unsigned) fl, (unsigned) pending ); + RETURN( MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + } + frag_backup_offset = 0; + frag_backup_len = fl; + } + else + { + /* Yes, the accumulator is already processed. */ + int overflow; + TRACE( trace_comment, "The accumulator has already been processed" ); + + frag_backup_offset = commit; + frag_backup_len = fl - commit; + overflow = ( frag_backup_len + pending < pending ); + + if( overflow || + al - fo < frag_backup_len + pending ) + { + rd->end = commit; + rd->pending = 0; + TRACE( trace_error, "The accumulator is too small to handle the backup." ); + TRACE( trace_error, "* Remaining size: %u", (unsigned) ( al - fo ) ); + TRACE( trace_error, "* Needed: %u (%u + %u)", + (unsigned) ( frag_backup_len + pending ), + (unsigned) frag_backup_len, (unsigned) pending ); + RETURN( MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + } + } + + frag += frag_backup_offset; + acc += fo; + memcpy( acc, frag, frag_backup_len ); + + TRACE( trace_comment, "Backup %u bytes into accumulator", + (unsigned) frag_backup_len ); + + rd->acc_avail = fo + frag_backup_len; + rd->acc_share.acc_remaining = pending; + + if( paused != NULL ) + *paused = 1; + } + + rd->frag = NULL; + rd->frag_len = 0; + + rd->commit = 0; + rd->end = 0; + rd->pending = 0; + + TRACE( trace_comment, "Final state: aa %u, al %u, ar %u", + (unsigned) rd->acc_avail, (unsigned) rd->acc_len, + (unsigned) rd->acc_share.acc_remaining ); + RETURN( 0 ); +} From d2f9f53f7fc2172fa0100843bdff5d67c3083633 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:11:11 +0000 Subject: [PATCH 07/68] Add typedef's for MPS buffer size types Most buffers that MPS deals with are small and representable with integer types of width 16-bit or more. For highly memory constrained systems, it is therefore a potential for significant memory savings to use 16-bit types for buffer sizes throughout MPS. In prepraration for this, this commit introduces typdefs ``` mbedtls_mps_size_t mbedtls_mps_stored_size_t ``` for buffer sizes in the MPS implementation and the MPS structures, respectively. So far, those MUST be defined as `size_t`: While an effort has been made to write most of MPS code in terms of `mbedtls_mps_[stored_]size_t` in a way that would allow narrower types, those aren't yet supported. Still, we retain the typedefs in order to avoid unnecessary rewriting of a large body of the MPS codebase. Signed-off-by: Hanno Becker --- library/mps/common.h | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/library/mps/common.h b/library/mps/common.h index 84c584105..1ea33f9b1 100644 --- a/library/mps/common.h +++ b/library/mps/common.h @@ -26,6 +26,8 @@ #ifndef MBEDTLS_MPS_COMMON_H #define MBEDTLS_MPS_COMMON_H +#include + /** * \name SECTION: MPS Configuration * @@ -52,4 +54,55 @@ /* \} name SECTION: MPS Configuration */ +/** + * \name SECTION: Common types + * + * Various common types used throughout MPS. + * \{ + */ + +/** \brief The type of buffer sizes and offsets used in MPS structures. + * + * This is an unsigned integer type that should be large enough to + * hold the length of any buffer resp. message processed by MPS. + * + * The reason to pick a value as small as possible here is + * to reduce the size of MPS structures. + * + * \warning Care has to be taken when using a narrower type + * than ::mbedtls_mps_size_t here because of + * potential truncation during conversion. + * + * \warning Handshake messages in TLS may be up to 2^24 ~ 16Mb in size. + * If mbedtls_mps_[opt_]stored_size_t is smaller than that, the + * maximum handshake message is restricted accordingly. + * + * For now, we use the default type of size_t throughout, and the use of + * smaller types or different types for ::mbedtls_mps_size_t and + * ::mbedtls_mps_stored_size_t is not yet supported. + * + */ +typedef size_t mbedtls_mps_stored_size_t; +#define MBEDTLS_MPS_SIZE_MAX ( (mbedtls_mps_size_t) -1 ) + +/** \brief The type of buffer sizes and offsets used in the MPS API + * and implementation. + * + * This must be at least as wide as ::mbedtls_stored_size_t but + * may be chosen to be strictly larger if more suitable for the + * target architecture. + * + * For example, in a test build for ARM Thumb, using uint_fast16_t + * instead of uint16_t reduced the code size from 1060 Byte to 962 Byte, + * so almost 10%. + */ +typedef size_t mbedtls_mps_size_t; + +#if (mbedtls_mps_size_t) -1 > (mbedtls_mps_stored_size_t) -1 +#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t." +#endif + +/* \} SECTION: Common types */ + + #endif /* MBEDTLS_MPS_COMMON_H */ From 0ea0db4368e58679f54f4672dad570a3a21eea3d Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:15:11 +0000 Subject: [PATCH 08/68] Add MPS reader translation unit to Makefile and CMakeLists Signed-off-by: Hanno Becker --- library/CMakeLists.txt | 1 + library/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index cff4cf975..67074d6d1 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -47,6 +47,7 @@ set(src_crypto md4.c md5.c memory_buffer_alloc.c + mps/reader.c nist_kw.c oid.c padlock.c diff --git a/library/Makefile b/library/Makefile index 55af96e8f..a67160c46 100644 --- a/library/Makefile +++ b/library/Makefile @@ -104,6 +104,7 @@ OBJS_CRYPTO= \ md4.o \ md5.o \ memory_buffer_alloc.o \ + mps/reader.o \ nist_kw.o \ oid.o \ padlock.o \ From 75ac1f7b953db12d330140c7cc257a9329966bc8 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:25:26 +0000 Subject: [PATCH 09/68] Add implementation for MPS assertion macros Signed-off-by: Hanno Becker --- library/mps/common.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/library/mps/common.h b/library/mps/common.h index 1ea33f9b1..8ea80c174 100644 --- a/library/mps/common.h +++ b/library/mps/common.h @@ -52,6 +52,24 @@ /*! This flag controls whether tracing for MPS should be enabled. */ //#define MBEDTLS_MPS_TRACE +#if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS) + +#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) \ + do \ + { \ + if( !(cond) ) \ + { \ + TRACE( trace_error, string ); \ + RETURN( MBEDTLS_ERR_MPS_INTERNAL_ERROR ); \ + } \ + } while( 0 ) + +#else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */ + +#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) do {} while( 0 ) + +#endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */ + /* \} name SECTION: MPS Configuration */ /** From 447e8a5ecdd8c246b21baa0b16fa060e442df751 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:27:12 +0000 Subject: [PATCH 10/68] Add internal header for MPS errors This commit adds an internal header `library/mps/error.h` related to error codes in MPS. For now, those error codes can be considered internal and thus we don't have to avoid clashes with other Mbed TLS error codes. This is OK as long as it's true that MPS isn't public API, and its error codes are never forwarded to the return values of public API calls. The error code allocation of MPS will likely need revisiting over time. Signed-off-by: Hanno Becker --- library/mps/error.h | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 library/mps/error.h diff --git a/library/mps/error.h b/library/mps/error.h new file mode 100644 index 000000000..3c4180f33 --- /dev/null +++ b/library/mps/error.h @@ -0,0 +1,89 @@ +/* + * 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) + */ + +/** + * \file error.h + * + * \brief Error codes used by MPS + */ + +#ifndef MBEDTLS_MPS_ERROR_H +#define MBEDTLS_MPS_ERROR_H + + +/* TODO: The error code allocation needs to be revisited: + * + * - Should we make (some of) the MPS Reader error codes public? + * If so, we need to adjust MBEDTLS_READER_MAKE_ERROR() to hit + * a gap in the Mbed TLS public error space. + * If not, we have to make sure we don't forward those errors + * at the level of the public API -- no risk at the moment as + * long as MPS is an experimental component not accessible from + * public API. + */ + +#ifndef MBEDTLS_MPS_ERR_BASE +#define MBEDTLS_MPS_ERR_BASE ( 1 << 0 ) +#endif + +/** + * \name SECTION: MPS Reader error codes + * + * \{ + */ + +#ifndef MBEDTLS_MPS_READER_ERR_BASE +#define MBEDTLS_MPS_READER_ERR_BASE ( 1 << 7 ) +#endif + +#define MBEDTLS_MPS_READER_MAKE_ERROR(code) \ + ( -( MBEDTLS_MPS_READER_ERR_BASE | (code) ) ) + +/*! An attempt to reclaim the data buffer from a reader failed because + * the user hasn't yet read and committed all of it. */ +#define MBEDTLS_ERR_MPS_READER_DATA_LEFT MBEDTLS_MPS_READER_MAKE_ERROR( 0x1 ) + +/*! An invalid argument was passed to the reader. */ +#define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR( 0x2 ) + +/*! An attempt to move a reader to consuming mode through mbedtls_reader_feed() + * after pausing failed because the provided data is not sufficient to serve the + * the read requests that lead to the pausing. */ +#define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR( 0x3 ) + +/*! A read request failed because not enough data is available in the reader. */ +#define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR( 0x4 ) + +/*!< A read request after pausing and reactivating the reader failed because + * the request is not in line with the request made prior to pausing. The user + * must not change it's 'strategy' after pausing and reactivating a reader. */ +#define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR( 0x5 ) + +/*! An attempt to reclaim the data buffer from a reader fails because the reader + * has no accumulator it can use to backup the data that hasn't been processed. */ +#define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR( 0x6 ) + +/*! An attempt to reclaim the data buffer from a reader fails beacuse the + * accumulator passed to the reader is not large enough to hold both the + * data that hasn't been processed and the excess of the last read-request. */ +#define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR( 0x7 ) + +/* \} name SECTION: MPS Reader error codes */ + +#endif /* MBEDTLS_MPS_ERROR_H */ From ac267f3485b19e3dcee59f8a7ab0aaeb4a2398d5 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:25:41 +0000 Subject: [PATCH 11/68] Add MPS configuration option for state validation See the documentation in library/mps/common.h which this commit modifies. Signed-off-by: Hanno Becker --- library/mps/common.h | 63 ++++++++++++++++++++++++++++++++++++++++++++ library/mps/error.h | 18 +++++++++++++ 2 files changed, 81 insertions(+) diff --git a/library/mps/common.h b/library/mps/common.h index 8ea80c174..37a4cefe5 100644 --- a/library/mps/common.h +++ b/library/mps/common.h @@ -34,6 +34,46 @@ * \{ */ +/*! This flag controls whether the MPS-internal components + * (reader, writer, Layer 1-3) perform validation of the + * expected abstract state at the entry of API calls. + * + * Context: All MPS API functions impose assumptions/preconditions on the + * context on which they operate. For example, every structure has a notion of + * state integrity which is established by `xxx_init()` and preserved by any + * calls to the MPS API which satisfy their preconditions and either succeed, + * or fail with an error code which is explicitly documented to not corrupt + * structure integrity (such as WANT_READ and WANT_WRITE); + * apart from `xxx_init()` any function assumes state integrity as a + * precondition (but usually more). If any of the preconditions is violated, + * the function's behavior is entirely undefined. + * In addition to state integrity, all MPS structures have a more refined + * notion of abstract state that the API operates on. For example, all layers + * have a notion of 'abtract read state' which indicates if incoming data has + * been passed to the user, e.g. through mps_l2_read_start() for Layer 2 + * or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to + * call these reading functions again until the incoming data has been + * explicitly 'consumed', e.g. through mps_l2_read_consume() for Layer 2 or + * mps_l3_read_consume() on Layer 3. However, even if it doesn't make sense, + * it's a design choice whether the API should fail gracefully on such + * non-sensical calls or not, and that's what this option is about: + * + * This option determines whether the expected abstract state + * is part of the API preconditions or not. If it is, the function's + * behavior is undefined if the abstract state is not as expected. + * If it is set, API is required to fail gracefully with error + * #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED, and without changing the abstract + * state of the input context, if the abstract state is unexpected but + * all other preconditions are satisfied. + * + * For example: Enabling this makes mps_l2_read_done() fail if + * no incoming record is currently open; disabling this would + * lead to undefined behavior in this case. + * + * Comment this to remove state validation. + */ +#define MBEDTLS_MPS_STATE_VALIDATION + /*! This flag enables/disables assertions on the internal state of MPS. * * Assertions are sanity checks that should never trigger when MPS @@ -52,6 +92,28 @@ /*! This flag controls whether tracing for MPS should be enabled. */ //#define MBEDTLS_MPS_TRACE +#if defined(MBEDTLS_MPS_STATE_VALIDATION) + +#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \ + do \ + { \ + if( !(cond) ) \ + { \ + TRACE( trace_error, string ); \ + RETURN( MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED ); \ + } \ + } while( 0 ) + +#else /* MBEDTLS_MPS_STATE_VALIDATION */ + +#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \ + do \ + { \ + ( cond ); \ + } while( 0 ) + +#endif /* MBEDTLS_MPS_STATE_VALIDATION */ + #if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS) #define MBEDTLS_MPS_ASSERT_RAW( cond, string ) \ @@ -70,6 +132,7 @@ #endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */ + /* \} name SECTION: MPS Configuration */ /** diff --git a/library/mps/error.h b/library/mps/error.h index 3c4180f33..8916d6068 100644 --- a/library/mps/error.h +++ b/library/mps/error.h @@ -42,6 +42,24 @@ #define MBEDTLS_MPS_ERR_BASE ( 1 << 0 ) #endif +/** + * \name SECTION: MPS general error codes + * + * \{ + */ + +#ifndef MBEDTLS_MPS_ERR_BASE +#define MBEDTLS_MPS_ERR_BASE ( 1 << 10 ) +#endif + +#define MBEDTLS_MPS_MAKE_ERROR(code) \ + ( -( MBEDTLS_MPS_ERR_BASE | (code) ) ) + + +#define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR( 0x1 ) + +/* \} name SECTION: MPS general error codes */ + /** * \name SECTION: MPS Reader error codes * From 09d880aa38bbf4621d785538ca7b44814177ae55 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:43:30 +0000 Subject: [PATCH 12/68] MPS Reader Tests: Test basic feed-get-commit-reclaim cycle This commit adds an MPS unit test suite `test_suite_mps` which will subsequently be populated with unit tests for all components of MPS. As a start, a test case ``` mbedtls_mps_reader_no_pausing_single_step_single_round() ``` is added which exercises the most basic usage of the MPS reader component; see the test case description for more details. Signed-off-by: Hanno Becker --- tests/CMakeLists.txt | 1 + tests/suites/test_suite_mps.data | 5 +++ tests/suites/test_suite_mps.function | 62 ++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 tests/suites/test_suite_mps.data create mode 100644 tests/suites/test_suite_mps.function diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c141704b5..049b1306b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -134,6 +134,7 @@ add_test_suite(md) add_test_suite(mdx) add_test_suite(memory_buffer_alloc) add_test_suite(mpi) +add_test_suite(mps) add_test_suite(net) add_test_suite(nist_kw) add_test_suite(oid) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data new file mode 100644 index 000000000..ba8958235 --- /dev/null +++ b/tests/suites/test_suite_mps.data @@ -0,0 +1,5 @@ +MPS Reader: Single step, single round, pausing disabled +mbedtls_mps_reader_no_pausing_single_step_single_round:0 + +MPS Reader: Single step, single round, pausing enabled but unused +mbedtls_mps_reader_no_pausing_single_step_single_round:1 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function new file mode 100644 index 000000000..9b06c9ca8 --- /dev/null +++ b/tests/suites/test_suite_mps.function @@ -0,0 +1,62 @@ +/* BEGIN_HEADER */ + +#include + +/* TODO: How are test suites supposed to include internal headers? */ +#include "../library/mps/reader.h" + +/* + * Compile-time configuration for test suite. + */ + +/* Comment/Uncomment this to disable/enable the + * testing of the various MPS layers. + * This can be useful for time-consuming instrumentation + * tasks such as the conversion of E-ACSL annotations + * into runtime assertions. */ +#define TEST_SUITE_MPS_READER + +/* End of compile-time configuration. */ + +/* END_HEADER */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) +{ + /* This test exercises the most basic use of the MPS reader: + * - The 'producing' layer provides a buffer + * - The 'consuming' layer fetches it in a single go. + * - After processing, the consuming layer commit the data + * and returns back to the producing layer. + * + * Parameters: + * - with_acc: 0 if the reader should be initialized without accumulator. + * 1 if the reader should be initialized with accumulator. + * + * Whether the accumulator is present or not should not matter, + * since the consumer's request can be fulfilled from the data + * that the producer has provided. + */ + unsigned char bufA[100]; + unsigned char acc[10]; + unsigned char *tmp; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + if( with_acc == 0 ) + mbedtls_reader_init( &rd, NULL, 0 ); + else + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + /* Consumption (upper layer) */ + /* Consume exactly what's available */ + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 100, bufA, 100 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Wrapup (lower layer) */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From 0e4edfc08376217b773f1d7e930f6f697485e43d Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 07:52:29 +0000 Subject: [PATCH 13/68] MPS Reader Tests: Add test for >1 feed-get-commit-reclaim cycles Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 6 ++++ tests/suites/test_suite_mps.function | 51 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index ba8958235..41e00525a 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -3,3 +3,9 @@ mbedtls_mps_reader_no_pausing_single_step_single_round:0 MPS Reader: Single step, single round, pausing enabled but unused mbedtls_mps_reader_no_pausing_single_step_single_round:1 + +MPS Reader: Single step, multiple rounds, pausing disabled +mbedtls_mps_reader_no_pausing_single_step_multiple_rounds:0 + +MPS Reader: Single step, multiple rounds, pausing enabled but unused +mbedtls_mps_reader_no_pausing_single_step_multiple_rounds:1 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 9b06c9ca8..f29197442 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -60,3 +60,54 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_no_pausing_single_step_multiple_rounds( int with_acc ) +{ + /* This test exercises multiple rounds o fthe basic use of the MPS reader: + * - The 'producing' layer provides a buffer + * - The 'consuming' layer fetches it in a single go. + * - After processing, the consuming layer commit the data + * and returns back to the producing layer. + * + * Parameters: + * - with_acc: 0 if the reader should be initialized without accumulator. + * 1 if the reader should be initialized with accumulator. + * + * Whether the accumulator is present or not should not matter, + * since the consumer's request can be fulfilled from the data + * that the producer has provided. + */ + + unsigned char bufA[100], bufB[100]; + unsigned char acc[10]; + unsigned char *tmp; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + bufB[i] = ~ ((unsigned char) i); + + /* Preparation (lower layer) */ + if( with_acc == 0 ) + mbedtls_reader_init( &rd, NULL, 0 ); + else + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + /* Consumption (upper layer) */ + /* Consume exactly what's available */ + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 100, bufA, 100 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + /* Consumption */ + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 100, bufB, 100 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Wrapup (lower layer) */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From dbd8a9648728c956f042eb62f5ec9b3bc3b58d7c Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:01:16 +0000 Subject: [PATCH 14/68] MPS Reader Tests: Add test for feed-{get,get,...}-commit-reclaim Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 6 ++++ tests/suites/test_suite_mps.function | 49 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index 41e00525a..9b1ab2cd8 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -9,3 +9,9 @@ mbedtls_mps_reader_no_pausing_single_step_multiple_rounds:0 MPS Reader: Single step, multiple rounds, pausing enabled but unused mbedtls_mps_reader_no_pausing_single_step_multiple_rounds:1 + +MPS Reader: Multiple steps, single round, pausing disabled +mbedtls_mps_reader_no_pausing_multiple_steps_single_round:0 + +MPS Reader: Multiple steps, single round, pausing enabled but unused +mbedtls_mps_reader_no_pausing_multiple_steps_single_round:1 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index f29197442..9ef023ad7 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -111,3 +111,52 @@ void mbedtls_mps_reader_no_pausing_single_step_multiple_rounds( int with_acc ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_no_pausing_multiple_steps_single_round( int with_acc ) +{ + /* This test exercises one round of the following: + * - The 'producing' layer provides a buffer + * - The 'consuming' layer fetches it in multiple calls + * to `mbedtls_reader_get()`, without comitting in between. + * - After processing, the consuming layer commit the data + * and returns back to the producing layer. + * + * Parameters: + * - with_acc: 0 if the reader should be initialized without accumulator. + * 1 if the reader should be initialized with accumulator. + * + * Whether the accumulator is present or not should not matter, + * since the consumer's request can be fulfilled from the data + * that the producer has provided. + */ + + /* Lower layer provides data that the upper layer fully consumes + * through multiple `get` calls. */ + unsigned char buf[100]; + unsigned char acc[10]; + unsigned char *tmp; + mbedtls_mps_size_t tmp_len; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + if( with_acc == 0 ) + mbedtls_reader_init( &rd, NULL, 0 ); + else + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, buf, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 70, buf + 10, 70 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, &tmp_len ) == 0 ); + ASSERT_COMPARE( tmp, tmp_len, buf + 80, 20 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Wrapup (lower layer) */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From 7973b2dcacea0455b65711642c4bdfd041c27179 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:11:40 +0000 Subject: [PATCH 15/68] MPS Reader Tests: Test two rounds of fetching in multiple steps Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 6 ++++ tests/suites/test_suite_mps.function | 44 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index 9b1ab2cd8..a31cc8d40 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -15,3 +15,9 @@ mbedtls_mps_reader_no_pausing_multiple_steps_single_round:0 MPS Reader: Multiple steps, single round, pausing enabled but unused mbedtls_mps_reader_no_pausing_multiple_steps_single_round:1 + +MPS Reader: Multiple steps, multiple rounds, pausing disabled +mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds:0 + +MPS Reader: Multiple steps, multiple rounds, pausing enabled but unused +mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds:1 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 9ef023ad7..44b44190e 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -160,3 +160,47 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_single_round( int with_acc ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds( int with_acc ) +{ + /* This test exercises one round of fetching a buffer in multiple chunks + * and passing it back to the producer afterwards, followed by another + * single-step sequence of feed-fetch-commit-reclaim. + */ + unsigned char bufA[100], bufB[100]; + unsigned char acc[10]; + unsigned char *tmp; + mbedtls_mps_size_t tmp_len; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + bufB[i] = ~ ((unsigned char) i); + + /* Preparation (lower layer) */ + if( with_acc == 0 ) + mbedtls_reader_init( &rd, NULL, 0 ); + else + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 70, bufA + 10, 70 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, &tmp_len ) == 0 ); + ASSERT_COMPARE( tmp, tmp_len, bufA + 80, 20 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + /* Consumption */ + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 100, bufB, 100 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From 7d86b74cef3cb31084eb5e4719b46b2a1ee8bfab Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:14:38 +0000 Subject: [PATCH 16/68] MPS Reader Tests: Request more data than what's available Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 3 +++ tests/suites/test_suite_mps.function | 32 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index a31cc8d40..e9bc43d65 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -21,3 +21,6 @@ mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds:0 MPS Reader: Multiple steps, multiple rounds, pausing enabled but unused mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds:1 + +MPS Reader: Pausing needed but disabled +mbedtls_mps_reader_pausing_needed_disabled: diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 44b44190e..aeaad27fd 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -204,3 +204,35 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds( int with_acc mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_pausing_needed_disabled() +{ + /* This test exercises the behaviour of the MPS reader when a read requests + * of the consumer exceeds what has been provided by the producer, and when + * no accumulator is available in the reader. + * + * In this case, we expect the reader to fail. + */ + + unsigned char buf[100]; + unsigned char *tmp; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, NULL, 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 50, buf, 50 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + /* Wrapup (lower layer) */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From caf1a3f6639bcff75c2c6f59c4199b4e43f3a162 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:18:12 +0000 Subject: [PATCH 17/68] MPS Reader Tests: Accumulator too small Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 3 +++ tests/suites/test_suite_mps.function | 33 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index e9bc43d65..b7333a34b 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -24,3 +24,6 @@ mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds:1 MPS Reader: Pausing needed but disabled mbedtls_mps_reader_pausing_needed_disabled: + +MPS Reader: Pausing needed + enabled, but buffer too small +mbedtls_mps_reader_pausing_needed_buffer_too_small: diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index aeaad27fd..f5bb95b0f 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -236,3 +236,36 @@ void mbedtls_mps_reader_pausing_needed_disabled() mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_pausing_needed_buffer_too_small() +{ + /* This test exercises the behaviour of the MPS reader with accumulator + * in the situation where a read requests goes beyond the bounds of the + * current read buffer, _and_ the reader's accumulator is too small to + * hold the requested amount of data. + * + * In this case, we expect the reader to fail. */ + + unsigned char buf[100]; + unsigned char acc[10]; + unsigned char *tmp; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 50, buf, 50 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + /* Wrapup (lower layer) */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From e82952acb3a9be44f1703830ca823be8f4631afb Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:27:29 +0000 Subject: [PATCH 18/68] MPS Reader Tests: Test use of accumulator Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 18 ++++ tests/suites/test_suite_mps.function | 123 +++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index b7333a34b..2bfa04b64 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -27,3 +27,21 @@ mbedtls_mps_reader_pausing_needed_disabled: MPS Reader: Pausing needed + enabled, but buffer too small mbedtls_mps_reader_pausing_needed_buffer_too_small: + +MPS Reader: Pausing, repeat single call without commit +mbedtls_mps_reader_pausing:0 + +MPS Reader: Pausing, repeat single call with commit +mbedtls_mps_reader_pausing:1 + +MPS Reader: Pausing, repeat multiple calls without commit +mbedtls_mps_reader_pausing:2 + +MPS Reader: Pausing, repeat multiple calls with commit #0 +mbedtls_mps_reader_pausing:3 + +MPS Reader: Pausing, repeat multiple calls with commit #1 +mbedtls_mps_reader_pausing:4 + +MPS Reader: Pausing, repeat multiple calls with commit #2 +mbedtls_mps_reader_pausing:5 \ No newline at end of file diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index f5bb95b0f..1d774248c 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -269,3 +269,126 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_pausing( int option ) +{ + /* This test exercises the behaviour of the reader when the + * accumulator is used to fufill the consumer's request. + * + * More detailed: + * - The producer feeds some data. + * - The consumer asks for more data than what's available. + * - The reader remembers the request and goes back to + * producing mode, waiting for more data from the producer. + * - The producer provides another chunk of data which is + * sufficient to fulfill the original read request. + * - The consumer retries the original read request, which + * should now succeed. + * + * This test comes in multiple variants controlled by the + * `option` parameter and documented below. + */ + + unsigned char bufA[100], bufB[100]; + unsigned char *tmp; + unsigned char acc[40]; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + bufB[i] = ~ ((unsigned char) i); + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + + /* Consumption (upper layer) */ + /* Ask for more than what's available. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 80, bufA, 80 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + switch( option ) + { + case 0: /* Single uncommitted fetch at pausing */ + case 1: + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + break; + default: /* Multiple uncommitted fetches at pausing */ + break; + } + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + + /* Consumption */ + switch( option ) + { + case 0: /* Single fetch at pausing, re-fetch with commit. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + break; + + case 1: /* Single fetch at pausing, re-fetch without commit. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + break; + + case 2: /* Multiple fetches at pausing, repeat without commit. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + break; + + case 3: /* Multiple fetches at pausing, repeat with commit 1. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + break; + + case 4: /* Multiple fetches at pausing, repeat with commit 2. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + break; + + case 5: /* Multiple fetches at pausing, repeat with commit 3. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + break; + + default: + TEST_ASSERT( 0 ); + } + + /* In all cases, fetch the rest of the second buffer. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 90, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 90, bufB + 10, 90 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From aac41225d351b2d96826d432112fc9f092041be6 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:36:36 +0000 Subject: [PATCH 19/68] MPS Reader Tests: Test multiple feed() calls to fulfill read request Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 11 ++- tests/suites/test_suite_mps.function | 106 +++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index 2bfa04b64..f622f5367 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -44,4 +44,13 @@ MPS Reader: Pausing, repeat multiple calls with commit #1 mbedtls_mps_reader_pausing:4 MPS Reader: Pausing, repeat multiple calls with commit #2 -mbedtls_mps_reader_pausing:5 \ No newline at end of file +mbedtls_mps_reader_pausing:5 + +MPS Reader: Pausing, feed 50 bytes in 10b + 10b + 80b +mbedtls_mps_reader_pausing_multiple_feeds:0 + +MPS Reader: Pausing, feed 50 bytes in 50x1b +mbedtls_mps_reader_pausing_multiple_feeds:1 + +MPS Reader: Pausing, feed 50 bytes in 49x1b + 51b +mbedtls_mps_reader_pausing_multiple_feeds:2 \ No newline at end of file diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 1d774248c..85aba84b8 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -392,3 +392,109 @@ void mbedtls_mps_reader_pausing( int option ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_pausing_multiple_feeds( int option ) +{ + /* This test exercises the behaviour of the MPS reader + * in the following situation: + * - The consumer has asked for mre than what's available, so the + * reader pauses and waits for further input data via + * `mbedtls_reader_feed()` + * - Multiple such calls to `mbedtls_reader_feed()` are necessary + * to fulfill the original request, and the reader needs to do + * the necessary bookkeeping under the hood. + * + * This test comes in a few variants differing in the number and + * size of feed calls that the producer issues while the reader is + * accumulating the necessary data - see the comments below. + */ + + unsigned char bufA[100], bufB[100]; + unsigned char *tmp; + unsigned char acc[70]; + mbedtls_reader rd; + mbedtls_mps_size_t fetch_len; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + bufB[i] = ~ ((unsigned char) i); + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + + /* Consumption (upper layer) */ + /* Ask for more than what's available. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 80, bufA, 80 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* 20 left, ask for 70 -> 50 overhead */ + TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + switch( option ) + { + case 0: /* 10 + 10 + 80 byte feed */ + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, 10 ) == + MBEDTLS_ERR_MPS_READER_NEED_MORE ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 10, 10 ) == + MBEDTLS_ERR_MPS_READER_NEED_MORE ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 20, 80 ) == 0 ); + break; + + case 1: /* 50 x 1byte */ + for( int num_feed=0; num_feed<49; num_feed++ ) + { + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + num_feed, 1 ) == + MBEDTLS_ERR_MPS_READER_NEED_MORE ); + } + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 49, 1 ) == 0 ); + break; + + case 2: /* 49 x 1byte + 51bytes */ + for( int num_feed=0; num_feed<49; num_feed++ ) + { + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + num_feed, 1 ) == + MBEDTLS_ERR_MPS_READER_NEED_MORE ); + } + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 49, 51 ) == 0 ); + break; + + default: + TEST_ASSERT( 0 ); + break; + } + + /* Consumption */ + TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); + ASSERT_COMPARE( tmp + 20, 50, bufB, 50 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 1000, &tmp, &fetch_len ) == 0 ); + switch( option ) + { + case 0: + TEST_ASSERT( fetch_len == 50 ); + break; + + case 1: + TEST_ASSERT( fetch_len == 0 ); + break; + + case 2: + TEST_ASSERT( fetch_len == 50 ); + break; + + default: + TEST_ASSERT( 0 ); + break; + } + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From cb2a88ed3818dedf359c7b4fe1eab72b3e48785c Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:39:37 +0000 Subject: [PATCH 20/68] MPS Reader Tests: Attempt reclaim while more data is available Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 11 ++++- tests/suites/test_suite_mps.function | 61 ++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index f622f5367..9b94b3b04 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -53,4 +53,13 @@ MPS Reader: Pausing, feed 50 bytes in 50x1b mbedtls_mps_reader_pausing_multiple_feeds:1 MPS Reader: Pausing, feed 50 bytes in 49x1b + 51b -mbedtls_mps_reader_pausing_multiple_feeds:2 \ No newline at end of file +mbedtls_mps_reader_pausing_multiple_feeds:2 + +MPS Reader: Reclaim with data remaining #0 +mbedtls_mps_reader_reclaim_data_left:0 + +MPS Reader: Reclaim with data remaining #1 +mbedtls_mps_reader_reclaim_data_left:1 + +MPS Reader: Reclaim with data remaining #2 +mbedtls_mps_reader_reclaim_data_left:2 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 85aba84b8..dd90b056a 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -498,3 +498,64 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) mbedtls_reader_free( &rd ); } /* END_CASE */ + + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_reclaim_data_left( int option ) +{ + /* This test exercises the behaviour of the MPS reader when a + * call to mbedtls_reader_reclaim() is made before all data + * provided by the producer has been fetched and committed. */ + + unsigned char buf[100]; + unsigned char *tmp; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, NULL, 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + + /* Consumption (upper layer) */ + switch( option ) + { + case 0: + /* Fetch (but not commit) the entire buffer. */ + TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ), &tmp, NULL ) + == 0 ); + ASSERT_COMPARE( tmp, 100, buf, 100 ); + break; + + case 1: + /* Fetch (but not commit) parts of the buffer. */ + TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ) / 2, + &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, sizeof( buf ) / 2, buf, sizeof( buf ) / 2 ); + break; + + case 2: + /* Fetch and commit parts of the buffer, then + * fetch but not commit the rest of the buffer. */ + TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ) / 2, + &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, sizeof( buf ) / 2, buf, sizeof( buf ) / 2 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ) / 2, + &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, sizeof( buf ) / 2, + buf + sizeof( buf ) / 2, + sizeof( buf ) / 2 ); + break; + + default: + TEST_ASSERT( 0 ); + break; + } + + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_DATA_LEFT ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From e1f173c36f147fdaac20e9ca3b9d6c1ef1d1492a Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 08:43:58 +0000 Subject: [PATCH 21/68] MPS Reader Tests: Continue fetching after reclaim() was rejected Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 3 +++ tests/suites/test_suite_mps.function | 35 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index 9b94b3b04..b4e1f75a0 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -63,3 +63,6 @@ mbedtls_mps_reader_reclaim_data_left:1 MPS Reader: Reclaim with data remaining #2 mbedtls_mps_reader_reclaim_data_left:2 + +MPS Reader: Reclaim with data remaining, continue fetching +mbedtls_mps_reader_reclaim_data_left_retry: diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index dd90b056a..485d2a11d 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -559,3 +559,38 @@ void mbedtls_mps_reader_reclaim_data_left( int option ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_reclaim_data_left_retry() +{ + /* This test exercises the behaviour of the MPS reader when an attempt + * by the producer to reclaim the reader fails because of more data pending + * to be processed, and the consumer subsequently fetches more data. */ + unsigned char buf[100]; + unsigned char *tmp; + mbedtls_reader rd; + + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, NULL, 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 50, buf, 50 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 50, buf + 50, 50 ); + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_DATA_LEFT ); + /* Consumption */ + TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 50, buf + 50, 50 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From b6fdd35a38ecd25c2c7a1f82ebd7f80a5cf8e41b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 09:17:56 +0000 Subject: [PATCH 22/68] MPS Reader Tests: Use accumulator multiple times Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 12 +++ tests/suites/test_suite_mps.function | 134 +++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index b4e1f75a0..d9f7c4287 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -66,3 +66,15 @@ mbedtls_mps_reader_reclaim_data_left:2 MPS Reader: Reclaim with data remaining, continue fetching mbedtls_mps_reader_reclaim_data_left_retry: + +MPS Reader: Pausing several times, #0 +mbedtls_mps_reader_multiple_pausing:0 + +MPS Reader: Pausing several times, #1 +mbedtls_mps_reader_multiple_pausing:1 + +MPS Reader: Pausing several times, #2 +mbedtls_mps_reader_multiple_pausing:2 + +MPS Reader: Pausing several times, #3 +mbedtls_mps_reader_multiple_pausing:3 \ No newline at end of file diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 485d2a11d..4d02d0acf 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -594,3 +594,137 @@ void mbedtls_mps_reader_reclaim_data_left_retry() mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_multiple_pausing( int option ) +{ + /* This test exercises the behaviour of the MPS reader + * in the following situation: + * - A read request via `mbedtls_reader_get()` can't + * be served and the reader is paused to accumulate + * the desired amount of data from the producer. + * - Once enough data is availble, the consumer successfully + * reads the data from the reader, but afterwards exceeds + * the available data again - pausing is necessary for a + * second time. + */ + + unsigned char bufA[100], bufB[20], bufC[10]; + unsigned char *tmp; + unsigned char acc[50]; + mbedtls_mps_size_t tmp_len; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + bufB[i] = ~ ((unsigned char) i); + for( int i=0; (unsigned) i < sizeof( bufC ); i++ ) + bufC[i] = ~ ((unsigned char) i); + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + + /* Consumption (upper layer) */ + /* Ask for more than what's available. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 80, bufA, 80 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + + switch( option ) + { + case 0: /* Fetch same chunks, commit afterwards, and + * then exceed bounds of new buffer; accumulator + * large enough. */ + + /* Consume */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, &tmp_len ) == 0 ); + ASSERT_COMPARE( tmp, tmp_len, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Prepare */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufC, sizeof( bufC ) ) == 0 );; + + /* Consume */ + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufB + 10, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufC, 10 ); + break; + + case 1: /* Fetch same chunks, commit afterwards, and + * then exceed bounds of new buffer; accumulator + * not large enough. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 51, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Prepare */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + break; + + case 2: /* Fetch same chunks, don't commit afterwards, and + * then exceed bounds of new buffer; accumulator + * large enough. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Prepare */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufC, sizeof( bufC ) ) == 0 );; + + /* Consume */ + TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); + ASSERT_COMPARE( tmp + 20, 20, bufB, 20 ); + ASSERT_COMPARE( tmp + 40, 10, bufC, 10 ); + break; + + case 3: /* Fetch same chunks, don't commit afterwards, and + * then exceed bounds of new buffer; accumulator + * not large enough. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); + ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 21, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + + /* Prepare */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + break; + + default: + TEST_ASSERT( 0 ); + break; + } + + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From 714cbeb4f50e73401d03e9c0014ae192bd19962f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 09:23:15 +0000 Subject: [PATCH 23/68] MPS Reader Tests: Add random test This commit adds a test exercising the reader in a random way and comparing the outcomes against what we expect based on the abstract model of the reader from the producer's and consumer's perspective. Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 14 +- tests/suites/test_suite_mps.function | 183 +++++++++++++++++++++++++++ 2 files changed, 196 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index d9f7c4287..a751cfaf1 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -77,4 +77,16 @@ MPS Reader: Pausing several times, #2 mbedtls_mps_reader_multiple_pausing:2 MPS Reader: Pausing several times, #3 -mbedtls_mps_reader_multiple_pausing:3 \ No newline at end of file +mbedtls_mps_reader_multiple_pausing:3 + +MPS Reader: Random usage, 20 rds, feed 100, get 200, acc 50 +mbedtls_mps_reader_random_usage:20:100:200:50 + +MPS Reader: Random usage, 1000 rds, feed 10, get 100, acc 80 +mbedtls_mps_reader_random_usage:1000:10:100:80 + +MPS Reader: Random usage, 10000 rds, feed 1, get 100, acc 80 +mbedtls_mps_reader_random_usage:10000:1:100:80 + +MPS Reader: Random usage, 100 rds, feed 100, get 1000, acc 500 +mbedtls_mps_reader_random_usage:100:100:1000:500 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 4d02d0acf..b3ec79bf5 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -728,3 +728,186 @@ void mbedtls_mps_reader_multiple_pausing( int option ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER:MBEDTLS_MPS_STATE_VALIDATION */ +void mbedtls_mps_reader_random_usage( int num_out_chunks, + int max_chunk_size, + int max_request, + int acc_size ) + +{ + /* Randomly pass a reader object back and forth between lower and + * upper layer and let each of them call the respective reader API + * functions in a random fashion. + * + * On the lower layer, we're tracking and concatenating + * the data passed to successful feed calls. + * + * For the upper layer, we track and concatenate buffers + * obtained from successful get calls. + * + * As long as the lower layer calls reclaim at least once, (resetting the + * fetched but not-yet-committed data), this should always lead to the same + * stream of outgoing/incoming data for the lower/upper layers, even if + * most of the random calls fail. + * + * NOTE: This test uses rand() for random data, which is not optimal. + * Instead, it would be better to get the random data from a + * static buffer. This both eases reproducibility and allows + * simple conversion to a fuzz target. + */ + int ret; + unsigned char *acc = NULL; + unsigned char *outgoing = NULL, *incoming = NULL; + unsigned char *cur_chunk = NULL; + size_t cur_out_chunk, out_pos, in_commit, in_fetch; + int rand_op; /* Lower layer: + * - Reclaim (0) + * - Feed (1) + * Upper layer: + * - Get, do tolerate smaller output (0) + * - Get, don't tolerate smaller output (1) + * - Commit (2) */ + int mode = 0; /* Lower layer (0) or Upper layer (1) */ + int reclaimed = 1; /* Have to call reclaim at least once before + * returning the reader to the upper layer. */ + mbedtls_reader rd; + + if( acc_size > 0 ) + { + ASSERT_ALLOC( acc, acc_size ); + } + + /* This probably needs to be changed because we want + * our tests to be deterministic. */ + // srand( time( NULL ) ); + + ASSERT_ALLOC( outgoing, num_out_chunks * max_chunk_size ); + ASSERT_ALLOC( incoming, num_out_chunks * max_chunk_size ); + + mbedtls_reader_init( &rd, acc, acc_size ); + + cur_out_chunk = 0; + in_commit = 0; + in_fetch = 0; + out_pos = 0; + while( cur_out_chunk < (unsigned) num_out_chunks ) + { + if( mode == 0 ) + { + /* Choose randomly between reclaim and feed */ + rand_op = rand() % 2; + + if( rand_op == 0 ) + { + /* Reclaim */ + ret = mbedtls_reader_reclaim( &rd, NULL ); + + if( ret == 0 ) + { + TEST_ASSERT( cur_chunk != NULL ); + mbedtls_free( cur_chunk ); + cur_chunk = NULL; + } + reclaimed = 1; + } + else + { + /* Feed reader with a random chunk */ + unsigned char *tmp = NULL; + size_t tmp_size; + if( cur_out_chunk == (unsigned) num_out_chunks ) + continue; + + tmp_size = ( rand() % max_chunk_size ) + 1; + ASSERT_ALLOC( tmp, tmp_size ); + + TEST_ASSERT( mbedtls_test_rnd_std_rand( NULL, tmp, tmp_size ) == 0 ); + ret = mbedtls_reader_feed( &rd, tmp, tmp_size ); + + if( ret == 0 || ret == MBEDTLS_ERR_MPS_READER_NEED_MORE ) + { + cur_out_chunk++; + memcpy( outgoing + out_pos, tmp, tmp_size ); + out_pos += tmp_size; + } + + if( ret == 0 ) + { + TEST_ASSERT( cur_chunk == NULL ); + cur_chunk = tmp; + } + else + { + mbedtls_free( tmp ); + } + + } + + /* Randomly switch to consumption mode if reclaim + * was called at least once. */ + if( reclaimed == 1 && rand() % 3 == 0 ) + { + in_fetch = 0; + mode = 1; + } + } + else + { + /* Choose randomly between get tolerating fewer data, + * get not tolerating fewer data, and commit. */ + rand_op = rand() % 3; + if( rand_op == 0 || rand_op == 1 ) + { + mbedtls_mps_size_t get_size, real_size; + unsigned char *chunk_get; + get_size = ( rand() % max_request ) + 1; + if( rand_op == 0 ) + { + ret = mbedtls_reader_get( &rd, get_size, &chunk_get, + &real_size ); + } + else + { + real_size = get_size; + ret = mbedtls_reader_get( &rd, get_size, &chunk_get, NULL ); + } + + /* Check if output is in accordance with what was written */ + if( ret == 0 ) + { + memcpy( incoming + in_commit + in_fetch, + chunk_get, real_size ); + TEST_ASSERT( memcmp( incoming + in_commit + in_fetch, + outgoing + in_commit + in_fetch, + real_size ) == 0 ); + in_fetch += real_size; + } + } + else if( rand_op == 2 ) /* Commit */ + { + ret = mbedtls_reader_commit( &rd ); + if( ret == 0 ) + { + in_commit += in_fetch; + in_fetch = 0; + } + } + + /* Randomly switch back to preparation */ + if( rand() % 3 == 0 ) + { + reclaimed = 0; + mode = 0; + } + } + } + + /* Cleanup */ + mbedtls_reader_free( &rd ); + mbedtls_free( incoming ); + mbedtls_free( outgoing ); + mbedtls_free( acc ); + mbedtls_free( cur_chunk ); +} +/* END_CASE */ From 223b72e40e13b794a2b7eee2841c8def4ec29aeb Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 09:31:31 +0000 Subject: [PATCH 24/68] MPS Reader Tests: Exercise inconsistent reads after pausing Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 27 +++++ tests/suites/test_suite_mps.function | 148 +++++++++++++++++++++++++++ 2 files changed, 175 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index a751cfaf1..a1a6e5c26 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -90,3 +90,30 @@ mbedtls_mps_reader_random_usage:10000:1:100:80 MPS Reader: Random usage, 100 rds, feed 100, get 1000, acc 500 mbedtls_mps_reader_random_usage:100:100:1000:500 + +MPS Reader: Pausing, inconsistent continuation, #0 +mbedtls_reader_inconsistent_usage:0 + +MPS Reader: Pausing, inconsistent continuation, #1 +mbedtls_reader_inconsistent_usage:1 + +MPS Reader: Pausing, inconsistent continuation, #2 +mbedtls_reader_inconsistent_usage:2 + +MPS Reader: Pausing, inconsistent continuation, #3 +mbedtls_reader_inconsistent_usage:3 + +MPS Reader: Pausing, inconsistent continuation, #4 +mbedtls_reader_inconsistent_usage:4 + +MPS Reader: Pausing, inconsistent continuation, #5 +mbedtls_reader_inconsistent_usage:5 + +MPS Reader: Pausing, inconsistent continuation, #6 +mbedtls_reader_inconsistent_usage:6 + +MPS Reader: Pausing, inconsistent continuation, #7 +mbedtls_reader_inconsistent_usage:7 + +MPS Reader: Pausing, inconsistent continuation, #8 +mbedtls_reader_inconsistent_usage:8 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index b3ec79bf5..6f2eb653a 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -911,3 +911,151 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, mbedtls_free( cur_chunk ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_reader_inconsistent_usage( int option ) +{ + /* This test exercises the behaviour of the MPS reader + * in the following situation: + * - The consumer asks for more data than what's available + * - The reader is paused and receives more data from the + * producer until the original read request can be fulfilled. + * - The consumer does not repeat the original request but + * requests data in a different way. + * + * The reader does not guarantee that inconsistent read requests + * after pausing will succeed, and this test triggers some cases + * where the request fails. + */ + + unsigned char bufA[100], bufB[100]; + unsigned char *tmp; + unsigned char acc[40]; + mbedtls_reader rd; + int success = 0; + for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + bufA[i] = (unsigned char) i; + for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + bufB[i] = ~ ((unsigned char) i); + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + /* Preparation */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + /* Consumption */ + switch( option ) + { + case 0: + /* Ask for buffered data in a single chunk, no commit */ + TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); + ASSERT_COMPARE( tmp + 20, 10, bufB, 10 ); + success = 1; + break; + + case 1: + /* Ask for buffered data in a single chunk, with commit */ + TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); + ASSERT_COMPARE( tmp + 20, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + success = 1; + break; + + case 2: + /* Ask for more than was requested when pausing, #1 */ + TEST_ASSERT( mbedtls_reader_get( &rd, 31, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); + break; + + case 3: + /* Ask for more than was requested when pausing #2 */ + TEST_ASSERT( mbedtls_reader_get( &rd, (mbedtls_mps_size_t) -1, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); + break; + + case 4: + /* Asking for buffered data in different + * chunks than before CAN fail. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); + break; + + case 5: + /* Asking for buffered data different chunks + * than before NEED NOT fail - no commits */ + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); + ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); + success = 1; + break; + + case 6: + /* Asking for buffered data different chunks + * than before NEED NOT fail - intermediate commit */ + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); + ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); + success = 1; + break; + + case 7: + /* Asking for buffered data different chunks + * than before NEED NOT fail - end commit */ + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); + ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + success = 1; + break; + + case 8: + /* Asking for buffered data different chunks + * than before NEED NOT fail - intermediate & end commit */ + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); + TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); + ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + success = 1; + break; + + default: + TEST_ASSERT( 0 ); + break; + } + + if( success == 1 ) + { + /* In all succeeding cases, fetch the rest of the second buffer. */ + TEST_ASSERT( mbedtls_reader_get( &rd, 90, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 90, bufB + 10, 90 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + } + + /* Wrapup */ + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From 2b8bad3e80a591c126c258e2d43b22acd1de6028 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 09:40:05 +0000 Subject: [PATCH 25/68] MPS Reader Tests: Test feed() of NULL buffer Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 3 +++ tests/suites/test_suite_mps.function | 38 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index a1a6e5c26..158302b8e 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -117,3 +117,6 @@ mbedtls_reader_inconsistent_usage:7 MPS Reader: Pausing, inconsistent continuation, #8 mbedtls_reader_inconsistent_usage:8 + +MPS Reader: Feed with invalid buffer (NULL) +mbedtls_mps_reader_feed_empty:0 diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 6f2eb653a..f2040f8f6 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -1059,3 +1059,41 @@ void mbedtls_reader_inconsistent_usage( int option ) mbedtls_reader_free( &rd ); } /* END_CASE */ + +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_feed_empty( int option ) +{ + /* This test exercises the behaviour of the reader when it is + * fed a NULL buffer. */ + unsigned char buf[100]; + unsigned char *tmp; + mbedtls_reader rd; + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + + /* Preparation (lower layer) */ + mbedtls_reader_init( &rd, NULL, 0 ); + switch( option ) + { + case 0: /* NULL buffer */ + TEST_ASSERT( mbedtls_reader_feed( &rd, NULL, sizeof( buf ) ) == + MBEDTLS_ERR_MPS_READER_INVALID_ARG ); + break; + + default: + TEST_ASSERT( 0 ); + break; + } + /* Subsequent feed-calls should still succeed. */ + TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 100, buf, 100 ); + TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + + /* Wrapup */ + TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_reader_free( &rd ); +} +/* END_CASE */ From b910016049910544899c677f8da5c99855788d85 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 12 Jan 2021 09:46:03 +0000 Subject: [PATCH 26/68] 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 ); From c518c3b7bb36072bf72555aa6779eed2079504fa Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 28 Jan 2021 07:08:08 +0000 Subject: [PATCH 27/68] Rename MPS files library/mps/xxx.[ch] to library/mps_xxx.[ch] Signed-off-by: Hanno Becker --- library/CMakeLists.txt | 4 ++-- library/Makefile | 4 ++-- library/{mps/common.h => mps_common.h} | 0 library/{mps/error.h => mps_error.h} | 0 library/{mps/reader.c => mps_reader.c} | 6 +++--- library/{mps/reader.h => mps_reader.h} | 4 ++-- library/{mps/trace.c => mps_trace.c} | 4 ++-- library/{mps/trace.h => mps_trace.h} | 5 ++--- tests/suites/test_suite_mps.function | 2 +- 9 files changed, 14 insertions(+), 15 deletions(-) rename library/{mps/common.h => mps_common.h} (100%) rename library/{mps/error.h => mps_error.h} (100%) rename library/{mps/reader.c => mps_reader.c} (99%) rename library/{mps/reader.h => mps_reader.h} (99%) rename library/{mps/trace.c => mps_trace.c} (98%) rename library/{mps/trace.h => mps_trace.h} (99%) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 2c1bccb29..220fbf92b 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -47,8 +47,8 @@ set(src_crypto md4.c md5.c memory_buffer_alloc.c - mps/reader.c - mps/trace.o + mps_reader.c + mps_trace.c nist_kw.c oid.c padlock.c diff --git a/library/Makefile b/library/Makefile index 0fb6eeb56..419291acf 100644 --- a/library/Makefile +++ b/library/Makefile @@ -104,8 +104,8 @@ OBJS_CRYPTO= \ md4.o \ md5.o \ memory_buffer_alloc.o \ - mps/reader.o \ - mps/trace.o \ + mps_reader.o \ + mps_trace.o \ nist_kw.o \ oid.o \ padlock.o \ diff --git a/library/mps/common.h b/library/mps_common.h similarity index 100% rename from library/mps/common.h rename to library/mps_common.h diff --git a/library/mps/error.h b/library/mps_error.h similarity index 100% rename from library/mps/error.h rename to library/mps_error.h diff --git a/library/mps/reader.c b/library/mps_reader.c similarity index 99% rename from library/mps/reader.c rename to library/mps_reader.c index 791b8bd72..e6fbb0708 100644 --- a/library/mps/reader.c +++ b/library/mps_reader.c @@ -19,9 +19,9 @@ * This file is part of Mbed TLS (https://tls.mbed.org) */ -#include "reader.h" -#include "common.h" -#include "trace.h" +#include "mps_reader.h" +#include "mps_common.h" +#include "mps_trace.h" #include diff --git a/library/mps/reader.h b/library/mps_reader.h similarity index 99% rename from library/mps/reader.h rename to library/mps_reader.h index 5801e1c87..403917067 100644 --- a/library/mps/reader.h +++ b/library/mps_reader.h @@ -116,8 +116,8 @@ #include -#include "common.h" -#include "error.h" +#include "mps_common.h" +#include "mps_error.h" struct mbedtls_reader; typedef struct mbedtls_reader mbedtls_reader; diff --git a/library/mps/trace.c b/library/mps_trace.c similarity index 98% rename from library/mps/trace.c rename to library/mps_trace.c index 61965dca1..06c6e2668 100644 --- a/library/mps/trace.c +++ b/library/mps_trace.c @@ -19,11 +19,11 @@ * This file is part of Mbed TLS (https://tls.mbed.org) */ -#include "common.h" +#include "mps_common.h" #if defined(MBEDTLS_MPS_TRACE) -#include "trace.h" +#include "mps_trace.h" #include static int trace_depth_ = 0; diff --git a/library/mps/trace.h b/library/mps_trace.h similarity index 99% rename from library/mps/trace.h rename to library/mps_trace.h index b1da7ede2..f03ba9a42 100644 --- a/library/mps/trace.h +++ b/library/mps_trace.h @@ -27,10 +27,9 @@ #define MBEDTLS_MPS_TRACE_H #include "common.h" +#include "mps_common.h" +#include "mps_trace.h" -#include "../common.h" - -#include "trace.h" #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index f2040f8f6..3c841631f 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -3,7 +3,7 @@ #include /* TODO: How are test suites supposed to include internal headers? */ -#include "../library/mps/reader.h" +#include "../library/mps_reader.h" /* * Compile-time configuration for test suite. From 984fbded58ba2c0c6359e044bad9b72061800acf Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 28 Jan 2021 09:02:18 +0000 Subject: [PATCH 28/68] Move MPS trace macros to MBEDTLS_MPS_ namespace Signed-off-by: Hanno Becker --- library/mps_common.h | 36 +++++----- library/mps_error.h | 3 +- library/mps_reader.c | 154 +++++++++++++++++++++++++---------------- library/mps_reader.h | 4 +- library/mps_trace.c | 24 +++---- library/mps_trace.h | 158 +++++++++++++++++++++---------------------- 6 files changed, 208 insertions(+), 171 deletions(-) diff --git a/library/mps_common.h b/library/mps_common.h index 37a4cefe5..1ac3bd8b2 100644 --- a/library/mps_common.h +++ b/library/mps_common.h @@ -26,6 +26,8 @@ #ifndef MBEDTLS_MPS_COMMON_H #define MBEDTLS_MPS_COMMON_H +#include "mps_error.h" + #include /** @@ -90,18 +92,18 @@ #define MBEDTLS_MPS_ENABLE_ASSERTIONS /*! This flag controls whether tracing for MPS should be enabled. */ -//#define MBEDTLS_MPS_TRACE +//#define MBEDTLS_MPS_ENABLE_TRACE #if defined(MBEDTLS_MPS_STATE_VALIDATION) -#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \ - do \ - { \ - if( !(cond) ) \ - { \ - TRACE( trace_error, string ); \ - RETURN( MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED ); \ - } \ +#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \ + do \ + { \ + if( !(cond) ) \ + { \ + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, string ); \ + MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED ); \ + } \ } while( 0 ) #else /* MBEDTLS_MPS_STATE_VALIDATION */ @@ -116,14 +118,14 @@ #if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS) -#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) \ - do \ - { \ - if( !(cond) ) \ - { \ - TRACE( trace_error, string ); \ - RETURN( MBEDTLS_ERR_MPS_INTERNAL_ERROR ); \ - } \ +#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) \ + do \ + { \ + if( !(cond) ) \ + { \ + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, string ); \ + MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_INTERNAL_ERROR ); \ + } \ } while( 0 ) #else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */ diff --git a/library/mps_error.h b/library/mps_error.h index 8916d6068..8d8306455 100644 --- a/library/mps_error.h +++ b/library/mps_error.h @@ -30,7 +30,7 @@ /* TODO: The error code allocation needs to be revisited: * * - Should we make (some of) the MPS Reader error codes public? - * If so, we need to adjust MBEDTLS_READER_MAKE_ERROR() to hit + * If so, we need to adjust MBEDTLS_MPS_READER_MAKE_ERROR() to hit * a gap in the Mbed TLS public error space. * If not, we have to make sure we don't forward those errors * at the level of the public API -- no risk at the moment as @@ -57,6 +57,7 @@ #define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR( 0x1 ) +#define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR( 0x2 ) /* \} name SECTION: MPS general error codes */ diff --git a/library/mps_reader.c b/library/mps_reader.c index e6fbb0708..8a686898c 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -30,9 +30,9 @@ #define inline __inline #endif -#if defined(MBEDTLS_MPS_TRACE) -static int trace_id = TRACE_BIT_READER; -#endif /* MBEDTLS_MPS_TRACE */ +#if defined(MBEDTLS_MPS_ENABLE_TRACE) +static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; +#endif /* MBEDTLS_MPS_ENABLE_TRACE */ /* * GENERAL NOTE ON CODING STYLE @@ -92,18 +92,18 @@ int mbedtls_reader_init( mbedtls_reader *rd, unsigned char *acc, mbedtls_mps_size_t acc_len ) { - TRACE_INIT( "reader_init, acc len %u", (unsigned) acc_len ); + MBEDTLS_MPS_TRACE_INIT( "reader_init, acc len %u", (unsigned) acc_len ); mps_reader_zero( rd ); rd->acc = acc; rd->acc_len = acc_len; - RETURN( 0 ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } int mbedtls_reader_free( mbedtls_reader *rd ) { - TRACE_INIT( "reader_free" ); + MBEDTLS_MPS_TRACE_INIT( "reader_free" ); mps_reader_zero( rd ); - RETURN( 0 ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } int mbedtls_reader_feed( mbedtls_reader *rd, @@ -112,11 +112,11 @@ int mbedtls_reader_feed( mbedtls_reader *rd, { unsigned char *acc; mbedtls_mps_size_t copy_to_acc; - TRACE_INIT( "reader_feed, frag %p, len %u", + MBEDTLS_MPS_TRACE_INIT( "reader_feed, frag %p, len %u", (void*) new_frag, (unsigned) new_frag_len ); if( new_frag == NULL ) - RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG ); + MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG ); MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag == NULL, "mbedtls_reader_feed() requires reader to be in producing mode" ); @@ -138,7 +138,8 @@ int mbedtls_reader_feed( mbedtls_reader *rd, if( copy_to_acc > 0 ) memcpy( acc, new_frag, copy_to_acc ); - TRACE( trace_comment, "Copy new data of size %u of %u into accumulator at offset %u", + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Copy new data of size %u of %u into accumulator at offset %u", (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) aa ); /* Check if, with the new fragment, we have enough data. */ @@ -149,10 +150,11 @@ int mbedtls_reader_feed( mbedtls_reader *rd, aa += copy_to_acc; rd->acc_share.acc_remaining = ar; rd->acc_avail = aa; - RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE ); + MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE ); } - TRACE( trace_comment, "Enough data available to serve user request" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Enough data available to serve user request" ); rd->acc_share.frag_offset = aa; aa += copy_to_acc; @@ -167,7 +169,7 @@ int mbedtls_reader_feed( mbedtls_reader *rd, rd->frag_len = new_frag_len; rd->commit = 0; rd->end = 0; - RETURN( 0 ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } @@ -178,7 +180,8 @@ int mbedtls_reader_get( mbedtls_reader *rd, { unsigned char *frag, *acc; mbedtls_mps_size_t end, fo, fl, frag_fetched, frag_remaining; - TRACE_INIT( "reader_get %p, desired %u", (void*) rd, (unsigned) desired ); + MBEDTLS_MPS_TRACE_INIT( "reader_get %p, desired %u", + (void*) rd, (unsigned) desired ); frag = rd->frag; MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, @@ -193,7 +196,8 @@ int mbedtls_reader_get( mbedtls_reader *rd, else fo = rd->acc_share.frag_offset; - TRACE( trace_comment, "frag_off %u, end %u, acc_avail %d", + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "frag_off %u, end %u, acc_avail %d", (unsigned) fo, (unsigned) rd->end, acc == NULL ? -1 : (int) rd->acc_avail ); @@ -201,7 +205,8 @@ int mbedtls_reader_get( mbedtls_reader *rd, end = rd->end; if( end < fo ) { - TRACE( trace_comment, "Serve the request from the accumulator" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Serve the request from the accumulator" ); if( fo - end < desired ) { /* Illustration of supported and unsupported cases: @@ -281,7 +286,8 @@ int mbedtls_reader_get( mbedtls_reader *rd, * If we believe we adhere to this restricted usage throughout * the library, this check is a good opportunity to * validate this. */ - RETURN( MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); + MBEDTLS_MPS_TRACE_RETURN( + MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); } } @@ -294,11 +300,12 @@ int mbedtls_reader_get( mbedtls_reader *rd, rd->end = end; rd->pending = 0; - RETURN( 0 ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } /* Attempt to serve the request from the current fragment */ - TRACE( trace_comment, "Serve the request from the current fragment." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Serve the request from the current fragment." ); fl = rd->frag_len; frag_fetched = end - fo; /* The amount of data from the current fragment @@ -309,7 +316,9 @@ int mbedtls_reader_get( mbedtls_reader *rd, /* Check if we can serve the read request from the fragment. */ if( frag_remaining < desired ) { - TRACE( trace_comment, "There's not enough data in the current fragment to serve the request." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "There's not enough data in the current fragment " + "to serve the request." ); /* There's not enough data in the current fragment, * so either just RETURN what we have or fail. */ if( buflen == NULL ) @@ -317,10 +326,11 @@ int mbedtls_reader_get( mbedtls_reader *rd, if( frag_remaining > 0 ) { rd->pending = desired - frag_remaining; - TRACE( trace_comment, "Remember to collect %u bytes before re-opening", + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Remember to collect %u bytes before re-opening", (unsigned) rd->pending ); } - RETURN( MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); } desired = frag_remaining; @@ -335,14 +345,14 @@ int mbedtls_reader_get( mbedtls_reader *rd, end += desired; rd->end = end; rd->pending = 0; - RETURN( 0 ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } int mbedtls_reader_commit( mbedtls_reader *rd ) { unsigned char *acc; mbedtls_mps_size_t aa, end, fo, shift; - TRACE_INIT( "reader_commit" ); + MBEDTLS_MPS_TRACE_INIT( "reader_commit" ); MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag != NULL, "mbedtls_reader_commit() requires reader to be in consuming mode" ); @@ -352,21 +362,24 @@ int mbedtls_reader_commit( mbedtls_reader *rd ) if( acc == NULL ) { - TRACE( trace_comment, "No accumulator, just shift end" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "No accumulator, just shift end" ); rd->commit = end; - RETURN( 0 ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } fo = rd->acc_share.frag_offset; if( end >= fo ) { - TRACE( trace_comment, "Started to serve fragment, get rid of accumulator" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Started to serve fragment, get rid of accumulator" ); shift = fo; aa = 0; } else { - TRACE( trace_comment, "Still serving from accumulator" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Still serving from accumulator" ); aa = rd->acc_avail; shift = end; memmove( acc, acc + shift, aa - shift ); @@ -381,9 +394,10 @@ int mbedtls_reader_commit( mbedtls_reader *rd ) rd->commit = end; rd->end = end; - TRACE( trace_comment, "Final state: (end=commit,fo,avail) = (%u,%u,%u)", - (unsigned) end, (unsigned) fo, (unsigned) aa ); - RETURN( 0 ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Final state: (end=commit,fo,avail) = (%u,%u,%u)", + (unsigned) end, (unsigned) fo, (unsigned) aa ); + MBEDTLS_MPS_TRACE_RETURN( 0 ); } int mbedtls_reader_reclaim( mbedtls_reader *rd, @@ -392,7 +406,7 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, unsigned char *frag, *acc; mbedtls_mps_size_t pending, commit; mbedtls_mps_size_t al, fo, fl; - TRACE_INIT( "reader_reclaim" ); + MBEDTLS_MPS_TRACE_INIT( "reader_reclaim" ); if( paused != NULL ) *paused = 0; @@ -413,27 +427,33 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, if( pending == 0 ) { - TRACE( trace_comment, "No unsatisfied read-request has been logged." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "No unsatisfied read-request has been logged." ); /* Check if there's data left to be consumed. */ if( commit < fo || commit - fo < fl ) { - TRACE( trace_comment, "There is data left to be consumed." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "There is data left to be consumed." ); rd->end = commit; - RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT ); + MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT ); } - TRACE( trace_comment, "The fragment has been completely processed and committed." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "The fragment has been completely processed and committed." ); } else { mbedtls_mps_size_t frag_backup_offset; mbedtls_mps_size_t frag_backup_len; - TRACE( trace_comment, "There has been an unsatisfied read-request with %u bytes overhead.", - (unsigned) pending ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "There has been an unsatisfied read-request with %u bytes overhead.", + (unsigned) pending ); if( acc == NULL ) { - TRACE( trace_comment, "No accumulator present" ); - RETURN( MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "No accumulator present" ); + MBEDTLS_MPS_TRACE_RETURN( + MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR ); } al = rd->acc_len; @@ -443,7 +463,8 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, { /* No, accumulator is still being processed. */ int overflow; - TRACE( trace_comment, "Still processing data from the accumulator" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Still processing data from the accumulator" ); overflow = ( fo + fl < fo ) || ( fo + fl + pending < fo + fl ); @@ -451,12 +472,16 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, { rd->end = commit; rd->pending = 0; - TRACE( trace_error, "The accumulator is too small to handle the backup." ); - TRACE( trace_error, "* Remaining size: %u", (unsigned) al ); - TRACE( trace_error, "* Needed: %u (%u + %u + %u)", - (unsigned) ( fo + fl + pending ), - (unsigned) fo, (unsigned) fl, (unsigned) pending ); - RETURN( MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "The accumulator is too small to handle the backup." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "* Remaining size: %u", (unsigned) al ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "* Needed: %u (%u + %u + %u)", + (unsigned) ( fo + fl + pending ), + (unsigned) fo, (unsigned) fl, (unsigned) pending ); + MBEDTLS_MPS_TRACE_RETURN( + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); } frag_backup_offset = 0; frag_backup_len = fl; @@ -465,7 +490,8 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, { /* Yes, the accumulator is already processed. */ int overflow; - TRACE( trace_comment, "The accumulator has already been processed" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "The accumulator has already been processed" ); frag_backup_offset = commit; frag_backup_len = fl - commit; @@ -476,12 +502,17 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, { rd->end = commit; rd->pending = 0; - TRACE( trace_error, "The accumulator is too small to handle the backup." ); - TRACE( trace_error, "* Remaining size: %u", (unsigned) ( al - fo ) ); - TRACE( trace_error, "* Needed: %u (%u + %u)", - (unsigned) ( frag_backup_len + pending ), - (unsigned) frag_backup_len, (unsigned) pending ); - RETURN( MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "The accumulator is too small to handle the backup." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "* Remaining size: %u", (unsigned) ( al - fo ) ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "* Needed: %u (%u + %u)", + (unsigned) ( frag_backup_len + pending ), + (unsigned) frag_backup_len, (unsigned) pending ); + MBEDTLS_MPS_TRACE_RETURN( + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); } } @@ -489,8 +520,9 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, acc += fo; memcpy( acc, frag, frag_backup_len ); - TRACE( trace_comment, "Backup %u bytes into accumulator", - (unsigned) frag_backup_len ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Backup %u bytes into accumulator", + (unsigned) frag_backup_len ); rd->acc_avail = fo + frag_backup_len; rd->acc_share.acc_remaining = pending; @@ -506,8 +538,10 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, rd->end = 0; rd->pending = 0; - TRACE( trace_comment, "Final state: aa %u, al %u, ar %u", - (unsigned) rd->acc_avail, (unsigned) rd->acc_len, - (unsigned) rd->acc_share.acc_remaining ); - RETURN( 0 ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Final state: aa %u, al %u, ar %u", + (unsigned) rd->acc_avail, (unsigned) rd->acc_len, + (unsigned) rd->acc_share.acc_remaining ); + + MBEDTLS_MPS_TRACE_RETURN( 0 ); } diff --git a/library/mps_reader.h b/library/mps_reader.h index 403917067..ec59d33c3 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -257,7 +257,7 @@ int mbedtls_reader_free( mbedtls_reader *reader ); * moved to consuming state, and ownership of \p buf * will be passed to the reader until mbedtls_reader_reclaim() * is called. - * \return \c MBEDTLS_ERR_READER_NEED_MORE if more input data is + * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is * required to fulfill a previous request to mbedtls_reader_get(). * In this case, the reader remains in producing state and * takes no ownership of the provided buffer (an internal copy @@ -308,7 +308,7 @@ int mbedtls_reader_reclaim( mbedtls_reader *reader, * (if \c buflen == \c NULL). The user hass ownership * of the buffer until the next call to mbedtls_reader_commit(). * or mbedtls_reader_reclaim(). - * \return #MBEDTLS_ERR_READER_OUT_OF_DATA if there is not enough + * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough * data available to serve the read request. In this case, * the reader remains intact, and additional data can be * provided by reclaiming the current input buffer via diff --git a/library/mps_trace.c b/library/mps_trace.c index 06c6e2668..ceddffb56 100644 --- a/library/mps_trace.c +++ b/library/mps_trace.c @@ -21,7 +21,7 @@ #include "mps_common.h" -#if defined(MBEDTLS_MPS_TRACE) +#if defined(MBEDTLS_MPS_ENABLE_TRACE) #include "mps_trace.h" #include @@ -50,7 +50,7 @@ static char const * colors[] = #define MPS_TRACE_BUF_SIZE 100 -void trace_print_msg( int id, int line, const char *format, ... ) +void mbedtls_mps_trace_print_msg( int id, int line, const char *format, ... ) { int ret; char str[MPS_TRACE_BUF_SIZE]; @@ -66,27 +66,27 @@ void trace_print_msg( int id, int line, const char *format, ... ) } } -int trace_get_depth() +int mbedtls_mps_trace_get_depth() { return trace_depth_; } -void trace_dec_depth() +void mbedtls_mps_trace_dec_depth() { trace_depth_--; } -void trace_inc_depth() +void mbedtls_mps_trace_inc_depth() { trace_depth_++; } -void trace_color( int id ) +void mbedtls_mps_trace_color( int id ) { if( id > (int) ( sizeof( colors ) / sizeof( *colors ) ) ) return; printf( "%s", colors[ id ] ); } -void trace_indent( int level, trace_type ty ) +void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty ) { if( level > 0 ) { @@ -98,19 +98,19 @@ void trace_indent( int level, trace_type ty ) switch( ty ) { - case trace_comment: + case mbedtls_mps_trace_comment: mbedtls_printf( "@ " ); break; - case trace_call: + case mbedtls_mps_trace_call: mbedtls_printf( "+--> " ); break; - case trace_error: + case mbedtls_mps_trace_error: mbedtls_printf( "E " ); break; - case trace_return: + case mbedtls_mps_trace_return: mbedtls_printf( "< " ); break; @@ -119,4 +119,4 @@ void trace_indent( int level, trace_type ty ) } } -#endif /* MBEDTLS_MPS_TRACE */ +#endif /* MBEDTLS_MPS_ENABLE_TRACE */ diff --git a/library/mps_trace.h b/library/mps_trace.h index f03ba9a42..d94ceb912 100644 --- a/library/mps_trace.h +++ b/library/mps_trace.h @@ -23,8 +23,8 @@ * \brief Tracing module for MPS */ -#ifndef MBEDTLS_MPS_TRACE_H -#define MBEDTLS_MPS_TRACE_H +#ifndef MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H +#define MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H #include "common.h" #include "mps_common.h" @@ -38,138 +38,138 @@ #define mbedtls_vsnprintf vsnprintf #endif /* MBEDTLS_PLATFORM_C */ -#if defined(MBEDTLS_MPS_TRACE) +#if defined(MBEDTLS_MPS_ENABLE_TRACE) /* * 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 +#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_1 +#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_2 +#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_3 +#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_4 +#define MBEDTLS_MPS_TRACE_ENABLE_READER +#define MBEDTLS_MPS_TRACE_ENABLE_WRITER /* * To use the existing trace module, only change - * TRACE_ENABLE_XXX above, but don't modify the + * MBEDTLS_MPS_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; + mbedtls_mps_trace_comment, + mbedtls_mps_trace_call, + mbedtls_mps_trace_error, + mbedtls_mps_trace_return +} mbedtls_mps_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 +#define MBEDTLS_MPS_TRACE_BIT_LAYER_1 1 +#define MBEDTLS_MPS_TRACE_BIT_LAYER_2 2 +#define MBEDTLS_MPS_TRACE_BIT_LAYER_3 3 +#define MBEDTLS_MPS_TRACE_BIT_LAYER_4 4 +#define MBEDTLS_MPS_TRACE_BIT_WRITER 5 +#define MBEDTLS_MPS_TRACE_BIT_READER 6 -#if defined(TRACE_ENABLE_LAYER_1) -#define TRACE_MASK_LAYER_1 (1u << TRACE_BIT_LAYER_1 ) +#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_1) +#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_1 ) #else -#define TRACE_MASK_LAYER_1 0 +#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 0 #endif -#if defined(TRACE_ENABLE_LAYER_2) -#define TRACE_MASK_LAYER_2 (1u << TRACE_BIT_LAYER_2 ) +#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_2) +#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_2 ) #else -#define TRACE_MASK_LAYER_2 0 +#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 0 #endif -#if defined(TRACE_ENABLE_LAYER_3) -#define TRACE_MASK_LAYER_3 (1u << TRACE_BIT_LAYER_3 ) +#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_3) +#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_3 ) #else -#define TRACE_MASK_LAYER_3 0 +#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 0 #endif -#if defined(TRACE_ENABLE_LAYER_4) -#define TRACE_MASK_LAYER_4 (1u << TRACE_BIT_LAYER_4 ) +#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_4) +#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_4 ) #else -#define TRACE_MASK_LAYER_4 0 +#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 0 #endif -#if defined(TRACE_ENABLE_READER) -#define TRACE_MASK_READER (1u << TRACE_BIT_READER ) +#if defined(MBEDTLS_MPS_TRACE_ENABLE_READER) +#define MBEDTLS_MPS_TRACE_MASK_READER (1u << MBEDTLS_MPS_TRACE_BIT_READER ) #else -#define TRACE_MASK_READER 0 +#define MBEDTLS_MPS_TRACE_MASK_READER 0 #endif -#if defined(TRACE_ENABLE_WRITER) -#define TRACE_MASK_WRITER (1u << TRACE_BIT_WRITER ) +#if defined(MBEDTLS_MPS_TRACE_ENABLE_WRITER) +#define MBEDTLS_MPS_TRACE_MASK_WRITER (1u << MBEDTLS_MPS_TRACE_BIT_WRITER ) #else -#define TRACE_MASK_WRITER 0 +#define MBEDTLS_MPS_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 ) +#define MBEDTLS_MPS_TRACE_MASK ( MBEDTLS_MPS_TRACE_MASK_LAYER_1 | \ + MBEDTLS_MPS_TRACE_MASK_LAYER_2 | \ + MBEDTLS_MPS_TRACE_MASK_LAYER_3 | \ + MBEDTLS_MPS_TRACE_MASK_LAYER_4 | \ + MBEDTLS_MPS_TRACE_MASK_READER | \ + MBEDTLS_MPS_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 ); +int mbedtls_mps_trace_get_depth( void ); +void mbedtls_mps_trace_inc_depth( void ); +void mbedtls_mps_trace_dec_depth( void ); -void trace_color( int id ); -void trace_indent( int level, trace_type ty ); +void mbedtls_mps_trace_color( int id ); +void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty ); -void trace_print_msg( int id, int line, const char *format, ... ); +void mbedtls_mps_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 ); \ +#define MBEDTLS_MPS_TRACE( type, ... ) \ + do { \ + if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \ + break; \ + mbedtls_mps_trace_indent( mbedtls_mps_trace_get_depth(), type ); \ + mbedtls_mps_trace_color( mbedtls_mps_trace_id ); \ + mbedtls_mps_trace_print_msg( mbedtls_mps_trace_id, __LINE__, __VA_ARGS__ ); \ + mbedtls_mps_trace_color( 0 ); \ } while( 0 ) -#define TRACE_INIT( ... ) \ - do { \ - if( ! ( TRACE_MASK & ( 1u << trace_id ) ) ) \ - break; \ - TRACE( trace_call, __VA_ARGS__ ); \ - trace_inc_depth(); \ +#define MBEDTLS_MPS_TRACE_INIT( ... ) \ + do { \ + if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \ + break; \ + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_call, __VA_ARGS__ ); \ + mbedtls_mps_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(); \ +#define MBEDTLS_MPS_TRACE_END( val ) \ + do { \ + if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \ + break; \ + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_return, "%d (-%#04x)", \ + (int) (val), -((unsigned)(val)) ); \ + mbedtls_mps_trace_dec_depth(); \ } while( 0 ) -#define RETURN( val ) \ +#define MBEDTLS_MPS_TRACE_RETURN( val ) \ do { \ /* Breaks tail recursion. */ \ int ret__ = val; \ - TRACE_END( ret__ ); \ + MBEDTLS_MPS_TRACE_END( ret__ ); \ return( ret__ ); \ } while( 0 ) #else /* MBEDTLS_MPS_TRACE */ -#define TRACE( type, ... ) do { } while( 0 ) -#define TRACE_INIT( ... ) do { } while( 0 ) -#define TRACE_END do { } while( 0 ) +#define MBEDTLS_MPS_TRACE( type, ... ) do { } while( 0 ) +#define MBEDTLS_MPS_TRACE_INIT( ... ) do { } while( 0 ) +#define MBEDTLS_MPS_TRACE_END do { } while( 0 ) -#define RETURN( val ) return( val ); +#define MBEDTLS_MPS_TRACE_RETURN( val ) return( val ); #endif /* MBEDTLS_MPS_TRACE */ -#endif /* MBEDTLS_MPS_TRACE_H */ +#endif /* MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H */ From 8899396fd14ecff8efb5a635b67e6b0227eccd31 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 28 Jan 2021 09:45:47 +0000 Subject: [PATCH 29/68] Move MPS reader to mbedtls_mps_ namespace Signed-off-by: Hanno Becker --- library/mps_error.h | 2 +- library/mps_reader.c | 42 +-- library/mps_reader.h | 70 ++--- tests/suites/test_suite_mps.function | 428 +++++++++++++-------------- 4 files changed, 271 insertions(+), 271 deletions(-) diff --git a/library/mps_error.h b/library/mps_error.h index 8d8306455..807a72afe 100644 --- a/library/mps_error.h +++ b/library/mps_error.h @@ -81,7 +81,7 @@ /*! An invalid argument was passed to the reader. */ #define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR( 0x2 ) -/*! An attempt to move a reader to consuming mode through mbedtls_reader_feed() +/*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed() * after pausing failed because the provided data is not sufficient to serve the * the read requests that lead to the pausing. */ #define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR( 0x3 ) diff --git a/library/mps_reader.c b/library/mps_reader.c index 8a686898c..ffe19dd27 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -66,7 +66,7 @@ static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; * */ -static inline void mps_reader_zero( mbedtls_reader *rd ) +static inline void mps_reader_zero( mbedtls_mps_reader *rd ) { /* A plain memset() would likely be more efficient, * but the current way of zeroing makes it harder @@ -74,7 +74,7 @@ static inline void mps_reader_zero( mbedtls_reader *rd ) * It's also more suitable for VF efforts since it * doesn't require reasoning about structs being * interpreted as unstructured binary blobs. */ - static mbedtls_reader const zero = + static mbedtls_mps_reader const zero = { .frag = NULL, .frag_len = 0, .commit = 0, @@ -88,9 +88,9 @@ static inline void mps_reader_zero( mbedtls_reader *rd ) *rd = zero; } -int mbedtls_reader_init( mbedtls_reader *rd, - unsigned char *acc, - mbedtls_mps_size_t acc_len ) +int mbedtls_mps_reader_init( mbedtls_mps_reader *rd, + unsigned char *acc, + mbedtls_mps_size_t acc_len ) { MBEDTLS_MPS_TRACE_INIT( "reader_init, acc len %u", (unsigned) acc_len ); mps_reader_zero( rd ); @@ -99,16 +99,16 @@ int mbedtls_reader_init( mbedtls_reader *rd, MBEDTLS_MPS_TRACE_RETURN( 0 ); } -int mbedtls_reader_free( mbedtls_reader *rd ) +int mbedtls_mps_reader_free( mbedtls_mps_reader *rd ) { MBEDTLS_MPS_TRACE_INIT( "reader_free" ); mps_reader_zero( rd ); MBEDTLS_MPS_TRACE_RETURN( 0 ); } -int mbedtls_reader_feed( mbedtls_reader *rd, - unsigned char *new_frag, - mbedtls_mps_size_t new_frag_len ) +int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, + unsigned char *new_frag, + mbedtls_mps_size_t new_frag_len ) { unsigned char *acc; mbedtls_mps_size_t copy_to_acc; @@ -119,7 +119,7 @@ int mbedtls_reader_feed( mbedtls_reader *rd, MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG ); MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag == NULL, - "mbedtls_reader_feed() requires reader to be in producing mode" ); + "mbedtls_mps_reader_feed() requires reader to be in producing mode" ); acc = rd->acc; if( acc != NULL ) @@ -173,10 +173,10 @@ int mbedtls_reader_feed( mbedtls_reader *rd, } -int mbedtls_reader_get( mbedtls_reader *rd, - mbedtls_mps_size_t desired, - unsigned char **buffer, - mbedtls_mps_size_t *buflen ) +int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, + mbedtls_mps_size_t desired, + unsigned char **buffer, + mbedtls_mps_size_t *buflen ) { unsigned char *frag, *acc; mbedtls_mps_size_t end, fo, fl, frag_fetched, frag_remaining; @@ -185,7 +185,7 @@ int mbedtls_reader_get( mbedtls_reader *rd, frag = rd->frag; MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, - "mbedtls_reader_get() requires reader to be in consuming mode" ); + "mbedtls_mps_reader_get() requires reader to be in consuming mode" ); /* The fragment offset indicates the offset of the fragment * from the accmulator, if the latter is present. Use a offset @@ -269,7 +269,7 @@ int mbedtls_reader_get( mbedtls_reader *rd, * fo/frag_offset aa/acc_avail * * In case of Allowed #1 and #2 we're switching to serve from - * `frag` starting from the next call to mbedtls_reader_get(). + * `frag` starting from the next call to mbedtls_mps_reader_get(). */ mbedtls_mps_size_t aa; @@ -348,14 +348,14 @@ int mbedtls_reader_get( mbedtls_reader *rd, MBEDTLS_MPS_TRACE_RETURN( 0 ); } -int mbedtls_reader_commit( mbedtls_reader *rd ) +int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd ) { unsigned char *acc; mbedtls_mps_size_t aa, end, fo, shift; MBEDTLS_MPS_TRACE_INIT( "reader_commit" ); MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag != NULL, - "mbedtls_reader_commit() requires reader to be in consuming mode" ); + "mbedtls_mps_reader_commit() requires reader to be in consuming mode" ); acc = rd->acc; end = rd->end; @@ -400,8 +400,8 @@ int mbedtls_reader_commit( mbedtls_reader *rd ) MBEDTLS_MPS_TRACE_RETURN( 0 ); } -int mbedtls_reader_reclaim( mbedtls_reader *rd, - mbedtls_mps_size_t *paused ) +int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, + mbedtls_mps_size_t *paused ) { unsigned char *frag, *acc; mbedtls_mps_size_t pending, commit; @@ -413,7 +413,7 @@ int mbedtls_reader_reclaim( mbedtls_reader *rd, frag = rd->frag; MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, - "mbedtls_reader_reclaim() requires reader to be in consuming mode" ); + "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" ); acc = rd->acc; pending = rd->pending; diff --git a/library/mps_reader.h b/library/mps_reader.h index ec59d33c3..5648ede83 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -57,9 +57,9 @@ * From the perspective of the consumer, the state of the * reader is a potentially empty list of input buffers that * the reader has provided to the consumer. - * New buffers can be requested through calls to mbedtls_reader_get(), + * New buffers can be requested through calls to mbedtls_mps_reader_get(), * while previously obtained input buffers can be marked processed - * through calls to mbedtls_reader_consume(), emptying the list of + * through calls to mbedtls_mps_reader_consume(), emptying the list of * input buffers and invalidating them from the consumer's perspective. * The consumer need not be aware of the distinction between consumer * and producer mode, because he only interfaces with the reader @@ -82,9 +82,9 @@ * while the Attached state belongs to consuming mode. * * Transitioning from Unset or Accumulating to Attached is - * done via calls to mbedtls_reader_feed(), while transitioning + * done via calls to mbedtls_mps_reader_feed(), while transitioning * from Consuming to either Unset or Accumulating (depending - * on what has been processed) is done via mbedtls_reader_reclaim(). + * on what has been processed) is done via mbedtls_mps_reader_reclaim(). * * The following diagram depicts the producer-state progression: * @@ -119,18 +119,18 @@ #include "mps_common.h" #include "mps_error.h" -struct mbedtls_reader; -typedef struct mbedtls_reader mbedtls_reader; +struct mbedtls_mps_reader; +typedef struct mbedtls_mps_reader mbedtls_mps_reader; /* * Structure definitions */ -struct mbedtls_reader +struct mbedtls_mps_reader { unsigned char *frag; /*!< The fragment of incoming data managed by * the reader; it is provided to the reader - * through mbedtls_reader_feed(). The reader + * through mbedtls_mps_reader_feed(). The reader * does not own the fragment and does not * perform any allocation operations on it, * but does have read and write access to it. */ @@ -146,18 +146,18 @@ struct mbedtls_reader mbedtls_mps_stored_size_t end; /*!< The offset of the end of the last chunk * passed to the user through a call to - * mbedtls_reader_get(), relative to the first + * mbedtls_mps_reader_get(), relative to the first * byte in the accumulator. * This is only used when the reader is in * consuming mode, i.e. \c frag != \c NULL; * otherwise, its value is \c 0. */ mbedtls_mps_stored_size_t pending; /*!< The amount of incoming data missing on the - * last call to mbedtls_reader_get(). + * last call to mbedtls_mps_reader_get(). * In particular, it is \c 0 if the last call * was successful. * If a reader is reclaimed after an - * unsuccessful call to mbedtls_reader_get(), + * unsuccessful call to mbedtls_mps_reader_get(), * this variable is used to have the reader * remember how much data should be accumulated * before the reader can be passed back to @@ -171,7 +171,7 @@ struct mbedtls_reader * separate struct and using a pointer here. */ unsigned char *acc; /*!< The accumulator is used to gather incoming - * data if a read-request via mbedtls_reader_get() + * data if a read-request via mbedtls_mps_reader_get() * cannot be served from the current fragment. */ mbedtls_mps_stored_size_t acc_len; /*!< The total size of the accumulator. */ @@ -218,8 +218,8 @@ struct mbedtls_reader * * \param reader The reader to be initialized. * \param acc The buffer to be used as a temporary accumulator - * in case read requests through mbedtls_reader_get() - * exceed the buffer provided by mbedtls_reader_feed(). + * in case read requests through mbedtls_mps_reader_get() + * exceed the buffer provided by mbedtls_mps_reader_feed(). * This buffer is owned by the caller and exclusive use * for reading and writing is given to the reade for the * duration of the reader's lifetime. It is thus the caller's @@ -231,9 +231,9 @@ struct mbedtls_reader * \return \c 0 on success. * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. */ -int mbedtls_reader_init( mbedtls_reader *reader, - unsigned char *acc, - mbedtls_mps_size_t acc_len ); +int mbedtls_mps_reader_init( mbedtls_mps_reader *reader, + unsigned char *acc, + mbedtls_mps_size_t acc_len ); /** * \brief Free a reader object @@ -243,7 +243,7 @@ int mbedtls_reader_init( mbedtls_reader *reader, * \return \c 0 on success. * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. */ -int mbedtls_reader_free( mbedtls_reader *reader ); +int mbedtls_mps_reader_free( mbedtls_mps_reader *reader ); /** * \brief Pass chunk of data for the reader to manage. @@ -255,19 +255,19 @@ int mbedtls_reader_free( mbedtls_reader *reader ); * * \return \c 0 on success. In this case, the reader will be * moved to consuming state, and ownership of \p buf - * will be passed to the reader until mbedtls_reader_reclaim() + * will be passed to the reader until mbedtls_mps_reader_reclaim() * is called. * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is - * required to fulfill a previous request to mbedtls_reader_get(). + * required to fulfill a previous request to mbedtls_mps_reader_get(). * In this case, the reader remains in producing state and * takes no ownership of the provided buffer (an internal copy * is made instead). * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on * different kinds of failures. */ -int mbedtls_reader_feed( mbedtls_reader *reader, - unsigned char *buf, - mbedtls_mps_size_t buflen ); +int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader, + unsigned char *buf, + mbedtls_mps_size_t buflen ); /** * \brief Reclaim reader's access to the current input buffer. @@ -278,14 +278,14 @@ int mbedtls_reader_feed( mbedtls_reader *reader, * modified to indicate whether the reader has been paused * (value \c 1) or not (value \c 0). Pausing happens if there * is uncommitted data and a previous request to - * mbedtls_reader_get() has exceeded the bounds of the + * mbedtls_mps_reader_get() has exceeded the bounds of the * input buffer. * * \return \c 0 on success. * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. */ -int mbedtls_reader_reclaim( mbedtls_reader *reader, - mbedtls_mps_size_t *paused ); +int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader, + mbedtls_mps_size_t *paused ); /* * Usage API (Upper layer) @@ -306,14 +306,14 @@ int mbedtls_reader_reclaim( mbedtls_reader *reader, * address of a buffer of size \c *buflen * (if \c buflen != \c NULL) or \c desired * (if \c buflen == \c NULL). The user hass ownership - * of the buffer until the next call to mbedtls_reader_commit(). - * or mbedtls_reader_reclaim(). + * of the buffer until the next call to mbedtls_mps_reader_commit(). + * or mbedtls_mps_reader_reclaim(). * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough * data available to serve the read request. In this case, * the reader remains intact, and additional data can be * provided by reclaiming the current input buffer via - * mbedtls_reader_reclaim() and feeding a new one via - * mbedtls_reader_feed(). + * mbedtls_mps_reader_reclaim() and feeding a new one via + * mbedtls_mps_reader_feed(). * \return Another negative \c MBEDTLS_ERR_READER_XXX error * code for different kinds of failure. * @@ -323,10 +323,10 @@ int mbedtls_reader_reclaim( mbedtls_reader *reader, * address as buflen and checking \c *buflen == \c desired * afterwards. */ -int mbedtls_reader_get( mbedtls_reader *reader, - mbedtls_mps_size_t desired, - unsigned char **buffer, - mbedtls_mps_size_t *buflen ); +int mbedtls_mps_reader_get( mbedtls_mps_reader *reader, + mbedtls_mps_size_t desired, + unsigned char **buffer, + mbedtls_mps_size_t *buflen ); /** * \brief Signal that all input buffers previously obtained @@ -344,6 +344,6 @@ int mbedtls_reader_get( mbedtls_reader *reader, * pointers corresponding to the committed data anymore. * */ -int mbedtls_reader_commit( mbedtls_reader *reader ); +int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader ); #endif /* MBEDTLS_READER_H */ diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 3c841631f..2bf787a87 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -40,24 +40,24 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) unsigned char bufA[100]; unsigned char acc[10]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; /* Preparation (lower layer) */ if( with_acc == 0 ) - mbedtls_reader_init( &rd, NULL, 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); else - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ /* Consume exactly what's available */ - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 100, bufA, 100 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup (lower layer) */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -82,7 +82,7 @@ void mbedtls_mps_reader_no_pausing_single_step_multiple_rounds( int with_acc ) unsigned char bufA[100], bufB[100]; unsigned char acc[10]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) @@ -90,25 +90,25 @@ void mbedtls_mps_reader_no_pausing_single_step_multiple_rounds( int with_acc ) /* Preparation (lower layer) */ if( with_acc == 0 ) - mbedtls_reader_init( &rd, NULL, 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); else - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ /* Consume exactly what's available */ - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 100, bufA, 100 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); /* Consumption */ - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 100, bufB, 100 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup (lower layer) */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -118,7 +118,7 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_single_round( int with_acc ) /* This test exercises one round of the following: * - The 'producing' layer provides a buffer * - The 'consuming' layer fetches it in multiple calls - * to `mbedtls_reader_get()`, without comitting in between. + * to `mbedtls_mps_reader_get()`, without comitting in between. * - After processing, the consuming layer commit the data * and returns back to the producing layer. * @@ -137,27 +137,27 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_single_round( int with_acc ) unsigned char acc[10]; unsigned char *tmp; mbedtls_mps_size_t tmp_len; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ if( with_acc == 0 ) - mbedtls_reader_init( &rd, NULL, 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); else - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, buf, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 70, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 70, buf + 10, 70 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, &tmp_len ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 30, &tmp, &tmp_len ) == 0 ); ASSERT_COMPARE( tmp, tmp_len, buf + 80, 20 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup (lower layer) */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -172,7 +172,7 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds( int with_acc unsigned char acc[10]; unsigned char *tmp; mbedtls_mps_size_t tmp_len; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) @@ -180,28 +180,28 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds( int with_acc /* Preparation (lower layer) */ if( with_acc == 0 ) - mbedtls_reader_init( &rd, NULL, 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); else - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 70, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 70, bufA + 10, 70 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, &tmp_len ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 30, &tmp, &tmp_len ) == 0 ); ASSERT_COMPARE( tmp, tmp_len, bufA + 80, 20 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); /* Consumption */ - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 100, bufB, 100 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -217,23 +217,23 @@ void mbedtls_mps_reader_pausing_needed_disabled() unsigned char buf[100]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, NULL, 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 50, buf, 50 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Wrapup (lower layer) */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR ); - mbedtls_reader_free( &rd ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -250,23 +250,23 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() unsigned char buf[100]; unsigned char acc[10]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 50, buf, 50 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Wrapup (lower layer) */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); - mbedtls_reader_free( &rd ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -293,89 +293,89 @@ void mbedtls_mps_reader_pausing( int option ) unsigned char bufA[100], bufB[100]; unsigned char *tmp; unsigned char acc[40]; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ /* Ask for more than what's available. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 80, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 80, bufA, 80 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); switch( option ) { case 0: /* Single uncommitted fetch at pausing */ case 1: - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); break; default: /* Multiple uncommitted fetches at pausing */ break; } - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); /* Consumption */ switch( option ) { case 0: /* Single fetch at pausing, re-fetch with commit. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); break; case 1: /* Single fetch at pausing, re-fetch without commit. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); break; case 2: /* Multiple fetches at pausing, repeat without commit. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); break; case 3: /* Multiple fetches at pausing, repeat with commit 1. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); break; case 4: /* Multiple fetches at pausing, repeat with commit 2. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); break; case 5: /* Multiple fetches at pausing, repeat with commit 3. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); break; default: @@ -383,13 +383,13 @@ void mbedtls_mps_reader_pausing( int option ) } /* In all cases, fetch the rest of the second buffer. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 90, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 90, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 90, bufB + 10, 90 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -400,8 +400,8 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) * in the following situation: * - The consumer has asked for mre than what's available, so the * reader pauses and waits for further input data via - * `mbedtls_reader_feed()` - * - Multiple such calls to `mbedtls_reader_feed()` are necessary + * `mbedtls_mps_reader_feed()` + * - Multiple such calls to `mbedtls_mps_reader_feed()` are necessary * to fulfill the original request, and the reader needs to do * the necessary bookkeeping under the hood. * @@ -413,7 +413,7 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) unsigned char bufA[100], bufB[100]; unsigned char *tmp; unsigned char acc[70]; - mbedtls_reader rd; + mbedtls_mps_reader rd; mbedtls_mps_size_t fetch_len; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; @@ -421,46 +421,46 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ /* Ask for more than what's available. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 80, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 80, bufA, 80 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* 20 left, ask for 70 -> 50 overhead */ - TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 70, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); switch( option ) { case 0: /* 10 + 10 + 80 byte feed */ - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, 10 ) == + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, 10 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 10, 10 ) == + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + 10, 10 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 20, 80 ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + 20, 80 ) == 0 ); break; case 1: /* 50 x 1byte */ for( int num_feed=0; num_feed<49; num_feed++ ) { - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + num_feed, 1 ) == + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + num_feed, 1 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); } - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 49, 1 ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + 49, 1 ) == 0 ); break; case 2: /* 49 x 1byte + 51bytes */ for( int num_feed=0; num_feed<49; num_feed++ ) { - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + num_feed, 1 ) == + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + num_feed, 1 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); } - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB + 49, 51 ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + 49, 51 ) == 0 ); break; default: @@ -469,10 +469,10 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) } /* Consumption */ - TEST_ASSERT( mbedtls_reader_get( &rd, 70, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 70, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); ASSERT_COMPARE( tmp + 20, 50, bufB, 50 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 1000, &tmp, &fetch_len ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 1000, &tmp, &fetch_len ) == 0 ); switch( option ) { case 0: @@ -491,11 +491,11 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) TEST_ASSERT( 0 ); break; } - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -504,32 +504,32 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) void mbedtls_mps_reader_reclaim_data_left( int option ) { /* This test exercises the behaviour of the MPS reader when a - * call to mbedtls_reader_reclaim() is made before all data + * call to mbedtls_mps_reader_reclaim() is made before all data * provided by the producer has been fetched and committed. */ unsigned char buf[100]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, NULL, 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); /* Consumption (upper layer) */ switch( option ) { case 0: /* Fetch (but not commit) the entire buffer. */ - TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ), &tmp, NULL ) + TEST_ASSERT( mbedtls_mps_reader_get( &rd, sizeof( buf ), &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 100, buf, 100 ); break; case 1: /* Fetch (but not commit) parts of the buffer. */ - TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ) / 2, + TEST_ASSERT( mbedtls_mps_reader_get( &rd, sizeof( buf ) / 2, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, sizeof( buf ) / 2, buf, sizeof( buf ) / 2 ); break; @@ -537,11 +537,11 @@ void mbedtls_mps_reader_reclaim_data_left( int option ) case 2: /* Fetch and commit parts of the buffer, then * fetch but not commit the rest of the buffer. */ - TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ) / 2, + TEST_ASSERT( mbedtls_mps_reader_get( &rd, sizeof( buf ) / 2, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, sizeof( buf ) / 2, buf, sizeof( buf ) / 2 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, sizeof( buf ) / 2, + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, sizeof( buf ) / 2, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, sizeof( buf ) / 2, buf + sizeof( buf ) / 2, @@ -554,9 +554,9 @@ void mbedtls_mps_reader_reclaim_data_left( int option ) } /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_DATA_LEFT ); - mbedtls_reader_free( &rd ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -568,30 +568,30 @@ void mbedtls_mps_reader_reclaim_data_left_retry() * to be processed, and the consumer subsequently fetches more data. */ unsigned char buf[100]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, NULL, 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 50, buf, 50 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 50, buf + 50, 50 ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_DATA_LEFT ); /* Consumption */ - TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 50, buf + 50, 50 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -600,7 +600,7 @@ void mbedtls_mps_reader_multiple_pausing( int option ) { /* This test exercises the behaviour of the MPS reader * in the following situation: - * - A read request via `mbedtls_reader_get()` can't + * - A read request via `mbedtls_mps_reader_get()` can't * be served and the reader is paused to accumulate * the desired amount of data from the producer. * - Once enough data is availble, the consumer successfully @@ -613,7 +613,7 @@ void mbedtls_mps_reader_multiple_pausing( int option ) unsigned char *tmp; unsigned char acc[50]; mbedtls_mps_size_t tmp_len; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) @@ -622,22 +622,22 @@ void mbedtls_mps_reader_multiple_pausing( int option ) bufC[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ /* Ask for more than what's available. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 80, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 80, bufA, 80 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); switch( option ) { @@ -646,21 +646,21 @@ void mbedtls_mps_reader_multiple_pausing( int option ) * large enough. */ /* Consume */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, &tmp_len ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, &tmp_len ) == 0 ); ASSERT_COMPARE( tmp, tmp_len, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Prepare */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufC, sizeof( bufC ) ) == 0 );; + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufC, sizeof( bufC ) ) == 0 );; /* Consume */ - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufB + 10, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufC, 10 ); break; @@ -668,37 +668,37 @@ void mbedtls_mps_reader_multiple_pausing( int option ) case 1: /* Fetch same chunks, commit afterwards, and * then exceed bounds of new buffer; accumulator * not large enough. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 51, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 51, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Prepare */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); break; case 2: /* Fetch same chunks, don't commit afterwards, and * then exceed bounds of new buffer; accumulator * large enough. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Prepare */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufC, sizeof( bufC ) ) == 0 );; + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufC, sizeof( bufC ) ) == 0 );; /* Consume */ - TEST_ASSERT( mbedtls_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); ASSERT_COMPARE( tmp + 20, 20, bufB, 20 ); ASSERT_COMPARE( tmp + 40, 10, bufC, 10 ); @@ -707,16 +707,16 @@ void mbedtls_mps_reader_multiple_pausing( int option ) case 3: /* Fetch same chunks, don't commit afterwards, and * then exceed bounds of new buffer; accumulator * not large enough. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 80, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 10, bufA + 90, 10 ); ASSERT_COMPARE( tmp + 10, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 21, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 21, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Prepare */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); break; @@ -725,7 +725,7 @@ void mbedtls_mps_reader_multiple_pausing( int option ) break; } - mbedtls_reader_free( &rd ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -771,7 +771,7 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, int mode = 0; /* Lower layer (0) or Upper layer (1) */ int reclaimed = 1; /* Have to call reclaim at least once before * returning the reader to the upper layer. */ - mbedtls_reader rd; + mbedtls_mps_reader rd; if( acc_size > 0 ) { @@ -785,7 +785,7 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, ASSERT_ALLOC( outgoing, num_out_chunks * max_chunk_size ); ASSERT_ALLOC( incoming, num_out_chunks * max_chunk_size ); - mbedtls_reader_init( &rd, acc, acc_size ); + mbedtls_mps_reader_init( &rd, acc, acc_size ); cur_out_chunk = 0; in_commit = 0; @@ -801,7 +801,7 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, if( rand_op == 0 ) { /* Reclaim */ - ret = mbedtls_reader_reclaim( &rd, NULL ); + ret = mbedtls_mps_reader_reclaim( &rd, NULL ); if( ret == 0 ) { @@ -823,7 +823,7 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, ASSERT_ALLOC( tmp, tmp_size ); TEST_ASSERT( mbedtls_test_rnd_std_rand( NULL, tmp, tmp_size ) == 0 ); - ret = mbedtls_reader_feed( &rd, tmp, tmp_size ); + ret = mbedtls_mps_reader_feed( &rd, tmp, tmp_size ); if( ret == 0 || ret == MBEDTLS_ERR_MPS_READER_NEED_MORE ) { @@ -864,13 +864,13 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, get_size = ( rand() % max_request ) + 1; if( rand_op == 0 ) { - ret = mbedtls_reader_get( &rd, get_size, &chunk_get, + ret = mbedtls_mps_reader_get( &rd, get_size, &chunk_get, &real_size ); } else { real_size = get_size; - ret = mbedtls_reader_get( &rd, get_size, &chunk_get, NULL ); + ret = mbedtls_mps_reader_get( &rd, get_size, &chunk_get, NULL ); } /* Check if output is in accordance with what was written */ @@ -886,7 +886,7 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, } else if( rand_op == 2 ) /* Commit */ { - ret = mbedtls_reader_commit( &rd ); + ret = mbedtls_mps_reader_commit( &rd ); if( ret == 0 ) { in_commit += in_fetch; @@ -904,7 +904,7 @@ void mbedtls_mps_reader_random_usage( int num_out_chunks, } /* Cleanup */ - mbedtls_reader_free( &rd ); + mbedtls_mps_reader_free( &rd ); mbedtls_free( incoming ); mbedtls_free( outgoing ); mbedtls_free( acc ); @@ -931,7 +931,7 @@ void mbedtls_reader_inconsistent_usage( int option ) unsigned char bufA[100], bufB[100]; unsigned char *tmp; unsigned char acc[40]; - mbedtls_reader rd; + mbedtls_mps_reader rd; int success = 0; for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; @@ -939,23 +939,23 @@ void mbedtls_reader_inconsistent_usage( int option ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, acc, sizeof( acc ) ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufA, sizeof( bufA ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 80, &tmp, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 20, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 80, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 20, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Preparation */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); /* Consumption */ switch( option ) { case 0: /* Ask for buffered data in a single chunk, no commit */ - TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 30, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); ASSERT_COMPARE( tmp + 20, 10, bufB, 10 ); success = 1; @@ -963,40 +963,40 @@ void mbedtls_reader_inconsistent_usage( int option ) case 1: /* Ask for buffered data in a single chunk, with commit */ - TEST_ASSERT( mbedtls_reader_get( &rd, 30, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 30, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 20, bufA + 80, 20 ); ASSERT_COMPARE( tmp + 20, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); success = 1; break; case 2: /* Ask for more than was requested when pausing, #1 */ - TEST_ASSERT( mbedtls_reader_get( &rd, 31, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 31, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); break; case 3: /* Ask for more than was requested when pausing #2 */ - TEST_ASSERT( mbedtls_reader_get( &rd, (mbedtls_mps_size_t) -1, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, (mbedtls_mps_size_t) -1, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); break; case 4: /* Asking for buffered data in different * chunks than before CAN fail. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 10, &tmp, NULL ) == + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS ); break; case 5: /* Asking for buffered data different chunks * than before NEED NOT fail - no commits */ - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); success = 1; @@ -1005,10 +1005,10 @@ void mbedtls_reader_inconsistent_usage( int option ) case 6: /* Asking for buffered data different chunks * than before NEED NOT fail - intermediate commit */ - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); success = 1; @@ -1017,25 +1017,25 @@ void mbedtls_reader_inconsistent_usage( int option ) case 7: /* Asking for buffered data different chunks * than before NEED NOT fail - end commit */ - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); success = 1; break; case 8: /* Asking for buffered data different chunks * than before NEED NOT fail - intermediate & end commit */ - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 15, bufA + 80, 15 ); - TEST_ASSERT( mbedtls_reader_get( &rd, 15, &tmp, NULL ) == 0 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 15, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); ASSERT_COMPARE( tmp, 5, bufA + 95, 5 ); ASSERT_COMPARE( tmp + 5, 10, bufB, 10 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); success = 1; break; @@ -1047,16 +1047,16 @@ void mbedtls_reader_inconsistent_usage( int option ) if( success == 1 ) { /* In all succeeding cases, fetch the rest of the second buffer. */ - TEST_ASSERT( mbedtls_reader_get( &rd, 90, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 90, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 90, bufB + 10, 90 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); } /* Wrapup */ - mbedtls_reader_free( &rd ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -1067,16 +1067,16 @@ void mbedtls_mps_reader_feed_empty( int option ) * fed a NULL buffer. */ unsigned char buf[100]; unsigned char *tmp; - mbedtls_reader rd; + mbedtls_mps_reader rd; for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ - mbedtls_reader_init( &rd, NULL, 0 ); + mbedtls_mps_reader_init( &rd, NULL, 0 ); switch( option ) { case 0: /* NULL buffer */ - TEST_ASSERT( mbedtls_reader_feed( &rd, NULL, sizeof( buf ) ) == + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, NULL, sizeof( buf ) ) == MBEDTLS_ERR_MPS_READER_INVALID_ARG ); break; @@ -1085,15 +1085,15 @@ void mbedtls_mps_reader_feed_empty( int option ) break; } /* Subsequent feed-calls should still succeed. */ - TEST_ASSERT( mbedtls_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); /* Consumption (upper layer) */ - TEST_ASSERT( mbedtls_reader_get( &rd, 100, &tmp, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 100, buf, 100 ); - TEST_ASSERT( mbedtls_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup */ - TEST_ASSERT( mbedtls_reader_reclaim( &rd, NULL ) == 0 ); - mbedtls_reader_free( &rd ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ From bc64f945e44a9f0de6ec932894669aa964630f85 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Thu, 28 Jan 2021 10:43:32 +0000 Subject: [PATCH 30/68] Update VS2010 project file Signed-off-by: Hanno Becker --- visualc/VS2010/mbedTLS.vcxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 0fb1b5c7f..09c5341fb 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -251,6 +251,10 @@ + + + + @@ -310,6 +314,8 @@ + + From 014f683ca95a987c203a24beb84b48840e73a3ec Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 06:52:21 +0000 Subject: [PATCH 31/68] Test MPS reader when reclaim fails because the acc is too small Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 2bf787a87..d256532bb 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -245,12 +245,19 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() * current read buffer, _and_ the reader's accumulator is too small to * hold the requested amount of data. * - * In this case, we expect the reader to fail. */ + * In this case, we expect mbedtls_mps_reader_reclaim() to fail, + * but it should be possible to continue fetching data as if + * there had been no excess request via mbedtls_mps_reader_get() + * and the call to mbedtls_mps_reader_reclaim() had been rejected + * because of data remaining. + */ unsigned char buf[100]; unsigned char acc[10]; unsigned char *tmp; mbedtls_mps_reader rd; + mbedtls_mps_size_t tmp_len; + for( int i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; @@ -261,11 +268,17 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); ASSERT_COMPARE( tmp, 50, buf, 50 ); TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 10, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 10, buf + 50, 10 ); TEST_ASSERT( mbedtls_mps_reader_get( &rd, 100, &tmp, NULL ) == MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Wrapup (lower layer) */ TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, &tmp_len ) == 0 ); + ASSERT_COMPARE( tmp, tmp_len, buf + 50, 50 ); + mbedtls_mps_reader_free( &rd ); } /* END_CASE */ From 4f84e20eb018b11df08e8fe8d4bd81a79fcb0372 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 06:54:30 +0000 Subject: [PATCH 32/68] Don't invalidate MPS reader buffers upon commit call Previously, the semantics of mbedtls_mps_reader_commit() was to invalidate all buffers previously fetched via mbedtls_mps_reader_get(), forbidding any further use by the 'consumer'. This was in fact a necessary constraint for the current implementation, which did some memory moving in mbedtls_mps_reader_commit(). This commit simplifies the reader's semantics and implementation in the following way: - API: A call to mbedtls_mps_reader_commit() does no longer invalidate the buffers previously obtained via mbedtls_mps_reader_get(). Instead, they can continue to be used until mbedtls_mps_reader_reclaim() is called. Calling mbedtls_mps_reader_commit() now only sets a marker indicating which parts of the data received through mbedtls_mps_reader_get() need not be backed up once mbedtls_mps_reader_reclaim() is called. Allowing the user to call mbedtls_mbedtls_reader_commit() multiple times before mbedtls_mps_reader_reclaim() is mere convenience: We'd get exactly the same functionality if instead of mbedtls_mps_reader_commit(), there was an additional argument to mbedtls_mps_reader_reclaim() indicating how much data to retain. However, the present design is more convenient for the user and doesn't appear to introduce any unnecessary complexity (anymore), so we stick with it for now. - Implementation: mbedtls_mps_reader_commit() is now a 1-liner, setting the 'commit-marker', but doing nothing else. Instead, the complexity of mbedtls_mp_reader_reclaim() slightly increases because it has to deal with creating backups from both the accumulator and the current fragment. In the previous implementation, which shifted the accumulator content with every call to mbedtls_mps_reader_commit(), only the backup from the fragment was necessary; with the new implementation which doesn't shift anything in mbedtls_mps_reader_commit(), we need to do the accumulator shift in mbedtls_mps_reader_reclaim(). Signed-off-by: Hanno Becker --- library/mps_reader.c | 165 +++++++++++++++++-------------------------- library/mps_reader.h | 97 +++++++++++++------------ 2 files changed, 118 insertions(+), 144 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index ffe19dd27..9f08c5267 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -350,53 +350,14 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd ) { - unsigned char *acc; - mbedtls_mps_size_t aa, end, fo, shift; + mbedtls_mps_size_t end; MBEDTLS_MPS_TRACE_INIT( "reader_commit" ); - MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag != NULL, "mbedtls_mps_reader_commit() requires reader to be in consuming mode" ); - acc = rd->acc; end = rd->end; - - if( acc == NULL ) - { - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "No accumulator, just shift end" ); - rd->commit = end; - MBEDTLS_MPS_TRACE_RETURN( 0 ); - } - - fo = rd->acc_share.frag_offset; - if( end >= fo ) - { - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "Started to serve fragment, get rid of accumulator" ); - shift = fo; - aa = 0; - } - else - { - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "Still serving from accumulator" ); - aa = rd->acc_avail; - shift = end; - memmove( acc, acc + shift, aa - shift ); - aa -= shift; - } - - end -= shift; - fo -= shift; - - rd->acc_share.frag_offset = fo; - rd->acc_avail = aa; rd->commit = end; - rd->end = end; - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "Final state: (end=commit,fo,avail) = (%u,%u,%u)", - (unsigned) end, (unsigned) fo, (unsigned) aa ); MBEDTLS_MPS_TRACE_RETURN( 0 ); } @@ -406,7 +367,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, unsigned char *frag, *acc; mbedtls_mps_size_t pending, commit; mbedtls_mps_size_t al, fo, fl; - MBEDTLS_MPS_TRACE_INIT( "reader_reclaim" ); + MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_reclaim" ); if( paused != NULL ) *paused = 0; @@ -429,6 +390,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, { MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "No unsatisfied read-request has been logged." ); + /* Check if there's data left to be consumed. */ if( commit < fo || commit - fo < fl ) { @@ -437,16 +399,28 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, rd->end = commit; MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT ); } + + rd->acc_avail = 0; + rd->acc_share.acc_remaining = 0; + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "The fragment has been completely processed and committed." ); + "Fragment has been fully processed and committed." ); } else { + int overflow; + + mbedtls_mps_size_t acc_backup_offset; + mbedtls_mps_size_t acc_backup_len; mbedtls_mps_size_t frag_backup_offset; mbedtls_mps_size_t frag_backup_len; + + mbedtls_mps_size_t backup_len; + mbedtls_mps_size_t acc_len_needed; + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "There has been an unsatisfied read-request with %u bytes overhead.", - (unsigned) pending ); + "There has been an unsatisfied read with %u bytes overhead.", + (unsigned) pending ); if( acc == NULL ) { @@ -462,69 +436,61 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, if( commit < fo ) { /* No, accumulator is still being processed. */ - int overflow; - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "Still processing data from the accumulator" ); - - overflow = - ( fo + fl < fo ) || ( fo + fl + pending < fo + fl ); - if( overflow || al < fo + fl + pending ) - { - rd->end = commit; - rd->pending = 0; - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "The accumulator is too small to handle the backup." ); - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "* Remaining size: %u", (unsigned) al ); - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "* Needed: %u (%u + %u + %u)", - (unsigned) ( fo + fl + pending ), - (unsigned) fo, (unsigned) fl, (unsigned) pending ); - MBEDTLS_MPS_TRACE_RETURN( - MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); - } frag_backup_offset = 0; frag_backup_len = fl; + acc_backup_offset = commit; + acc_backup_len = fo - commit; } else { /* Yes, the accumulator is already processed. */ - int overflow; - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "The accumulator has already been processed" ); - - frag_backup_offset = commit; - frag_backup_len = fl - commit; - overflow = ( frag_backup_len + pending < pending ); - - if( overflow || - al - fo < frag_backup_len + pending ) - { - rd->end = commit; - rd->pending = 0; - - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "The accumulator is too small to handle the backup." ); - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "* Remaining size: %u", (unsigned) ( al - fo ) ); - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "* Needed: %u (%u + %u)", - (unsigned) ( frag_backup_len + pending ), - (unsigned) frag_backup_len, (unsigned) pending ); - MBEDTLS_MPS_TRACE_RETURN( - MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); - } + frag_backup_offset = commit - fo; + frag_backup_len = fl - frag_backup_offset; + acc_backup_offset = 0; + acc_backup_len = 0; } - frag += frag_backup_offset; - acc += fo; - memcpy( acc, frag, frag_backup_len ); + backup_len = acc_backup_len + frag_backup_len; + acc_len_needed = backup_len + pending; + + overflow = 0; + overflow |= ( backup_len < acc_backup_len ); + overflow |= ( acc_len_needed < backup_len ); + + if( overflow || al < acc_len_needed ) + { + /* Except for the different return code, we behave as if + * there hadn't been a call to mbedtls_mps_reader_get() + * since the last commit. */ + rd->end = commit; + rd->pending = 0; + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "The accumulator is too small to handle the backup." ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "* Size: %u", (unsigned) al ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, + "* Needed: %u (%u + %u)", + (unsigned) acc_len_needed, + (unsigned) backup_len, (unsigned) pending ); + MBEDTLS_MPS_TRACE_RETURN( + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + } MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "Backup %u bytes into accumulator", - (unsigned) frag_backup_len ); + "Fragment backup: %u", (unsigned) frag_backup_len ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "Accumulator backup: %u", (unsigned) acc_backup_len ); - rd->acc_avail = fo + frag_backup_len; + /* Move uncommitted parts from the accumulator to the front + * of the accumulator. */ + memmove( acc, acc + acc_backup_offset, acc_backup_len ); + + /* Copy uncmmitted parts of the current fragment to the + * accumulator. */ + memcpy( acc + acc_backup_len, + frag + frag_backup_offset, frag_backup_len ); + + rd->acc_avail = backup_len; rd->acc_share.acc_remaining = pending; if( paused != NULL ) @@ -534,14 +500,13 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, rd->frag = NULL; rd->frag_len = 0; - rd->commit = 0; - rd->end = 0; - rd->pending = 0; + rd->commit = 0; + rd->end = 0; + rd->pending = 0; MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Final state: aa %u, al %u, ar %u", (unsigned) rd->acc_avail, (unsigned) rd->acc_len, (unsigned) rd->acc_share.acc_remaining ); - MBEDTLS_MPS_TRACE_RETURN( 0 ); } diff --git a/library/mps_reader.h b/library/mps_reader.h index 5648ede83..560445732 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -31,7 +31,7 @@ * a 'consumer' which fetches and processes it in chunks of * again arbitrary, and potentially different, size. * - * Readers can be seen as datagram-to-stream converters, + * Readers can thus be seen as datagram-to-stream converters, * and they abstract away the following two tasks from the user: * 1. The pointer arithmetic of stepping through a producer- * provided chunk in smaller chunks. @@ -54,36 +54,39 @@ * be satisfiable. * - Repeat the above. * - * From the perspective of the consumer, the state of the - * reader is a potentially empty list of input buffers that - * the reader has provided to the consumer. - * New buffers can be requested through calls to mbedtls_mps_reader_get(), - * while previously obtained input buffers can be marked processed - * through calls to mbedtls_mps_reader_consume(), emptying the list of - * input buffers and invalidating them from the consumer's perspective. - * The consumer need not be aware of the distinction between consumer - * and producer mode, because he only interfaces with the reader - * when the latter is in consuming mode. + * The abstract states of the reader from the producer's and + * consumer's perspective are as follows: * - * From the perspective of the producer, the state of the reader - * is one of the following: - * - Attached: An incoming data buffer is currently - * being managed by the reader, and - * - Unset: No incoming data buffer is currently - * managed by the reader, and all previously - * handed incoming data buffers have been - * fully processed. - * - Accumulating: No incoming data buffer is currently - * managed by the reader, but some data - * from the previous incoming data buffer - * hasn't been processed yet and is internally - * held back. - * The Unset and Accumulating states belong to producing mode, - * while the Attached state belongs to consuming mode. + * - From the perspective of the consumer, the state of the + * reader consists of the following: + * - A byte stream representing (concatenation of) the data + * received through calls to mbedtls_mps_reader_get(), + * - A marker within that byte stream indicating which data + * need not be retained when the reader is passed back to + * the producer via mbedtls_mps_reader_reclaim(). + * The marker can be set via mbedtls_mps_reader_commit() + * which places it at the end of the current byte stream. + * The consumer need not be aware of the distinction between consumer + * and producer mode, because he only interfaces with the reader + * when the latter is in consuming mode. * - * Transitioning from Unset or Accumulating to Attached is - * done via calls to mbedtls_mps_reader_feed(), while transitioning - * from Consuming to either Unset or Accumulating (depending + * - From the perspective of the producer, the reader's state is one of: + * - Attached: The reader is in consuming mode. + * - Unset: No incoming data buffer is currently managed by the reader, + * and all previously handed incoming data buffers have been + * fully processed. More data needs to be fed into the reader + * via mbedtls_mps_reader_feed(). + * + * - Accumulating: No incoming data buffer is currently managed by the + * reader, but some data from the previous incoming data + * buffer hasn't been processed yet and is internally + * held back. + * The Attached state belongs to consuming mode, while the Unset and + * Accumulating states belong to producing mode. + * + * Transitioning from the Unset or Accumulating state to Attached is + * done via successful calls to mbedtls_mps_reader_feed(), while + * transitioning from Consuming to either Unset or Accumulating (depending * on what has been processed) is done via mbedtls_mps_reader_reclaim(). * * The following diagram depicts the producer-state progression: @@ -94,9 +97,9 @@ * | | | | * | | | | * | feed +---------+---+--+ | - * +--------------------------------------> Attached <---+ - * | / | - * +--------------------------------------> Consuming <---+ + * +--------------------------------------> <---+ + * | Attached | + * +--------------------------------------> <---+ * | feed, enough data available +---------+---+--+ | * | to serve previous consumer request | | | * | | | | @@ -108,6 +111,10 @@ * +--------+ * feed, need more data to serve * previous consumer request + * | + * | + * producing mode | consuming mode + * | * */ @@ -141,7 +148,7 @@ struct mbedtls_mps_reader /*!< The offset of the last commit, relative * to the first byte in the accumulator. * This is only used when the reader is in - * consuming mode, i.e. frag != NULL; + * consuming mode, i.e. \c frag != \c NULL; * otherwise, its value is \c 0. */ mbedtls_mps_stored_size_t end; /*!< The offset of the end of the last chunk @@ -306,8 +313,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader, * address of a buffer of size \c *buflen * (if \c buflen != \c NULL) or \c desired * (if \c buflen == \c NULL). The user hass ownership - * of the buffer until the next call to mbedtls_mps_reader_commit(). - * or mbedtls_mps_reader_reclaim(). + * of the buffer until the next call mbedtls_mps_reader_reclaim(). * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough * data available to serve the read request. In this case, * the reader remains intact, and additional data can be @@ -329,19 +335,22 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *reader, mbedtls_mps_size_t *buflen ); /** - * \brief Signal that all input buffers previously obtained - * from mbedtls_writer_get() are fully processed. + * \brief Mark data obtained from mbedtls_writer_get() as processed. * - * This function marks the previously fetched data as fully - * processed and invalidates their respective buffers. + * This call indicates that all data received from prior calls to + * mbedtls_mps_reader_fetch() has been or will have been + * processed when mbedtls_mps_reader_reclaim() is called, + * and thus need not be backed up. * - * \param reader The reader context to use. + * This function has no user observable effect until + * mbedtls_mps_reader_reclaim() is called. In particular, + * buffers received from mbedtls_mps_reader_fetch() remain + * valid until mbedtls_mps_reader_reclaim() is called. * - * \return \c 0 on success. - * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. + * \param reader The reader context to use. * - * \warning Once this function is called, you must not use the - * pointers corresponding to the committed data anymore. + * \return \c 0 on success. + * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. * */ int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader ); From 0bea62f2d758061529b6bc01627d3ed0afc6a0b4 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 07:54:19 +0000 Subject: [PATCH 33/68] Fix typo in reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 9f08c5267..a1c0a1cd1 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -71,7 +71,7 @@ static inline void mps_reader_zero( mbedtls_mps_reader *rd ) /* A plain memset() would likely be more efficient, * but the current way of zeroing makes it harder * to overlook fields which should not be zero-initialized. - * It's also more suitable for VF efforts since it + * It's also more suitable for FV efforts since it * doesn't require reasoning about structs being * interpreted as unstructured binary blobs. */ static mbedtls_mps_reader const zero = From f81e41f1e4ca4baa77464c8f3ddf2759a0135df1 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 08:04:01 +0000 Subject: [PATCH 34/68] Improve readability of MPS reader implementation Signed-off-by: Hanno Becker --- library/mps_reader.c | 135 ++++++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 45 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index a1c0a1cd1..508f65ab4 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -66,6 +66,54 @@ static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; * */ +static inline int mps_reader_is_accumulating( + mbedtls_mps_reader const *rd ) +{ + mbedtls_mps_size_t ar; + if( rd->acc == NULL ) + return( 0 ); + + ar = rd->acc_share.acc_remaining; + return( ar > 0 ); +} + +static inline int mps_reader_is_producing( + mbedtls_mps_reader const *rd ) +{ + unsigned char *frag = rd->frag; + return( frag == NULL ); +} + +static inline int mps_reader_is_consuming( + mbedtls_mps_reader const *rd ) +{ + return( !mps_reader_is_producing( rd ) ); +} + +static inline mbedtls_mps_size_t mps_reader_get_fragment_offset( + mbedtls_mps_reader const *rd ) +{ + unsigned char *acc = rd->acc; + mbedtls_mps_size_t fo; + + if( acc == NULL ) + return( 0 ); + + fo = rd->acc_share.frag_offset; + return( fo ); +} + +static inline mbedtls_mps_size_t mps_reader_serving_from_accumulator( + mbedtls_mps_reader const *rd ) +{ + mbedtls_mps_size_t fo, end; + + fo = mps_reader_get_fragment_offset( rd ); + end = rd->end; + + return( end < fo ); +} + static inline void mps_reader_zero( mbedtls_mps_reader *rd ) { /* A plain memset() would likely be more efficient, @@ -92,7 +140,9 @@ int mbedtls_mps_reader_init( mbedtls_mps_reader *rd, unsigned char *acc, mbedtls_mps_size_t acc_len ) { - MBEDTLS_MPS_TRACE_INIT( "reader_init, acc len %u", (unsigned) acc_len ); + MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_init" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "* Accumulator size: %u bytes", (unsigned) acc_len ); mps_reader_zero( rd ); rd->acc = acc; rd->acc_len = acc_len; @@ -101,7 +151,7 @@ int mbedtls_mps_reader_init( mbedtls_mps_reader *rd, int mbedtls_mps_reader_free( mbedtls_mps_reader *rd ) { - MBEDTLS_MPS_TRACE_INIT( "reader_free" ); + MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_free" ); mps_reader_zero( rd ); MBEDTLS_MPS_TRACE_RETURN( 0 ); } @@ -110,31 +160,31 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, unsigned char *new_frag, mbedtls_mps_size_t new_frag_len ) { - unsigned char *acc; mbedtls_mps_size_t copy_to_acc; - MBEDTLS_MPS_TRACE_INIT( "reader_feed, frag %p, len %u", - (void*) new_frag, (unsigned) new_frag_len ); + MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_feed" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "* Fragment length: %u bytes", (unsigned) new_frag_len ); if( new_frag == NULL ) MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG ); - MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag == NULL, + MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_producing( rd ), "mbedtls_mps_reader_feed() requires reader to be in producing mode" ); - acc = rd->acc; - if( acc != NULL ) + if( mps_reader_is_accumulating( rd ) ) { - mbedtls_mps_size_t aa, ar; + unsigned char *acc = rd->acc; + mbedtls_mps_size_t ar = rd->acc_share.acc_remaining; + mbedtls_mps_size_t aa = rd->acc_avail; - ar = rd->acc_share.acc_remaining; - aa = rd->acc_avail; + /* Skip over parts of the accumulator that have already been filled. */ + acc += aa; copy_to_acc = ar; if( copy_to_acc > new_frag_len ) copy_to_acc = new_frag_len; - acc += aa; - + /* Copy new contents to accumulator. */ if( copy_to_acc > 0 ) memcpy( acc, new_frag, copy_to_acc ); @@ -146,21 +196,24 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, ar -= copy_to_acc; if( ar > 0 ) { - /* Need more data */ + /* We need to accumulate more data. Stay in producing mode. */ aa += copy_to_acc; rd->acc_share.acc_remaining = ar; rd->acc_avail = aa; MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE ); } + /* We have filled the accumulator: Move to consuming mode. */ + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Enough data available to serve user request" ); + /* Remember overlap of accumulator and fragment. */ rd->acc_share.frag_offset = aa; aa += copy_to_acc; rd->acc_avail = aa; } - else + else /* Not accumulating */ { rd->acc_share.frag_offset = 0; } @@ -178,33 +231,23 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, unsigned char **buffer, mbedtls_mps_size_t *buflen ) { - unsigned char *frag, *acc; - mbedtls_mps_size_t end, fo, fl, frag_fetched, frag_remaining; - MBEDTLS_MPS_TRACE_INIT( "reader_get %p, desired %u", - (void*) rd, (unsigned) desired ); + unsigned char *frag; + mbedtls_mps_size_t fl, fo, end, frag_fetched, frag_remaining; + MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_get" ); + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, + "* Bytes requested: %u", (unsigned) desired ); - frag = rd->frag; - MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, + MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ), "mbedtls_mps_reader_get() requires reader to be in consuming mode" ); - /* The fragment offset indicates the offset of the fragment - * from the accmulator, if the latter is present. Use a offset - * of \c 0 if no accumulator is used. */ - acc = rd->acc; - if( acc == NULL ) - fo = 0; - else - fo = rd->acc_share.frag_offset; - - MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, - "frag_off %u, end %u, acc_avail %d", - (unsigned) fo, (unsigned) rd->end, - acc == NULL ? -1 : (int) rd->acc_avail ); + end = rd->end; + fo = mps_reader_get_fragment_offset( rd ); /* Check if we're still serving from the accumulator. */ - end = rd->end; - if( end < fo ) + if( mps_reader_serving_from_accumulator( rd ) ) { + unsigned char *acc; + MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Serve the request from the accumulator" ); if( fo - end < desired ) @@ -291,7 +334,9 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, } } + acc = rd->acc; acc += end; + *buffer = acc; if( buflen != NULL ) *buflen = desired; @@ -310,7 +355,6 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, fl = rd->frag_len; frag_fetched = end - fo; /* The amount of data from the current fragment * that has already been passed to the user. */ - frag += frag_fetched; frag_remaining = fl - frag_fetched; /* Remaining data in fragment */ /* Check if we can serve the read request from the fragment. */ @@ -338,6 +382,10 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, /* There's enough data in the current fragment to serve the * (potentially modified) read request. */ + + frag = rd->frag; + frag += frag_fetched; + *buffer = frag; if( buflen != NULL ) *buflen = desired; @@ -351,8 +399,8 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd ) { mbedtls_mps_size_t end; - MBEDTLS_MPS_TRACE_INIT( "reader_commit" ); - MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag != NULL, + MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_commit" ); + MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ), "mbedtls_mps_reader_commit() requires reader to be in consuming mode" ); end = rd->end; @@ -372,19 +420,16 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, if( paused != NULL ) *paused = 0; - frag = rd->frag; - MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL, + MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ), "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" ); + frag = rd->frag; acc = rd->acc; pending = rd->pending; commit = rd->commit; fl = rd->frag_len; - if( acc == NULL ) - fo = 0; - else - fo = rd->acc_share.frag_offset; + fo = mps_reader_get_fragment_offset( rd ); if( pending == 0 ) { From b1855434eb4b122e8d6f7b05929a56de173bbba2 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 08:07:35 +0000 Subject: [PATCH 35/68] Rename mbedtls_mps_reader::acc_avail -> acc_available Signed-off-by: Hanno Becker --- library/mps_reader.c | 40 ++++++++++++++++++++-------------------- library/mps_reader.h | 4 ++-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 508f65ab4..53a9072a9 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -123,15 +123,15 @@ static inline void mps_reader_zero( mbedtls_mps_reader *rd ) * doesn't require reasoning about structs being * interpreted as unstructured binary blobs. */ static mbedtls_mps_reader const zero = - { .frag = NULL, - .frag_len = 0, - .commit = 0, - .end = 0, - .pending = 0, - .acc = NULL, - .acc_len = 0, - .acc_avail = 0, - .acc_share = { .acc_remaining = 0 } + { .frag = NULL, + .frag_len = 0, + .commit = 0, + .end = 0, + .pending = 0, + .acc = NULL, + .acc_len = 0, + .acc_available = 0, + .acc_share = { .acc_remaining = 0 } }; *rd = zero; } @@ -175,7 +175,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, { unsigned char *acc = rd->acc; mbedtls_mps_size_t ar = rd->acc_share.acc_remaining; - mbedtls_mps_size_t aa = rd->acc_avail; + mbedtls_mps_size_t aa = rd->acc_available; /* Skip over parts of the accumulator that have already been filled. */ acc += aa; @@ -199,7 +199,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, /* We need to accumulate more data. Stay in producing mode. */ aa += copy_to_acc; rd->acc_share.acc_remaining = ar; - rd->acc_avail = aa; + rd->acc_available = aa; MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE ); } @@ -211,7 +211,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, /* Remember overlap of accumulator and fragment. */ rd->acc_share.frag_offset = aa; aa += copy_to_acc; - rd->acc_avail = aa; + rd->acc_available = aa; } else /* Not accumulating */ { @@ -266,7 +266,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_avail + * fo/frag_offset aa/acc_available * * - Allowed #2 * @@ -280,7 +280,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_avail + * fo/frag_offset aa/acc_available * * - Not allowed #1 (could be served, but we don't actually use it): * @@ -294,7 +294,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_avail + * fo/frag_offset aa/acc_available * * * - Not allowed #2 (can't be served with a contiguous buffer): @@ -309,14 +309,14 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_avail + * fo/frag_offset aa/acc_available * * In case of Allowed #1 and #2 we're switching to serve from * `frag` starting from the next call to mbedtls_mps_reader_get(). */ mbedtls_mps_size_t aa; - aa = rd->acc_avail; + aa = rd->acc_available; if( aa - end != desired ) { /* It might be possible to serve some of these situations by @@ -445,7 +445,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT ); } - rd->acc_avail = 0; + rd->acc_available = 0; rd->acc_share.acc_remaining = 0; MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, @@ -535,7 +535,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, memcpy( acc + acc_backup_len, frag + frag_backup_offset, frag_backup_len ); - rd->acc_avail = backup_len; + rd->acc_available = backup_len; rd->acc_share.acc_remaining = pending; if( paused != NULL ) @@ -551,7 +551,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Final state: aa %u, al %u, ar %u", - (unsigned) rd->acc_avail, (unsigned) rd->acc_len, + (unsigned) rd->acc_available, (unsigned) rd->acc_len, (unsigned) rd->acc_share.acc_remaining ); MBEDTLS_MPS_TRACE_RETURN( 0 ); } diff --git a/library/mps_reader.h b/library/mps_reader.h index 560445732..9e501b045 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -182,7 +182,7 @@ struct mbedtls_mps_reader * cannot be served from the current fragment. */ mbedtls_mps_stored_size_t acc_len; /*!< The total size of the accumulator. */ - mbedtls_mps_stored_size_t acc_avail; + mbedtls_mps_stored_size_t acc_available; /*!< The number of bytes currently gathered in * the accumulator. This is both used in * producing and in consuming mode: @@ -204,7 +204,7 @@ struct mbedtls_mps_reader * fragment from the beginning of the * accumulator. * It is only used in consuming mode. - * Must not be larger than \c acc_avail. */ + * Must not be larger than \c acc_available. */ } acc_share; }; From 49cc1317b0c6f3289fa7f8ec40cec52a1dcb2b52 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 08:17:32 +0000 Subject: [PATCH 36/68] Fix typo in MPS reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/mps_reader.h b/library/mps_reader.h index 9e501b045..34da18d60 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -281,7 +281,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader, * * \param reader The reader context to use. The reader must be * in producing state. - * \param paused If not \c NULL, the intger at address \p paused will be + * \param paused If not \c NULL, the integer at address \p paused will be * modified to indicate whether the reader has been paused * (value \c 1) or not (value \c 0). Pausing happens if there * is uncommitted data and a previous request to From a408c1719cac9d49a5e4f5650f75109904648b83 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 08:17:39 +0000 Subject: [PATCH 37/68] Clarify wording in MPS reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/mps_reader.h b/library/mps_reader.h index 34da18d60..2163a35b8 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -167,8 +167,8 @@ struct mbedtls_mps_reader * unsuccessful call to mbedtls_mps_reader_get(), * this variable is used to have the reader * remember how much data should be accumulated - * before the reader can be passed back to - * the user again. + * so that the call to mbedtls_mps_reader_get() + * succeeds next time. * This is only used when the reader is in * consuming mode, i.e. \c frag != \c NULL; * otherwise, its value is \c 0. */ From 8fc107c9fb6e30251877e99234486dac0203f04b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 08:19:16 +0000 Subject: [PATCH 38/68] Clarify wording in MPS reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/mps_reader.h b/library/mps_reader.h index 2163a35b8..48bec8252 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -146,7 +146,8 @@ struct mbedtls_mps_reader * Must be 0 if \c frag == \c NULL. */ mbedtls_mps_stored_size_t commit; /*!< The offset of the last commit, relative - * to the first byte in the accumulator. + * to the first byte in the fragment or, if + * present, the accumulator. * This is only used when the reader is in * consuming mode, i.e. \c frag != \c NULL; * otherwise, its value is \c 0. */ From 3d0db8169040731d1dab4d120b63925f364b6b99 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Feb 2021 08:22:52 +0000 Subject: [PATCH 39/68] Fix typo in MPS reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/mps_reader.h b/library/mps_reader.h index 48bec8252..271809fd0 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -45,7 +45,7 @@ * moving it from 'producing' to 'consuming' mode. * - The consumer subsequently fetches and processes the buffer * content. Once that's done -- or partially done and a consumer's - * requests can't be fulfilled -- the producer revokes the reader's + * request can't be fulfilled -- the producer revokes the reader's * access to the incoming data buffer, putting the reader back to * producing mode. * - The producer subsequently gathers more incoming data and hands From 53314aade1371a120116a5308667ee178d4699ee Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:03:37 +0000 Subject: [PATCH 40/68] Adjust spacing for MPS reader entries in library/Makefile Existing entries use combination of tabs and spaces, for whatever reason. Signed-off-by: Hanno Becker --- library/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Makefile b/library/Makefile index 419291acf..13b0b2934 100644 --- a/library/Makefile +++ b/library/Makefile @@ -104,8 +104,8 @@ OBJS_CRYPTO= \ md4.o \ md5.o \ memory_buffer_alloc.o \ - mps_reader.o \ - mps_trace.o \ + mps_reader.o \ + mps_trace.o \ nist_kw.o \ oid.o \ padlock.o \ From 6e3484e123e2e211d1619d0662241b1601d57638 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:09:03 +0000 Subject: [PATCH 41/68] Clarify documentation of MBEDTLS_MPS_STATE_VALIDATION Signed-off-by: Hanno Becker --- library/mps_common.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/library/mps_common.h b/library/mps_common.h index 1ac3bd8b2..467e6cc30 100644 --- a/library/mps_common.h +++ b/library/mps_common.h @@ -61,12 +61,15 @@ * non-sensical calls or not, and that's what this option is about: * * This option determines whether the expected abstract state - * is part of the API preconditions or not. If it is, the function's - * behavior is undefined if the abstract state is not as expected. - * If it is set, API is required to fail gracefully with error - * #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED, and without changing the abstract - * state of the input context, if the abstract state is unexpected but - * all other preconditions are satisfied. + * is part of the API preconditions or not: If the option is set, + * then the abstract state is not part of the precondition and is + * thus required to be validated by the implementation. If an unexpected + * abstract state is encountered, the implementation must fail gracefully + * with error #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED. + * Conversely, if this option is not set, then the expected abstract state + * is included in the preconditions of the respective API calls, and + * an implementation's behaviour is undefined if the abstract state is + * not as expected. * * For example: Enabling this makes mps_l2_read_done() fail if * no incoming record is currently open; disabling this would From 46101c76f934baa6ebab2369508c8ebb22b8a71f Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:11:15 +0000 Subject: [PATCH 42/68] Improve wording of documentation of mbedtls_mps_size_t Signed-off-by: Hanno Becker --- library/mps_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/mps_common.h b/library/mps_common.h index 467e6cc30..b91cd7268 100644 --- a/library/mps_common.h +++ b/library/mps_common.h @@ -150,7 +150,7 @@ /** \brief The type of buffer sizes and offsets used in MPS structures. * * This is an unsigned integer type that should be large enough to - * hold the length of any buffer resp. message processed by MPS. + * hold the length of any buffer or message processed by MPS. * * The reason to pick a value as small as possible here is * to reduce the size of MPS structures. From 4a079c5be7acace9d46fa92ed95d235a5d7ef0ed Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:13:28 +0000 Subject: [PATCH 43/68] Fix documentation for mbedtls_mps_[stored_]size_t Signed-off-by: Hanno Becker --- library/mps_common.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/mps_common.h b/library/mps_common.h index b91cd7268..e541f4fb0 100644 --- a/library/mps_common.h +++ b/library/mps_common.h @@ -169,7 +169,7 @@ * */ typedef size_t mbedtls_mps_stored_size_t; -#define MBEDTLS_MPS_SIZE_MAX ( (mbedtls_mps_size_t) -1 ) +#define MBEDTLS_MPS_STORED_SIZE_MAX ( (mbedtls_mps_stored_size_t) -1 ) /** \brief The type of buffer sizes and offsets used in the MPS API * and implementation. @@ -183,8 +183,9 @@ typedef size_t mbedtls_mps_stored_size_t; * so almost 10%. */ typedef size_t mbedtls_mps_size_t; +#define MBEDTLS_MPS_SIZE_MAX ( (mbedtls_mps_size_t) -1 ) -#if (mbedtls_mps_size_t) -1 > (mbedtls_mps_stored_size_t) -1 +#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX #error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t." #endif From d913e2e982774c53083b215988834a22dc202f7b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:15:13 +0000 Subject: [PATCH 44/68] Remove duplicate definition of MBEDTLS_MPS_ERR_BASE Signed-off-by: Hanno Becker --- library/mps_error.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/library/mps_error.h b/library/mps_error.h index 807a72afe..eaca956d6 100644 --- a/library/mps_error.h +++ b/library/mps_error.h @@ -38,10 +38,6 @@ * public API. */ -#ifndef MBEDTLS_MPS_ERR_BASE -#define MBEDTLS_MPS_ERR_BASE ( 1 << 0 ) -#endif - /** * \name SECTION: MPS general error codes * @@ -49,13 +45,12 @@ */ #ifndef MBEDTLS_MPS_ERR_BASE -#define MBEDTLS_MPS_ERR_BASE ( 1 << 10 ) +#define MBEDTLS_MPS_ERR_BASE ( 0 ) #endif #define MBEDTLS_MPS_MAKE_ERROR(code) \ ( -( MBEDTLS_MPS_ERR_BASE | (code) ) ) - #define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR( 0x1 ) #define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR( 0x2 ) @@ -68,7 +63,7 @@ */ #ifndef MBEDTLS_MPS_READER_ERR_BASE -#define MBEDTLS_MPS_READER_ERR_BASE ( 1 << 7 ) +#define MBEDTLS_MPS_READER_ERR_BASE ( 1 << 8 ) #endif #define MBEDTLS_MPS_READER_MAKE_ERROR(code) \ From f1cfa319c41fe1be5699f01f4bc3a5a821f12e19 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:15:44 +0000 Subject: [PATCH 45/68] Fix typos in documentation of MBEDTLS_ERR_MPS_READER_NEED_MORE Signed-off-by: Hanno Becker --- library/mps_error.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/mps_error.h b/library/mps_error.h index eaca956d6..c11a01fa5 100644 --- a/library/mps_error.h +++ b/library/mps_error.h @@ -78,22 +78,22 @@ /*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed() * after pausing failed because the provided data is not sufficient to serve the - * the read requests that lead to the pausing. */ + * read requests that led to the pausing. */ #define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR( 0x3 ) -/*! A read request failed because not enough data is available in the reader. */ +/*! A get request failed because not enough data is available in the reader. */ #define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR( 0x4 ) -/*!< A read request after pausing and reactivating the reader failed because +/*!< A get request after pausing and reactivating the reader failed because * the request is not in line with the request made prior to pausing. The user * must not change it's 'strategy' after pausing and reactivating a reader. */ #define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR( 0x5 ) -/*! An attempt to reclaim the data buffer from a reader fails because the reader +/*! An attempt to reclaim the data buffer from a reader failed because the reader * has no accumulator it can use to backup the data that hasn't been processed. */ #define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR( 0x6 ) -/*! An attempt to reclaim the data buffer from a reader fails beacuse the +/*! An attempt to reclaim the data buffer from a reader failed because the * accumulator passed to the reader is not large enough to hold both the * data that hasn't been processed and the excess of the last read-request. */ #define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR( 0x7 ) From fea81b399734dba75182340c7108839e0a96cdf2 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 15:18:11 +0000 Subject: [PATCH 46/68] Improve and fix wording in MPS reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.c | 3 +- library/mps_reader.h | 89 ++++++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 34 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 53a9072a9..6fda74031 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -43,8 +43,9 @@ static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; * and significantly increases the C-code line count, but * should not increase the size of generated assembly. * - * This reason for this is twofold: + * The reason for this is twofold: * (1) It will ease verification efforts using the VST + * (Verified Software Toolchain) * whose program logic cannot directly reason * about instructions containing a load or store in * addition to other operations (e.g. *p = *q or diff --git a/library/mps_reader.h b/library/mps_reader.h index 271809fd0..61027d911 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -49,7 +49,7 @@ * access to the incoming data buffer, putting the reader back to * producing mode. * - The producer subsequently gathers more incoming data and hands - * it to reader until the latter switches back to consuming mode + * it to the reader until it switches back to consuming mode * if enough data is available for the last consumer request to * be satisfiable. * - Repeat the above. @@ -62,12 +62,13 @@ * - A byte stream representing (concatenation of) the data * received through calls to mbedtls_mps_reader_get(), * - A marker within that byte stream indicating which data - * need not be retained when the reader is passed back to - * the producer via mbedtls_mps_reader_reclaim(). - * The marker can be set via mbedtls_mps_reader_commit() + * can be considered processed, and hence need not be retained, + * when the reader is passed back to the producer via + * mbedtls_mps_reader_reclaim(). + * The marker is set via mbedtls_mps_reader_commit() * which places it at the end of the current byte stream. * The consumer need not be aware of the distinction between consumer - * and producer mode, because he only interfaces with the reader + * and producer mode, because it only interfaces with the reader * when the latter is in consuming mode. * * - From the perspective of the producer, the reader's state is one of: @@ -86,7 +87,7 @@ * * Transitioning from the Unset or Accumulating state to Attached is * done via successful calls to mbedtls_mps_reader_feed(), while - * transitioning from Consuming to either Unset or Accumulating (depending + * transitioning from Attached to either Unset or Accumulating (depending * on what has been processed) is done via mbedtls_mps_reader_reclaim(). * * The following diagram depicts the producer-state progression: @@ -140,14 +141,21 @@ struct mbedtls_mps_reader * through mbedtls_mps_reader_feed(). The reader * does not own the fragment and does not * perform any allocation operations on it, - * but does have read and write access to it. */ + * but does have read and write access to it. + * + * The reader is in consuming mode if + * and only if \c frag is not \c NULL. */ mbedtls_mps_stored_size_t frag_len; /*!< The length of the current fragment. * Must be 0 if \c frag == \c NULL. */ mbedtls_mps_stored_size_t commit; /*!< The offset of the last commit, relative - * to the first byte in the fragment or, if - * present, the accumulator. + * to the first byte in the fragment, if + * no accumulator is present. If an accumulator + * is present, it is viewed as a prefix to the + * current fragment, and this variable contains + * an offset from the beginning of the accumulator. + * * This is only used when the reader is in * consuming mode, i.e. \c frag != \c NULL; * otherwise, its value is \c 0. */ @@ -155,7 +163,12 @@ struct mbedtls_mps_reader /*!< The offset of the end of the last chunk * passed to the user through a call to * mbedtls_mps_reader_get(), relative to the first - * byte in the accumulator. + * byte in the fragment, if no accumulator is + * present. If an accumulator is present, it is + * viewed as a prefix to the current fragment, and + * this variable contains an offset from the + * beginning of the accumulator. + * * This is only used when the reader is in * consuming mode, i.e. \c frag != \c NULL; * otherwise, its value is \c 0. */ @@ -190,9 +203,9 @@ struct mbedtls_mps_reader * While producing, it is increased until * it reaches the value of \c acc_remaining below. * While consuming, it is used to judge if a - * read request can be served from the + * get request can be served from the * accumulator or not. - * Must not be larger than acc_len. */ + * Must not be larger than \c acc_len. */ union { mbedtls_mps_stored_size_t acc_remaining; @@ -201,9 +214,11 @@ struct mbedtls_mps_reader * only used in producing mode. * Must be at most acc_len - acc_available. */ mbedtls_mps_stored_size_t frag_offset; - /*!< This indicates the offset of the current + /*!< If an accumulator is present and in use, this + * field indicates the offset of the current * fragment from the beginning of the - * accumulator. + * accumulator. If no accumulator is present + * or the accumulator is not in use, this is \c 0. * It is only used in consuming mode. * Must not be larger than \c acc_available. */ } acc_share; @@ -226,10 +241,10 @@ struct mbedtls_mps_reader * * \param reader The reader to be initialized. * \param acc The buffer to be used as a temporary accumulator - * in case read requests through mbedtls_mps_reader_get() + * in case get requests through mbedtls_mps_reader_get() * exceed the buffer provided by mbedtls_mps_reader_feed(). * This buffer is owned by the caller and exclusive use - * for reading and writing is given to the reade for the + * for reading and writing is given to the reader for the * duration of the reader's lifetime. It is thus the caller's * responsibility to maintain (and not touch) the buffer for * the lifetime of the reader, and to properly zeroize and @@ -257,17 +272,20 @@ int mbedtls_mps_reader_free( mbedtls_mps_reader *reader ); * \brief Pass chunk of data for the reader to manage. * * \param reader The reader context to use. The reader must be - * in producing state. + * in producing mode. * \param buf The buffer to be managed by the reader. * \param buflen The size in Bytes of \p buffer. * * \return \c 0 on success. In this case, the reader will be - * moved to consuming state, and ownership of \p buf - * will be passed to the reader until mbedtls_mps_reader_reclaim() - * is called. + * moved to consuming mode and obtains read access + * of \p buf until mbedtls_mps_reader_reclaim() + * is called. It is the responsibility of the caller + * to ensure that the \p buf persists and is not changed + * between successful calls to mbedtls_mps_reader_feed() + * and mbedtls_mps_reader_reclaim(). * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is * required to fulfill a previous request to mbedtls_mps_reader_get(). - * In this case, the reader remains in producing state and + * In this case, the reader remains in producing mode and * takes no ownership of the provided buffer (an internal copy * is made instead). * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on @@ -281,7 +299,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader, * \brief Reclaim reader's access to the current input buffer. * * \param reader The reader context to use. The reader must be - * in producing state. + * in consuming mode. * \param paused If not \c NULL, the integer at address \p paused will be * modified to indicate whether the reader has been paused * (value \c 1) or not (value \c 0). Pausing happens if there @@ -303,7 +321,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader, * \brief Request data from the reader. * * \param reader The reader context to use. The reader must - * in consuming state. + * be in consuming mode. * \param desired The desired amount of data to be read, in Bytes. * \param buffer The address to store the buffer pointer in. * This must not be \c NULL. @@ -313,14 +331,19 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader, * \return \c 0 on success. In this case, \c *buf holds the * address of a buffer of size \c *buflen * (if \c buflen != \c NULL) or \c desired - * (if \c buflen == \c NULL). The user hass ownership - * of the buffer until the next call mbedtls_mps_reader_reclaim(). + * (if \c buflen == \c NULL). The user has read access + * to the buffer and guarantee of stability of the data + * until the next call to mbedtls_mps_reader_reclaim(). * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough - * data available to serve the read request. In this case, - * the reader remains intact, and additional data can be - * provided by reclaiming the current input buffer via - * mbedtls_mps_reader_reclaim() and feeding a new one via - * mbedtls_mps_reader_feed(). + * data available to serve the get request. In this case, the + * reader remains intact and in consuming mode, and the consumer + * should retry the call after a successful cycle of + * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed(). + * If, after such a cycle, the consumer requests a different + * amount of data, the result is implementation-defined; + * progress is guaranteed only if the same amount of data + * is requested after a mbedtls_mps_reader_reclaim() and + * mbedtls_mps_reader_feed() cycle. * \return Another negative \c MBEDTLS_ERR_READER_XXX error * code for different kinds of failure. * @@ -336,16 +359,16 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *reader, mbedtls_mps_size_t *buflen ); /** - * \brief Mark data obtained from mbedtls_writer_get() as processed. + * \brief Mark data obtained from mbedtls_mps_reader_get() as processed. * * This call indicates that all data received from prior calls to - * mbedtls_mps_reader_fetch() has been or will have been + * mbedtls_mps_reader_get() has been or will have been * processed when mbedtls_mps_reader_reclaim() is called, * and thus need not be backed up. * * This function has no user observable effect until * mbedtls_mps_reader_reclaim() is called. In particular, - * buffers received from mbedtls_mps_reader_fetch() remain + * buffers received from mbedtls_mps_reader_get() remain * valid until mbedtls_mps_reader_reclaim() is called. * * \param reader The reader context to use. From b9c086adc5323571f96094eab51018befd0a66ea Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:04:06 +0000 Subject: [PATCH 47/68] Use `int` pointer for `paused` param in mbedtls_mps_reader_reclaim() Signed-off-by: Hanno Becker --- library/mps_reader.c | 2 +- library/mps_reader.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 6fda74031..722143372 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -411,7 +411,7 @@ int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd ) } int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, - mbedtls_mps_size_t *paused ) + int *paused ) { unsigned char *frag, *acc; mbedtls_mps_size_t pending, commit; diff --git a/library/mps_reader.h b/library/mps_reader.h index 61027d911..d1cad7f9b 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -311,7 +311,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader, * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure. */ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader, - mbedtls_mps_size_t *paused ); + int *paused ); /* * Usage API (Upper layer) From 1682a8b6feccfe48d9a64c64cfe6891a51e4c8fc Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:38:56 +0000 Subject: [PATCH 48/68] Don't use abbreviated names for local variables in MPS reader Signed-off-by: Hanno Becker --- library/mps_reader.c | 73 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 722143372..62186c930 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -70,12 +70,12 @@ static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER; static inline int mps_reader_is_accumulating( mbedtls_mps_reader const *rd ) { - mbedtls_mps_size_t ar; + mbedtls_mps_size_t acc_remaining; if( rd->acc == NULL ) return( 0 ); - ar = rd->acc_share.acc_remaining; - return( ar > 0 ); + acc_remaining = rd->acc_share.acc_remaining; + return( acc_remaining > 0 ); } static inline int mps_reader_is_producing( @@ -95,24 +95,24 @@ static inline mbedtls_mps_size_t mps_reader_get_fragment_offset( mbedtls_mps_reader const *rd ) { unsigned char *acc = rd->acc; - mbedtls_mps_size_t fo; + mbedtls_mps_size_t frag_offset; if( acc == NULL ) return( 0 ); - fo = rd->acc_share.frag_offset; - return( fo ); + frag_offset = rd->acc_share.frag_offset; + return( frag_offset ); } static inline mbedtls_mps_size_t mps_reader_serving_from_accumulator( mbedtls_mps_reader const *rd ) { - mbedtls_mps_size_t fo, end; + mbedtls_mps_size_t frag_offset, end; - fo = mps_reader_get_fragment_offset( rd ); + frag_offset = mps_reader_get_fragment_offset( rd ); end = rd->end; - return( end < fo ); + return( end < frag_offset ); } static inline void mps_reader_zero( mbedtls_mps_reader *rd ) @@ -233,7 +233,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, mbedtls_mps_size_t *buflen ) { unsigned char *frag; - mbedtls_mps_size_t fl, fo, end, frag_fetched, frag_remaining; + mbedtls_mps_size_t frag_len, frag_offset, end, frag_fetched, frag_remaining; MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_get" ); MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "* Bytes requested: %u", (unsigned) desired ); @@ -242,7 +242,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, "mbedtls_mps_reader_get() requires reader to be in consuming mode" ); end = rd->end; - fo = mps_reader_get_fragment_offset( rd ); + frag_offset = mps_reader_get_fragment_offset( rd ); /* Check if we're still serving from the accumulator. */ if( mps_reader_serving_from_accumulator( rd ) ) @@ -251,7 +251,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Serve the request from the accumulator" ); - if( fo - end < desired ) + if( frag_offset - end < desired ) { /* Illustration of supported and unsupported cases: * @@ -316,9 +316,9 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * `frag` starting from the next call to mbedtls_mps_reader_get(). */ - mbedtls_mps_size_t aa; - aa = rd->acc_available; - if( aa - end != desired ) + mbedtls_mps_size_t acc_available; + acc_available = rd->acc_available; + if( acc_available - end != desired ) { /* It might be possible to serve some of these situations by * making additional space in the accumulator, removing those @@ -353,10 +353,11 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Serve the request from the current fragment." ); - fl = rd->frag_len; - frag_fetched = end - fo; /* The amount of data from the current fragment - * that has already been passed to the user. */ - frag_remaining = fl - frag_fetched; /* Remaining data in fragment */ + frag_len = rd->frag_len; + frag_fetched = end - frag_offset; /* The amount of data from the current + * fragment that has already been passed + * to the user. */ + frag_remaining = frag_len - frag_fetched; /* Remaining data in fragment */ /* Check if we can serve the read request from the fragment. */ if( frag_remaining < desired ) @@ -415,22 +416,22 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, { unsigned char *frag, *acc; mbedtls_mps_size_t pending, commit; - mbedtls_mps_size_t al, fo, fl; + mbedtls_mps_size_t acc_len, frag_offset, frag_len; MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_reclaim" ); if( paused != NULL ) *paused = 0; MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ), - "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" ); + "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" ); - frag = rd->frag; - acc = rd->acc; - pending = rd->pending; - commit = rd->commit; - fl = rd->frag_len; + frag = rd->frag; + acc = rd->acc; + pending = rd->pending; + commit = rd->commit; + frag_len = rd->frag_len; - fo = mps_reader_get_fragment_offset( rd ); + frag_offset = mps_reader_get_fragment_offset( rd ); if( pending == 0 ) { @@ -438,7 +439,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, "No unsatisfied read-request has been logged." ); /* Check if there's data left to be consumed. */ - if( commit < fo || commit - fo < fl ) + if( commit < frag_offset || commit - frag_offset < frag_len ) { MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "There is data left to be consumed." ); @@ -475,23 +476,23 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR ); } - al = rd->acc_len; + acc_len = rd->acc_len; /* Check if the upper layer has already fetched * and committed the contents of the accumulator. */ - if( commit < fo ) + if( commit < frag_offset ) { /* No, accumulator is still being processed. */ frag_backup_offset = 0; - frag_backup_len = fl; + frag_backup_len = frag_len; acc_backup_offset = commit; - acc_backup_len = fo - commit; + acc_backup_len = frag_offset - commit; } else { /* Yes, the accumulator is already processed. */ - frag_backup_offset = commit - fo; - frag_backup_len = fl - frag_backup_offset; + frag_backup_offset = commit - frag_offset; + frag_backup_len = frag_len - frag_backup_offset; acc_backup_offset = 0; acc_backup_len = 0; } @@ -503,7 +504,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, overflow |= ( backup_len < acc_backup_len ); overflow |= ( acc_len_needed < backup_len ); - if( overflow || al < acc_len_needed ) + if( overflow || acc_len < acc_len_needed ) { /* Except for the different return code, we behave as if * there hadn't been a call to mbedtls_mps_reader_get() @@ -513,7 +514,7 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, "The accumulator is too small to handle the backup." ); MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, - "* Size: %u", (unsigned) al ); + "* Size: %u", (unsigned) acc_len ); MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error, "* Needed: %u (%u + %u)", (unsigned) acc_len_needed, From 97c8e930e20d72f32269b756fd340eda64816615 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:39:36 +0000 Subject: [PATCH 49/68] Fix diagram in documentation of MPS reader Signed-off-by: Hanno Becker --- library/mps_reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 62186c930..ee2312c9c 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -294,7 +294,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * +------v-------------v------+ * | acc | * +---------------------------+ - * | | + * | | * fo/frag_offset aa/acc_available * * From 77e4f485e15d6b7a53531242407bf2388f02f512 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:46:06 +0000 Subject: [PATCH 50/68] Move illustration of (un)supported cases in MPS reader documentation Signed-off-by: Hanno Becker --- library/mps_reader.c | 126 +++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index ee2312c9c..ac2955fec 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -247,75 +247,75 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, /* Check if we're still serving from the accumulator. */ if( mps_reader_serving_from_accumulator( rd ) ) { + /* Illustration of supported and unsupported cases: + * + * - Allowed #1 + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end+desired + * | | + * +-----v-------v-------------+ + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_available + * + * - Allowed #2 + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end+desired + * | | + * +----------v----------------v + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_available + * + * - Not allowed #1 (could be served, but we don't actually use it): + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end+desired + * | | + * +------v-------------v------+ + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_available + * + * + * - Not allowed #2 (can't be served with a contiguous buffer): + * + * +-----------------------------------+ + * | frag | + * +-----------------------------------+ + * + * end end + desired + * | | + * +------v--------------------+ v + * | acc | + * +---------------------------+ + * | | + * fo/frag_offset aa/acc_available + * + * In case of Allowed #2 we're switching to serve from + * `frag` starting from the next call to mbedtls_mps_reader_get(). + */ + unsigned char *acc; MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Serve the request from the accumulator" ); if( frag_offset - end < desired ) { - /* Illustration of supported and unsupported cases: - * - * - Allowed #1 - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end+desired - * | | - * +-----v-------v-------------+ - * | acc | - * +---------------------------+ - * | | - * fo/frag_offset aa/acc_available - * - * - Allowed #2 - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end+desired - * | | - * +----------v----------------v - * | acc | - * +---------------------------+ - * | | - * fo/frag_offset aa/acc_available - * - * - Not allowed #1 (could be served, but we don't actually use it): - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end+desired - * | | - * +------v-------------v------+ - * | acc | - * +---------------------------+ - * | | - * fo/frag_offset aa/acc_available - * - * - * - Not allowed #2 (can't be served with a contiguous buffer): - * - * +-----------------------------------+ - * | frag | - * +-----------------------------------+ - * - * end end + desired - * | | - * +------v--------------------+ v - * | acc | - * +---------------------------+ - * | | - * fo/frag_offset aa/acc_available - * - * In case of Allowed #1 and #2 we're switching to serve from - * `frag` starting from the next call to mbedtls_mps_reader_get(). - */ - mbedtls_mps_size_t acc_available; acc_available = rd->acc_available; if( acc_available - end != desired ) From 8a04b10ed841bfe9e799a585f43ccd87add9b187 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:49:24 +0000 Subject: [PATCH 51/68] Fix include path for MPS reader header in MPS test suite Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index d256532bb..c619d6aad 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -2,8 +2,7 @@ #include -/* TODO: How are test suites supposed to include internal headers? */ -#include "../library/mps_reader.h" +#include "mps_reader.h" /* * Compile-time configuration for test suite. From b17212a8bfbebea4198c741efa8dad8a0fedaef0 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:50:01 +0000 Subject: [PATCH 52/68] Use size_t instead of int for index in buffer loops in MPS unit test Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 44 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index c619d6aad..55cbd3db6 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -40,7 +40,7 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) unsigned char acc[10]; unsigned char *tmp; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; /* Preparation (lower layer) */ @@ -82,9 +82,9 @@ void mbedtls_mps_reader_no_pausing_single_step_multiple_rounds( int with_acc ) unsigned char acc[10]; unsigned char *tmp; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; - for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ @@ -137,7 +137,7 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_single_round( int with_acc ) unsigned char *tmp; mbedtls_mps_size_t tmp_len; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ @@ -172,9 +172,9 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds( int with_acc unsigned char *tmp; mbedtls_mps_size_t tmp_len; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; - for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ @@ -217,7 +217,7 @@ void mbedtls_mps_reader_pausing_needed_disabled() unsigned char buf[100]; unsigned char *tmp; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ @@ -257,7 +257,7 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() mbedtls_mps_reader rd; mbedtls_mps_size_t tmp_len; - for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ @@ -306,9 +306,9 @@ void mbedtls_mps_reader_pausing( int option ) unsigned char *tmp; unsigned char acc[40]; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; - for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ @@ -427,9 +427,9 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) unsigned char acc[70]; mbedtls_mps_reader rd; mbedtls_mps_size_t fetch_len; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; - for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ @@ -458,7 +458,7 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) break; case 1: /* 50 x 1byte */ - for( int num_feed=0; num_feed<49; num_feed++ ) + for( size_t num_feed=0; num_feed<49; num_feed++ ) { TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + num_feed, 1 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); @@ -467,7 +467,7 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) break; case 2: /* 49 x 1byte + 51bytes */ - for( int num_feed=0; num_feed<49; num_feed++ ) + for( size_t num_feed=0; num_feed<49; num_feed++ ) { TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + num_feed, 1 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); @@ -522,7 +522,7 @@ void mbedtls_mps_reader_reclaim_data_left( int option ) unsigned char buf[100]; unsigned char *tmp; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ @@ -582,7 +582,7 @@ void mbedtls_mps_reader_reclaim_data_left_retry() unsigned char *tmp; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ @@ -626,11 +626,11 @@ void mbedtls_mps_reader_multiple_pausing( int option ) unsigned char acc[50]; mbedtls_mps_size_t tmp_len; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; - for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); - for( int i=0; (unsigned) i < sizeof( bufC ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufC ); i++ ) bufC[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ @@ -945,9 +945,9 @@ void mbedtls_reader_inconsistent_usage( int option ) unsigned char acc[40]; mbedtls_mps_reader rd; int success = 0; - for( int i=0; (unsigned) i < sizeof( bufA ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; - for( int i=0; (unsigned) i < sizeof( bufB ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( bufB ); i++ ) bufB[i] = ~ ((unsigned char) i); /* Preparation (lower layer) */ @@ -1080,7 +1080,7 @@ void mbedtls_mps_reader_feed_empty( int option ) unsigned char buf[100]; unsigned char *tmp; mbedtls_mps_reader rd; - for( int i=0; (unsigned) i < sizeof( buf ); i++ ) + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) buf[i] = (unsigned char) i; /* Preparation (lower layer) */ From 5047b567583f82508fc0859a15618dbd7561f408 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:52:02 +0000 Subject: [PATCH 53/68] Improve wording in MPS unit tests Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 55cbd3db6..30e65d4d0 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -25,8 +25,8 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) /* This test exercises the most basic use of the MPS reader: * - The 'producing' layer provides a buffer * - The 'consuming' layer fetches it in a single go. - * - After processing, the consuming layer commit the data - * and returns back to the producing layer. + * - After processing, the consuming layer commits the data + * and the reader is moved back to producing mode. * * Parameters: * - with_acc: 0 if the reader should be initialized without accumulator. @@ -63,11 +63,11 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) /* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ void mbedtls_mps_reader_no_pausing_single_step_multiple_rounds( int with_acc ) { - /* This test exercises multiple rounds o fthe basic use of the MPS reader: + /* This test exercises multiple rounds of the basic use of the MPS reader: * - The 'producing' layer provides a buffer * - The 'consuming' layer fetches it in a single go. - * - After processing, the consuming layer commit the data - * and returns back to the producing layer. + * - After processing, the consuming layer commits the data + * and the reader is moved back to producing mode. * * Parameters: * - with_acc: 0 if the reader should be initialized without accumulator. @@ -117,16 +117,16 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_single_round( int with_acc ) /* This test exercises one round of the following: * - The 'producing' layer provides a buffer * - The 'consuming' layer fetches it in multiple calls - * to `mbedtls_mps_reader_get()`, without comitting in between. - * - After processing, the consuming layer commit the data - * and returns back to the producing layer. + * to `mbedtls_mps_reader_get()`, without committing in between. + * - After processing, the consuming layer commits the data + * and the reader is moved back to producing mode. * * Parameters: * - with_acc: 0 if the reader should be initialized without accumulator. * 1 if the reader should be initialized with accumulator. * * Whether the accumulator is present or not should not matter, - * since the consumer's request can be fulfilled from the data + * since the consumer's requests can be fulfilled from the data * that the producer has provided. */ @@ -207,7 +207,7 @@ void mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds( int with_acc /* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ void mbedtls_mps_reader_pausing_needed_disabled() { - /* This test exercises the behaviour of the MPS reader when a read requests + /* This test exercises the behaviour of the MPS reader when a read request * of the consumer exceeds what has been provided by the producer, and when * no accumulator is available in the reader. * @@ -240,7 +240,7 @@ void mbedtls_mps_reader_pausing_needed_disabled() void mbedtls_mps_reader_pausing_needed_buffer_too_small() { /* This test exercises the behaviour of the MPS reader with accumulator - * in the situation where a read requests goes beyond the bounds of the + * in the situation where a read request goes beyond the bounds of the * current read buffer, _and_ the reader's accumulator is too small to * hold the requested amount of data. * @@ -286,7 +286,7 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() void mbedtls_mps_reader_pausing( int option ) { /* This test exercises the behaviour of the reader when the - * accumulator is used to fufill the consumer's request. + * accumulator is used to fufill a consumer's request. * * More detailed: * - The producer feeds some data. @@ -410,7 +410,7 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) { /* This test exercises the behaviour of the MPS reader * in the following situation: - * - The consumer has asked for mre than what's available, so the + * - The consumer has asked for more than what's available, so the * reader pauses and waits for further input data via * `mbedtls_mps_reader_feed()` * - Multiple such calls to `mbedtls_mps_reader_feed()` are necessary @@ -615,7 +615,7 @@ void mbedtls_mps_reader_multiple_pausing( int option ) * - A read request via `mbedtls_mps_reader_get()` can't * be served and the reader is paused to accumulate * the desired amount of data from the producer. - * - Once enough data is availble, the consumer successfully + * - Once enough data is available, the consumer successfully * reads the data from the reader, but afterwards exceeds * the available data again - pausing is necessary for a * second time. @@ -1076,7 +1076,7 @@ void mbedtls_reader_inconsistent_usage( int option ) void mbedtls_mps_reader_feed_empty( int option ) { /* This test exercises the behaviour of the reader when it is - * fed a NULL buffer. */ + * fed with a NULL buffer. */ unsigned char buf[100]; unsigned char *tmp; mbedtls_mps_reader rd; From 15da2fcf81d74e674253fb0b144498ba5a922018 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:57:14 +0000 Subject: [PATCH 54/68] Remove unnecessary parameter in MPS reader unit test Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 2 +- tests/suites/test_suite_mps.function | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index 158302b8e..f25d70332 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -119,4 +119,4 @@ MPS Reader: Pausing, inconsistent continuation, #8 mbedtls_reader_inconsistent_usage:8 MPS Reader: Feed with invalid buffer (NULL) -mbedtls_mps_reader_feed_empty:0 +mbedtls_mps_reader_feed_empty: diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 30e65d4d0..d67e7d227 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -1073,7 +1073,7 @@ void mbedtls_reader_inconsistent_usage( int option ) /* END_CASE */ /* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ -void mbedtls_mps_reader_feed_empty( int option ) +void mbedtls_mps_reader_feed_empty() { /* This test exercises the behaviour of the reader when it is * fed with a NULL buffer. */ @@ -1085,17 +1085,10 @@ void mbedtls_mps_reader_feed_empty( int option ) /* Preparation (lower layer) */ mbedtls_mps_reader_init( &rd, NULL, 0 ); - switch( option ) - { - case 0: /* NULL buffer */ - TEST_ASSERT( mbedtls_mps_reader_feed( &rd, NULL, sizeof( buf ) ) == - MBEDTLS_ERR_MPS_READER_INVALID_ARG ); - break; - default: - TEST_ASSERT( 0 ); - break; - } + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, NULL, sizeof( buf ) ) == + MBEDTLS_ERR_MPS_READER_INVALID_ARG ); + /* Subsequent feed-calls should still succeed. */ TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); From 2332f8f435c04a291b7294d97f8a136f42902fe2 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 22 Feb 2021 16:58:16 +0000 Subject: [PATCH 55/68] Rename static variable for MPS trace depth Signed-off-by: Hanno Becker --- library/mps_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/mps_trace.c b/library/mps_trace.c index ceddffb56..28b05bb79 100644 --- a/library/mps_trace.c +++ b/library/mps_trace.c @@ -26,7 +26,7 @@ #include "mps_trace.h" #include -static int trace_depth_ = 0; +static int trace_depth = 0; #define color_default "\x1B[0m" #define color_red "\x1B[1;31m" @@ -68,15 +68,15 @@ void mbedtls_mps_trace_print_msg( int id, int line, const char *format, ... ) int mbedtls_mps_trace_get_depth() { - return trace_depth_; + return trace_depth; } void mbedtls_mps_trace_dec_depth() { - trace_depth_--; + trace_depth--; } void mbedtls_mps_trace_inc_depth() { - trace_depth_++; + trace_depth++; } void mbedtls_mps_trace_color( int id ) From 61d7eedcb533b394b5374056729adeb3c30dbfbb Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 5 Mar 2021 05:09:37 +0000 Subject: [PATCH 56/68] Fix Doxygen headers for MPS files Signed-off-by: Hanno Becker --- library/mps_common.h | 2 +- library/mps_error.h | 2 +- library/mps_reader.h | 2 +- library/mps_trace.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/mps_common.h b/library/mps_common.h index e541f4fb0..dd6e31bb2 100644 --- a/library/mps_common.h +++ b/library/mps_common.h @@ -18,7 +18,7 @@ */ /** - * \file common.h + * \file mps_common.h * * \brief Common functions and macros used by MPS */ diff --git a/library/mps_error.h b/library/mps_error.h index c11a01fa5..f78d9a05f 100644 --- a/library/mps_error.h +++ b/library/mps_error.h @@ -18,7 +18,7 @@ */ /** - * \file error.h + * \file mps_error.h * * \brief Error codes used by MPS */ diff --git a/library/mps_reader.h b/library/mps_reader.h index d1cad7f9b..427c1bd25 100644 --- a/library/mps_reader.h +++ b/library/mps_reader.h @@ -18,7 +18,7 @@ */ /** - * \file reader.h + * \file mps_reader.h * * \brief This file defines reader objects, which together with their * sibling writer objects form the basis for the communication diff --git a/library/mps_trace.h b/library/mps_trace.h index d94ceb912..048d5739a 100644 --- a/library/mps_trace.h +++ b/library/mps_trace.h @@ -18,7 +18,7 @@ */ /** - * \file trace.h + * \file mps_trace.h * * \brief Tracing module for MPS */ From 43c8f8cf79b97d555d76af9c9240e9f948b95ec9 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 5 Mar 2021 05:16:45 +0000 Subject: [PATCH 57/68] Put MPS under the umbrella of the TLS 1.3 experimental configuration Signed-off-by: Hanno Becker --- library/mps_reader.c | 6 ++++++ library/mps_trace.c | 5 +++++ tests/suites/test_suite_mps.function | 5 +++++ 3 files changed, 16 insertions(+) diff --git a/library/mps_reader.c b/library/mps_reader.c index ac2955fec..c23446cff 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -19,6 +19,10 @@ * This file is part of Mbed TLS (https://tls.mbed.org) */ +#include "common.h" + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + #include "mps_reader.h" #include "mps_common.h" #include "mps_trace.h" @@ -557,3 +561,5 @@ int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd, (unsigned) rd->acc_share.acc_remaining ); MBEDTLS_MPS_TRACE_RETURN( 0 ); } + +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ diff --git a/library/mps_trace.c b/library/mps_trace.c index 28b05bb79..dc0577daa 100644 --- a/library/mps_trace.c +++ b/library/mps_trace.c @@ -19,6 +19,10 @@ * This file is part of Mbed TLS (https://tls.mbed.org) */ +#include "common.h" + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + #include "mps_common.h" #if defined(MBEDTLS_MPS_ENABLE_TRACE) @@ -120,3 +124,4 @@ void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty ) } #endif /* MBEDTLS_MPS_ENABLE_TRACE */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index d67e7d227..57a84cb12 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -19,6 +19,11 @@ /* END_HEADER */ +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL + * END_DEPENDENCIES + */ + /* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) { From 7594c680497dff34fd6d2021f78c432f31f29694 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 5 Mar 2021 05:17:11 +0000 Subject: [PATCH 58/68] Document status of MPS upstreaming Signed-off-by: Hanno Becker --- docs/architecture/tls13-experimental.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/architecture/tls13-experimental.md b/docs/architecture/tls13-experimental.md index 3db16e0a6..10cbfa1e7 100644 --- a/docs/architecture/tls13-experimental.md +++ b/docs/architecture/tls13-experimental.md @@ -47,3 +47,22 @@ together with their level of testing: Those functions are implemented in `library/ssl_tls13_keys.c` and tested in `test_suite_ssl` using test vectors from RFC 8448 and https://tls13.ulfheim.net/. + +- New TLS Message Processing Stack (MPS) + + The TLS 1.3 prototype is developed alongside a rewrite of the TLS messaging layer, + encompassing low-level details such as record parsing, handshake reassembly, and + DTLS retransmission state machine. + + MPS has the following components: + - Layer 1 (Datagram handling) + - Layer 2 (Record handling) + - Layer 3 (Message handling) + - Layer 4 (Retransmission State Machine) + - Reader (Abstracted pointer arithmetic and reassembly logic for incoming data) + - Writer (Abstracted pointer arithmetic and fragmentation logic for outgoing data) + + Of those components, the following have been upstreamed + as part of `MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL`: + + - Reader ([`library/mps_reader.h`](../../library/mps_reader.h)) From 00931492daeca0a840b45cb8968545e2399c0cdd Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Mar 2021 15:39:17 +0000 Subject: [PATCH 59/68] Fix spacing in MPS test suite Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 57a84cb12..99c28093e 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -463,7 +463,7 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) break; case 1: /* 50 x 1byte */ - for( size_t num_feed=0; num_feed<49; num_feed++ ) + for( size_t num_feed = 0; num_feed < 49; num_feed++ ) { TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + num_feed, 1 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); @@ -472,7 +472,7 @@ void mbedtls_mps_reader_pausing_multiple_feeds( int option ) break; case 2: /* 49 x 1byte + 51bytes */ - for( size_t num_feed=0; num_feed<49; num_feed++ ) + for( size_t num_feed = 0; num_feed < 49; num_feed++ ) { TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB + num_feed, 1 ) == MBEDTLS_ERR_MPS_READER_NEED_MORE ); From 032b35268424d6cd131744a2a20591061c6ea85e Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Mar 2021 16:23:26 +0000 Subject: [PATCH 60/68] Improve naming of local variables in MPS reader implementation Signed-off-by: Hanno Becker --- library/mps_reader.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index c23446cff..097f2fe22 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -179,13 +179,13 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, if( mps_reader_is_accumulating( rd ) ) { unsigned char *acc = rd->acc; - mbedtls_mps_size_t ar = rd->acc_share.acc_remaining; - mbedtls_mps_size_t aa = rd->acc_available; + mbedtls_mps_size_t acc_remaining = rd->acc_share.acc_remaining; + mbedtls_mps_size_t acc_available = rd->acc_available; /* Skip over parts of the accumulator that have already been filled. */ - acc += aa; + acc += acc_available; - copy_to_acc = ar; + copy_to_acc = acc_remaining; if( copy_to_acc > new_frag_len ) copy_to_acc = new_frag_len; @@ -195,16 +195,16 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Copy new data of size %u of %u into accumulator at offset %u", - (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) aa ); + (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) acc_available ); /* Check if, with the new fragment, we have enough data. */ - ar -= copy_to_acc; - if( ar > 0 ) + acc_remaining -= copy_to_acc; + if( acc_remaining > 0 ) { /* We need to accumulate more data. Stay in producing mode. */ - aa += copy_to_acc; - rd->acc_share.acc_remaining = ar; - rd->acc_available = aa; + acc_available += copy_to_acc; + rd->acc_share.acc_remaining = acc_remaining; + rd->acc_available = acc_available; MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE ); } @@ -214,9 +214,9 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, "Enough data available to serve user request" ); /* Remember overlap of accumulator and fragment. */ - rd->acc_share.frag_offset = aa; - aa += copy_to_acc; - rd->acc_available = aa; + rd->acc_share.frag_offset = acc_available; + acc_available += copy_to_acc; + rd->acc_available = acc_available; } else /* Not accumulating */ { From d7fcbfa71e245c43acd20a9da5a80972c8cc46c3 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Mar 2021 16:25:38 +0000 Subject: [PATCH 61/68] Test `paused` argument of MPS reader mbedtls_mps_reader_reclaim() Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 99c28093e..aaaca97cd 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -44,6 +44,7 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) unsigned char bufA[100]; unsigned char acc[10]; unsigned char *tmp; + int paused; mbedtls_mps_reader rd; for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; @@ -60,7 +61,8 @@ void mbedtls_mps_reader_no_pausing_single_step_single_round( int with_acc ) ASSERT_COMPARE( tmp, 100, bufA, 100 ); TEST_ASSERT( mbedtls_mps_reader_commit( &rd ) == 0 ); /* Wrapup (lower layer) */ - TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, &paused ) == 0 ); + TEST_ASSERT( paused == 0 ); mbedtls_mps_reader_free( &rd ); } /* END_CASE */ @@ -310,6 +312,7 @@ void mbedtls_mps_reader_pausing( int option ) unsigned char bufA[100], bufB[100]; unsigned char *tmp; unsigned char acc[40]; + int paused; mbedtls_mps_reader rd; for( size_t i=0; (unsigned) i < sizeof( bufA ); i++ ) bufA[i] = (unsigned char) i; @@ -340,7 +343,8 @@ void mbedtls_mps_reader_pausing( int option ) MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); /* Preparation */ - TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == 0 ); + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, &paused ) == 0 ); + TEST_ASSERT( paused == 1 ); TEST_ASSERT( mbedtls_mps_reader_feed( &rd, bufB, sizeof( bufB ) ) == 0 ); /* Consumption */ From 756abeb4e116baa0e45710fbbf2786f91a0e32dc Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Mar 2021 16:28:09 +0000 Subject: [PATCH 62/68] Fix typo in MPS test suite Signed-off-by: Hanno Becker --- .gitignore | 1 + tests/suites/test_suite_mps.function | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 39cdc4ea5..999c60216 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ massif-* /TAGS /cscope*.out /tags +/cmake_baremetal/tests/test_suite_aes.ecb.datax diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index aaaca97cd..d4cb69b78 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -293,7 +293,7 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() void mbedtls_mps_reader_pausing( int option ) { /* This test exercises the behaviour of the reader when the - * accumulator is used to fufill a consumer's request. + * accumulator is used to fulfill a consumer's request. * * More detailed: * - The producer feeds some data. From d4d33a1b6b5f9f83aff7cd4bd5eeca0a035a7505 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Mar 2021 16:45:04 +0000 Subject: [PATCH 63/68] Remove unnecessary check before calling memcpy() This check was added earlier to avoid useless calls to `memcpy()` with length `0` in the _frequent_ case where we're not accumulating. By now, the whole code path has been moved to a branch which is only executed if the reader is accumulating, and the only time this check would be relevant is if we happen to feed an empty fragment to the reader. In this case, the call to memcpy() could be removed, but since this case is exceptional and the call to memcpy() is still correct even for a length 0 copy, we remove the check for simplicity of the code. Signed-off-by: Hanno Becker --- library/mps_reader.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 097f2fe22..63a19543a 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -190,8 +190,7 @@ int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd, copy_to_acc = new_frag_len; /* Copy new contents to accumulator. */ - if( copy_to_acc > 0 ) - memcpy( acc, new_frag, copy_to_acc ); + memcpy( acc, new_frag, copy_to_acc ); MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment, "Copy new data of size %u of %u into accumulator at offset %u", From 1b1e7eb611c23c7b20e8c9371638fbe36f6c87f4 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Mon, 8 Mar 2021 16:57:08 +0000 Subject: [PATCH 64/68] Add unit test for integer overflow in mbedtls_mps_reader_reclaim() Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.data | 3 +++ tests/suites/test_suite_mps.function | 32 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tests/suites/test_suite_mps.data b/tests/suites/test_suite_mps.data index f25d70332..442f32188 100644 --- a/tests/suites/test_suite_mps.data +++ b/tests/suites/test_suite_mps.data @@ -120,3 +120,6 @@ mbedtls_reader_inconsistent_usage:8 MPS Reader: Feed with invalid buffer (NULL) mbedtls_mps_reader_feed_empty: + +MPS Reader: Excess request leading to integer overflow +mbedtls_mps_reader_reclaim_overflow: diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index d4cb69b78..870e201e9 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -289,6 +289,38 @@ void mbedtls_mps_reader_pausing_needed_buffer_too_small() } /* END_CASE */ +/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ +void mbedtls_mps_reader_reclaim_overflow() +{ + /* This test exercises the behaviour of the MPS reader with accumulator + * in the situation where upon calling mbedtls_mps_reader_reclaim(), the + * uncommitted data together with the excess data missing in the last + * call to medtls_mps_reader_get() exceeds the bounds of the the type + * holding the buffer length. + */ + + unsigned char buf[100]; + unsigned char acc[50]; + unsigned char *tmp; + mbedtls_mps_reader rd; + + /* Preparation (lower layer) */ + mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); + TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); + /* Consumption (upper layer) */ + TEST_ASSERT( mbedtls_mps_reader_get( &rd, 50, &tmp, NULL ) == 0 ); + ASSERT_COMPARE( tmp, 50, buf, 50 ); + /* Excess request */ + TEST_ASSERT( mbedtls_mps_reader_get( &rd, (mbedtls_mps_size_t) -1, &tmp, NULL ) == + MBEDTLS_ERR_MPS_READER_OUT_OF_DATA ); + /* Wrapup (lower layer) */ + TEST_ASSERT( mbedtls_mps_reader_reclaim( &rd, NULL ) == + MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL ); + + mbedtls_mps_reader_free( &rd ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ void mbedtls_mps_reader_pausing( int option ) { From 3c6386cde54dba5eecf80db3de939df9b3767ff6 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 19 Mar 2021 05:23:19 +0000 Subject: [PATCH 65/68] Revert accidental gitignore change Signed-off-by: Hanno Becker --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 999c60216..39cdc4ea5 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,3 @@ massif-* /TAGS /cscope*.out /tags -/cmake_baremetal/tests/test_suite_aes.ecb.datax From 5b3841d592681ffa11a3e6564d00df1aaeec3b40 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 19 Mar 2021 05:23:30 +0000 Subject: [PATCH 66/68] Fix uninitialized memory bug in MPS reader test Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 870e201e9..6bd74b1d9 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -304,6 +304,9 @@ void mbedtls_mps_reader_reclaim_overflow() unsigned char *tmp; mbedtls_mps_reader rd; + for( size_t i=0; (unsigned) i < sizeof( buf ); i++ ) + buf[i] = (unsigned char) i; + /* Preparation (lower layer) */ mbedtls_mps_reader_init( &rd, acc, sizeof( acc ) ); TEST_ASSERT( mbedtls_mps_reader_feed( &rd, buf, sizeof( buf ) ) == 0 ); From c0b1b252bc105349c61803480d06b44bc94df1d7 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 26 Mar 2021 19:18:01 +0000 Subject: [PATCH 67/68] Update tests/suites/test_suite_mps.function Signed-off-by: Hanno Becker --- tests/suites/test_suite_mps.function | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_mps.function b/tests/suites/test_suite_mps.function index 6bd74b1d9..9df8a3c6e 100644 --- a/tests/suites/test_suite_mps.function +++ b/tests/suites/test_suite_mps.function @@ -295,7 +295,7 @@ void mbedtls_mps_reader_reclaim_overflow() /* This test exercises the behaviour of the MPS reader with accumulator * in the situation where upon calling mbedtls_mps_reader_reclaim(), the * uncommitted data together with the excess data missing in the last - * call to medtls_mps_reader_get() exceeds the bounds of the the type + * call to medtls_mps_reader_get() exceeds the bounds of the type * holding the buffer length. */ From ecb02fbbc5a2c24bc913f787b24175e8a791c00b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 26 Mar 2021 19:20:49 +0000 Subject: [PATCH 68/68] Apply suggestions from code review Signed-off-by: Hanno Becker --- library/mps_reader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/mps_reader.c b/library/mps_reader.c index 63a19543a..848634d6b 100644 --- a/library/mps_reader.c +++ b/library/mps_reader.c @@ -264,7 +264,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_available + * frag_offset acc_available * * - Allowed #2 * @@ -278,7 +278,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_available + * frag_offset acc_available * * - Not allowed #1 (could be served, but we don't actually use it): * @@ -292,7 +292,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_available + * frag_offset acc_available * * * - Not allowed #2 (can't be served with a contiguous buffer): @@ -307,7 +307,7 @@ int mbedtls_mps_reader_get( mbedtls_mps_reader *rd, * | acc | * +---------------------------+ * | | - * fo/frag_offset aa/acc_available + * frag_offset acc_available * * In case of Allowed #2 we're switching to serve from * `frag` starting from the next call to mbedtls_mps_reader_get().