blob: 271809fd0cdd9a238479577417fc508cbab87885 [file] [log] [blame]
Hanno Becker1c0cd102021-01-12 07:01:23 +00001/*
2 * Copyright The Mbed TLS Contributors
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * This file is part of mbed TLS (https://tls.mbed.org)
18 */
19
20/**
21 * \file reader.h
22 *
23 * \brief This file defines reader objects, which together with their
24 * sibling writer objects form the basis for the communication
25 * between the various layers of the Mbed TLS messaging stack,
26 * as well as the communication between the messaging stack and
27 * the (D)TLS handshake protocol implementation.
28 *
29 * Readers provide a means of transferring incoming data from
30 * a 'producer' providing it in chunks of arbitrary size, to
31 * a 'consumer' which fetches and processes it in chunks of
32 * again arbitrary, and potentially different, size.
33 *
Hanno Becker4f84e202021-02-08 06:54:30 +000034 * Readers can thus be seen as datagram-to-stream converters,
Hanno Becker1c0cd102021-01-12 07:01:23 +000035 * and they abstract away the following two tasks from the user:
36 * 1. The pointer arithmetic of stepping through a producer-
37 * provided chunk in smaller chunks.
38 * 2. The merging of incoming data chunks in case the
39 * consumer requests data in larger chunks than what the
40 * producer provides.
41 *
42 * The basic abstract flow of operation is the following:
43 * - Initially, the reader is in 'producing mode'.
44 * - The producer hands an incoming data buffer to the reader,
45 * moving it from 'producing' to 'consuming' mode.
46 * - The consumer subsequently fetches and processes the buffer
47 * content. Once that's done -- or partially done and a consumer's
Hanno Becker3d0db812021-02-08 08:22:52 +000048 * request can't be fulfilled -- the producer revokes the reader's
Hanno Becker1c0cd102021-01-12 07:01:23 +000049 * access to the incoming data buffer, putting the reader back to
50 * producing mode.
51 * - The producer subsequently gathers more incoming data and hands
52 * it to reader until the latter switches back to consuming mode
53 * if enough data is available for the last consumer request to
54 * be satisfiable.
55 * - Repeat the above.
56 *
Hanno Becker4f84e202021-02-08 06:54:30 +000057 * The abstract states of the reader from the producer's and
58 * consumer's perspective are as follows:
Hanno Becker1c0cd102021-01-12 07:01:23 +000059 *
Hanno Becker4f84e202021-02-08 06:54:30 +000060 * - From the perspective of the consumer, the state of the
61 * reader consists of the following:
62 * - A byte stream representing (concatenation of) the data
63 * received through calls to mbedtls_mps_reader_get(),
64 * - A marker within that byte stream indicating which data
65 * need not be retained when the reader is passed back to
66 * the producer via mbedtls_mps_reader_reclaim().
67 * The marker can be set via mbedtls_mps_reader_commit()
68 * which places it at the end of the current byte stream.
69 * The consumer need not be aware of the distinction between consumer
70 * and producer mode, because he only interfaces with the reader
71 * when the latter is in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +000072 *
Hanno Becker4f84e202021-02-08 06:54:30 +000073 * - From the perspective of the producer, the reader's state is one of:
74 * - Attached: The reader is in consuming mode.
75 * - Unset: No incoming data buffer is currently managed by the reader,
76 * and all previously handed incoming data buffers have been
77 * fully processed. More data needs to be fed into the reader
78 * via mbedtls_mps_reader_feed().
79 *
80 * - Accumulating: No incoming data buffer is currently managed by the
81 * reader, but some data from the previous incoming data
82 * buffer hasn't been processed yet and is internally
83 * held back.
84 * The Attached state belongs to consuming mode, while the Unset and
85 * Accumulating states belong to producing mode.
86 *
87 * Transitioning from the Unset or Accumulating state to Attached is
88 * done via successful calls to mbedtls_mps_reader_feed(), while
89 * transitioning from Consuming to either Unset or Accumulating (depending
Hanno Becker88993962021-01-28 09:45:47 +000090 * on what has been processed) is done via mbedtls_mps_reader_reclaim().
Hanno Becker1c0cd102021-01-12 07:01:23 +000091 *
92 * The following diagram depicts the producer-state progression:
93 *
94 * +------------------+ reclaim
95 * | Unset +<-------------------------------------+ get
96 * +--------|---------+ | +------+
97 * | | | |
98 * | | | |
99 * | feed +---------+---+--+ |
Hanno Becker4f84e202021-02-08 06:54:30 +0000100 * +--------------------------------------> <---+
101 * | Attached |
102 * +--------------------------------------> <---+
Hanno Becker1c0cd102021-01-12 07:01:23 +0000103 * | feed, enough data available +---------+---+--+ |
104 * | to serve previous consumer request | | |
105 * | | | |
106 * +--------+---------+ | +------+
107 * +----> Accumulating |<-------------------------------------+ commit
108 * | +---+--------------+ reclaim, previous read request
109 * | | couldn't be fulfilled
110 * | |
111 * +--------+
112 * feed, need more data to serve
113 * previous consumer request
Hanno Becker4f84e202021-02-08 06:54:30 +0000114 * |
115 * |
116 * producing mode | consuming mode
117 * |
Hanno Becker1c0cd102021-01-12 07:01:23 +0000118 *
119 */
120
121#ifndef MBEDTLS_READER_H
122#define MBEDTLS_READER_H
123
124#include <stdio.h>
125
Hanno Beckerc518c3b2021-01-28 07:08:08 +0000126#include "mps_common.h"
127#include "mps_error.h"
Hanno Becker1c0cd102021-01-12 07:01:23 +0000128
Hanno Becker88993962021-01-28 09:45:47 +0000129struct mbedtls_mps_reader;
130typedef struct mbedtls_mps_reader mbedtls_mps_reader;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000131
132/*
133 * Structure definitions
134 */
135
Hanno Becker88993962021-01-28 09:45:47 +0000136struct mbedtls_mps_reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000137{
138 unsigned char *frag; /*!< The fragment of incoming data managed by
139 * the reader; it is provided to the reader
Hanno Becker88993962021-01-28 09:45:47 +0000140 * through mbedtls_mps_reader_feed(). The reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000141 * does not own the fragment and does not
142 * perform any allocation operations on it,
143 * but does have read and write access to it. */
144 mbedtls_mps_stored_size_t frag_len;
145 /*!< The length of the current fragment.
146 * Must be 0 if \c frag == \c NULL. */
147 mbedtls_mps_stored_size_t commit;
148 /*!< The offset of the last commit, relative
Hanno Becker8fc107c2021-02-08 08:19:16 +0000149 * to the first byte in the fragment or, if
150 * present, the accumulator.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000151 * This is only used when the reader is in
Hanno Becker4f84e202021-02-08 06:54:30 +0000152 * consuming mode, i.e. \c frag != \c NULL;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000153 * otherwise, its value is \c 0. */
154 mbedtls_mps_stored_size_t end;
155 /*!< The offset of the end of the last chunk
156 * passed to the user through a call to
Hanno Becker88993962021-01-28 09:45:47 +0000157 * mbedtls_mps_reader_get(), relative to the first
Hanno Becker1c0cd102021-01-12 07:01:23 +0000158 * byte in the accumulator.
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. */
162 mbedtls_mps_stored_size_t pending;
163 /*!< The amount of incoming data missing on the
Hanno Becker88993962021-01-28 09:45:47 +0000164 * last call to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000165 * In particular, it is \c 0 if the last call
166 * was successful.
167 * If a reader is reclaimed after an
Hanno Becker88993962021-01-28 09:45:47 +0000168 * unsuccessful call to mbedtls_mps_reader_get(),
Hanno Becker1c0cd102021-01-12 07:01:23 +0000169 * this variable is used to have the reader
170 * remember how much data should be accumulated
Hanno Beckera408c172021-02-08 08:17:39 +0000171 * so that the call to mbedtls_mps_reader_get()
172 * succeeds next time.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000173 * 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. */
176
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;
185 /*!< The total size of the accumulator. */
Hanno Beckerb1855432021-02-08 08:07:35 +0000186 mbedtls_mps_stored_size_t acc_available;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000187 /*!< 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 * read request can be served from the
194 * accumulator or not.
195 * Must not be larger than acc_len. */
196 union
197 {
198 mbedtls_mps_stored_size_t acc_remaining;
199 /*!< This indicates the amount of data still
200 * to be gathered in the accumulator. It is
201 * only used in producing mode.
202 * Must be at most acc_len - acc_available. */
203 mbedtls_mps_stored_size_t frag_offset;
204 /*!< This indicates the offset of the current
205 * fragment from the beginning of the
206 * accumulator.
207 * It is only used in consuming mode.
Hanno Beckerb1855432021-02-08 08:07:35 +0000208 * Must not be larger than \c acc_available. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000209 } acc_share;
210};
211
212/*
213 * API organization:
214 * A reader object is usually prepared and maintained
215 * by some lower layer and passed for usage to an upper
216 * layer, and the API naturally splits according to which
217 * layer is supposed to use the respective functions.
218 */
219
220/*
221 * Maintenance API (Lower layer)
222 */
223
224/**
225 * \brief Initialize a reader object
226 *
227 * \param reader The reader to be initialized.
228 * \param acc The buffer to be used as a temporary accumulator
Hanno Becker88993962021-01-28 09:45:47 +0000229 * in case read requests through mbedtls_mps_reader_get()
230 * exceed the buffer provided by mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000231 * This buffer is owned by the caller and exclusive use
232 * for reading and writing is given to the reade for the
233 * duration of the reader's lifetime. It is thus the caller's
234 * responsibility to maintain (and not touch) the buffer for
235 * the lifetime of the reader, and to properly zeroize and
236 * free the memory after the reader has been destroyed.
237 * \param acc_len The size in Bytes of \p acc.
238 *
239 * \return \c 0 on success.
240 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
241 */
Hanno Becker88993962021-01-28 09:45:47 +0000242int mbedtls_mps_reader_init( mbedtls_mps_reader *reader,
243 unsigned char *acc,
244 mbedtls_mps_size_t acc_len );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000245
246/**
247 * \brief Free a reader object
248 *
249 * \param reader The reader to be freed.
250 *
251 * \return \c 0 on success.
252 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
253 */
Hanno Becker88993962021-01-28 09:45:47 +0000254int mbedtls_mps_reader_free( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000255
256/**
257 * \brief Pass chunk of data for the reader to manage.
258 *
259 * \param reader The reader context to use. The reader must be
260 * in producing state.
261 * \param buf The buffer to be managed by the reader.
262 * \param buflen The size in Bytes of \p buffer.
263 *
264 * \return \c 0 on success. In this case, the reader will be
265 * moved to consuming state, and ownership of \p buf
Hanno Becker88993962021-01-28 09:45:47 +0000266 * will be passed to the reader until mbedtls_mps_reader_reclaim()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000267 * is called.
Hanno Becker984fbde2021-01-28 09:02:18 +0000268 * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
Hanno Becker88993962021-01-28 09:45:47 +0000269 * required to fulfill a previous request to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000270 * In this case, the reader remains in producing state and
271 * takes no ownership of the provided buffer (an internal copy
272 * is made instead).
273 * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
274 * different kinds of failures.
275 */
Hanno Becker88993962021-01-28 09:45:47 +0000276int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
277 unsigned char *buf,
278 mbedtls_mps_size_t buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000279
280/**
281 * \brief Reclaim reader's access to the current input buffer.
282 *
283 * \param reader The reader context to use. The reader must be
284 * in producing state.
Hanno Becker49cc1312021-02-08 08:17:32 +0000285 * \param paused If not \c NULL, the integer at address \p paused will be
Hanno Becker1c0cd102021-01-12 07:01:23 +0000286 * modified to indicate whether the reader has been paused
287 * (value \c 1) or not (value \c 0). Pausing happens if there
288 * is uncommitted data and a previous request to
Hanno Becker88993962021-01-28 09:45:47 +0000289 * mbedtls_mps_reader_get() has exceeded the bounds of the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000290 * input buffer.
291 *
292 * \return \c 0 on success.
293 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
294 */
Hanno Becker88993962021-01-28 09:45:47 +0000295int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
296 mbedtls_mps_size_t *paused );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000297
298/*
299 * Usage API (Upper layer)
300 */
301
302/**
303 * \brief Request data from the reader.
304 *
305 * \param reader The reader context to use. The reader must
306 * in consuming state.
307 * \param desired The desired amount of data to be read, in Bytes.
308 * \param buffer The address to store the buffer pointer in.
309 * This must not be \c NULL.
310 * \param buflen The address to store the actual buffer
311 * length in, or \c NULL.
312 *
313 * \return \c 0 on success. In this case, \c *buf holds the
314 * address of a buffer of size \c *buflen
315 * (if \c buflen != \c NULL) or \c desired
316 * (if \c buflen == \c NULL). The user hass ownership
Hanno Becker4f84e202021-02-08 06:54:30 +0000317 * of the buffer until the next call mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000318 * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
Hanno Becker1c0cd102021-01-12 07:01:23 +0000319 * data available to serve the read request. In this case,
320 * the reader remains intact, and additional data can be
321 * provided by reclaiming the current input buffer via
Hanno Becker88993962021-01-28 09:45:47 +0000322 * mbedtls_mps_reader_reclaim() and feeding a new one via
323 * mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000324 * \return Another negative \c MBEDTLS_ERR_READER_XXX error
325 * code for different kinds of failure.
326 *
327 * \note Passing \c NULL as \p buflen is a convenient way to
328 * indicate that fragmentation is not tolerated.
329 * It's functionally equivalent to passing a valid
330 * address as buflen and checking \c *buflen == \c desired
331 * afterwards.
332 */
Hanno Becker88993962021-01-28 09:45:47 +0000333int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
334 mbedtls_mps_size_t desired,
335 unsigned char **buffer,
336 mbedtls_mps_size_t *buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000337
338/**
Hanno Becker4f84e202021-02-08 06:54:30 +0000339 * \brief Mark data obtained from mbedtls_writer_get() as processed.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000340 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000341 * This call indicates that all data received from prior calls to
342 * mbedtls_mps_reader_fetch() has been or will have been
343 * processed when mbedtls_mps_reader_reclaim() is called,
344 * and thus need not be backed up.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000345 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000346 * This function has no user observable effect until
347 * mbedtls_mps_reader_reclaim() is called. In particular,
348 * buffers received from mbedtls_mps_reader_fetch() remain
349 * valid until mbedtls_mps_reader_reclaim() is called.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000350 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000351 * \param reader The reader context to use.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000352 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000353 * \return \c 0 on success.
354 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000355 *
356 */
Hanno Becker88993962021-01-28 09:45:47 +0000357int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000358
359#endif /* MBEDTLS_READER_H */