blob: 3193a5e334e329998680de0fddcd848beb1b5677 [file] [log] [blame]
Hanno Becker1c0cd102021-01-12 07:01:23 +00001/*
2 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00003 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Hanno Becker1c0cd102021-01-12 07:01:23 +00004 */
5
6/**
Hanno Becker61d7eed2021-03-05 05:09:37 +00007 * \file mps_reader.h
Hanno Becker1c0cd102021-01-12 07:01:23 +00008 *
9 * \brief This file defines reader objects, which together with their
10 * sibling writer objects form the basis for the communication
11 * between the various layers of the Mbed TLS messaging stack,
12 * as well as the communication between the messaging stack and
13 * the (D)TLS handshake protocol implementation.
14 *
15 * Readers provide a means of transferring incoming data from
16 * a 'producer' providing it in chunks of arbitrary size, to
17 * a 'consumer' which fetches and processes it in chunks of
18 * again arbitrary, and potentially different, size.
19 *
Hanno Becker4f84e202021-02-08 06:54:30 +000020 * Readers can thus be seen as datagram-to-stream converters,
Hanno Becker1c0cd102021-01-12 07:01:23 +000021 * and they abstract away the following two tasks from the user:
22 * 1. The pointer arithmetic of stepping through a producer-
23 * provided chunk in smaller chunks.
24 * 2. The merging of incoming data chunks in case the
25 * consumer requests data in larger chunks than what the
26 * producer provides.
27 *
28 * The basic abstract flow of operation is the following:
29 * - Initially, the reader is in 'producing mode'.
30 * - The producer hands an incoming data buffer to the reader,
31 * moving it from 'producing' to 'consuming' mode.
32 * - The consumer subsequently fetches and processes the buffer
33 * content. Once that's done -- or partially done and a consumer's
Hanno Becker3d0db812021-02-08 08:22:52 +000034 * request can't be fulfilled -- the producer revokes the reader's
Hanno Becker1c0cd102021-01-12 07:01:23 +000035 * access to the incoming data buffer, putting the reader back to
36 * producing mode.
37 * - The producer subsequently gathers more incoming data and hands
Hanno Beckerfea81b32021-02-22 15:18:11 +000038 * it to the reader until it switches back to consuming mode
Hanno Becker1c0cd102021-01-12 07:01:23 +000039 * if enough data is available for the last consumer request to
40 * be satisfiable.
41 * - Repeat the above.
42 *
Hanno Becker4f84e202021-02-08 06:54:30 +000043 * The abstract states of the reader from the producer's and
44 * consumer's perspective are as follows:
Hanno Becker1c0cd102021-01-12 07:01:23 +000045 *
Hanno Becker4f84e202021-02-08 06:54:30 +000046 * - From the perspective of the consumer, the state of the
47 * reader consists of the following:
48 * - A byte stream representing (concatenation of) the data
49 * received through calls to mbedtls_mps_reader_get(),
50 * - A marker within that byte stream indicating which data
Hanno Beckerfea81b32021-02-22 15:18:11 +000051 * can be considered processed, and hence need not be retained,
52 * when the reader is passed back to the producer via
53 * mbedtls_mps_reader_reclaim().
54 * The marker is set via mbedtls_mps_reader_commit()
Hanno Becker4f84e202021-02-08 06:54:30 +000055 * which places it at the end of the current byte stream.
56 * The consumer need not be aware of the distinction between consumer
Hanno Beckerfea81b32021-02-22 15:18:11 +000057 * and producer mode, because it only interfaces with the reader
Hanno Becker4f84e202021-02-08 06:54:30 +000058 * when the latter is in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +000059 *
Hanno Becker4f84e202021-02-08 06:54:30 +000060 * - From the perspective of the producer, the reader's state is one of:
61 * - Attached: The reader is in consuming mode.
62 * - Unset: No incoming data buffer is currently managed by the reader,
63 * and all previously handed incoming data buffers have been
64 * fully processed. More data needs to be fed into the reader
65 * via mbedtls_mps_reader_feed().
66 *
67 * - Accumulating: No incoming data buffer is currently managed by the
68 * reader, but some data from the previous incoming data
69 * buffer hasn't been processed yet and is internally
70 * held back.
71 * The Attached state belongs to consuming mode, while the Unset and
72 * Accumulating states belong to producing mode.
73 *
74 * Transitioning from the Unset or Accumulating state to Attached is
75 * done via successful calls to mbedtls_mps_reader_feed(), while
Hanno Beckerfea81b32021-02-22 15:18:11 +000076 * transitioning from Attached to either Unset or Accumulating (depending
Hanno Becker88993962021-01-28 09:45:47 +000077 * on what has been processed) is done via mbedtls_mps_reader_reclaim().
Hanno Becker1c0cd102021-01-12 07:01:23 +000078 *
79 * The following diagram depicts the producer-state progression:
80 *
81 * +------------------+ reclaim
82 * | Unset +<-------------------------------------+ get
83 * +--------|---------+ | +------+
84 * | | | |
85 * | | | |
86 * | feed +---------+---+--+ |
Hanno Becker4f84e202021-02-08 06:54:30 +000087 * +--------------------------------------> <---+
88 * | Attached |
89 * +--------------------------------------> <---+
Hanno Becker1c0cd102021-01-12 07:01:23 +000090 * | feed, enough data available +---------+---+--+ |
91 * | to serve previous consumer request | | |
92 * | | | |
93 * +--------+---------+ | +------+
94 * +----> Accumulating |<-------------------------------------+ commit
95 * | +---+--------------+ reclaim, previous read request
96 * | | couldn't be fulfilled
97 * | |
98 * +--------+
99 * feed, need more data to serve
100 * previous consumer request
Hanno Becker4f84e202021-02-08 06:54:30 +0000101 * |
102 * |
103 * producing mode | consuming mode
104 * |
Hanno Becker1c0cd102021-01-12 07:01:23 +0000105 *
106 */
107
108#ifndef MBEDTLS_READER_H
109#define MBEDTLS_READER_H
110
111#include <stdio.h>
112
Hanno Beckerc518c3b2021-01-28 07:08:08 +0000113#include "mps_common.h"
114#include "mps_error.h"
Hanno Becker1c0cd102021-01-12 07:01:23 +0000115
Hanno Becker88993962021-01-28 09:45:47 +0000116struct mbedtls_mps_reader;
117typedef struct mbedtls_mps_reader mbedtls_mps_reader;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000118
119/*
120 * Structure definitions
121 */
122
Gilles Peskine449bd832023-01-11 14:50:10 +0100123struct mbedtls_mps_reader {
Hanno Becker1c0cd102021-01-12 07:01:23 +0000124 unsigned char *frag; /*!< The fragment of incoming data managed by
125 * the reader; it is provided to the reader
Hanno Becker88993962021-01-28 09:45:47 +0000126 * through mbedtls_mps_reader_feed(). The reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000127 * does not own the fragment and does not
128 * perform any allocation operations on it,
Hanno Beckerfea81b32021-02-22 15:18:11 +0000129 * but does have read and write access to it.
130 *
131 * The reader is in consuming mode if
132 * and only if \c frag is not \c NULL. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000133 mbedtls_mps_stored_size_t frag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 /*!< The length of the current fragment.
135 * Must be 0 if \c frag == \c NULL. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000136 mbedtls_mps_stored_size_t commit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 /*!< The offset of the last commit, relative
138 * to the first byte in the fragment, if
139 * no accumulator is present. If an accumulator
140 * is present, it is viewed as a prefix to the
141 * current fragment, and this variable contains
142 * an offset from the beginning of the accumulator.
143 *
144 * This is only used when the reader is in
145 * consuming mode, i.e. \c frag != \c NULL;
146 * otherwise, its value is \c 0. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000147 mbedtls_mps_stored_size_t end;
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 /*!< The offset of the end of the last chunk
149 * passed to the user through a call to
150 * mbedtls_mps_reader_get(), relative to the first
151 * byte in the fragment, if no accumulator is
152 * present. If an accumulator is present, it is
153 * viewed as a prefix to the current fragment, and
154 * this variable contains an offset from the
155 * beginning of the accumulator.
156 *
157 * This is only used when the reader is in
158 * consuming mode, i.e. \c frag != \c NULL;
159 * otherwise, its value is \c 0. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000160 mbedtls_mps_stored_size_t pending;
Gilles Peskine449bd832023-01-11 14:50:10 +0100161 /*!< The amount of incoming data missing on the
162 * last call to mbedtls_mps_reader_get().
163 * In particular, it is \c 0 if the last call
164 * was successful.
165 * If a reader is reclaimed after an
166 * unsuccessful call to mbedtls_mps_reader_get(),
167 * this variable is used to have the reader
168 * remember how much data should be accumulated
169 * so that the call to mbedtls_mps_reader_get()
170 * succeeds next time.
171 * This is only used when the reader is in
172 * consuming mode, i.e. \c frag != \c NULL;
173 * otherwise, its value is \c 0. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000174
175 /* The accumulator is only needed if we need to be able to pause
176 * the reader. A few bytes could be saved by moving this to a
177 * separate struct and using a pointer here. */
178
179 unsigned char *acc; /*!< The accumulator is used to gather incoming
Hanno Becker88993962021-01-28 09:45:47 +0000180 * data if a read-request via mbedtls_mps_reader_get()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000181 * cannot be served from the current fragment. */
182 mbedtls_mps_stored_size_t acc_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 /*!< The total size of the accumulator. */
Hanno Beckerb1855432021-02-08 08:07:35 +0000184 mbedtls_mps_stored_size_t acc_available;
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 /*!< The number of bytes currently gathered in
186 * the accumulator. This is both used in
187 * producing and in consuming mode:
188 * While producing, it is increased until
189 * it reaches the value of \c acc_remaining below.
190 * While consuming, it is used to judge if a
191 * get request can be served from the
192 * accumulator or not.
193 * Must not be larger than \c acc_len. */
194 union {
Hanno Becker1c0cd102021-01-12 07:01:23 +0000195 mbedtls_mps_stored_size_t acc_remaining;
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 /*!< This indicates the amount of data still
197 * to be gathered in the accumulator. It is
198 * only used in producing mode.
199 * Must be at most acc_len - acc_available. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000200 mbedtls_mps_stored_size_t frag_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 /*!< If an accumulator is present and in use, this
202 * field indicates the offset of the current
203 * fragment from the beginning of the
204 * accumulator. If no accumulator is present
205 * or the accumulator is not in use, this is \c 0.
206 * It is only used in consuming mode.
207 * Must not be larger than \c acc_available. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000208 } acc_share;
209};
210
211/*
212 * API organization:
213 * A reader object is usually prepared and maintained
214 * by some lower layer and passed for usage to an upper
215 * layer, and the API naturally splits according to which
216 * layer is supposed to use the respective functions.
217 */
218
219/*
220 * Maintenance API (Lower layer)
221 */
222
223/**
224 * \brief Initialize a reader object
225 *
226 * \param reader The reader to be initialized.
227 * \param acc The buffer to be used as a temporary accumulator
Hanno Beckerfea81b32021-02-22 15:18:11 +0000228 * in case get requests through mbedtls_mps_reader_get()
Hanno Becker88993962021-01-28 09:45:47 +0000229 * exceed the buffer provided by mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000230 * This buffer is owned by the caller and exclusive use
Hanno Beckerfea81b32021-02-22 15:18:11 +0000231 * for reading and writing is given to the reader for the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000232 * duration of the reader's lifetime. It is thus the caller's
233 * responsibility to maintain (and not touch) the buffer for
234 * the lifetime of the reader, and to properly zeroize and
235 * free the memory after the reader has been destroyed.
236 * \param acc_len The size in Bytes of \p acc.
237 *
238 * \return \c 0 on success.
239 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
240 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241int mbedtls_mps_reader_init(mbedtls_mps_reader *reader,
242 unsigned char *acc,
243 mbedtls_mps_size_t acc_len);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000244
245/**
246 * \brief Free a reader object
247 *
248 * \param reader The reader to be freed.
249 *
250 * \return \c 0 on success.
251 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
252 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100253int mbedtls_mps_reader_free(mbedtls_mps_reader *reader);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000254
255/**
256 * \brief Pass chunk of data for the reader to manage.
257 *
258 * \param reader The reader context to use. The reader must be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000259 * in producing mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000260 * \param buf The buffer to be managed by the reader.
261 * \param buflen The size in Bytes of \p buffer.
262 *
263 * \return \c 0 on success. In this case, the reader will be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000264 * moved to consuming mode and obtains read access
265 * of \p buf until mbedtls_mps_reader_reclaim()
266 * is called. It is the responsibility of the caller
267 * to ensure that the \p buf persists and is not changed
268 * between successful calls to mbedtls_mps_reader_feed()
269 * and mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000270 * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
Hanno Becker88993962021-01-28 09:45:47 +0000271 * required to fulfill a previous request to mbedtls_mps_reader_get().
Hanno Beckerfea81b32021-02-22 15:18:11 +0000272 * In this case, the reader remains in producing mode and
Hanno Becker1c0cd102021-01-12 07:01:23 +0000273 * takes no ownership of the provided buffer (an internal copy
274 * is made instead).
275 * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
276 * different kinds of failures.
277 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100278int mbedtls_mps_reader_feed(mbedtls_mps_reader *reader,
279 unsigned char *buf,
280 mbedtls_mps_size_t buflen);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000281
282/**
283 * \brief Reclaim reader's access to the current input buffer.
284 *
285 * \param reader The reader context to use. The reader must be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000286 * in consuming mode.
Hanno Becker49cc1312021-02-08 08:17:32 +0000287 * \param paused If not \c NULL, the integer at address \p paused will be
Hanno Becker1c0cd102021-01-12 07:01:23 +0000288 * modified to indicate whether the reader has been paused
289 * (value \c 1) or not (value \c 0). Pausing happens if there
290 * is uncommitted data and a previous request to
Hanno Becker88993962021-01-28 09:45:47 +0000291 * mbedtls_mps_reader_get() has exceeded the bounds of the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000292 * input buffer.
293 *
294 * \return \c 0 on success.
295 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
296 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100297int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *reader,
298 int *paused);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000299
300/*
301 * Usage API (Upper layer)
302 */
303
304/**
305 * \brief Request data from the reader.
306 *
307 * \param reader The reader context to use. The reader must
Hanno Beckerfea81b32021-02-22 15:18:11 +0000308 * be in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000309 * \param desired The desired amount of data to be read, in Bytes.
310 * \param buffer The address to store the buffer pointer in.
311 * This must not be \c NULL.
312 * \param buflen The address to store the actual buffer
313 * length in, or \c NULL.
314 *
315 * \return \c 0 on success. In this case, \c *buf holds the
316 * address of a buffer of size \c *buflen
317 * (if \c buflen != \c NULL) or \c desired
Hanno Beckerfea81b32021-02-22 15:18:11 +0000318 * (if \c buflen == \c NULL). The user has read access
319 * to the buffer and guarantee of stability of the data
320 * until the next call to mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000321 * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
Hanno Beckerfea81b32021-02-22 15:18:11 +0000322 * data available to serve the get request. In this case, the
323 * reader remains intact and in consuming mode, and the consumer
324 * should retry the call after a successful cycle of
325 * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
326 * If, after such a cycle, the consumer requests a different
327 * amount of data, the result is implementation-defined;
328 * progress is guaranteed only if the same amount of data
329 * is requested after a mbedtls_mps_reader_reclaim() and
330 * mbedtls_mps_reader_feed() cycle.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000331 * \return Another negative \c MBEDTLS_ERR_READER_XXX error
332 * code for different kinds of failure.
333 *
334 * \note Passing \c NULL as \p buflen is a convenient way to
335 * indicate that fragmentation is not tolerated.
336 * It's functionally equivalent to passing a valid
337 * address as buflen and checking \c *buflen == \c desired
338 * afterwards.
339 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100340int mbedtls_mps_reader_get(mbedtls_mps_reader *reader,
341 mbedtls_mps_size_t desired,
342 unsigned char **buffer,
343 mbedtls_mps_size_t *buflen);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000344
345/**
Hanno Beckerfea81b32021-02-22 15:18:11 +0000346 * \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000347 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000348 * This call indicates that all data received from prior calls to
Hanno Beckerfea81b32021-02-22 15:18:11 +0000349 * mbedtls_mps_reader_get() has been or will have been
Hanno Becker4f84e202021-02-08 06:54:30 +0000350 * processed when mbedtls_mps_reader_reclaim() is called,
351 * and thus need not be backed up.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000352 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000353 * This function has no user observable effect until
354 * mbedtls_mps_reader_reclaim() is called. In particular,
Hanno Beckerfea81b32021-02-22 15:18:11 +0000355 * buffers received from mbedtls_mps_reader_get() remain
Hanno Becker4f84e202021-02-08 06:54:30 +0000356 * valid until mbedtls_mps_reader_reclaim() is called.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000357 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000358 * \param reader The reader context to use.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000359 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000360 * \return \c 0 on success.
361 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000362 *
363 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100364int mbedtls_mps_reader_commit(mbedtls_mps_reader *reader);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000365
366#endif /* MBEDTLS_READER_H */