blob: 5648ede839103324aeb2d43391420cc16a022ec1 [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 *
34 * Readers can be seen as datagram-to-stream converters,
35 * 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 *
57 * From the perspective of the consumer, the state of the
58 * reader is a potentially empty list of input buffers that
59 * the reader has provided to the consumer.
Hanno Becker88993962021-01-28 09:45:47 +000060 * New buffers can be requested through calls to mbedtls_mps_reader_get(),
Hanno Becker1c0cd102021-01-12 07:01:23 +000061 * while previously obtained input buffers can be marked processed
Hanno Becker88993962021-01-28 09:45:47 +000062 * through calls to mbedtls_mps_reader_consume(), emptying the list of
Hanno Becker1c0cd102021-01-12 07:01:23 +000063 * input buffers and invalidating them from the consumer's perspective.
64 * The consumer need not be aware of the distinction between consumer
65 * and producer mode, because he only interfaces with the reader
66 * when the latter is in consuming mode.
67 *
68 * From the perspective of the producer, the state of the reader
69 * is one of the following:
70 * - Attached: An incoming data buffer is currently
71 * being managed by the reader, and
72 * - Unset: No incoming data buffer is currently
73 * managed by the reader, and all previously
74 * handed incoming data buffers have been
75 * fully processed.
76 * - Accumulating: No incoming data buffer is currently
77 * managed by the reader, but some data
78 * from the previous incoming data buffer
79 * hasn't been processed yet and is internally
80 * held back.
81 * The Unset and Accumulating states belong to producing mode,
82 * while the Attached state belongs to consuming mode.
83 *
84 * Transitioning from Unset or Accumulating to Attached is
Hanno Becker88993962021-01-28 09:45:47 +000085 * done via calls to mbedtls_mps_reader_feed(), while transitioning
Hanno Becker1c0cd102021-01-12 07:01:23 +000086 * from Consuming to either Unset or Accumulating (depending
Hanno Becker88993962021-01-28 09:45:47 +000087 * on what has been processed) is done via mbedtls_mps_reader_reclaim().
Hanno Becker1c0cd102021-01-12 07:01:23 +000088 *
89 * The following diagram depicts the producer-state progression:
90 *
91 * +------------------+ reclaim
92 * | Unset +<-------------------------------------+ get
93 * +--------|---------+ | +------+
94 * | | | |
95 * | | | |
96 * | feed +---------+---+--+ |
97 * +--------------------------------------> Attached <---+
98 * | / |
99 * +--------------------------------------> Consuming <---+
100 * | feed, enough data available +---------+---+--+ |
101 * | to serve previous consumer request | | |
102 * | | | |
103 * +--------+---------+ | +------+
104 * +----> Accumulating |<-------------------------------------+ commit
105 * | +---+--------------+ reclaim, previous read request
106 * | | couldn't be fulfilled
107 * | |
108 * +--------+
109 * feed, need more data to serve
110 * previous consumer request
111 *
112 */
113
114#ifndef MBEDTLS_READER_H
115#define MBEDTLS_READER_H
116
117#include <stdio.h>
118
Hanno Beckerc518c3b2021-01-28 07:08:08 +0000119#include "mps_common.h"
120#include "mps_error.h"
Hanno Becker1c0cd102021-01-12 07:01:23 +0000121
Hanno Becker88993962021-01-28 09:45:47 +0000122struct mbedtls_mps_reader;
123typedef struct mbedtls_mps_reader mbedtls_mps_reader;
Hanno Becker1c0cd102021-01-12 07:01:23 +0000124
125/*
126 * Structure definitions
127 */
128
Hanno Becker88993962021-01-28 09:45:47 +0000129struct mbedtls_mps_reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000130{
131 unsigned char *frag; /*!< The fragment of incoming data managed by
132 * the reader; it is provided to the reader
Hanno Becker88993962021-01-28 09:45:47 +0000133 * through mbedtls_mps_reader_feed(). The reader
Hanno Becker1c0cd102021-01-12 07:01:23 +0000134 * does not own the fragment and does not
135 * perform any allocation operations on it,
136 * but does have read and write access to it. */
137 mbedtls_mps_stored_size_t frag_len;
138 /*!< The length of the current fragment.
139 * Must be 0 if \c frag == \c NULL. */
140 mbedtls_mps_stored_size_t commit;
141 /*!< The offset of the last commit, relative
142 * to the first byte in the accumulator.
143 * This is only used when the reader is in
144 * consuming mode, i.e. frag != NULL;
145 * otherwise, its value is \c 0. */
146 mbedtls_mps_stored_size_t end;
147 /*!< The offset of the end of the last chunk
148 * passed to the user through a call to
Hanno Becker88993962021-01-28 09:45:47 +0000149 * mbedtls_mps_reader_get(), relative to the first
Hanno Becker1c0cd102021-01-12 07:01:23 +0000150 * byte in the accumulator.
151 * This is only used when the reader is in
152 * consuming mode, i.e. \c frag != \c NULL;
153 * otherwise, its value is \c 0. */
154 mbedtls_mps_stored_size_t pending;
155 /*!< The amount of incoming data missing on the
Hanno Becker88993962021-01-28 09:45:47 +0000156 * last call to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000157 * In particular, it is \c 0 if the last call
158 * was successful.
159 * If a reader is reclaimed after an
Hanno Becker88993962021-01-28 09:45:47 +0000160 * unsuccessful call to mbedtls_mps_reader_get(),
Hanno Becker1c0cd102021-01-12 07:01:23 +0000161 * this variable is used to have the reader
162 * remember how much data should be accumulated
163 * before the reader can be passed back to
164 * the user again.
165 * This is only used when the reader is in
166 * consuming mode, i.e. \c frag != \c NULL;
167 * otherwise, its value is \c 0. */
168
169 /* The accumulator is only needed if we need to be able to pause
170 * the reader. A few bytes could be saved by moving this to a
171 * separate struct and using a pointer here. */
172
173 unsigned char *acc; /*!< The accumulator is used to gather incoming
Hanno Becker88993962021-01-28 09:45:47 +0000174 * data if a read-request via mbedtls_mps_reader_get()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000175 * cannot be served from the current fragment. */
176 mbedtls_mps_stored_size_t acc_len;
177 /*!< The total size of the accumulator. */
178 mbedtls_mps_stored_size_t acc_avail;
179 /*!< The number of bytes currently gathered in
180 * the accumulator. This is both used in
181 * producing and in consuming mode:
182 * While producing, it is increased until
183 * it reaches the value of \c acc_remaining below.
184 * While consuming, it is used to judge if a
185 * read request can be served from the
186 * accumulator or not.
187 * Must not be larger than acc_len. */
188 union
189 {
190 mbedtls_mps_stored_size_t acc_remaining;
191 /*!< This indicates the amount of data still
192 * to be gathered in the accumulator. It is
193 * only used in producing mode.
194 * Must be at most acc_len - acc_available. */
195 mbedtls_mps_stored_size_t frag_offset;
196 /*!< This indicates the offset of the current
197 * fragment from the beginning of the
198 * accumulator.
199 * It is only used in consuming mode.
200 * Must not be larger than \c acc_avail. */
201 } acc_share;
202};
203
204/*
205 * API organization:
206 * A reader object is usually prepared and maintained
207 * by some lower layer and passed for usage to an upper
208 * layer, and the API naturally splits according to which
209 * layer is supposed to use the respective functions.
210 */
211
212/*
213 * Maintenance API (Lower layer)
214 */
215
216/**
217 * \brief Initialize a reader object
218 *
219 * \param reader The reader to be initialized.
220 * \param acc The buffer to be used as a temporary accumulator
Hanno Becker88993962021-01-28 09:45:47 +0000221 * in case read requests through mbedtls_mps_reader_get()
222 * exceed the buffer provided by mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000223 * This buffer is owned by the caller and exclusive use
224 * for reading and writing is given to the reade for the
225 * duration of the reader's lifetime. It is thus the caller's
226 * responsibility to maintain (and not touch) the buffer for
227 * the lifetime of the reader, and to properly zeroize and
228 * free the memory after the reader has been destroyed.
229 * \param acc_len The size in Bytes of \p acc.
230 *
231 * \return \c 0 on success.
232 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
233 */
Hanno Becker88993962021-01-28 09:45:47 +0000234int mbedtls_mps_reader_init( mbedtls_mps_reader *reader,
235 unsigned char *acc,
236 mbedtls_mps_size_t acc_len );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000237
238/**
239 * \brief Free a reader object
240 *
241 * \param reader The reader to be freed.
242 *
243 * \return \c 0 on success.
244 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
245 */
Hanno Becker88993962021-01-28 09:45:47 +0000246int mbedtls_mps_reader_free( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000247
248/**
249 * \brief Pass chunk of data for the reader to manage.
250 *
251 * \param reader The reader context to use. The reader must be
252 * in producing state.
253 * \param buf The buffer to be managed by the reader.
254 * \param buflen The size in Bytes of \p buffer.
255 *
256 * \return \c 0 on success. In this case, the reader will be
257 * moved to consuming state, and ownership of \p buf
Hanno Becker88993962021-01-28 09:45:47 +0000258 * will be passed to the reader until mbedtls_mps_reader_reclaim()
Hanno Becker1c0cd102021-01-12 07:01:23 +0000259 * is called.
Hanno Becker984fbde2021-01-28 09:02:18 +0000260 * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
Hanno Becker88993962021-01-28 09:45:47 +0000261 * required to fulfill a previous request to mbedtls_mps_reader_get().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000262 * In this case, the reader remains in producing state and
263 * takes no ownership of the provided buffer (an internal copy
264 * is made instead).
265 * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
266 * different kinds of failures.
267 */
Hanno Becker88993962021-01-28 09:45:47 +0000268int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
269 unsigned char *buf,
270 mbedtls_mps_size_t buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000271
272/**
273 * \brief Reclaim reader's access to the current input buffer.
274 *
275 * \param reader The reader context to use. The reader must be
276 * in producing state.
277 * \param paused If not \c NULL, the intger at address \p paused will be
278 * modified to indicate whether the reader has been paused
279 * (value \c 1) or not (value \c 0). Pausing happens if there
280 * is uncommitted data and a previous request to
Hanno Becker88993962021-01-28 09:45:47 +0000281 * mbedtls_mps_reader_get() has exceeded the bounds of the
Hanno Becker1c0cd102021-01-12 07:01:23 +0000282 * input buffer.
283 *
284 * \return \c 0 on success.
285 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
286 */
Hanno Becker88993962021-01-28 09:45:47 +0000287int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
288 mbedtls_mps_size_t *paused );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000289
290/*
291 * Usage API (Upper layer)
292 */
293
294/**
295 * \brief Request data from the reader.
296 *
297 * \param reader The reader context to use. The reader must
298 * in consuming state.
299 * \param desired The desired amount of data to be read, in Bytes.
300 * \param buffer The address to store the buffer pointer in.
301 * This must not be \c NULL.
302 * \param buflen The address to store the actual buffer
303 * length in, or \c NULL.
304 *
305 * \return \c 0 on success. In this case, \c *buf holds the
306 * address of a buffer of size \c *buflen
307 * (if \c buflen != \c NULL) or \c desired
308 * (if \c buflen == \c NULL). The user hass ownership
Hanno Becker88993962021-01-28 09:45:47 +0000309 * of the buffer until the next call to mbedtls_mps_reader_commit().
310 * or mbedtls_mps_reader_reclaim().
Hanno Becker984fbde2021-01-28 09:02:18 +0000311 * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
Hanno Becker1c0cd102021-01-12 07:01:23 +0000312 * data available to serve the read request. In this case,
313 * the reader remains intact, and additional data can be
314 * provided by reclaiming the current input buffer via
Hanno Becker88993962021-01-28 09:45:47 +0000315 * mbedtls_mps_reader_reclaim() and feeding a new one via
316 * mbedtls_mps_reader_feed().
Hanno Becker1c0cd102021-01-12 07:01:23 +0000317 * \return Another negative \c MBEDTLS_ERR_READER_XXX error
318 * code for different kinds of failure.
319 *
320 * \note Passing \c NULL as \p buflen is a convenient way to
321 * indicate that fragmentation is not tolerated.
322 * It's functionally equivalent to passing a valid
323 * address as buflen and checking \c *buflen == \c desired
324 * afterwards.
325 */
Hanno Becker88993962021-01-28 09:45:47 +0000326int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
327 mbedtls_mps_size_t desired,
328 unsigned char **buffer,
329 mbedtls_mps_size_t *buflen );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000330
331/**
332 * \brief Signal that all input buffers previously obtained
333 * from mbedtls_writer_get() are fully processed.
334 *
335 * This function marks the previously fetched data as fully
336 * processed and invalidates their respective buffers.
337 *
338 * \param reader The reader context to use.
339 *
340 * \return \c 0 on success.
341 * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
342 *
343 * \warning Once this function is called, you must not use the
344 * pointers corresponding to the committed data anymore.
345 *
346 */
Hanno Becker88993962021-01-28 09:45:47 +0000347int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
Hanno Becker1c0cd102021-01-12 07:01:23 +0000348
349#endif /* MBEDTLS_READER_H */