blob: d877ee54acdf2907d83a088d93f9f96067e7f280 [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 *
Gilles Peskinee820c0a2023-08-03 17:45:20 +02005 * This file is part of Mbed TLS (https://tls.mbed.org)
Hanno Becker1c0cd102021-01-12 07:01:23 +00006 */
7
8/**
Hanno Becker61d7eed2021-03-05 05:09:37 +00009 * \file mps_reader.h
Hanno Becker1c0cd102021-01-12 07:01:23 +000010 *
11 * \brief This file defines reader objects, which together with their
12 * sibling writer objects form the basis for the communication
13 * between the various layers of the Mbed TLS messaging stack,
14 * as well as the communication between the messaging stack and
15 * the (D)TLS handshake protocol implementation.
16 *
17 * Readers provide a means of transferring incoming data from
18 * a 'producer' providing it in chunks of arbitrary size, to
19 * a 'consumer' which fetches and processes it in chunks of
20 * again arbitrary, and potentially different, size.
21 *
Hanno Becker4f84e202021-02-08 06:54:30 +000022 * Readers can thus be seen as datagram-to-stream converters,
Hanno Becker1c0cd102021-01-12 07:01:23 +000023 * and they abstract away the following two tasks from the user:
24 * 1. The pointer arithmetic of stepping through a producer-
25 * provided chunk in smaller chunks.
26 * 2. The merging of incoming data chunks in case the
27 * consumer requests data in larger chunks than what the
28 * producer provides.
29 *
30 * The basic abstract flow of operation is the following:
31 * - Initially, the reader is in 'producing mode'.
32 * - The producer hands an incoming data buffer to the reader,
33 * moving it from 'producing' to 'consuming' mode.
34 * - The consumer subsequently fetches and processes the buffer
35 * content. Once that's done -- or partially done and a consumer's
Hanno Becker3d0db812021-02-08 08:22:52 +000036 * request can't be fulfilled -- the producer revokes the reader's
Hanno Becker1c0cd102021-01-12 07:01:23 +000037 * access to the incoming data buffer, putting the reader back to
38 * producing mode.
39 * - The producer subsequently gathers more incoming data and hands
Hanno Beckerfea81b32021-02-22 15:18:11 +000040 * it to the reader until it switches back to consuming mode
Hanno Becker1c0cd102021-01-12 07:01:23 +000041 * if enough data is available for the last consumer request to
42 * be satisfiable.
43 * - Repeat the above.
44 *
Hanno Becker4f84e202021-02-08 06:54:30 +000045 * The abstract states of the reader from the producer's and
46 * consumer's perspective are as follows:
Hanno Becker1c0cd102021-01-12 07:01:23 +000047 *
Hanno Becker4f84e202021-02-08 06:54:30 +000048 * - From the perspective of the consumer, the state of the
49 * reader consists of the following:
50 * - A byte stream representing (concatenation of) the data
51 * received through calls to mbedtls_mps_reader_get(),
52 * - A marker within that byte stream indicating which data
Hanno Beckerfea81b32021-02-22 15:18:11 +000053 * can be considered processed, and hence need not be retained,
54 * when the reader is passed back to the producer via
55 * mbedtls_mps_reader_reclaim().
56 * The marker is set via mbedtls_mps_reader_commit()
Hanno Becker4f84e202021-02-08 06:54:30 +000057 * which places it at the end of the current byte stream.
58 * The consumer need not be aware of the distinction between consumer
Hanno Beckerfea81b32021-02-22 15:18:11 +000059 * and producer mode, because it only interfaces with the reader
Hanno Becker4f84e202021-02-08 06:54:30 +000060 * when the latter is in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +000061 *
Hanno Becker4f84e202021-02-08 06:54:30 +000062 * - From the perspective of the producer, the reader's state is one of:
63 * - Attached: The reader is in consuming mode.
64 * - Unset: No incoming data buffer is currently managed by the reader,
65 * and all previously handed incoming data buffers have been
66 * fully processed. More data needs to be fed into the reader
67 * via mbedtls_mps_reader_feed().
68 *
69 * - Accumulating: No incoming data buffer is currently managed by the
70 * reader, but some data from the previous incoming data
71 * buffer hasn't been processed yet and is internally
72 * held back.
73 * The Attached state belongs to consuming mode, while the Unset and
74 * Accumulating states belong to producing mode.
75 *
76 * Transitioning from the Unset or Accumulating state to Attached is
77 * done via successful calls to mbedtls_mps_reader_feed(), while
Hanno Beckerfea81b32021-02-22 15:18:11 +000078 * transitioning from Attached to either Unset or Accumulating (depending
Hanno Becker88993962021-01-28 09:45:47 +000079 * on what has been processed) is done via mbedtls_mps_reader_reclaim().
Hanno Becker1c0cd102021-01-12 07:01:23 +000080 *
81 * The following diagram depicts the producer-state progression:
82 *
83 * +------------------+ reclaim
84 * | Unset +<-------------------------------------+ get
85 * +--------|---------+ | +------+
86 * | | | |
87 * | | | |
88 * | feed +---------+---+--+ |
Hanno Becker4f84e202021-02-08 06:54:30 +000089 * +--------------------------------------> <---+
90 * | Attached |
91 * +--------------------------------------> <---+
Hanno Becker1c0cd102021-01-12 07:01:23 +000092 * | feed, enough data available +---------+---+--+ |
93 * | to serve previous consumer request | | |
94 * | | | |
95 * +--------+---------+ | +------+
96 * +----> Accumulating |<-------------------------------------+ commit
97 * | +---+--------------+ reclaim, previous read request
98 * | | couldn't be fulfilled
99 * | |
100 * +--------+
101 * feed, need more data to serve
102 * previous consumer request
Hanno Becker4f84e202021-02-08 06:54:30 +0000103 * |
104 * |
105 * producing mode | consuming mode
106 * |
Hanno Becker1c0cd102021-01-12 07:01:23 +0000107 *
108 */
109
110#ifndef MBEDTLS_READER_H
111#define MBEDTLS_READER_H
112
113#include <stdio.h>
114
Hanno Beckerc518c3b2021-01-28 07:08:08 +0000115#include "mps_common.h"
116#include "mps_error.h"
Hanno Becker1c0cd102021-01-12 07:01:23 +0000117
Hanno Becker88993962021-01-28 09:45:47 +0000118struct mbedtls_mps_reader;
119typedef struct mbedtls_mps_reader mbedtls_mps_reader;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000120
121/*
122 * Structure definitions
123 */
124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125struct mbedtls_mps_reader {
Hanno Becker1c0cd102021-01-12 07:01:23 +0000126 unsigned char *frag; /*!< The fragment of incoming data managed by
127 * the reader; it is provided to the reader
Hanno Becker88993962021-01-28 09:45:47 +0000128 * through mbedtls_mps_reader_feed(). The reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000129 * does not own the fragment and does not
130 * perform any allocation operations on it,
Hanno Beckerfea81b32021-02-22 15:18:11 +0000131 * but does have read and write access to it.
132 *
133 * The reader is in consuming mode if
134 * and only if \c frag is not \c NULL. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000135 mbedtls_mps_stored_size_t frag_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 /*!< The length of the current fragment.
137 * Must be 0 if \c frag == \c NULL. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000138 mbedtls_mps_stored_size_t commit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 /*!< The offset of the last commit, relative
140 * to the first byte in the fragment, if
141 * no accumulator is present. If an accumulator
142 * is present, it is viewed as a prefix to the
143 * current fragment, and this variable contains
144 * an offset from the beginning of the accumulator.
145 *
146 * This is only used when the reader is in
147 * consuming mode, i.e. \c frag != \c NULL;
148 * otherwise, its value is \c 0. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000149 mbedtls_mps_stored_size_t end;
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 /*!< The offset of the end of the last chunk
151 * passed to the user through a call to
152 * mbedtls_mps_reader_get(), relative to the first
153 * byte in the fragment, if no accumulator is
154 * present. If an accumulator is present, it is
155 * viewed as a prefix to the current fragment, and
156 * this variable contains an offset from the
157 * beginning of the accumulator.
158 *
159 * This is only used when the reader is in
160 * consuming mode, i.e. \c frag != \c NULL;
161 * otherwise, its value is \c 0. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000162 mbedtls_mps_stored_size_t pending;
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 /*!< The amount of incoming data missing on the
164 * last call to mbedtls_mps_reader_get().
165 * In particular, it is \c 0 if the last call
166 * was successful.
167 * If a reader is reclaimed after an
168 * unsuccessful call to mbedtls_mps_reader_get(),
169 * this variable is used to have the reader
170 * remember how much data should be accumulated
171 * so that the call to mbedtls_mps_reader_get()
172 * succeeds next time.
173 * This is only used when the reader is in
174 * consuming mode, i.e. \c frag != \c NULL;
175 * otherwise, its value is \c 0. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000176
177 /* The accumulator is only needed if we need to be able to pause
178 * the reader. A few bytes could be saved by moving this to a
179 * separate struct and using a pointer here. */
180
181 unsigned char *acc; /*!< The accumulator is used to gather incoming
Hanno Becker88993962021-01-28 09:45:47 +0000182 * data if a read-request via mbedtls_mps_reader_get()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000183 * cannot be served from the current fragment. */
184 mbedtls_mps_stored_size_t acc_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 /*!< The total size of the accumulator. */
Hanno Beckerb1855432021-02-08 08:07:35 +0000186 mbedtls_mps_stored_size_t acc_available;
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 /*!< The number of bytes currently gathered in
188 * the accumulator. This is both used in
189 * producing and in consuming mode:
190 * While producing, it is increased until
191 * it reaches the value of \c acc_remaining below.
192 * While consuming, it is used to judge if a
193 * get request can be served from the
194 * accumulator or not.
195 * Must not be larger than \c acc_len. */
196 union {
Hanno Becker1c0cd102021-01-12 07:01:23 +0000197 mbedtls_mps_stored_size_t acc_remaining;
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 /*!< This indicates the amount of data still
199 * to be gathered in the accumulator. It is
200 * only used in producing mode.
201 * Must be at most acc_len - acc_available. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000202 mbedtls_mps_stored_size_t frag_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 /*!< If an accumulator is present and in use, this
204 * field indicates the offset of the current
205 * fragment from the beginning of the
206 * accumulator. If no accumulator is present
207 * or the accumulator is not in use, this is \c 0.
208 * It is only used in consuming mode.
209 * Must not be larger than \c acc_available. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000210 } acc_share;
211};
212
213/*
214 * API organization:
215 * A reader object is usually prepared and maintained
216 * by some lower layer and passed for usage to an upper
217 * layer, and the API naturally splits according to which
218 * layer is supposed to use the respective functions.
219 */
220
221/*
222 * Maintenance API (Lower layer)
223 */
224
225/**
226 * \brief Initialize a reader object
227 *
228 * \param reader The reader to be initialized.
229 * \param acc The buffer to be used as a temporary accumulator
Hanno Beckerfea81b32021-02-22 15:18:11 +0000230 * in case get requests through mbedtls_mps_reader_get()
Hanno Becker88993962021-01-28 09:45:47 +0000231 * exceed the buffer provided by mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000232 * This buffer is owned by the caller and exclusive use
Hanno Beckerfea81b32021-02-22 15:18:11 +0000233 * for reading and writing is given to the reader for the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000234 * duration of the reader's lifetime. It is thus the caller's
235 * responsibility to maintain (and not touch) the buffer for
236 * the lifetime of the reader, and to properly zeroize and
237 * free the memory after the reader has been destroyed.
238 * \param acc_len The size in Bytes of \p acc.
239 *
240 * \return \c 0 on success.
241 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
242 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100243int mbedtls_mps_reader_init(mbedtls_mps_reader *reader,
244 unsigned char *acc,
245 mbedtls_mps_size_t acc_len);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000246
247/**
248 * \brief Free a reader object
249 *
250 * \param reader The reader to be freed.
251 *
252 * \return \c 0 on success.
253 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
254 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100255int mbedtls_mps_reader_free(mbedtls_mps_reader *reader);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000256
257/**
258 * \brief Pass chunk of data for the reader to manage.
259 *
260 * \param reader The reader context to use. The reader must be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000261 * in producing mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000262 * \param buf The buffer to be managed by the reader.
263 * \param buflen The size in Bytes of \p buffer.
264 *
265 * \return \c 0 on success. In this case, the reader will be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000266 * moved to consuming mode and obtains read access
267 * of \p buf until mbedtls_mps_reader_reclaim()
268 * is called. It is the responsibility of the caller
269 * to ensure that the \p buf persists and is not changed
270 * between successful calls to mbedtls_mps_reader_feed()
271 * and mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000272 * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
Hanno Becker88993962021-01-28 09:45:47 +0000273 * required to fulfill a previous request to mbedtls_mps_reader_get().
Hanno Beckerfea81b32021-02-22 15:18:11 +0000274 * In this case, the reader remains in producing mode and
Hanno Becker1c0cd102021-01-12 07:01:23 +0000275 * takes no ownership of the provided buffer (an internal copy
276 * is made instead).
277 * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
278 * different kinds of failures.
279 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100280int mbedtls_mps_reader_feed(mbedtls_mps_reader *reader,
281 unsigned char *buf,
282 mbedtls_mps_size_t buflen);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000283
284/**
285 * \brief Reclaim reader's access to the current input buffer.
286 *
287 * \param reader The reader context to use. The reader must be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000288 * in consuming mode.
Hanno Becker49cc1312021-02-08 08:17:32 +0000289 * \param paused If not \c NULL, the integer at address \p paused will be
Hanno Becker1c0cd102021-01-12 07:01:23 +0000290 * modified to indicate whether the reader has been paused
291 * (value \c 1) or not (value \c 0). Pausing happens if there
292 * is uncommitted data and a previous request to
Hanno Becker88993962021-01-28 09:45:47 +0000293 * mbedtls_mps_reader_get() has exceeded the bounds of the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000294 * input buffer.
295 *
296 * \return \c 0 on success.
297 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
298 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100299int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *reader,
300 int *paused);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000301
302/*
303 * Usage API (Upper layer)
304 */
305
306/**
307 * \brief Request data from the reader.
308 *
309 * \param reader The reader context to use. The reader must
Hanno Beckerfea81b32021-02-22 15:18:11 +0000310 * be in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000311 * \param desired The desired amount of data to be read, in Bytes.
312 * \param buffer The address to store the buffer pointer in.
313 * This must not be \c NULL.
314 * \param buflen The address to store the actual buffer
315 * length in, or \c NULL.
316 *
317 * \return \c 0 on success. In this case, \c *buf holds the
318 * address of a buffer of size \c *buflen
319 * (if \c buflen != \c NULL) or \c desired
Hanno Beckerfea81b32021-02-22 15:18:11 +0000320 * (if \c buflen == \c NULL). The user has read access
321 * to the buffer and guarantee of stability of the data
322 * until the next call to mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000323 * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
Hanno Beckerfea81b32021-02-22 15:18:11 +0000324 * data available to serve the get request. In this case, the
325 * reader remains intact and in consuming mode, and the consumer
326 * should retry the call after a successful cycle of
327 * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
328 * If, after such a cycle, the consumer requests a different
329 * amount of data, the result is implementation-defined;
330 * progress is guaranteed only if the same amount of data
331 * is requested after a mbedtls_mps_reader_reclaim() and
332 * mbedtls_mps_reader_feed() cycle.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000333 * \return Another negative \c MBEDTLS_ERR_READER_XXX error
334 * code for different kinds of failure.
335 *
336 * \note Passing \c NULL as \p buflen is a convenient way to
337 * indicate that fragmentation is not tolerated.
338 * It's functionally equivalent to passing a valid
339 * address as buflen and checking \c *buflen == \c desired
340 * afterwards.
341 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100342int mbedtls_mps_reader_get(mbedtls_mps_reader *reader,
343 mbedtls_mps_size_t desired,
344 unsigned char **buffer,
345 mbedtls_mps_size_t *buflen);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000346
347/**
Hanno Beckerfea81b32021-02-22 15:18:11 +0000348 * \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000349 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000350 * This call indicates that all data received from prior calls to
Hanno Beckerfea81b32021-02-22 15:18:11 +0000351 * mbedtls_mps_reader_get() has been or will have been
Hanno Becker4f84e202021-02-08 06:54:30 +0000352 * processed when mbedtls_mps_reader_reclaim() is called,
353 * and thus need not be backed up.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000354 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000355 * This function has no user observable effect until
356 * mbedtls_mps_reader_reclaim() is called. In particular,
Hanno Beckerfea81b32021-02-22 15:18:11 +0000357 * buffers received from mbedtls_mps_reader_get() remain
Hanno Becker4f84e202021-02-08 06:54:30 +0000358 * valid until mbedtls_mps_reader_reclaim() is called.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000359 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000360 * \param reader The reader context to use.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000361 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000362 * \return \c 0 on success.
363 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000364 *
365 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100366int mbedtls_mps_reader_commit(mbedtls_mps_reader *reader);
Hanno Becker1c0cd102021-01-12 07:01:23 +0000367
368#endif /* MBEDTLS_READER_H */