blob: 61027d911730aa2a2ad4d3472efafb723afb2c81 [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
Hanno Beckerfea81b32021-02-22 15:18:11 +000052 * it to the reader until it switches back to consuming mode
Hanno Becker1c0cd102021-01-12 07:01:23 +000053 * 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
Hanno Beckerfea81b32021-02-22 15:18:11 +000065 * can be considered processed, and hence need not be retained,
66 * when the reader is passed back to the producer via
67 * mbedtls_mps_reader_reclaim().
68 * The marker is set via mbedtls_mps_reader_commit()
Hanno Becker4f84e202021-02-08 06:54:30 +000069 * which places it at the end of the current byte stream.
70 * The consumer need not be aware of the distinction between consumer
Hanno Beckerfea81b32021-02-22 15:18:11 +000071 * and producer mode, because it only interfaces with the reader
Hanno Becker4f84e202021-02-08 06:54:30 +000072 * when the latter is in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +000073 *
Hanno Becker4f84e202021-02-08 06:54:30 +000074 * - From the perspective of the producer, the reader's state is one of:
75 * - Attached: The reader is in consuming mode.
76 * - Unset: No incoming data buffer is currently managed by the reader,
77 * and all previously handed incoming data buffers have been
78 * fully processed. More data needs to be fed into the reader
79 * via mbedtls_mps_reader_feed().
80 *
81 * - Accumulating: No incoming data buffer is currently managed by the
82 * reader, but some data from the previous incoming data
83 * buffer hasn't been processed yet and is internally
84 * held back.
85 * The Attached state belongs to consuming mode, while the Unset and
86 * Accumulating states belong to producing mode.
87 *
88 * Transitioning from the Unset or Accumulating state to Attached is
89 * done via successful calls to mbedtls_mps_reader_feed(), while
Hanno Beckerfea81b32021-02-22 15:18:11 +000090 * transitioning from Attached to either Unset or Accumulating (depending
Hanno Becker88993962021-01-28 09:45:47 +000091 * on what has been processed) is done via mbedtls_mps_reader_reclaim().
Hanno Becker1c0cd102021-01-12 07:01:23 +000092 *
93 * The following diagram depicts the producer-state progression:
94 *
95 * +------------------+ reclaim
96 * | Unset +<-------------------------------------+ get
97 * +--------|---------+ | +------+
98 * | | | |
99 * | | | |
100 * | feed +---------+---+--+ |
Hanno Becker4f84e202021-02-08 06:54:30 +0000101 * +--------------------------------------> <---+
102 * | Attached |
103 * +--------------------------------------> <---+
Hanno Becker1c0cd102021-01-12 07:01:23 +0000104 * | feed, enough data available +---------+---+--+ |
105 * | to serve previous consumer request | | |
106 * | | | |
107 * +--------+---------+ | +------+
108 * +----> Accumulating |<-------------------------------------+ commit
109 * | +---+--------------+ reclaim, previous read request
110 * | | couldn't be fulfilled
111 * | |
112 * +--------+
113 * feed, need more data to serve
114 * previous consumer request
Hanno Becker4f84e202021-02-08 06:54:30 +0000115 * |
116 * |
117 * producing mode | consuming mode
118 * |
Hanno Becker1c0cd102021-01-12 07:01:23 +0000119 *
120 */
121
122#ifndef MBEDTLS_READER_H
123#define MBEDTLS_READER_H
124
125#include <stdio.h>
126
Hanno Beckerc518c3b2021-01-28 07:08:08 +0000127#include "mps_common.h"
128#include "mps_error.h"
Hanno Becker1c0cd102021-01-12 07:01:23 +0000129
Hanno Becker88993962021-01-28 09:45:47 +0000130struct mbedtls_mps_reader;
131typedef struct mbedtls_mps_reader mbedtls_mps_reader;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000132
133/*
134 * Structure definitions
135 */
136
Hanno Becker88993962021-01-28 09:45:47 +0000137struct mbedtls_mps_reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000138{
139 unsigned char *frag; /*!< The fragment of incoming data managed by
140 * the reader; it is provided to the reader
Hanno Becker88993962021-01-28 09:45:47 +0000141 * through mbedtls_mps_reader_feed(). The reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000142 * does not own the fragment and does not
143 * perform any allocation operations on it,
Hanno Beckerfea81b32021-02-22 15:18:11 +0000144 * but does have read and write access to it.
145 *
146 * The reader is in consuming mode if
147 * and only if \c frag is not \c NULL. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000148 mbedtls_mps_stored_size_t frag_len;
149 /*!< The length of the current fragment.
150 * Must be 0 if \c frag == \c NULL. */
151 mbedtls_mps_stored_size_t commit;
152 /*!< The offset of the last commit, relative
Hanno Beckerfea81b32021-02-22 15:18:11 +0000153 * to the first byte in the fragment, if
154 * no accumulator is present. If an accumulator
155 * is present, it is viewed as a prefix to the
156 * current fragment, and this variable contains
157 * an offset from the beginning of the accumulator.
158 *
Hanno Becker1c0cd102021-01-12 07:01:23 +0000159 * This is only used when the reader is in
Hanno Becker4f84e202021-02-08 06:54:30 +0000160 * consuming mode, i.e. \c frag != \c NULL;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000161 * otherwise, its value is \c 0. */
162 mbedtls_mps_stored_size_t end;
163 /*!< The offset of the end of the last chunk
164 * passed to the user through a call to
Hanno Becker88993962021-01-28 09:45:47 +0000165 * mbedtls_mps_reader_get(), relative to the first
Hanno Beckerfea81b32021-02-22 15:18:11 +0000166 * byte in the fragment, if no accumulator is
167 * present. If an accumulator is present, it is
168 * viewed as a prefix to the current fragment, and
169 * this variable contains an offset from the
170 * beginning of the accumulator.
171 *
Hanno Becker1c0cd102021-01-12 07:01:23 +0000172 * 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 mbedtls_mps_stored_size_t pending;
176 /*!< The amount of incoming data missing on the
Hanno Becker88993962021-01-28 09:45:47 +0000177 * last call to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000178 * In particular, it is \c 0 if the last call
179 * was successful.
180 * If a reader is reclaimed after an
Hanno Becker88993962021-01-28 09:45:47 +0000181 * unsuccessful call to mbedtls_mps_reader_get(),
Hanno Becker1c0cd102021-01-12 07:01:23 +0000182 * this variable is used to have the reader
183 * remember how much data should be accumulated
Hanno Beckera408c172021-02-08 08:17:39 +0000184 * so that the call to mbedtls_mps_reader_get()
185 * succeeds next time.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000186 * This is only used when the reader is in
187 * consuming mode, i.e. \c frag != \c NULL;
188 * otherwise, its value is \c 0. */
189
190 /* The accumulator is only needed if we need to be able to pause
191 * the reader. A few bytes could be saved by moving this to a
192 * separate struct and using a pointer here. */
193
194 unsigned char *acc; /*!< The accumulator is used to gather incoming
Hanno Becker88993962021-01-28 09:45:47 +0000195 * data if a read-request via mbedtls_mps_reader_get()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000196 * cannot be served from the current fragment. */
197 mbedtls_mps_stored_size_t acc_len;
198 /*!< The total size of the accumulator. */
Hanno Beckerb1855432021-02-08 08:07:35 +0000199 mbedtls_mps_stored_size_t acc_available;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000200 /*!< The number of bytes currently gathered in
201 * the accumulator. This is both used in
202 * producing and in consuming mode:
203 * While producing, it is increased until
204 * it reaches the value of \c acc_remaining below.
205 * While consuming, it is used to judge if a
Hanno Beckerfea81b32021-02-22 15:18:11 +0000206 * get request can be served from the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000207 * accumulator or not.
Hanno Beckerfea81b32021-02-22 15:18:11 +0000208 * Must not be larger than \c acc_len. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000209 union
210 {
211 mbedtls_mps_stored_size_t acc_remaining;
212 /*!< This indicates the amount of data still
213 * to be gathered in the accumulator. It is
214 * only used in producing mode.
215 * Must be at most acc_len - acc_available. */
216 mbedtls_mps_stored_size_t frag_offset;
Hanno Beckerfea81b32021-02-22 15:18:11 +0000217 /*!< If an accumulator is present and in use, this
218 * field indicates the offset of the current
Hanno Becker1c0cd102021-01-12 07:01:23 +0000219 * fragment from the beginning of the
Hanno Beckerfea81b32021-02-22 15:18:11 +0000220 * accumulator. If no accumulator is present
221 * or the accumulator is not in use, this is \c 0.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000222 * It is only used in consuming mode.
Hanno Beckerb1855432021-02-08 08:07:35 +0000223 * Must not be larger than \c acc_available. */
Hanno Becker1c0cd102021-01-12 07:01:23 +0000224 } acc_share;
225};
226
227/*
228 * API organization:
229 * A reader object is usually prepared and maintained
230 * by some lower layer and passed for usage to an upper
231 * layer, and the API naturally splits according to which
232 * layer is supposed to use the respective functions.
233 */
234
235/*
236 * Maintenance API (Lower layer)
237 */
238
239/**
240 * \brief Initialize a reader object
241 *
242 * \param reader The reader to be initialized.
243 * \param acc The buffer to be used as a temporary accumulator
Hanno Beckerfea81b32021-02-22 15:18:11 +0000244 * in case get requests through mbedtls_mps_reader_get()
Hanno Becker88993962021-01-28 09:45:47 +0000245 * exceed the buffer provided by mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000246 * This buffer is owned by the caller and exclusive use
Hanno Beckerfea81b32021-02-22 15:18:11 +0000247 * for reading and writing is given to the reader for the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000248 * duration of the reader's lifetime. It is thus the caller's
249 * responsibility to maintain (and not touch) the buffer for
250 * the lifetime of the reader, and to properly zeroize and
251 * free the memory after the reader has been destroyed.
252 * \param acc_len The size in Bytes of \p acc.
253 *
254 * \return \c 0 on success.
255 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
256 */
Hanno Becker88993962021-01-28 09:45:47 +0000257int mbedtls_mps_reader_init( mbedtls_mps_reader *reader,
258 unsigned char *acc,
259 mbedtls_mps_size_t acc_len );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000260
261/**
262 * \brief Free a reader object
263 *
264 * \param reader The reader to be freed.
265 *
266 * \return \c 0 on success.
267 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
268 */
Hanno Becker88993962021-01-28 09:45:47 +0000269int mbedtls_mps_reader_free( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000270
271/**
272 * \brief Pass chunk of data for the reader to manage.
273 *
274 * \param reader The reader context to use. The reader must be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000275 * in producing mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000276 * \param buf The buffer to be managed by the reader.
277 * \param buflen The size in Bytes of \p buffer.
278 *
279 * \return \c 0 on success. In this case, the reader will be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000280 * moved to consuming mode and obtains read access
281 * of \p buf until mbedtls_mps_reader_reclaim()
282 * is called. It is the responsibility of the caller
283 * to ensure that the \p buf persists and is not changed
284 * between successful calls to mbedtls_mps_reader_feed()
285 * and mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000286 * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
Hanno Becker88993962021-01-28 09:45:47 +0000287 * required to fulfill a previous request to mbedtls_mps_reader_get().
Hanno Beckerfea81b32021-02-22 15:18:11 +0000288 * In this case, the reader remains in producing mode and
Hanno Becker1c0cd102021-01-12 07:01:23 +0000289 * takes no ownership of the provided buffer (an internal copy
290 * is made instead).
291 * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
292 * different kinds of failures.
293 */
Hanno Becker88993962021-01-28 09:45:47 +0000294int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
295 unsigned char *buf,
296 mbedtls_mps_size_t buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000297
298/**
299 * \brief Reclaim reader's access to the current input buffer.
300 *
301 * \param reader The reader context to use. The reader must be
Hanno Beckerfea81b32021-02-22 15:18:11 +0000302 * in consuming mode.
Hanno Becker49cc1312021-02-08 08:17:32 +0000303 * \param paused If not \c NULL, the integer at address \p paused will be
Hanno Becker1c0cd102021-01-12 07:01:23 +0000304 * modified to indicate whether the reader has been paused
305 * (value \c 1) or not (value \c 0). Pausing happens if there
306 * is uncommitted data and a previous request to
Hanno Becker88993962021-01-28 09:45:47 +0000307 * mbedtls_mps_reader_get() has exceeded the bounds of the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000308 * input buffer.
309 *
310 * \return \c 0 on success.
311 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
312 */
Hanno Becker88993962021-01-28 09:45:47 +0000313int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
314 mbedtls_mps_size_t *paused );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000315
316/*
317 * Usage API (Upper layer)
318 */
319
320/**
321 * \brief Request data from the reader.
322 *
323 * \param reader The reader context to use. The reader must
Hanno Beckerfea81b32021-02-22 15:18:11 +0000324 * be in consuming mode.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000325 * \param desired The desired amount of data to be read, in Bytes.
326 * \param buffer The address to store the buffer pointer in.
327 * This must not be \c NULL.
328 * \param buflen The address to store the actual buffer
329 * length in, or \c NULL.
330 *
331 * \return \c 0 on success. In this case, \c *buf holds the
332 * address of a buffer of size \c *buflen
333 * (if \c buflen != \c NULL) or \c desired
Hanno Beckerfea81b32021-02-22 15:18:11 +0000334 * (if \c buflen == \c NULL). The user has read access
335 * to the buffer and guarantee of stability of the data
336 * until the next call to mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000337 * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
Hanno Beckerfea81b32021-02-22 15:18:11 +0000338 * data available to serve the get request. In this case, the
339 * reader remains intact and in consuming mode, and the consumer
340 * should retry the call after a successful cycle of
341 * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
342 * If, after such a cycle, the consumer requests a different
343 * amount of data, the result is implementation-defined;
344 * progress is guaranteed only if the same amount of data
345 * is requested after a mbedtls_mps_reader_reclaim() and
346 * mbedtls_mps_reader_feed() cycle.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000347 * \return Another negative \c MBEDTLS_ERR_READER_XXX error
348 * code for different kinds of failure.
349 *
350 * \note Passing \c NULL as \p buflen is a convenient way to
351 * indicate that fragmentation is not tolerated.
352 * It's functionally equivalent to passing a valid
353 * address as buflen and checking \c *buflen == \c desired
354 * afterwards.
355 */
Hanno Becker88993962021-01-28 09:45:47 +0000356int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
357 mbedtls_mps_size_t desired,
358 unsigned char **buffer,
359 mbedtls_mps_size_t *buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000360
361/**
Hanno Beckerfea81b32021-02-22 15:18:11 +0000362 * \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000363 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000364 * This call indicates that all data received from prior calls to
Hanno Beckerfea81b32021-02-22 15:18:11 +0000365 * mbedtls_mps_reader_get() has been or will have been
Hanno Becker4f84e202021-02-08 06:54:30 +0000366 * processed when mbedtls_mps_reader_reclaim() is called,
367 * and thus need not be backed up.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000368 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000369 * This function has no user observable effect until
370 * mbedtls_mps_reader_reclaim() is called. In particular,
Hanno Beckerfea81b32021-02-22 15:18:11 +0000371 * buffers received from mbedtls_mps_reader_get() remain
Hanno Becker4f84e202021-02-08 06:54:30 +0000372 * valid until mbedtls_mps_reader_reclaim() is called.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000373 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000374 * \param reader The reader context to use.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000375 *
Hanno Becker4f84e202021-02-08 06:54:30 +0000376 * \return \c 0 on success.
377 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
Hanno Becker1c0cd102021-01-12 07:01:23 +0000378 *
379 */
Hanno Becker88993962021-01-28 09:45:47 +0000380int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000381
382#endif /* MBEDTLS_READER_H */