xref: /aosp_15_r20/external/mbedtls/library/mps_reader.h (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
3*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
4*62c56f98SSadaf Ebrahimi  */
5*62c56f98SSadaf Ebrahimi 
6*62c56f98SSadaf Ebrahimi /**
7*62c56f98SSadaf Ebrahimi  * \file mps_reader.h
8*62c56f98SSadaf Ebrahimi  *
9*62c56f98SSadaf Ebrahimi  * \brief This file defines reader objects, which together with their
10*62c56f98SSadaf Ebrahimi  *        sibling writer objects form the basis for the communication
11*62c56f98SSadaf Ebrahimi  *        between the various layers of the Mbed TLS messaging stack,
12*62c56f98SSadaf Ebrahimi  *        as well as the communication between the messaging stack and
13*62c56f98SSadaf Ebrahimi  *        the (D)TLS handshake protocol implementation.
14*62c56f98SSadaf Ebrahimi  *
15*62c56f98SSadaf Ebrahimi  * Readers provide a means of transferring incoming data from
16*62c56f98SSadaf Ebrahimi  * a 'producer' providing it in chunks of arbitrary size, to
17*62c56f98SSadaf Ebrahimi  * a 'consumer' which fetches and processes it in chunks of
18*62c56f98SSadaf Ebrahimi  * again arbitrary, and potentially different, size.
19*62c56f98SSadaf Ebrahimi  *
20*62c56f98SSadaf Ebrahimi  * Readers can thus be seen as datagram-to-stream converters,
21*62c56f98SSadaf Ebrahimi  * and they abstract away the following two tasks from the user:
22*62c56f98SSadaf Ebrahimi  * 1. The pointer arithmetic of stepping through a producer-
23*62c56f98SSadaf Ebrahimi  *    provided chunk in smaller chunks.
24*62c56f98SSadaf Ebrahimi  * 2. The merging of incoming data chunks in case the
25*62c56f98SSadaf Ebrahimi  *    consumer requests data in larger chunks than what the
26*62c56f98SSadaf Ebrahimi  *    producer provides.
27*62c56f98SSadaf Ebrahimi  *
28*62c56f98SSadaf Ebrahimi  * The basic abstract flow of operation is the following:
29*62c56f98SSadaf Ebrahimi  * - Initially, the reader is in 'producing mode'.
30*62c56f98SSadaf Ebrahimi  * - The producer hands an incoming data buffer to the reader,
31*62c56f98SSadaf Ebrahimi  *   moving it from 'producing' to 'consuming' mode.
32*62c56f98SSadaf Ebrahimi  * - The consumer subsequently fetches and processes the buffer
33*62c56f98SSadaf Ebrahimi  *   content. Once that's done -- or partially done and a consumer's
34*62c56f98SSadaf Ebrahimi  *   request can't be fulfilled -- the producer revokes the reader's
35*62c56f98SSadaf Ebrahimi  *   access to the incoming data buffer, putting the reader back to
36*62c56f98SSadaf Ebrahimi  *   producing mode.
37*62c56f98SSadaf Ebrahimi  * - The producer subsequently gathers more incoming data and hands
38*62c56f98SSadaf Ebrahimi  *   it to the reader until it switches back to consuming mode
39*62c56f98SSadaf Ebrahimi  *   if enough data is available for the last consumer request to
40*62c56f98SSadaf Ebrahimi  *   be satisfiable.
41*62c56f98SSadaf Ebrahimi  * - Repeat the above.
42*62c56f98SSadaf Ebrahimi  *
43*62c56f98SSadaf Ebrahimi  * The abstract states of the reader from the producer's and
44*62c56f98SSadaf Ebrahimi  * consumer's perspective are as follows:
45*62c56f98SSadaf Ebrahimi  *
46*62c56f98SSadaf Ebrahimi  * - From the perspective of the consumer, the state of the
47*62c56f98SSadaf Ebrahimi  *   reader consists of the following:
48*62c56f98SSadaf Ebrahimi  *   - A byte stream representing (concatenation of) the data
49*62c56f98SSadaf Ebrahimi  *     received through calls to mbedtls_mps_reader_get(),
50*62c56f98SSadaf Ebrahimi  *   - A marker within that byte stream indicating which data
51*62c56f98SSadaf Ebrahimi  *     can be considered processed, and hence need not be retained,
52*62c56f98SSadaf Ebrahimi  *     when the reader is passed back to the producer via
53*62c56f98SSadaf Ebrahimi  *     mbedtls_mps_reader_reclaim().
54*62c56f98SSadaf Ebrahimi  *     The marker is set via mbedtls_mps_reader_commit()
55*62c56f98SSadaf Ebrahimi  *     which places it at the end of the current byte stream.
56*62c56f98SSadaf Ebrahimi  *   The consumer need not be aware of the distinction between consumer
57*62c56f98SSadaf Ebrahimi  *   and producer mode, because it only interfaces with the reader
58*62c56f98SSadaf Ebrahimi  *   when the latter is in consuming mode.
59*62c56f98SSadaf Ebrahimi  *
60*62c56f98SSadaf Ebrahimi  * - From the perspective of the producer, the reader's state is one of:
61*62c56f98SSadaf Ebrahimi  *   - Attached: The reader is in consuming mode.
62*62c56f98SSadaf Ebrahimi  *   - Unset: No incoming data buffer is currently managed by the reader,
63*62c56f98SSadaf Ebrahimi  *            and all previously handed incoming data buffers have been
64*62c56f98SSadaf Ebrahimi  *            fully processed. More data needs to be fed into the reader
65*62c56f98SSadaf Ebrahimi  *            via mbedtls_mps_reader_feed().
66*62c56f98SSadaf Ebrahimi  *
67*62c56f98SSadaf Ebrahimi  *   - Accumulating: No incoming data buffer is currently managed by the
68*62c56f98SSadaf Ebrahimi  *                   reader, but some data from the previous incoming data
69*62c56f98SSadaf Ebrahimi  *                   buffer hasn't been processed yet and is internally
70*62c56f98SSadaf Ebrahimi  *                   held back.
71*62c56f98SSadaf Ebrahimi  *   The Attached state belongs to consuming mode, while the Unset and
72*62c56f98SSadaf Ebrahimi  *   Accumulating states belong to producing mode.
73*62c56f98SSadaf Ebrahimi  *
74*62c56f98SSadaf Ebrahimi  * Transitioning from the Unset or Accumulating state to Attached is
75*62c56f98SSadaf Ebrahimi  * done via successful calls to mbedtls_mps_reader_feed(), while
76*62c56f98SSadaf Ebrahimi  * transitioning from Attached to either Unset or Accumulating (depending
77*62c56f98SSadaf Ebrahimi  * on what has been processed) is done via mbedtls_mps_reader_reclaim().
78*62c56f98SSadaf Ebrahimi  *
79*62c56f98SSadaf Ebrahimi  * The following diagram depicts the producer-state progression:
80*62c56f98SSadaf Ebrahimi  *
81*62c56f98SSadaf Ebrahimi  *        +------------------+             reclaim
82*62c56f98SSadaf Ebrahimi  *        |      Unset       +<-------------------------------------+       get
83*62c56f98SSadaf Ebrahimi  *        +--------|---------+                                      |   +------+
84*62c56f98SSadaf Ebrahimi  *                 |                                                |   |      |
85*62c56f98SSadaf Ebrahimi  *                 |                                                |   |      |
86*62c56f98SSadaf Ebrahimi  *                 |                feed                  +---------+---+--+   |
87*62c56f98SSadaf Ebrahimi  *                 +-------------------------------------->                <---+
88*62c56f98SSadaf Ebrahimi  *                                                        |    Attached    |
89*62c56f98SSadaf Ebrahimi  *                 +-------------------------------------->                <---+
90*62c56f98SSadaf Ebrahimi  *                 |     feed, enough data available      +---------+---+--+   |
91*62c56f98SSadaf Ebrahimi  *                 |     to serve previous consumer request         |   |      |
92*62c56f98SSadaf Ebrahimi  *                 |                                                |   |      |
93*62c56f98SSadaf Ebrahimi  *        +--------+---------+                                      |   +------+
94*62c56f98SSadaf Ebrahimi  *   +---->   Accumulating   |<-------------------------------------+    commit
95*62c56f98SSadaf Ebrahimi  *   |    +---+--------------+      reclaim, previous read request
96*62c56f98SSadaf Ebrahimi  *   |        |                        couldn't be fulfilled
97*62c56f98SSadaf Ebrahimi  *   |        |
98*62c56f98SSadaf Ebrahimi  *   +--------+
99*62c56f98SSadaf Ebrahimi  *     feed, need more data to serve
100*62c56f98SSadaf Ebrahimi  *     previous consumer request
101*62c56f98SSadaf Ebrahimi  *                                         |
102*62c56f98SSadaf Ebrahimi  *                                         |
103*62c56f98SSadaf Ebrahimi  *               producing mode            |           consuming mode
104*62c56f98SSadaf Ebrahimi  *                                         |
105*62c56f98SSadaf Ebrahimi  *
106*62c56f98SSadaf Ebrahimi  */
107*62c56f98SSadaf Ebrahimi 
108*62c56f98SSadaf Ebrahimi #ifndef MBEDTLS_READER_H
109*62c56f98SSadaf Ebrahimi #define MBEDTLS_READER_H
110*62c56f98SSadaf Ebrahimi 
111*62c56f98SSadaf Ebrahimi #include <stdio.h>
112*62c56f98SSadaf Ebrahimi 
113*62c56f98SSadaf Ebrahimi #include "mps_common.h"
114*62c56f98SSadaf Ebrahimi #include "mps_error.h"
115*62c56f98SSadaf Ebrahimi 
116*62c56f98SSadaf Ebrahimi struct mbedtls_mps_reader;
117*62c56f98SSadaf Ebrahimi typedef struct mbedtls_mps_reader mbedtls_mps_reader;
118*62c56f98SSadaf Ebrahimi 
119*62c56f98SSadaf Ebrahimi /*
120*62c56f98SSadaf Ebrahimi  * Structure definitions
121*62c56f98SSadaf Ebrahimi  */
122*62c56f98SSadaf Ebrahimi 
123*62c56f98SSadaf Ebrahimi struct mbedtls_mps_reader {
124*62c56f98SSadaf Ebrahimi     unsigned char *frag;  /*!< The fragment of incoming data managed by
125*62c56f98SSadaf Ebrahimi                            *   the reader; it is provided to the reader
126*62c56f98SSadaf Ebrahimi                            *   through mbedtls_mps_reader_feed(). The reader
127*62c56f98SSadaf Ebrahimi                            *   does not own the fragment and does not
128*62c56f98SSadaf Ebrahimi                            *   perform any allocation operations on it,
129*62c56f98SSadaf Ebrahimi                            *   but does have read and write access to it.
130*62c56f98SSadaf Ebrahimi                            *
131*62c56f98SSadaf Ebrahimi                            *   The reader is in consuming mode if
132*62c56f98SSadaf Ebrahimi                            *   and only if \c frag is not \c NULL.          */
133*62c56f98SSadaf Ebrahimi     mbedtls_mps_stored_size_t frag_len;
134*62c56f98SSadaf Ebrahimi     /*!< The length of the current fragment.
135*62c56f98SSadaf Ebrahimi      *   Must be 0 if \c frag == \c NULL.             */
136*62c56f98SSadaf Ebrahimi     mbedtls_mps_stored_size_t commit;
137*62c56f98SSadaf Ebrahimi     /*!< The offset of the last commit, relative
138*62c56f98SSadaf Ebrahimi      *   to the first byte in the fragment, if
139*62c56f98SSadaf Ebrahimi      *   no accumulator is present. If an accumulator
140*62c56f98SSadaf Ebrahimi      *   is present, it is viewed as a prefix to the
141*62c56f98SSadaf Ebrahimi      *   current fragment, and this variable contains
142*62c56f98SSadaf Ebrahimi      *   an offset from the beginning of the accumulator.
143*62c56f98SSadaf Ebrahimi      *
144*62c56f98SSadaf Ebrahimi      *   This is only used when the reader is in
145*62c56f98SSadaf Ebrahimi      *   consuming mode, i.e. \c frag != \c NULL;
146*62c56f98SSadaf Ebrahimi      *   otherwise, its value is \c 0.                */
147*62c56f98SSadaf Ebrahimi     mbedtls_mps_stored_size_t end;
148*62c56f98SSadaf Ebrahimi     /*!< The offset of the end of the last chunk
149*62c56f98SSadaf Ebrahimi      *   passed to the user through a call to
150*62c56f98SSadaf Ebrahimi      *   mbedtls_mps_reader_get(), relative to the first
151*62c56f98SSadaf Ebrahimi      *   byte in the fragment, if no accumulator is
152*62c56f98SSadaf Ebrahimi      *   present. If an accumulator is present, it is
153*62c56f98SSadaf Ebrahimi      *   viewed as a prefix to the current fragment, and
154*62c56f98SSadaf Ebrahimi      *   this variable contains an offset from the
155*62c56f98SSadaf Ebrahimi      *   beginning of the accumulator.
156*62c56f98SSadaf Ebrahimi      *
157*62c56f98SSadaf Ebrahimi      *   This is only used when the reader is in
158*62c56f98SSadaf Ebrahimi      *   consuming mode, i.e. \c frag != \c NULL;
159*62c56f98SSadaf Ebrahimi      *   otherwise, its value is \c 0.                */
160*62c56f98SSadaf Ebrahimi     mbedtls_mps_stored_size_t pending;
161*62c56f98SSadaf Ebrahimi     /*!< The amount of incoming data missing on the
162*62c56f98SSadaf Ebrahimi      *   last call to mbedtls_mps_reader_get().
163*62c56f98SSadaf Ebrahimi      *   In particular, it is \c 0 if the last call
164*62c56f98SSadaf Ebrahimi      *   was successful.
165*62c56f98SSadaf Ebrahimi      *   If a reader is reclaimed after an
166*62c56f98SSadaf Ebrahimi      *   unsuccessful call to mbedtls_mps_reader_get(),
167*62c56f98SSadaf Ebrahimi      *   this variable is used to have the reader
168*62c56f98SSadaf Ebrahimi      *   remember how much data should be accumulated
169*62c56f98SSadaf Ebrahimi      *   so that the call to mbedtls_mps_reader_get()
170*62c56f98SSadaf Ebrahimi      *   succeeds next time.
171*62c56f98SSadaf Ebrahimi      *   This is only used when the reader is in
172*62c56f98SSadaf Ebrahimi      *   consuming mode, i.e. \c frag != \c NULL;
173*62c56f98SSadaf Ebrahimi      *   otherwise, its value is \c 0.                */
174*62c56f98SSadaf Ebrahimi 
175*62c56f98SSadaf Ebrahimi     /* The accumulator is only needed if we need to be able to pause
176*62c56f98SSadaf Ebrahimi      * the reader. A few bytes could be saved by moving this to a
177*62c56f98SSadaf Ebrahimi      * separate struct and using a pointer here. */
178*62c56f98SSadaf Ebrahimi 
179*62c56f98SSadaf Ebrahimi     unsigned char *acc;   /*!< The accumulator is used to gather incoming
180*62c56f98SSadaf Ebrahimi                            *   data if a read-request via mbedtls_mps_reader_get()
181*62c56f98SSadaf Ebrahimi                            *   cannot be served from the current fragment.   */
182*62c56f98SSadaf Ebrahimi     mbedtls_mps_stored_size_t acc_len;
183*62c56f98SSadaf Ebrahimi     /*!< The total size of the accumulator.           */
184*62c56f98SSadaf Ebrahimi     mbedtls_mps_stored_size_t acc_available;
185*62c56f98SSadaf Ebrahimi     /*!< The number of bytes currently gathered in
186*62c56f98SSadaf Ebrahimi      *   the accumulator. This is both used in
187*62c56f98SSadaf Ebrahimi      *   producing and in consuming mode:
188*62c56f98SSadaf Ebrahimi      *   While producing, it is increased until
189*62c56f98SSadaf Ebrahimi      *   it reaches the value of \c acc_remaining below.
190*62c56f98SSadaf Ebrahimi      *   While consuming, it is used to judge if a
191*62c56f98SSadaf Ebrahimi      *   get request can be served from the
192*62c56f98SSadaf Ebrahimi      *   accumulator or not.
193*62c56f98SSadaf Ebrahimi      *   Must not be larger than \c acc_len.           */
194*62c56f98SSadaf Ebrahimi     union {
195*62c56f98SSadaf Ebrahimi         mbedtls_mps_stored_size_t acc_remaining;
196*62c56f98SSadaf Ebrahimi         /*!< This indicates the amount of data still
197*62c56f98SSadaf Ebrahimi          *   to be gathered in the accumulator. It is
198*62c56f98SSadaf Ebrahimi          *   only used in producing mode.
199*62c56f98SSadaf Ebrahimi          *   Must be at most acc_len - acc_available.  */
200*62c56f98SSadaf Ebrahimi         mbedtls_mps_stored_size_t frag_offset;
201*62c56f98SSadaf Ebrahimi         /*!< If an accumulator is present and in use, this
202*62c56f98SSadaf Ebrahimi          *   field indicates the offset of the current
203*62c56f98SSadaf Ebrahimi          *   fragment from the beginning of the
204*62c56f98SSadaf Ebrahimi          *   accumulator. If no accumulator is present
205*62c56f98SSadaf Ebrahimi          *   or the accumulator is not in use, this is \c 0.
206*62c56f98SSadaf Ebrahimi          *   It is only used in consuming mode.
207*62c56f98SSadaf Ebrahimi          *   Must not be larger than \c acc_available. */
208*62c56f98SSadaf Ebrahimi     } acc_share;
209*62c56f98SSadaf Ebrahimi };
210*62c56f98SSadaf Ebrahimi 
211*62c56f98SSadaf Ebrahimi /*
212*62c56f98SSadaf Ebrahimi  * API organization:
213*62c56f98SSadaf Ebrahimi  * A reader object is usually prepared and maintained
214*62c56f98SSadaf Ebrahimi  * by some lower layer and passed for usage to an upper
215*62c56f98SSadaf Ebrahimi  * layer, and the API naturally splits according to which
216*62c56f98SSadaf Ebrahimi  * layer is supposed to use the respective functions.
217*62c56f98SSadaf Ebrahimi  */
218*62c56f98SSadaf Ebrahimi 
219*62c56f98SSadaf Ebrahimi /*
220*62c56f98SSadaf Ebrahimi  * Maintenance API (Lower layer)
221*62c56f98SSadaf Ebrahimi  */
222*62c56f98SSadaf Ebrahimi 
223*62c56f98SSadaf Ebrahimi /**
224*62c56f98SSadaf Ebrahimi  * \brief           Initialize a reader object
225*62c56f98SSadaf Ebrahimi  *
226*62c56f98SSadaf Ebrahimi  * \param reader    The reader to be initialized.
227*62c56f98SSadaf Ebrahimi  * \param acc       The buffer to be used as a temporary accumulator
228*62c56f98SSadaf Ebrahimi  *                  in case get requests through mbedtls_mps_reader_get()
229*62c56f98SSadaf Ebrahimi  *                  exceed the buffer provided by mbedtls_mps_reader_feed().
230*62c56f98SSadaf Ebrahimi  *                  This buffer is owned by the caller and exclusive use
231*62c56f98SSadaf Ebrahimi  *                  for reading and writing is given to the reader for the
232*62c56f98SSadaf Ebrahimi  *                  duration of the reader's lifetime. It is thus the caller's
233*62c56f98SSadaf Ebrahimi  *                  responsibility to maintain (and not touch) the buffer for
234*62c56f98SSadaf Ebrahimi  *                  the lifetime of the reader, and to properly zeroize and
235*62c56f98SSadaf Ebrahimi  *                  free the memory after the reader has been destroyed.
236*62c56f98SSadaf Ebrahimi  * \param acc_len   The size in Bytes of \p acc.
237*62c56f98SSadaf Ebrahimi  *
238*62c56f98SSadaf Ebrahimi  * \return          \c 0 on success.
239*62c56f98SSadaf Ebrahimi  * \return          A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
240*62c56f98SSadaf Ebrahimi  */
241*62c56f98SSadaf Ebrahimi int mbedtls_mps_reader_init(mbedtls_mps_reader *reader,
242*62c56f98SSadaf Ebrahimi                             unsigned char *acc,
243*62c56f98SSadaf Ebrahimi                             mbedtls_mps_size_t acc_len);
244*62c56f98SSadaf Ebrahimi 
245*62c56f98SSadaf Ebrahimi /**
246*62c56f98SSadaf Ebrahimi  * \brief           Free a reader object
247*62c56f98SSadaf Ebrahimi  *
248*62c56f98SSadaf Ebrahimi  * \param reader    The reader to be freed.
249*62c56f98SSadaf Ebrahimi  *
250*62c56f98SSadaf Ebrahimi  * \return          \c 0 on success.
251*62c56f98SSadaf Ebrahimi  * \return          A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
252*62c56f98SSadaf Ebrahimi  */
253*62c56f98SSadaf Ebrahimi int mbedtls_mps_reader_free(mbedtls_mps_reader *reader);
254*62c56f98SSadaf Ebrahimi 
255*62c56f98SSadaf Ebrahimi /**
256*62c56f98SSadaf Ebrahimi  * \brief           Pass chunk of data for the reader to manage.
257*62c56f98SSadaf Ebrahimi  *
258*62c56f98SSadaf Ebrahimi  * \param reader    The reader context to use. The reader must be
259*62c56f98SSadaf Ebrahimi  *                  in producing mode.
260*62c56f98SSadaf Ebrahimi  * \param buf       The buffer to be managed by the reader.
261*62c56f98SSadaf Ebrahimi  * \param buflen    The size in Bytes of \p buffer.
262*62c56f98SSadaf Ebrahimi  *
263*62c56f98SSadaf Ebrahimi  * \return          \c 0 on success. In this case, the reader will be
264*62c56f98SSadaf Ebrahimi  *                  moved to consuming mode and obtains read access
265*62c56f98SSadaf Ebrahimi  *                  of \p buf until mbedtls_mps_reader_reclaim()
266*62c56f98SSadaf Ebrahimi  *                  is called. It is the responsibility of the caller
267*62c56f98SSadaf Ebrahimi  *                  to ensure that the \p buf persists and is not changed
268*62c56f98SSadaf Ebrahimi  *                  between successful calls to mbedtls_mps_reader_feed()
269*62c56f98SSadaf Ebrahimi  *                  and mbedtls_mps_reader_reclaim().
270*62c56f98SSadaf Ebrahimi  * \return          \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
271*62c56f98SSadaf Ebrahimi  *                  required to fulfill a previous request to mbedtls_mps_reader_get().
272*62c56f98SSadaf Ebrahimi  *                  In this case, the reader remains in producing mode and
273*62c56f98SSadaf Ebrahimi  *                  takes no ownership of the provided buffer (an internal copy
274*62c56f98SSadaf Ebrahimi  *                  is made instead).
275*62c56f98SSadaf Ebrahimi  * \return          Another negative \c MBEDTLS_ERR_READER_XXX error code on
276*62c56f98SSadaf Ebrahimi  *                  different kinds of failures.
277*62c56f98SSadaf Ebrahimi  */
278*62c56f98SSadaf Ebrahimi int mbedtls_mps_reader_feed(mbedtls_mps_reader *reader,
279*62c56f98SSadaf Ebrahimi                             unsigned char *buf,
280*62c56f98SSadaf Ebrahimi                             mbedtls_mps_size_t buflen);
281*62c56f98SSadaf Ebrahimi 
282*62c56f98SSadaf Ebrahimi /**
283*62c56f98SSadaf Ebrahimi  * \brief           Reclaim reader's access to the current input buffer.
284*62c56f98SSadaf Ebrahimi  *
285*62c56f98SSadaf Ebrahimi  * \param reader    The reader context to use. The reader must be
286*62c56f98SSadaf Ebrahimi  *                  in consuming mode.
287*62c56f98SSadaf Ebrahimi  * \param paused    If not \c NULL, the integer at address \p paused will be
288*62c56f98SSadaf Ebrahimi  *                  modified to indicate whether the reader has been paused
289*62c56f98SSadaf Ebrahimi  *                  (value \c 1) or not (value \c 0). Pausing happens if there
290*62c56f98SSadaf Ebrahimi  *                  is uncommitted data and a previous request to
291*62c56f98SSadaf Ebrahimi  *                  mbedtls_mps_reader_get() has exceeded the bounds of the
292*62c56f98SSadaf Ebrahimi  *                  input buffer.
293*62c56f98SSadaf Ebrahimi  *
294*62c56f98SSadaf Ebrahimi  * \return          \c 0 on success.
295*62c56f98SSadaf Ebrahimi  * \return          A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
296*62c56f98SSadaf Ebrahimi  */
297*62c56f98SSadaf Ebrahimi int mbedtls_mps_reader_reclaim(mbedtls_mps_reader *reader,
298*62c56f98SSadaf Ebrahimi                                int *paused);
299*62c56f98SSadaf Ebrahimi 
300*62c56f98SSadaf Ebrahimi /*
301*62c56f98SSadaf Ebrahimi  * Usage API (Upper layer)
302*62c56f98SSadaf Ebrahimi  */
303*62c56f98SSadaf Ebrahimi 
304*62c56f98SSadaf Ebrahimi /**
305*62c56f98SSadaf Ebrahimi  * \brief           Request data from the reader.
306*62c56f98SSadaf Ebrahimi  *
307*62c56f98SSadaf Ebrahimi  * \param reader    The reader context to use. The reader must
308*62c56f98SSadaf Ebrahimi  *                  be in consuming mode.
309*62c56f98SSadaf Ebrahimi  * \param desired   The desired amount of data to be read, in Bytes.
310*62c56f98SSadaf Ebrahimi  * \param buffer    The address to store the buffer pointer in.
311*62c56f98SSadaf Ebrahimi  *                  This must not be \c NULL.
312*62c56f98SSadaf Ebrahimi  * \param buflen    The address to store the actual buffer
313*62c56f98SSadaf Ebrahimi  *                  length in, or \c NULL.
314*62c56f98SSadaf Ebrahimi  *
315*62c56f98SSadaf Ebrahimi  * \return          \c 0 on success. In this case, \c *buf holds the
316*62c56f98SSadaf Ebrahimi  *                  address of a buffer of size \c *buflen
317*62c56f98SSadaf Ebrahimi  *                  (if \c buflen != \c NULL) or \c desired
318*62c56f98SSadaf Ebrahimi  *                  (if \c buflen == \c NULL). The user has read access
319*62c56f98SSadaf Ebrahimi  *                  to the buffer and guarantee of stability of the data
320*62c56f98SSadaf Ebrahimi  *                  until the next call to mbedtls_mps_reader_reclaim().
321*62c56f98SSadaf Ebrahimi  * \return          #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
322*62c56f98SSadaf Ebrahimi  *                  data available to serve the get request. In this case, the
323*62c56f98SSadaf Ebrahimi  *                  reader remains intact and in consuming mode, and the consumer
324*62c56f98SSadaf Ebrahimi  *                  should retry the call after a successful cycle of
325*62c56f98SSadaf Ebrahimi  *                  mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
326*62c56f98SSadaf Ebrahimi  *                  If, after such a cycle, the consumer requests a different
327*62c56f98SSadaf Ebrahimi  *                  amount of data, the result is implementation-defined;
328*62c56f98SSadaf Ebrahimi  *                  progress is guaranteed only if the same amount of data
329*62c56f98SSadaf Ebrahimi  *                  is requested after a mbedtls_mps_reader_reclaim() and
330*62c56f98SSadaf Ebrahimi  *                  mbedtls_mps_reader_feed() cycle.
331*62c56f98SSadaf Ebrahimi  * \return          Another negative \c MBEDTLS_ERR_READER_XXX error
332*62c56f98SSadaf Ebrahimi  *                  code for different kinds of failure.
333*62c56f98SSadaf Ebrahimi  *
334*62c56f98SSadaf Ebrahimi  * \note            Passing \c NULL as \p buflen is a convenient way to
335*62c56f98SSadaf Ebrahimi  *                  indicate that fragmentation is not tolerated.
336*62c56f98SSadaf Ebrahimi  *                  It's functionally equivalent to passing a valid
337*62c56f98SSadaf Ebrahimi  *                  address as buflen and checking \c *buflen == \c desired
338*62c56f98SSadaf Ebrahimi  *                  afterwards.
339*62c56f98SSadaf Ebrahimi  */
340*62c56f98SSadaf Ebrahimi int mbedtls_mps_reader_get(mbedtls_mps_reader *reader,
341*62c56f98SSadaf Ebrahimi                            mbedtls_mps_size_t desired,
342*62c56f98SSadaf Ebrahimi                            unsigned char **buffer,
343*62c56f98SSadaf Ebrahimi                            mbedtls_mps_size_t *buflen);
344*62c56f98SSadaf Ebrahimi 
345*62c56f98SSadaf Ebrahimi /**
346*62c56f98SSadaf Ebrahimi  * \brief         Mark data obtained from mbedtls_mps_reader_get() as processed.
347*62c56f98SSadaf Ebrahimi  *
348*62c56f98SSadaf Ebrahimi  *                This call indicates that all data received from prior calls to
349*62c56f98SSadaf Ebrahimi  *                mbedtls_mps_reader_get() has been or will have been
350*62c56f98SSadaf Ebrahimi  *                processed when mbedtls_mps_reader_reclaim() is called,
351*62c56f98SSadaf Ebrahimi  *                and thus need not be backed up.
352*62c56f98SSadaf Ebrahimi  *
353*62c56f98SSadaf Ebrahimi  *                This function has no user observable effect until
354*62c56f98SSadaf Ebrahimi  *                mbedtls_mps_reader_reclaim() is called. In particular,
355*62c56f98SSadaf Ebrahimi  *                buffers received from mbedtls_mps_reader_get() remain
356*62c56f98SSadaf Ebrahimi  *                valid until mbedtls_mps_reader_reclaim() is called.
357*62c56f98SSadaf Ebrahimi  *
358*62c56f98SSadaf Ebrahimi  * \param reader  The reader context to use.
359*62c56f98SSadaf Ebrahimi  *
360*62c56f98SSadaf Ebrahimi  * \return        \c 0 on success.
361*62c56f98SSadaf Ebrahimi  * \return        A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
362*62c56f98SSadaf Ebrahimi  *
363*62c56f98SSadaf Ebrahimi  */
364*62c56f98SSadaf Ebrahimi int mbedtls_mps_reader_commit(mbedtls_mps_reader *reader);
365*62c56f98SSadaf Ebrahimi 
366*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_READER_H */
367