blob: 9f08c5267719b25816c01321e4652b7c9e699ac4 [file] [log] [blame]
Hanno Becker13cd7842021-01-12 07:08:33 +00001/*
2 * Message Processing Stack, Reader implementation
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of Mbed TLS (https://tls.mbed.org)
20 */
21
Hanno Beckerc518c3b2021-01-28 07:08:08 +000022#include "mps_reader.h"
23#include "mps_common.h"
24#include "mps_trace.h"
Hanno Becker13cd7842021-01-12 07:08:33 +000025
26#include <string.h>
27
28#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
29 !defined(inline) && !defined(__cplusplus)
30#define inline __inline
31#endif
32
Hanno Becker984fbde2021-01-28 09:02:18 +000033#if defined(MBEDTLS_MPS_ENABLE_TRACE)
34static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER;
35#endif /* MBEDTLS_MPS_ENABLE_TRACE */
Hanno Beckerb9100162021-01-12 09:46:03 +000036
Hanno Becker13cd7842021-01-12 07:08:33 +000037/*
38 * GENERAL NOTE ON CODING STYLE
39 *
40 * The following code intentionally separates memory loads
41 * and stores from other operations (arithmetic or branches).
42 * This leads to the introduction of many local variables
43 * and significantly increases the C-code line count, but
44 * should not increase the size of generated assembly.
45 *
46 * This reason for this is twofold:
47 * (1) It will ease verification efforts using the VST
48 * whose program logic cannot directly reason
49 * about instructions containing a load or store in
50 * addition to other operations (e.g. *p = *q or
51 * tmp = *p + 42).
52 * (2) Operating on local variables and writing the results
53 * back to the target contexts on success only
54 * allows to maintain structure invariants even
55 * on failure - this in turn has two benefits:
56 * (2.a) If for some reason an error code is not caught
57 * and operation continues, functions are nonetheless
58 * called with sane contexts, reducing the risk
59 * of dangerous behavior.
60 * (2.b) Randomized testing is easier if structures
61 * remain intact even in the face of failing
62 * and/or non-sensical calls.
63 * Moreover, it might even reduce code-size because
64 * the compiler need not write back temporary results
65 * to memory in case of failure.
66 *
67 */
68
Hanno Becker88993962021-01-28 09:45:47 +000069static inline void mps_reader_zero( mbedtls_mps_reader *rd )
Hanno Becker13cd7842021-01-12 07:08:33 +000070{
71 /* A plain memset() would likely be more efficient,
72 * but the current way of zeroing makes it harder
73 * to overlook fields which should not be zero-initialized.
74 * It's also more suitable for VF efforts since it
75 * doesn't require reasoning about structs being
76 * interpreted as unstructured binary blobs. */
Hanno Becker88993962021-01-28 09:45:47 +000077 static mbedtls_mps_reader const zero =
Hanno Becker13cd7842021-01-12 07:08:33 +000078 { .frag = NULL,
79 .frag_len = 0,
80 .commit = 0,
81 .end = 0,
82 .pending = 0,
83 .acc = NULL,
84 .acc_len = 0,
85 .acc_avail = 0,
86 .acc_share = { .acc_remaining = 0 }
87 };
88 *rd = zero;
89}
90
Hanno Becker88993962021-01-28 09:45:47 +000091int mbedtls_mps_reader_init( mbedtls_mps_reader *rd,
92 unsigned char *acc,
93 mbedtls_mps_size_t acc_len )
Hanno Becker13cd7842021-01-12 07:08:33 +000094{
Hanno Becker984fbde2021-01-28 09:02:18 +000095 MBEDTLS_MPS_TRACE_INIT( "reader_init, acc len %u", (unsigned) acc_len );
Hanno Becker13cd7842021-01-12 07:08:33 +000096 mps_reader_zero( rd );
97 rd->acc = acc;
98 rd->acc_len = acc_len;
Hanno Becker984fbde2021-01-28 09:02:18 +000099 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000100}
101
Hanno Becker88993962021-01-28 09:45:47 +0000102int mbedtls_mps_reader_free( mbedtls_mps_reader *rd )
Hanno Becker13cd7842021-01-12 07:08:33 +0000103{
Hanno Becker984fbde2021-01-28 09:02:18 +0000104 MBEDTLS_MPS_TRACE_INIT( "reader_free" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000105 mps_reader_zero( rd );
Hanno Becker984fbde2021-01-28 09:02:18 +0000106 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000107}
108
Hanno Becker88993962021-01-28 09:45:47 +0000109int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd,
110 unsigned char *new_frag,
111 mbedtls_mps_size_t new_frag_len )
Hanno Becker13cd7842021-01-12 07:08:33 +0000112{
113 unsigned char *acc;
114 mbedtls_mps_size_t copy_to_acc;
Hanno Becker984fbde2021-01-28 09:02:18 +0000115 MBEDTLS_MPS_TRACE_INIT( "reader_feed, frag %p, len %u",
Hanno Becker13cd7842021-01-12 07:08:33 +0000116 (void*) new_frag, (unsigned) new_frag_len );
117
118 if( new_frag == NULL )
Hanno Becker984fbde2021-01-28 09:02:18 +0000119 MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG );
Hanno Becker13cd7842021-01-12 07:08:33 +0000120
121 MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag == NULL,
Hanno Becker88993962021-01-28 09:45:47 +0000122 "mbedtls_mps_reader_feed() requires reader to be in producing mode" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000123
124 acc = rd->acc;
125 if( acc != NULL )
126 {
127 mbedtls_mps_size_t aa, ar;
128
129 ar = rd->acc_share.acc_remaining;
130 aa = rd->acc_avail;
131
132 copy_to_acc = ar;
133 if( copy_to_acc > new_frag_len )
134 copy_to_acc = new_frag_len;
135
136 acc += aa;
137
138 if( copy_to_acc > 0 )
139 memcpy( acc, new_frag, copy_to_acc );
140
Hanno Becker984fbde2021-01-28 09:02:18 +0000141 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
142 "Copy new data of size %u of %u into accumulator at offset %u",
Hanno Becker13cd7842021-01-12 07:08:33 +0000143 (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) aa );
144
145 /* Check if, with the new fragment, we have enough data. */
146 ar -= copy_to_acc;
147 if( ar > 0 )
148 {
149 /* Need more data */
150 aa += copy_to_acc;
151 rd->acc_share.acc_remaining = ar;
152 rd->acc_avail = aa;
Hanno Becker984fbde2021-01-28 09:02:18 +0000153 MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE );
Hanno Becker13cd7842021-01-12 07:08:33 +0000154 }
155
Hanno Becker984fbde2021-01-28 09:02:18 +0000156 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
157 "Enough data available to serve user request" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000158
159 rd->acc_share.frag_offset = aa;
160 aa += copy_to_acc;
161 rd->acc_avail = aa;
162 }
163 else
164 {
165 rd->acc_share.frag_offset = 0;
166 }
167
168 rd->frag = new_frag;
169 rd->frag_len = new_frag_len;
170 rd->commit = 0;
171 rd->end = 0;
Hanno Becker984fbde2021-01-28 09:02:18 +0000172 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000173}
174
175
Hanno Becker88993962021-01-28 09:45:47 +0000176int mbedtls_mps_reader_get( mbedtls_mps_reader *rd,
177 mbedtls_mps_size_t desired,
178 unsigned char **buffer,
179 mbedtls_mps_size_t *buflen )
Hanno Becker13cd7842021-01-12 07:08:33 +0000180{
181 unsigned char *frag, *acc;
182 mbedtls_mps_size_t end, fo, fl, frag_fetched, frag_remaining;
Hanno Becker984fbde2021-01-28 09:02:18 +0000183 MBEDTLS_MPS_TRACE_INIT( "reader_get %p, desired %u",
184 (void*) rd, (unsigned) desired );
Hanno Becker13cd7842021-01-12 07:08:33 +0000185
186 frag = rd->frag;
187 MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL,
Hanno Becker88993962021-01-28 09:45:47 +0000188 "mbedtls_mps_reader_get() requires reader to be in consuming mode" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000189
190 /* The fragment offset indicates the offset of the fragment
191 * from the accmulator, if the latter is present. Use a offset
192 * of \c 0 if no accumulator is used. */
193 acc = rd->acc;
194 if( acc == NULL )
195 fo = 0;
196 else
197 fo = rd->acc_share.frag_offset;
198
Hanno Becker984fbde2021-01-28 09:02:18 +0000199 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
200 "frag_off %u, end %u, acc_avail %d",
Hanno Becker13cd7842021-01-12 07:08:33 +0000201 (unsigned) fo, (unsigned) rd->end,
202 acc == NULL ? -1 : (int) rd->acc_avail );
203
204 /* Check if we're still serving from the accumulator. */
205 end = rd->end;
206 if( end < fo )
207 {
Hanno Becker984fbde2021-01-28 09:02:18 +0000208 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
209 "Serve the request from the accumulator" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000210 if( fo - end < desired )
211 {
212 /* Illustration of supported and unsupported cases:
213 *
214 * - Allowed #1
215 *
216 * +-----------------------------------+
217 * | frag |
218 * +-----------------------------------+
219 *
220 * end end+desired
221 * | |
222 * +-----v-------v-------------+
223 * | acc |
224 * +---------------------------+
225 * | |
226 * fo/frag_offset aa/acc_avail
227 *
228 * - Allowed #2
229 *
230 * +-----------------------------------+
231 * | frag |
232 * +-----------------------------------+
233 *
234 * end end+desired
235 * | |
236 * +----------v----------------v
237 * | acc |
238 * +---------------------------+
239 * | |
240 * fo/frag_offset aa/acc_avail
241 *
242 * - Not allowed #1 (could be served, but we don't actually use it):
243 *
244 * +-----------------------------------+
245 * | frag |
246 * +-----------------------------------+
247 *
248 * end end+desired
249 * | |
250 * +------v-------------v------+
251 * | acc |
252 * +---------------------------+
253 * | |
254 * fo/frag_offset aa/acc_avail
255 *
256 *
257 * - Not allowed #2 (can't be served with a contiguous buffer):
258 *
259 * +-----------------------------------+
260 * | frag |
261 * +-----------------------------------+
262 *
263 * end end + desired
264 * | |
265 * +------v--------------------+ v
266 * | acc |
267 * +---------------------------+
268 * | |
269 * fo/frag_offset aa/acc_avail
270 *
271 * In case of Allowed #1 and #2 we're switching to serve from
Hanno Becker88993962021-01-28 09:45:47 +0000272 * `frag` starting from the next call to mbedtls_mps_reader_get().
Hanno Becker13cd7842021-01-12 07:08:33 +0000273 */
274
275 mbedtls_mps_size_t aa;
276 aa = rd->acc_avail;
277 if( aa - end != desired )
278 {
279 /* It might be possible to serve some of these situations by
280 * making additional space in the accumulator, removing those
281 * parts that have already been committed.
282 * On the other hand, this brings additional complexity and
283 * enlarges the code size, while there doesn't seem to be a use
284 * case where we don't attempt exactly the same `get` calls when
285 * resuming on a reader than what we tried before pausing it.
286 * If we believe we adhere to this restricted usage throughout
287 * the library, this check is a good opportunity to
288 * validate this. */
Hanno Becker984fbde2021-01-28 09:02:18 +0000289 MBEDTLS_MPS_TRACE_RETURN(
290 MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS );
Hanno Becker13cd7842021-01-12 07:08:33 +0000291 }
292 }
293
294 acc += end;
295 *buffer = acc;
296 if( buflen != NULL )
297 *buflen = desired;
298
299 end += desired;
300 rd->end = end;
301 rd->pending = 0;
302
Hanno Becker984fbde2021-01-28 09:02:18 +0000303 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000304 }
305
306 /* Attempt to serve the request from the current fragment */
Hanno Becker984fbde2021-01-28 09:02:18 +0000307 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
308 "Serve the request from the current fragment." );
Hanno Becker13cd7842021-01-12 07:08:33 +0000309
310 fl = rd->frag_len;
311 frag_fetched = end - fo; /* The amount of data from the current fragment
312 * that has already been passed to the user. */
313 frag += frag_fetched;
314 frag_remaining = fl - frag_fetched; /* Remaining data in fragment */
315
316 /* Check if we can serve the read request from the fragment. */
317 if( frag_remaining < desired )
318 {
Hanno Becker984fbde2021-01-28 09:02:18 +0000319 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
320 "There's not enough data in the current fragment "
321 "to serve the request." );
Hanno Becker13cd7842021-01-12 07:08:33 +0000322 /* There's not enough data in the current fragment,
323 * so either just RETURN what we have or fail. */
324 if( buflen == NULL )
325 {
326 if( frag_remaining > 0 )
327 {
328 rd->pending = desired - frag_remaining;
Hanno Becker984fbde2021-01-28 09:02:18 +0000329 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
330 "Remember to collect %u bytes before re-opening",
Hanno Becker13cd7842021-01-12 07:08:33 +0000331 (unsigned) rd->pending );
332 }
Hanno Becker984fbde2021-01-28 09:02:18 +0000333 MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_OUT_OF_DATA );
Hanno Becker13cd7842021-01-12 07:08:33 +0000334 }
335
336 desired = frag_remaining;
337 }
338
339 /* There's enough data in the current fragment to serve the
340 * (potentially modified) read request. */
341 *buffer = frag;
342 if( buflen != NULL )
343 *buflen = desired;
344
345 end += desired;
346 rd->end = end;
347 rd->pending = 0;
Hanno Becker984fbde2021-01-28 09:02:18 +0000348 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000349}
350
Hanno Becker88993962021-01-28 09:45:47 +0000351int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd )
Hanno Becker13cd7842021-01-12 07:08:33 +0000352{
Hanno Becker4f84e202021-02-08 06:54:30 +0000353 mbedtls_mps_size_t end;
Hanno Becker984fbde2021-01-28 09:02:18 +0000354 MBEDTLS_MPS_TRACE_INIT( "reader_commit" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000355 MBEDTLS_MPS_STATE_VALIDATE_RAW( rd->frag != NULL,
Hanno Becker88993962021-01-28 09:45:47 +0000356 "mbedtls_mps_reader_commit() requires reader to be in consuming mode" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000357
Hanno Becker13cd7842021-01-12 07:08:33 +0000358 end = rd->end;
Hanno Becker13cd7842021-01-12 07:08:33 +0000359 rd->commit = end;
Hanno Becker13cd7842021-01-12 07:08:33 +0000360
Hanno Becker984fbde2021-01-28 09:02:18 +0000361 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000362}
363
Hanno Becker88993962021-01-28 09:45:47 +0000364int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd,
365 mbedtls_mps_size_t *paused )
Hanno Becker13cd7842021-01-12 07:08:33 +0000366{
367 unsigned char *frag, *acc;
368 mbedtls_mps_size_t pending, commit;
369 mbedtls_mps_size_t al, fo, fl;
Hanno Becker4f84e202021-02-08 06:54:30 +0000370 MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_reclaim" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000371
372 if( paused != NULL )
373 *paused = 0;
374
375 frag = rd->frag;
376 MBEDTLS_MPS_STATE_VALIDATE_RAW( frag != NULL,
Hanno Becker88993962021-01-28 09:45:47 +0000377 "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" );
Hanno Becker13cd7842021-01-12 07:08:33 +0000378
379 acc = rd->acc;
380 pending = rd->pending;
381 commit = rd->commit;
382 fl = rd->frag_len;
383
384 if( acc == NULL )
385 fo = 0;
386 else
387 fo = rd->acc_share.frag_offset;
388
389 if( pending == 0 )
390 {
Hanno Becker984fbde2021-01-28 09:02:18 +0000391 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
392 "No unsatisfied read-request has been logged." );
Hanno Becker4f84e202021-02-08 06:54:30 +0000393
Hanno Becker13cd7842021-01-12 07:08:33 +0000394 /* Check if there's data left to be consumed. */
395 if( commit < fo || commit - fo < fl )
396 {
Hanno Becker984fbde2021-01-28 09:02:18 +0000397 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
398 "There is data left to be consumed." );
Hanno Becker13cd7842021-01-12 07:08:33 +0000399 rd->end = commit;
Hanno Becker984fbde2021-01-28 09:02:18 +0000400 MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT );
Hanno Becker13cd7842021-01-12 07:08:33 +0000401 }
Hanno Becker4f84e202021-02-08 06:54:30 +0000402
403 rd->acc_avail = 0;
404 rd->acc_share.acc_remaining = 0;
405
Hanno Becker984fbde2021-01-28 09:02:18 +0000406 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
Hanno Becker4f84e202021-02-08 06:54:30 +0000407 "Fragment has been fully processed and committed." );
Hanno Becker13cd7842021-01-12 07:08:33 +0000408 }
409 else
410 {
Hanno Becker4f84e202021-02-08 06:54:30 +0000411 int overflow;
412
413 mbedtls_mps_size_t acc_backup_offset;
414 mbedtls_mps_size_t acc_backup_len;
Hanno Becker13cd7842021-01-12 07:08:33 +0000415 mbedtls_mps_size_t frag_backup_offset;
416 mbedtls_mps_size_t frag_backup_len;
Hanno Becker4f84e202021-02-08 06:54:30 +0000417
418 mbedtls_mps_size_t backup_len;
419 mbedtls_mps_size_t acc_len_needed;
420
Hanno Becker984fbde2021-01-28 09:02:18 +0000421 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
Hanno Becker4f84e202021-02-08 06:54:30 +0000422 "There has been an unsatisfied read with %u bytes overhead.",
423 (unsigned) pending );
Hanno Becker13cd7842021-01-12 07:08:33 +0000424
425 if( acc == NULL )
426 {
Hanno Becker984fbde2021-01-28 09:02:18 +0000427 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
428 "No accumulator present" );
429 MBEDTLS_MPS_TRACE_RETURN(
430 MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR );
Hanno Becker13cd7842021-01-12 07:08:33 +0000431 }
432 al = rd->acc_len;
433
434 /* Check if the upper layer has already fetched
435 * and committed the contents of the accumulator. */
436 if( commit < fo )
437 {
438 /* No, accumulator is still being processed. */
Hanno Becker13cd7842021-01-12 07:08:33 +0000439 frag_backup_offset = 0;
440 frag_backup_len = fl;
Hanno Becker4f84e202021-02-08 06:54:30 +0000441 acc_backup_offset = commit;
442 acc_backup_len = fo - commit;
Hanno Becker13cd7842021-01-12 07:08:33 +0000443 }
444 else
445 {
446 /* Yes, the accumulator is already processed. */
Hanno Becker4f84e202021-02-08 06:54:30 +0000447 frag_backup_offset = commit - fo;
448 frag_backup_len = fl - frag_backup_offset;
449 acc_backup_offset = 0;
450 acc_backup_len = 0;
Hanno Becker13cd7842021-01-12 07:08:33 +0000451 }
452
Hanno Becker4f84e202021-02-08 06:54:30 +0000453 backup_len = acc_backup_len + frag_backup_len;
454 acc_len_needed = backup_len + pending;
455
456 overflow = 0;
457 overflow |= ( backup_len < acc_backup_len );
458 overflow |= ( acc_len_needed < backup_len );
459
460 if( overflow || al < acc_len_needed )
461 {
462 /* Except for the different return code, we behave as if
463 * there hadn't been a call to mbedtls_mps_reader_get()
464 * since the last commit. */
465 rd->end = commit;
466 rd->pending = 0;
467 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error,
468 "The accumulator is too small to handle the backup." );
469 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error,
470 "* Size: %u", (unsigned) al );
471 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_error,
472 "* Needed: %u (%u + %u)",
473 (unsigned) acc_len_needed,
474 (unsigned) backup_len, (unsigned) pending );
475 MBEDTLS_MPS_TRACE_RETURN(
476 MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL );
477 }
Hanno Becker13cd7842021-01-12 07:08:33 +0000478
Hanno Becker984fbde2021-01-28 09:02:18 +0000479 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
Hanno Becker4f84e202021-02-08 06:54:30 +0000480 "Fragment backup: %u", (unsigned) frag_backup_len );
481 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
482 "Accumulator backup: %u", (unsigned) acc_backup_len );
Hanno Becker13cd7842021-01-12 07:08:33 +0000483
Hanno Becker4f84e202021-02-08 06:54:30 +0000484 /* Move uncommitted parts from the accumulator to the front
485 * of the accumulator. */
486 memmove( acc, acc + acc_backup_offset, acc_backup_len );
487
488 /* Copy uncmmitted parts of the current fragment to the
489 * accumulator. */
490 memcpy( acc + acc_backup_len,
491 frag + frag_backup_offset, frag_backup_len );
492
493 rd->acc_avail = backup_len;
Hanno Becker13cd7842021-01-12 07:08:33 +0000494 rd->acc_share.acc_remaining = pending;
495
496 if( paused != NULL )
497 *paused = 1;
498 }
499
500 rd->frag = NULL;
501 rd->frag_len = 0;
502
Hanno Becker4f84e202021-02-08 06:54:30 +0000503 rd->commit = 0;
504 rd->end = 0;
505 rd->pending = 0;
Hanno Becker13cd7842021-01-12 07:08:33 +0000506
Hanno Becker984fbde2021-01-28 09:02:18 +0000507 MBEDTLS_MPS_TRACE( mbedtls_mps_trace_comment,
508 "Final state: aa %u, al %u, ar %u",
509 (unsigned) rd->acc_avail, (unsigned) rd->acc_len,
510 (unsigned) rd->acc_share.acc_remaining );
Hanno Becker984fbde2021-01-28 09:02:18 +0000511 MBEDTLS_MPS_TRACE_RETURN( 0 );
Hanno Becker13cd7842021-01-12 07:08:33 +0000512}