1 /*
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 mps_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 thus 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  *   request 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 the reader until it 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  * The abstract states of the reader from the producer's and
58  * consumer's perspective are as follows:
59  *
60  * - 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  *     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()
69  *     which places it at the end of the current byte stream.
70  *   The consumer need not be aware of the distinction between consumer
71  *   and producer mode, because it only interfaces with the reader
72  *   when the latter is in consuming mode.
73  *
74  * - 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
90  * transitioning from Attached to either Unset or Accumulating (depending
91  * on what has been processed) is done via mbedtls_mps_reader_reclaim().
92  *
93  * The following diagram depicts the producer-state progression:
94  *
95  *        +------------------+             reclaim
96  *        |      Unset       +<-------------------------------------+       get
97  *        +--------|---------+                                      |   +------+
98  *                 |                                                |   |      |
99  *                 |                                                |   |      |
100  *                 |                feed                  +---------+---+--+   |
101  *                 +-------------------------------------->                <---+
102  *                                                        |    Attached    |
103  *                 +-------------------------------------->                <---+
104  *                 |     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
115  *                                         |
116  *                                         |
117  *               producing mode            |           consuming mode
118  *                                         |
119  *
120  */
121 
122 #ifndef MBEDTLS_READER_H
123 #define MBEDTLS_READER_H
124 
125 #include <stdio.h>
126 
127 #include "mps_common.h"
128 #include "mps_error.h"
129 
130 struct mbedtls_mps_reader;
131 typedef struct mbedtls_mps_reader mbedtls_mps_reader;
132 
133 /*
134  * Structure definitions
135  */
136 
137 struct mbedtls_mps_reader
138 {
139     unsigned char *frag;  /*!< The fragment of incoming data managed by
140                            *   the reader; it is provided to the reader
141                            *   through mbedtls_mps_reader_feed(). The reader
142                            *   does not own the fragment and does not
143                            *   perform any allocation operations on it,
144                            *   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.          */
148     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
153                            *   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                            *
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 end;
163                           /*!< The offset of the end of the last chunk
164                            *   passed to the user through a call to
165                            *   mbedtls_mps_reader_get(), relative to the first
166                            *   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                            *
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     mbedtls_mps_stored_size_t pending;
176                           /*!< The amount of incoming data missing on the
177                            *   last call to mbedtls_mps_reader_get().
178                            *   In particular, it is \c 0 if the last call
179                            *   was successful.
180                            *   If a reader is reclaimed after an
181                            *   unsuccessful call to mbedtls_mps_reader_get(),
182                            *   this variable is used to have the reader
183                            *   remember how much data should be accumulated
184                            *   so that the call to mbedtls_mps_reader_get()
185                            *   succeeds next time.
186                            *   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
195                            *   data if a read-request via mbedtls_mps_reader_get()
196                            *   cannot be served from the current fragment.   */
197     mbedtls_mps_stored_size_t acc_len;
198                            /*!< The total size of the accumulator.           */
199     mbedtls_mps_stored_size_t acc_available;
200                           /*!< 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
206                            *   get request can be served from the
207                            *   accumulator or not.
208                            *   Must not be larger than \c acc_len.           */
209     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;
217                               /*!< If an accumulator is present and in use, this
218                                *   field indicates the offset of the current
219                                *   fragment from the beginning of the
220                                *   accumulator. If no accumulator is present
221                                *   or the accumulator is not in use, this is \c 0.
222                                *   It is only used in consuming mode.
223                                *   Must not be larger than \c acc_available. */
224     } 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
244  *                  in case get requests through mbedtls_mps_reader_get()
245  *                  exceed the buffer provided by mbedtls_mps_reader_feed().
246  *                  This buffer is owned by the caller and exclusive use
247  *                  for reading and writing is given to the reader for the
248  *                  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  */
257 int mbedtls_mps_reader_init( mbedtls_mps_reader *reader,
258                              unsigned char *acc,
259                              mbedtls_mps_size_t acc_len );
260 
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  */
269 int mbedtls_mps_reader_free( mbedtls_mps_reader *reader );
270 
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
275  *                  in producing mode.
276  * \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
280  *                  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().
286  * \return          \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
287  *                  required to fulfill a previous request to mbedtls_mps_reader_get().
288  *                  In this case, the reader remains in producing mode and
289  *                  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  */
294 int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
295                              unsigned char *buf,
296                              mbedtls_mps_size_t buflen );
297 
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
302  *                  in consuming mode.
303  * \param paused    If not \c NULL, the integer at address \p paused will be
304  *                  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
307  *                  mbedtls_mps_reader_get() has exceeded the bounds of the
308  *                  input buffer.
309  *
310  * \return          \c 0 on success.
311  * \return          A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
312  */
313 int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
314                                 int *paused );
315 
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
324  *                  be in consuming mode.
325  * \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
334  *                  (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().
337  * \return          #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
338  *                  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.
347  * \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  */
356 int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
357                             mbedtls_mps_size_t desired,
358                             unsigned char **buffer,
359                             mbedtls_mps_size_t *buflen );
360 
361 /**
362  * \brief         Mark data obtained from mbedtls_mps_reader_get() as processed.
363  *
364  *                This call indicates that all data received from prior calls to
365  *                mbedtls_mps_reader_get() has been or will have been
366  *                processed when mbedtls_mps_reader_reclaim() is called,
367  *                and thus need not be backed up.
368  *
369  *                This function has no user observable effect until
370  *                mbedtls_mps_reader_reclaim() is called. In particular,
371  *                buffers received from mbedtls_mps_reader_get() remain
372  *                valid until mbedtls_mps_reader_reclaim() is called.
373  *
374  * \param reader  The reader context to use.
375  *
376  * \return        \c 0 on success.
377  * \return        A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
378  *
379  */
380 int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
381 
382 #endif /* MBEDTLS_READER_H */
383