blob: 9e501b045d88a58790e282ea57a946f04b5a74ca [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
48 * requests can't be fulfilled -- the producer revokes the reader's
49 * 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
149 * to the first byte in the accumulator.
150 * This is only used when the reader is in
Hanno Becker4f84e202021-02-08 06:54:30 +0000151 * consuming mode, i.e. \c frag != \c NULL;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000152 * otherwise, its value is \c 0. */
153 mbedtls_mps_stored_size_t end;
154 /*!< The offset of the end of the last chunk
155 * passed to the user through a call to
Hanno Becker88993962021-01-28 09:45:47 +0000156 * mbedtls_mps_reader_get(), relative to the first
Hanno Becker1c0cd102021-01-12 07:01:23 +0000157 * byte in the accumulator.
158 * This is only used when the reader is in
159 * consuming mode, i.e. \c frag != \c NULL;
160 * otherwise, its value is \c 0. */
161 mbedtls_mps_stored_size_t pending;
162 /*!< The amount of incoming data missing on the
Hanno Becker88993962021-01-28 09:45:47 +0000163 * last call to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000164 * In particular, it is \c 0 if the last call
165 * was successful.
166 * If a reader is reclaimed after an
Hanno Becker88993962021-01-28 09:45:47 +0000167 * unsuccessful call to mbedtls_mps_reader_get(),
Hanno Becker1c0cd102021-01-12 07:01:23 +0000168 * this variable is used to have the reader
169 * remember how much data should be accumulated
170 * before the reader can be passed back to
171 * the user again.
172 * This is only used when the reader is in
173 * consuming mode, i.e. \c frag != \c NULL;
174 * otherwise, its value is \c 0. */
175
176 /* The accumulator is only needed if we need to be able to pause
177 * the reader. A few bytes could be saved by moving this to a
178 * separate struct and using a pointer here. */
179
180 unsigned char *acc; /*!< The accumulator is used to gather incoming
Hanno Becker88993962021-01-28 09:45:47 +0000181 * data if a read-request via mbedtls_mps_reader_get()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000182 * cannot be served from the current fragment. */
183 mbedtls_mps_stored_size_t acc_len;
184 /*!< The total size of the accumulator. */
Hanno Beckerb1855432021-02-08 08:07:35 +0000185 mbedtls_mps_stored_size_t acc_available;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000186 /*!< The number of bytes currently gathered in
187 * the accumulator. This is both used in
188 * producing and in consuming mode:
189 * While producing, it is increased until
190 * it reaches the value of \c acc_remaining below.
191 * While consuming, it is used to judge if a
192 * read request can be served from the
193 * accumulator or not.
194 * Must not be larger than acc_len. */
195 union
196 {
197 mbedtls_mps_stored_size_t acc_remaining;
198 /*!< 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. */
202 mbedtls_mps_stored_size_t frag_offset;
203 /*!< This indicates the offset of the current
204 * fragment from the beginning of the
205 * accumulator.
206 * It is only used in consuming mode.
Hanno Beckerb1855432021-02-08 08:07:35 +0000207 * 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 Becker88993962021-01-28 09:45:47 +0000228 * in case read requests through mbedtls_mps_reader_get()
229 * 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
231 * for reading and writing is given to the reade for the
232 * 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 */
Hanno Becker88993962021-01-28 09:45:47 +0000241int 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 */
Hanno Becker88993962021-01-28 09:45:47 +0000253int 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
259 * in producing state.
260 * \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
264 * moved to consuming state, and ownership of \p buf
Hanno Becker88993962021-01-28 09:45:47 +0000265 * will be passed to the reader until mbedtls_mps_reader_reclaim()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000266 * is called.
Hanno Becker984fbde2021-01-28 09:02:18 +0000267 * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
Hanno Becker88993962021-01-28 09:45:47 +0000268 * required to fulfill a previous request to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000269 * In this case, the reader remains in producing state and
270 * takes no ownership of the provided buffer (an internal copy
271 * is made instead).
272 * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
273 * different kinds of failures.
274 */
Hanno Becker88993962021-01-28 09:45:47 +0000275int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
276 unsigned char *buf,
277 mbedtls_mps_size_t buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000278
279/**
280 * \brief Reclaim reader's access to the current input buffer.
281 *
282 * \param reader The reader context to use. The reader must be
283 * in producing state.
284 * \param paused If not \c NULL, the intger at address \p paused will be
285 * modified to indicate whether the reader has been paused
286 * (value \c 1) or not (value \c 0). Pausing happens if there
287 * is uncommitted data and a previous request to
Hanno Becker88993962021-01-28 09:45:47 +0000288 * mbedtls_mps_reader_get() has exceeded the bounds of the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000289 * input buffer.
290 *
291 * \return \c 0 on success.
292 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
293 */
Hanno Becker88993962021-01-28 09:45:47 +0000294int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
295 mbedtls_mps_size_t *paused );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000296
297/*
298 * Usage API (Upper layer)
299 */
300
301/**
302 * \brief Request data from the reader.
303 *
304 * \param reader The reader context to use. The reader must
305 * in consuming state.
306 * \param desired The desired amount of data to be read, in Bytes.
307 * \param buffer The address to store the buffer pointer in.
308 * This must not be \c NULL.
309 * \param buflen The address to store the actual buffer
310 * length in, or \c NULL.
311 *
312 * \return \c 0 on success. In this case, \c *buf holds the
313 * address of a buffer of size \c *buflen
314 * (if \c buflen != \c NULL) or \c desired
315 * (if \c buflen == \c NULL). The user hass ownership
Hanno Becker4f84e202021-02-08 06:54:30 +0000316 * of the buffer until the next call mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000317 * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
Hanno Becker1c0cd102021-01-12 07:01:23 +0000318 * data available to serve the read request. In this case,
319 * the reader remains intact, and additional data can be
320 * provided by reclaiming the current input buffer via
Hanno Becker88993962021-01-28 09:45:47 +0000321 * mbedtls_mps_reader_reclaim() and feeding a new one via
322 * mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000323 * \return Another negative \c MBEDTLS_ERR_READER_XXX error
324 * code for different kinds of failure.
325 *
326 * \note Passing \c NULL as \p buflen is a convenient way to
327 * indicate that fragmentation is not tolerated.
328 * It's functionally equivalent to passing a valid
329 * address as buflen and checking \c *buflen == \c desired
330 * afterwards.
331 */
Hanno Becker88993962021-01-28 09:45:47 +0000332int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
333 mbedtls_mps_size_t desired,
334 unsigned char **buffer,
335 mbedtls_mps_size_t *buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000336
337/**
Hanno Becker4f84e202021-02-08 06:54:30 +0000338 * \brief Mark data obtained from mbedtls_writer_get() as processed.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000339 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000340 * This call indicates that all data received from prior calls to
341 * mbedtls_mps_reader_fetch() has been or will have been
342 * processed when mbedtls_mps_reader_reclaim() is called,
343 * and thus need not be backed up.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000344 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000345 * This function has no user observable effect until
346 * mbedtls_mps_reader_reclaim() is called. In particular,
347 * buffers received from mbedtls_mps_reader_fetch() remain
348 * valid until mbedtls_mps_reader_reclaim() is called.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000349 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000350 * \param reader The reader context to use.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000351 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000352 * \return \c 0 on success.
353 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000354 *
355 */
Hanno Becker88993962021-01-28 09:45:47 +0000356int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000357
358#endif /* MBEDTLS_READER_H */