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