xref: /aosp_15_r20/external/mbedtls/tests/suites/test_suite_mps.function (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi/* BEGIN_HEADER */
2*62c56f98SSadaf Ebrahimi
3*62c56f98SSadaf Ebrahimi#include <stdlib.h>
4*62c56f98SSadaf Ebrahimi
5*62c56f98SSadaf Ebrahimi#include "mps_reader.h"
6*62c56f98SSadaf Ebrahimi
7*62c56f98SSadaf Ebrahimi/*
8*62c56f98SSadaf Ebrahimi * Compile-time configuration for test suite.
9*62c56f98SSadaf Ebrahimi */
10*62c56f98SSadaf Ebrahimi
11*62c56f98SSadaf Ebrahimi/* Comment/Uncomment this to disable/enable the
12*62c56f98SSadaf Ebrahimi * testing of the various MPS layers.
13*62c56f98SSadaf Ebrahimi * This can be useful for time-consuming instrumentation
14*62c56f98SSadaf Ebrahimi * tasks such as the conversion of E-ACSL annotations
15*62c56f98SSadaf Ebrahimi * into runtime assertions. */
16*62c56f98SSadaf Ebrahimi#define TEST_SUITE_MPS_READER
17*62c56f98SSadaf Ebrahimi
18*62c56f98SSadaf Ebrahimi/* End of compile-time configuration. */
19*62c56f98SSadaf Ebrahimi
20*62c56f98SSadaf Ebrahimi/* END_HEADER */
21*62c56f98SSadaf Ebrahimi
22*62c56f98SSadaf Ebrahimi/* BEGIN_DEPENDENCIES
23*62c56f98SSadaf Ebrahimi * depends_on:MBEDTLS_SSL_PROTO_TLS1_3
24*62c56f98SSadaf Ebrahimi * END_DEPENDENCIES
25*62c56f98SSadaf Ebrahimi */
26*62c56f98SSadaf Ebrahimi
27*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
28*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_no_pausing_single_step_single_round(int with_acc)
29*62c56f98SSadaf Ebrahimi{
30*62c56f98SSadaf Ebrahimi    /* This test exercises the most basic use of the MPS reader:
31*62c56f98SSadaf Ebrahimi     * - The 'producing' layer provides a buffer
32*62c56f98SSadaf Ebrahimi     * - The 'consuming' layer fetches it in a single go.
33*62c56f98SSadaf Ebrahimi     * - After processing, the consuming layer commits the data
34*62c56f98SSadaf Ebrahimi     *   and the reader is moved back to producing mode.
35*62c56f98SSadaf Ebrahimi     *
36*62c56f98SSadaf Ebrahimi     * Parameters:
37*62c56f98SSadaf Ebrahimi     * - with_acc: 0 if the reader should be initialized without accumulator.
38*62c56f98SSadaf Ebrahimi     *             1 if the reader should be initialized with accumulator.
39*62c56f98SSadaf Ebrahimi     *
40*62c56f98SSadaf Ebrahimi     *             Whether the accumulator is present or not should not matter,
41*62c56f98SSadaf Ebrahimi     *             since the consumer's request can be fulfilled from the data
42*62c56f98SSadaf Ebrahimi     *             that the producer has provided.
43*62c56f98SSadaf Ebrahimi     */
44*62c56f98SSadaf Ebrahimi    unsigned char bufA[100];
45*62c56f98SSadaf Ebrahimi    unsigned char acc[10];
46*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
47*62c56f98SSadaf Ebrahimi    int paused;
48*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
49*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
50*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
51*62c56f98SSadaf Ebrahimi    }
52*62c56f98SSadaf Ebrahimi
53*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
54*62c56f98SSadaf Ebrahimi    if (with_acc == 0) {
55*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, NULL, 0);
56*62c56f98SSadaf Ebrahimi    } else {
57*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
58*62c56f98SSadaf Ebrahimi    }
59*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
60*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
61*62c56f98SSadaf Ebrahimi    /* Consume exactly what's available */
62*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) == 0);
63*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 100, bufA, 100);
64*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
65*62c56f98SSadaf Ebrahimi    /* Wrapup (lower layer) */
66*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, &paused) == 0);
67*62c56f98SSadaf Ebrahimi    TEST_ASSERT(paused == 0);
68*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
69*62c56f98SSadaf Ebrahimi}
70*62c56f98SSadaf Ebrahimi/* END_CASE */
71*62c56f98SSadaf Ebrahimi
72*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
73*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_no_pausing_single_step_multiple_rounds(int with_acc)
74*62c56f98SSadaf Ebrahimi{
75*62c56f98SSadaf Ebrahimi    /* This test exercises multiple rounds of the basic use of the MPS reader:
76*62c56f98SSadaf Ebrahimi     * - The 'producing' layer provides a buffer
77*62c56f98SSadaf Ebrahimi     * - The 'consuming' layer fetches it in a single go.
78*62c56f98SSadaf Ebrahimi     * - After processing, the consuming layer commits the data
79*62c56f98SSadaf Ebrahimi     *   and the reader is moved back to producing mode.
80*62c56f98SSadaf Ebrahimi     *
81*62c56f98SSadaf Ebrahimi     * Parameters:
82*62c56f98SSadaf Ebrahimi     * - with_acc: 0 if the reader should be initialized without accumulator.
83*62c56f98SSadaf Ebrahimi     *             1 if the reader should be initialized with accumulator.
84*62c56f98SSadaf Ebrahimi     *
85*62c56f98SSadaf Ebrahimi     *             Whether the accumulator is present or not should not matter,
86*62c56f98SSadaf Ebrahimi     *             since the consumer's request can be fulfilled from the data
87*62c56f98SSadaf Ebrahimi     *             that the producer has provided.
88*62c56f98SSadaf Ebrahimi     */
89*62c56f98SSadaf Ebrahimi
90*62c56f98SSadaf Ebrahimi    unsigned char bufA[100], bufB[100];
91*62c56f98SSadaf Ebrahimi    unsigned char acc[10];
92*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
93*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
94*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
95*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
96*62c56f98SSadaf Ebrahimi    }
97*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufB); i++) {
98*62c56f98SSadaf Ebrahimi        bufB[i] = ~((unsigned char) i);
99*62c56f98SSadaf Ebrahimi    }
100*62c56f98SSadaf Ebrahimi
101*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
102*62c56f98SSadaf Ebrahimi    if (with_acc == 0) {
103*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, NULL, 0);
104*62c56f98SSadaf Ebrahimi    } else {
105*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
106*62c56f98SSadaf Ebrahimi    }
107*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
108*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
109*62c56f98SSadaf Ebrahimi    /* Consume exactly what's available */
110*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) == 0);
111*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 100, bufA, 100);
112*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
113*62c56f98SSadaf Ebrahimi    /* Preparation */
114*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
115*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB, sizeof(bufB)) == 0);
116*62c56f98SSadaf Ebrahimi    /* Consumption */
117*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) == 0);
118*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 100, bufB, 100);
119*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
120*62c56f98SSadaf Ebrahimi    /* Wrapup (lower layer) */
121*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
122*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
123*62c56f98SSadaf Ebrahimi}
124*62c56f98SSadaf Ebrahimi/* END_CASE */
125*62c56f98SSadaf Ebrahimi
126*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
127*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_no_pausing_multiple_steps_single_round(int with_acc)
128*62c56f98SSadaf Ebrahimi{
129*62c56f98SSadaf Ebrahimi    /* This test exercises one round of the following:
130*62c56f98SSadaf Ebrahimi     * - The 'producing' layer provides a buffer
131*62c56f98SSadaf Ebrahimi     * - The 'consuming' layer fetches it in multiple calls
132*62c56f98SSadaf Ebrahimi     *   to `mbedtls_mps_reader_get()`, without committing in between.
133*62c56f98SSadaf Ebrahimi     * - After processing, the consuming layer commits the data
134*62c56f98SSadaf Ebrahimi     *   and the reader is moved back to producing mode.
135*62c56f98SSadaf Ebrahimi     *
136*62c56f98SSadaf Ebrahimi     * Parameters:
137*62c56f98SSadaf Ebrahimi     * - with_acc: 0 if the reader should be initialized without accumulator.
138*62c56f98SSadaf Ebrahimi     *             1 if the reader should be initialized with accumulator.
139*62c56f98SSadaf Ebrahimi     *
140*62c56f98SSadaf Ebrahimi     *             Whether the accumulator is present or not should not matter,
141*62c56f98SSadaf Ebrahimi     *             since the consumer's requests can be fulfilled from the data
142*62c56f98SSadaf Ebrahimi     *             that the producer has provided.
143*62c56f98SSadaf Ebrahimi     */
144*62c56f98SSadaf Ebrahimi
145*62c56f98SSadaf Ebrahimi    /* Lower layer provides data that the upper layer fully consumes
146*62c56f98SSadaf Ebrahimi     * through multiple `get` calls. */
147*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
148*62c56f98SSadaf Ebrahimi    unsigned char acc[10];
149*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
150*62c56f98SSadaf Ebrahimi    mbedtls_mps_size_t tmp_len;
151*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
152*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
153*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
154*62c56f98SSadaf Ebrahimi    }
155*62c56f98SSadaf Ebrahimi
156*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
157*62c56f98SSadaf Ebrahimi    if (with_acc == 0) {
158*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, NULL, 0);
159*62c56f98SSadaf Ebrahimi    } else {
160*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
161*62c56f98SSadaf Ebrahimi    }
162*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
163*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
164*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
165*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 10, buf, 10);
166*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 70, &tmp, NULL) == 0);
167*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 70, buf + 10, 70);
168*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 30, &tmp, &tmp_len) == 0);
169*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, tmp_len, buf + 80, 20);
170*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
171*62c56f98SSadaf Ebrahimi    /* Wrapup (lower layer) */
172*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
173*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
174*62c56f98SSadaf Ebrahimi}
175*62c56f98SSadaf Ebrahimi/* END_CASE */
176*62c56f98SSadaf Ebrahimi
177*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
178*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_no_pausing_multiple_steps_multiple_rounds(int with_acc)
179*62c56f98SSadaf Ebrahimi{
180*62c56f98SSadaf Ebrahimi    /* This test exercises one round of fetching a buffer in multiple chunks
181*62c56f98SSadaf Ebrahimi     * and passing it back to the producer afterwards, followed by another
182*62c56f98SSadaf Ebrahimi     * single-step sequence of feed-fetch-commit-reclaim.
183*62c56f98SSadaf Ebrahimi     */
184*62c56f98SSadaf Ebrahimi    unsigned char bufA[100], bufB[100];
185*62c56f98SSadaf Ebrahimi    unsigned char acc[10];
186*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
187*62c56f98SSadaf Ebrahimi    mbedtls_mps_size_t tmp_len;
188*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
189*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
190*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
191*62c56f98SSadaf Ebrahimi    }
192*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufB); i++) {
193*62c56f98SSadaf Ebrahimi        bufB[i] = ~((unsigned char) i);
194*62c56f98SSadaf Ebrahimi    }
195*62c56f98SSadaf Ebrahimi
196*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
197*62c56f98SSadaf Ebrahimi    if (with_acc == 0) {
198*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, NULL, 0);
199*62c56f98SSadaf Ebrahimi    } else {
200*62c56f98SSadaf Ebrahimi        mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
201*62c56f98SSadaf Ebrahimi    }
202*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
203*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
204*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
205*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 10, bufA, 10);
206*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 70, &tmp, NULL) == 0);
207*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 70, bufA + 10, 70);
208*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 30, &tmp, &tmp_len) == 0);
209*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, tmp_len, bufA + 80, 20);
210*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
211*62c56f98SSadaf Ebrahimi    /* Preparation */
212*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
213*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB, sizeof(bufB)) == 0);
214*62c56f98SSadaf Ebrahimi    /* Consumption */
215*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) == 0);
216*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 100, bufB, 100);
217*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
218*62c56f98SSadaf Ebrahimi    /* Wrapup */
219*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
220*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
221*62c56f98SSadaf Ebrahimi}
222*62c56f98SSadaf Ebrahimi/* END_CASE */
223*62c56f98SSadaf Ebrahimi
224*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
225*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_pausing_needed_disabled()
226*62c56f98SSadaf Ebrahimi{
227*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader when a read request
228*62c56f98SSadaf Ebrahimi     * of the consumer exceeds what has been provided by the producer, and when
229*62c56f98SSadaf Ebrahimi     * no accumulator is available in the reader.
230*62c56f98SSadaf Ebrahimi     *
231*62c56f98SSadaf Ebrahimi     * In this case, we expect the reader to fail.
232*62c56f98SSadaf Ebrahimi     */
233*62c56f98SSadaf Ebrahimi
234*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
235*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
236*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
237*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
238*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
239*62c56f98SSadaf Ebrahimi    }
240*62c56f98SSadaf Ebrahimi
241*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
242*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, NULL, 0);
243*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
244*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
245*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
246*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 50, buf, 50);
247*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
248*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) ==
249*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
250*62c56f98SSadaf Ebrahimi    /* Wrapup (lower layer) */
251*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
252*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR);
253*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
254*62c56f98SSadaf Ebrahimi}
255*62c56f98SSadaf Ebrahimi/* END_CASE */
256*62c56f98SSadaf Ebrahimi
257*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
258*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_pausing_needed_buffer_too_small()
259*62c56f98SSadaf Ebrahimi{
260*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader with accumulator
261*62c56f98SSadaf Ebrahimi     * in the situation where a read request goes beyond the bounds of the
262*62c56f98SSadaf Ebrahimi     * current read buffer, _and_ the reader's accumulator is too small to
263*62c56f98SSadaf Ebrahimi     * hold the requested amount of data.
264*62c56f98SSadaf Ebrahimi     *
265*62c56f98SSadaf Ebrahimi     * In this case, we expect mbedtls_mps_reader_reclaim() to fail,
266*62c56f98SSadaf Ebrahimi     * but it should be possible to continue fetching data as if
267*62c56f98SSadaf Ebrahimi     * there had been no excess request via mbedtls_mps_reader_get()
268*62c56f98SSadaf Ebrahimi     * and the call to mbedtls_mps_reader_reclaim() had been rejected
269*62c56f98SSadaf Ebrahimi     * because of data remaining.
270*62c56f98SSadaf Ebrahimi     */
271*62c56f98SSadaf Ebrahimi
272*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
273*62c56f98SSadaf Ebrahimi    unsigned char acc[10];
274*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
275*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
276*62c56f98SSadaf Ebrahimi    mbedtls_mps_size_t tmp_len;
277*62c56f98SSadaf Ebrahimi
278*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
279*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
280*62c56f98SSadaf Ebrahimi    }
281*62c56f98SSadaf Ebrahimi
282*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
283*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
284*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
285*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
286*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
287*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 50, buf, 50);
288*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
289*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
290*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 10, buf + 50, 10);
291*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) ==
292*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
293*62c56f98SSadaf Ebrahimi    /* Wrapup (lower layer) */
294*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
295*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL);
296*62c56f98SSadaf Ebrahimi
297*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, &tmp_len) == 0);
298*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, tmp_len, buf + 50, 50);
299*62c56f98SSadaf Ebrahimi
300*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
301*62c56f98SSadaf Ebrahimi}
302*62c56f98SSadaf Ebrahimi/* END_CASE */
303*62c56f98SSadaf Ebrahimi
304*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
305*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_reclaim_overflow()
306*62c56f98SSadaf Ebrahimi{
307*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader with accumulator
308*62c56f98SSadaf Ebrahimi     * in the situation where upon calling mbedtls_mps_reader_reclaim(), the
309*62c56f98SSadaf Ebrahimi     * uncommitted data together with the excess data missing in the last
310*62c56f98SSadaf Ebrahimi     * call to mbedtls_mps_reader_get() exceeds the bounds of the type
311*62c56f98SSadaf Ebrahimi     * holding the buffer length.
312*62c56f98SSadaf Ebrahimi     */
313*62c56f98SSadaf Ebrahimi
314*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
315*62c56f98SSadaf Ebrahimi    unsigned char acc[50];
316*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
317*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
318*62c56f98SSadaf Ebrahimi
319*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
320*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
321*62c56f98SSadaf Ebrahimi    }
322*62c56f98SSadaf Ebrahimi
323*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
324*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
325*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
326*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
327*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
328*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 50, buf, 50);
329*62c56f98SSadaf Ebrahimi    /* Excess request */
330*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, (mbedtls_mps_size_t) -1, &tmp, NULL) ==
331*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
332*62c56f98SSadaf Ebrahimi    /* Wrapup (lower layer) */
333*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
334*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL);
335*62c56f98SSadaf Ebrahimi
336*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
337*62c56f98SSadaf Ebrahimi}
338*62c56f98SSadaf Ebrahimi/* END_CASE */
339*62c56f98SSadaf Ebrahimi
340*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
341*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_pausing(int option)
342*62c56f98SSadaf Ebrahimi{
343*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the reader when the
344*62c56f98SSadaf Ebrahimi     * accumulator is used to fulfill a consumer's request.
345*62c56f98SSadaf Ebrahimi     *
346*62c56f98SSadaf Ebrahimi     * More detailed:
347*62c56f98SSadaf Ebrahimi     * - The producer feeds some data.
348*62c56f98SSadaf Ebrahimi     * - The consumer asks for more data than what's available.
349*62c56f98SSadaf Ebrahimi     * - The reader remembers the request and goes back to
350*62c56f98SSadaf Ebrahimi     *   producing mode, waiting for more data from the producer.
351*62c56f98SSadaf Ebrahimi     * - The producer provides another chunk of data which is
352*62c56f98SSadaf Ebrahimi     *   sufficient to fulfill the original read request.
353*62c56f98SSadaf Ebrahimi     * - The consumer retries the original read request, which
354*62c56f98SSadaf Ebrahimi     *   should now succeed.
355*62c56f98SSadaf Ebrahimi     *
356*62c56f98SSadaf Ebrahimi     * This test comes in multiple variants controlled by the
357*62c56f98SSadaf Ebrahimi     * `option` parameter and documented below.
358*62c56f98SSadaf Ebrahimi     */
359*62c56f98SSadaf Ebrahimi
360*62c56f98SSadaf Ebrahimi    unsigned char bufA[100], bufB[100];
361*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
362*62c56f98SSadaf Ebrahimi    unsigned char acc[40];
363*62c56f98SSadaf Ebrahimi    int paused;
364*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
365*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
366*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
367*62c56f98SSadaf Ebrahimi    }
368*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufB); i++) {
369*62c56f98SSadaf Ebrahimi        bufB[i] = ~((unsigned char) i);
370*62c56f98SSadaf Ebrahimi    }
371*62c56f98SSadaf Ebrahimi
372*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
373*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
374*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
375*62c56f98SSadaf Ebrahimi
376*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
377*62c56f98SSadaf Ebrahimi    /* Ask for more than what's available. */
378*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 80, &tmp, NULL) == 0);
379*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 80, bufA, 80);
380*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
381*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
382*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
383*62c56f98SSadaf Ebrahimi    switch (option) {
384*62c56f98SSadaf Ebrahimi        case 0:  /* Single uncommitted fetch at pausing */
385*62c56f98SSadaf Ebrahimi        case 1:
386*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
387*62c56f98SSadaf Ebrahimi            break;
388*62c56f98SSadaf Ebrahimi        default: /* Multiple uncommitted fetches at pausing */
389*62c56f98SSadaf Ebrahimi            break;
390*62c56f98SSadaf Ebrahimi    }
391*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) ==
392*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
393*62c56f98SSadaf Ebrahimi
394*62c56f98SSadaf Ebrahimi    /* Preparation */
395*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, &paused) == 0);
396*62c56f98SSadaf Ebrahimi    TEST_ASSERT(paused == 1);
397*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB, sizeof(bufB)) == 0);
398*62c56f98SSadaf Ebrahimi
399*62c56f98SSadaf Ebrahimi    /* Consumption */
400*62c56f98SSadaf Ebrahimi    switch (option) {
401*62c56f98SSadaf Ebrahimi        case 0: /* Single fetch at pausing, re-fetch with commit. */
402*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
403*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
404*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
405*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
406*62c56f98SSadaf Ebrahimi            break;
407*62c56f98SSadaf Ebrahimi
408*62c56f98SSadaf Ebrahimi        case 1: /* Single fetch at pausing, re-fetch without commit. */
409*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
410*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
411*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
412*62c56f98SSadaf Ebrahimi            break;
413*62c56f98SSadaf Ebrahimi
414*62c56f98SSadaf Ebrahimi        case 2: /* Multiple fetches at pausing, repeat without commit. */
415*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
416*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
417*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
418*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
419*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
420*62c56f98SSadaf Ebrahimi            break;
421*62c56f98SSadaf Ebrahimi
422*62c56f98SSadaf Ebrahimi        case 3: /* Multiple fetches at pausing, repeat with commit 1. */
423*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
424*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
425*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
426*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
427*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
428*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
429*62c56f98SSadaf Ebrahimi            break;
430*62c56f98SSadaf Ebrahimi
431*62c56f98SSadaf Ebrahimi        case 4: /* Multiple fetches at pausing, repeat with commit 2. */
432*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
433*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
434*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
435*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
436*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
437*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
438*62c56f98SSadaf Ebrahimi            break;
439*62c56f98SSadaf Ebrahimi
440*62c56f98SSadaf Ebrahimi        case 5: /* Multiple fetches at pausing, repeat with commit 3. */
441*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
442*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
443*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
444*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
445*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
446*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
447*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
448*62c56f98SSadaf Ebrahimi            break;
449*62c56f98SSadaf Ebrahimi
450*62c56f98SSadaf Ebrahimi        default:
451*62c56f98SSadaf Ebrahimi            TEST_ASSERT(0);
452*62c56f98SSadaf Ebrahimi    }
453*62c56f98SSadaf Ebrahimi
454*62c56f98SSadaf Ebrahimi    /* In all cases, fetch the rest of the second buffer. */
455*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 90, &tmp, NULL) == 0);
456*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 90, bufB + 10, 90);
457*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
458*62c56f98SSadaf Ebrahimi
459*62c56f98SSadaf Ebrahimi    /* Wrapup */
460*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
461*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
462*62c56f98SSadaf Ebrahimi}
463*62c56f98SSadaf Ebrahimi/* END_CASE */
464*62c56f98SSadaf Ebrahimi
465*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
466*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_pausing_multiple_feeds(int option)
467*62c56f98SSadaf Ebrahimi{
468*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader
469*62c56f98SSadaf Ebrahimi     * in the following situation:
470*62c56f98SSadaf Ebrahimi     * - The consumer has asked for more than what's available, so the
471*62c56f98SSadaf Ebrahimi     *   reader pauses and waits for further input data via
472*62c56f98SSadaf Ebrahimi     *   `mbedtls_mps_reader_feed()`
473*62c56f98SSadaf Ebrahimi     * - Multiple such calls to `mbedtls_mps_reader_feed()` are necessary
474*62c56f98SSadaf Ebrahimi     *   to fulfill the original request, and the reader needs to do
475*62c56f98SSadaf Ebrahimi     *   the necessary bookkeeping under the hood.
476*62c56f98SSadaf Ebrahimi     *
477*62c56f98SSadaf Ebrahimi     * This test comes in a few variants differing in the number and
478*62c56f98SSadaf Ebrahimi     * size of feed calls that the producer issues while the reader is
479*62c56f98SSadaf Ebrahimi     * accumulating the necessary data - see the comments below.
480*62c56f98SSadaf Ebrahimi     */
481*62c56f98SSadaf Ebrahimi
482*62c56f98SSadaf Ebrahimi    unsigned char bufA[100], bufB[100];
483*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
484*62c56f98SSadaf Ebrahimi    unsigned char acc[70];
485*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
486*62c56f98SSadaf Ebrahimi    mbedtls_mps_size_t fetch_len;
487*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
488*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
489*62c56f98SSadaf Ebrahimi    }
490*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufB); i++) {
491*62c56f98SSadaf Ebrahimi        bufB[i] = ~((unsigned char) i);
492*62c56f98SSadaf Ebrahimi    }
493*62c56f98SSadaf Ebrahimi
494*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
495*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
496*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
497*62c56f98SSadaf Ebrahimi
498*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
499*62c56f98SSadaf Ebrahimi    /* Ask for more than what's available. */
500*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 80, &tmp, NULL) == 0);
501*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 80, bufA, 80);
502*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
503*62c56f98SSadaf Ebrahimi    /* 20 left, ask for 70 -> 50 overhead */
504*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 70, &tmp, NULL) ==
505*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
506*62c56f98SSadaf Ebrahimi
507*62c56f98SSadaf Ebrahimi    /* Preparation */
508*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
509*62c56f98SSadaf Ebrahimi    switch (option) {
510*62c56f98SSadaf Ebrahimi        case 0: /* 10 + 10 + 80 byte feed */
511*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB, 10) ==
512*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_NEED_MORE);
513*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB + 10, 10) ==
514*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_NEED_MORE);
515*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB + 20, 80) == 0);
516*62c56f98SSadaf Ebrahimi            break;
517*62c56f98SSadaf Ebrahimi
518*62c56f98SSadaf Ebrahimi        case 1: /* 50 x 1byte */
519*62c56f98SSadaf Ebrahimi            for (size_t num_feed = 0; num_feed < 49; num_feed++) {
520*62c56f98SSadaf Ebrahimi                TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB + num_feed, 1) ==
521*62c56f98SSadaf Ebrahimi                            MBEDTLS_ERR_MPS_READER_NEED_MORE);
522*62c56f98SSadaf Ebrahimi            }
523*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB + 49, 1) == 0);
524*62c56f98SSadaf Ebrahimi            break;
525*62c56f98SSadaf Ebrahimi
526*62c56f98SSadaf Ebrahimi        case 2: /* 49 x 1byte + 51bytes */
527*62c56f98SSadaf Ebrahimi            for (size_t num_feed = 0; num_feed < 49; num_feed++) {
528*62c56f98SSadaf Ebrahimi                TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB + num_feed, 1) ==
529*62c56f98SSadaf Ebrahimi                            MBEDTLS_ERR_MPS_READER_NEED_MORE);
530*62c56f98SSadaf Ebrahimi            }
531*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB + 49, 51) == 0);
532*62c56f98SSadaf Ebrahimi            break;
533*62c56f98SSadaf Ebrahimi
534*62c56f98SSadaf Ebrahimi        default:
535*62c56f98SSadaf Ebrahimi            TEST_ASSERT(0);
536*62c56f98SSadaf Ebrahimi            break;
537*62c56f98SSadaf Ebrahimi    }
538*62c56f98SSadaf Ebrahimi
539*62c56f98SSadaf Ebrahimi    /* Consumption */
540*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 70, &tmp, NULL) == 0);
541*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 20, bufA + 80, 20);
542*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp + 20, 50, bufB, 50);
543*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 1000, &tmp, &fetch_len) == 0);
544*62c56f98SSadaf Ebrahimi    switch (option) {
545*62c56f98SSadaf Ebrahimi        case 0:
546*62c56f98SSadaf Ebrahimi            TEST_ASSERT(fetch_len == 50);
547*62c56f98SSadaf Ebrahimi            break;
548*62c56f98SSadaf Ebrahimi
549*62c56f98SSadaf Ebrahimi        case 1:
550*62c56f98SSadaf Ebrahimi            TEST_ASSERT(fetch_len == 0);
551*62c56f98SSadaf Ebrahimi            break;
552*62c56f98SSadaf Ebrahimi
553*62c56f98SSadaf Ebrahimi        case 2:
554*62c56f98SSadaf Ebrahimi            TEST_ASSERT(fetch_len == 50);
555*62c56f98SSadaf Ebrahimi            break;
556*62c56f98SSadaf Ebrahimi
557*62c56f98SSadaf Ebrahimi        default:
558*62c56f98SSadaf Ebrahimi            TEST_ASSERT(0);
559*62c56f98SSadaf Ebrahimi            break;
560*62c56f98SSadaf Ebrahimi    }
561*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
562*62c56f98SSadaf Ebrahimi
563*62c56f98SSadaf Ebrahimi    /* Wrapup */
564*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
565*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
566*62c56f98SSadaf Ebrahimi}
567*62c56f98SSadaf Ebrahimi/* END_CASE */
568*62c56f98SSadaf Ebrahimi
569*62c56f98SSadaf Ebrahimi
570*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
571*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_reclaim_data_left(int option)
572*62c56f98SSadaf Ebrahimi{
573*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader when a
574*62c56f98SSadaf Ebrahimi     * call to mbedtls_mps_reader_reclaim() is made before all data
575*62c56f98SSadaf Ebrahimi     * provided by the producer has been fetched and committed. */
576*62c56f98SSadaf Ebrahimi
577*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
578*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
579*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
580*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
581*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
582*62c56f98SSadaf Ebrahimi    }
583*62c56f98SSadaf Ebrahimi
584*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
585*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, NULL, 0);
586*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
587*62c56f98SSadaf Ebrahimi
588*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
589*62c56f98SSadaf Ebrahimi    switch (option) {
590*62c56f98SSadaf Ebrahimi        case 0:
591*62c56f98SSadaf Ebrahimi            /* Fetch (but not commit) the entire buffer. */
592*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, sizeof(buf), &tmp, NULL)
593*62c56f98SSadaf Ebrahimi                        == 0);
594*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 100, buf, 100);
595*62c56f98SSadaf Ebrahimi            break;
596*62c56f98SSadaf Ebrahimi
597*62c56f98SSadaf Ebrahimi        case 1:
598*62c56f98SSadaf Ebrahimi            /* Fetch (but not commit) parts of the buffer. */
599*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, sizeof(buf) / 2,
600*62c56f98SSadaf Ebrahimi                                               &tmp, NULL) == 0);
601*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, sizeof(buf) / 2, buf, sizeof(buf) / 2);
602*62c56f98SSadaf Ebrahimi            break;
603*62c56f98SSadaf Ebrahimi
604*62c56f98SSadaf Ebrahimi        case 2:
605*62c56f98SSadaf Ebrahimi            /* Fetch and commit parts of the buffer, then
606*62c56f98SSadaf Ebrahimi             * fetch but not commit the rest of the buffer. */
607*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, sizeof(buf) / 2,
608*62c56f98SSadaf Ebrahimi                                               &tmp, NULL) == 0);
609*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, sizeof(buf) / 2, buf, sizeof(buf) / 2);
610*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
611*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, sizeof(buf) / 2,
612*62c56f98SSadaf Ebrahimi                                               &tmp, NULL) == 0);
613*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, sizeof(buf) / 2,
614*62c56f98SSadaf Ebrahimi                                buf + sizeof(buf) / 2,
615*62c56f98SSadaf Ebrahimi                                sizeof(buf) / 2);
616*62c56f98SSadaf Ebrahimi            break;
617*62c56f98SSadaf Ebrahimi
618*62c56f98SSadaf Ebrahimi        default:
619*62c56f98SSadaf Ebrahimi            TEST_ASSERT(0);
620*62c56f98SSadaf Ebrahimi            break;
621*62c56f98SSadaf Ebrahimi    }
622*62c56f98SSadaf Ebrahimi
623*62c56f98SSadaf Ebrahimi    /* Wrapup */
624*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
625*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_DATA_LEFT);
626*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
627*62c56f98SSadaf Ebrahimi}
628*62c56f98SSadaf Ebrahimi/* END_CASE */
629*62c56f98SSadaf Ebrahimi
630*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
631*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_reclaim_data_left_retry()
632*62c56f98SSadaf Ebrahimi{
633*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader when an attempt
634*62c56f98SSadaf Ebrahimi     * by the producer to reclaim the reader fails because of more data pending
635*62c56f98SSadaf Ebrahimi     * to be processed, and the consumer subsequently fetches more data. */
636*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
637*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
638*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
639*62c56f98SSadaf Ebrahimi
640*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
641*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
642*62c56f98SSadaf Ebrahimi    }
643*62c56f98SSadaf Ebrahimi
644*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
645*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, NULL, 0);
646*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
647*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
648*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
649*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 50, buf, 50);
650*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
651*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
652*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 50, buf + 50, 50);
653*62c56f98SSadaf Ebrahimi    /* Preparation */
654*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
655*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_DATA_LEFT);
656*62c56f98SSadaf Ebrahimi    /* Consumption */
657*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
658*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 50, buf + 50, 50);
659*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
660*62c56f98SSadaf Ebrahimi    /* Wrapup */
661*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
662*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
663*62c56f98SSadaf Ebrahimi}
664*62c56f98SSadaf Ebrahimi/* END_CASE */
665*62c56f98SSadaf Ebrahimi
666*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
667*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_multiple_pausing(int option)
668*62c56f98SSadaf Ebrahimi{
669*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader
670*62c56f98SSadaf Ebrahimi     * in the following situation:
671*62c56f98SSadaf Ebrahimi     * - A read request via `mbedtls_mps_reader_get()` can't
672*62c56f98SSadaf Ebrahimi     *   be served and the reader is paused to accumulate
673*62c56f98SSadaf Ebrahimi     *   the desired amount of data from the producer.
674*62c56f98SSadaf Ebrahimi     * - Once enough data is available, the consumer successfully
675*62c56f98SSadaf Ebrahimi     *   reads the data from the reader, but afterwards exceeds
676*62c56f98SSadaf Ebrahimi     *   the available data again - pausing is necessary for a
677*62c56f98SSadaf Ebrahimi     *   second time.
678*62c56f98SSadaf Ebrahimi     */
679*62c56f98SSadaf Ebrahimi
680*62c56f98SSadaf Ebrahimi    unsigned char bufA[100], bufB[20], bufC[10];
681*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
682*62c56f98SSadaf Ebrahimi    unsigned char acc[50];
683*62c56f98SSadaf Ebrahimi    mbedtls_mps_size_t tmp_len;
684*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
685*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
686*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
687*62c56f98SSadaf Ebrahimi    }
688*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufB); i++) {
689*62c56f98SSadaf Ebrahimi        bufB[i] = ~((unsigned char) i);
690*62c56f98SSadaf Ebrahimi    }
691*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufC); i++) {
692*62c56f98SSadaf Ebrahimi        bufC[i] = ~((unsigned char) i);
693*62c56f98SSadaf Ebrahimi    }
694*62c56f98SSadaf Ebrahimi
695*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
696*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
697*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
698*62c56f98SSadaf Ebrahimi
699*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
700*62c56f98SSadaf Ebrahimi    /* Ask for more than what's available. */
701*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 80, &tmp, NULL) == 0);
702*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 80, bufA, 80);
703*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
704*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
705*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
706*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) ==
707*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
708*62c56f98SSadaf Ebrahimi
709*62c56f98SSadaf Ebrahimi    /* Preparation */
710*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
711*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB, sizeof(bufB)) == 0);
712*62c56f98SSadaf Ebrahimi
713*62c56f98SSadaf Ebrahimi    switch (option) {
714*62c56f98SSadaf Ebrahimi        case 0: /* Fetch same chunks, commit afterwards, and
715*62c56f98SSadaf Ebrahimi                 * then exceed bounds of new buffer; accumulator
716*62c56f98SSadaf Ebrahimi                 * large enough. */
717*62c56f98SSadaf Ebrahimi
718*62c56f98SSadaf Ebrahimi            /* Consume */
719*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, &tmp_len) == 0);
720*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, tmp_len, bufA + 80, 10);
721*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
722*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
723*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
724*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
725*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) ==
726*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
727*62c56f98SSadaf Ebrahimi
728*62c56f98SSadaf Ebrahimi            /* Prepare */
729*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
730*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufC, sizeof(bufC)) == 0);;
731*62c56f98SSadaf Ebrahimi
732*62c56f98SSadaf Ebrahimi            /* Consume */
733*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
734*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufB + 10, 10);
735*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufC, 10);
736*62c56f98SSadaf Ebrahimi            break;
737*62c56f98SSadaf Ebrahimi
738*62c56f98SSadaf Ebrahimi        case 1: /* Fetch same chunks, commit afterwards, and
739*62c56f98SSadaf Ebrahimi                 * then exceed bounds of new buffer; accumulator
740*62c56f98SSadaf Ebrahimi                 * not large enough. */
741*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
742*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
743*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
744*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
745*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
746*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
747*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 51, &tmp, NULL) ==
748*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
749*62c56f98SSadaf Ebrahimi
750*62c56f98SSadaf Ebrahimi            /* Prepare */
751*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
752*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL);
753*62c56f98SSadaf Ebrahimi            break;
754*62c56f98SSadaf Ebrahimi
755*62c56f98SSadaf Ebrahimi        case 2: /* Fetch same chunks, don't commit afterwards, and
756*62c56f98SSadaf Ebrahimi                 * then exceed bounds of new buffer; accumulator
757*62c56f98SSadaf Ebrahimi                 * large enough. */
758*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
759*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
760*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
761*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
762*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
763*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) ==
764*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
765*62c56f98SSadaf Ebrahimi
766*62c56f98SSadaf Ebrahimi            /* Prepare */
767*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
768*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufC, sizeof(bufC)) == 0);;
769*62c56f98SSadaf Ebrahimi
770*62c56f98SSadaf Ebrahimi            /* Consume */
771*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 50, &tmp, NULL) == 0);
772*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 20, bufA + 80, 20);
773*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 20, 20, bufB, 20);
774*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 40, 10, bufC, 10);
775*62c56f98SSadaf Ebrahimi            break;
776*62c56f98SSadaf Ebrahimi
777*62c56f98SSadaf Ebrahimi        case 3: /* Fetch same chunks, don't commit afterwards, and
778*62c56f98SSadaf Ebrahimi                 * then exceed bounds of new buffer; accumulator
779*62c56f98SSadaf Ebrahimi                 * not large enough. */
780*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
781*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 80, 10);
782*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) == 0);
783*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 10, bufA + 90, 10);
784*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 10, 10, bufB, 10);
785*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 21, &tmp, NULL) ==
786*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
787*62c56f98SSadaf Ebrahimi
788*62c56f98SSadaf Ebrahimi            /* Prepare */
789*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) ==
790*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL);
791*62c56f98SSadaf Ebrahimi            break;
792*62c56f98SSadaf Ebrahimi
793*62c56f98SSadaf Ebrahimi        default:
794*62c56f98SSadaf Ebrahimi            TEST_ASSERT(0);
795*62c56f98SSadaf Ebrahimi            break;
796*62c56f98SSadaf Ebrahimi    }
797*62c56f98SSadaf Ebrahimi
798*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
799*62c56f98SSadaf Ebrahimi}
800*62c56f98SSadaf Ebrahimi/* END_CASE */
801*62c56f98SSadaf Ebrahimi
802*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER:MBEDTLS_MPS_STATE_VALIDATION */
803*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_random_usage(int num_out_chunks,
804*62c56f98SSadaf Ebrahimi                                     int max_chunk_size,
805*62c56f98SSadaf Ebrahimi                                     int max_request,
806*62c56f98SSadaf Ebrahimi                                     int acc_size)
807*62c56f98SSadaf Ebrahimi
808*62c56f98SSadaf Ebrahimi{
809*62c56f98SSadaf Ebrahimi    /* Randomly pass a reader object back and forth between lower and
810*62c56f98SSadaf Ebrahimi     * upper layer and let each of them call the respective reader API
811*62c56f98SSadaf Ebrahimi     * functions in a random fashion.
812*62c56f98SSadaf Ebrahimi     *
813*62c56f98SSadaf Ebrahimi     * On the lower layer, we're tracking and concatenating
814*62c56f98SSadaf Ebrahimi     * the data passed to successful feed calls.
815*62c56f98SSadaf Ebrahimi     *
816*62c56f98SSadaf Ebrahimi     * For the upper layer, we track and concatenate buffers
817*62c56f98SSadaf Ebrahimi     * obtained from successful get calls.
818*62c56f98SSadaf Ebrahimi     *
819*62c56f98SSadaf Ebrahimi     * As long as the lower layer calls reclaim at least once, (resetting the
820*62c56f98SSadaf Ebrahimi     * fetched but not-yet-committed data), this should always lead to the same
821*62c56f98SSadaf Ebrahimi     * stream of outgoing/incoming data for the lower/upper layers, even if
822*62c56f98SSadaf Ebrahimi     * most of the random calls fail.
823*62c56f98SSadaf Ebrahimi     *
824*62c56f98SSadaf Ebrahimi     * NOTE: This test uses rand() for random data, which is not optimal.
825*62c56f98SSadaf Ebrahimi     *       Instead, it would be better to get the random data from a
826*62c56f98SSadaf Ebrahimi     *       static buffer. This both eases reproducibility and allows
827*62c56f98SSadaf Ebrahimi     *       simple conversion to a fuzz target.
828*62c56f98SSadaf Ebrahimi     */
829*62c56f98SSadaf Ebrahimi    int ret;
830*62c56f98SSadaf Ebrahimi    unsigned char *acc = NULL;
831*62c56f98SSadaf Ebrahimi    unsigned char *outgoing = NULL, *incoming = NULL;
832*62c56f98SSadaf Ebrahimi    unsigned char *cur_chunk = NULL;
833*62c56f98SSadaf Ebrahimi    size_t cur_out_chunk, out_pos, in_commit, in_fetch;
834*62c56f98SSadaf Ebrahimi    int rand_op;  /* Lower layer:
835*62c56f98SSadaf Ebrahimi                   * - Reclaim (0)
836*62c56f98SSadaf Ebrahimi                   * - Feed (1)
837*62c56f98SSadaf Ebrahimi                   * Upper layer:
838*62c56f98SSadaf Ebrahimi                   * - Get, do tolerate smaller output (0)
839*62c56f98SSadaf Ebrahimi                   * - Get, don't tolerate smaller output (1)
840*62c56f98SSadaf Ebrahimi                   * - Commit (2) */
841*62c56f98SSadaf Ebrahimi    int mode = 0; /* Lower layer (0) or Upper layer (1) */
842*62c56f98SSadaf Ebrahimi    int reclaimed = 1; /* Have to call reclaim at least once before
843*62c56f98SSadaf Ebrahimi                        * returning the reader to the upper layer. */
844*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
845*62c56f98SSadaf Ebrahimi
846*62c56f98SSadaf Ebrahimi    if (acc_size > 0) {
847*62c56f98SSadaf Ebrahimi        TEST_CALLOC(acc, acc_size);
848*62c56f98SSadaf Ebrahimi    }
849*62c56f98SSadaf Ebrahimi
850*62c56f98SSadaf Ebrahimi    /* This probably needs to be changed because we want
851*62c56f98SSadaf Ebrahimi     * our tests to be deterministic. */
852*62c56f98SSadaf Ebrahimi    //    srand( time( NULL ) );
853*62c56f98SSadaf Ebrahimi
854*62c56f98SSadaf Ebrahimi    TEST_CALLOC(outgoing, num_out_chunks * max_chunk_size);
855*62c56f98SSadaf Ebrahimi    TEST_CALLOC(incoming, num_out_chunks * max_chunk_size);
856*62c56f98SSadaf Ebrahimi
857*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, acc_size);
858*62c56f98SSadaf Ebrahimi
859*62c56f98SSadaf Ebrahimi    cur_out_chunk = 0;
860*62c56f98SSadaf Ebrahimi    in_commit = 0;
861*62c56f98SSadaf Ebrahimi    in_fetch = 0;
862*62c56f98SSadaf Ebrahimi    out_pos = 0;
863*62c56f98SSadaf Ebrahimi    while (cur_out_chunk < (unsigned) num_out_chunks) {
864*62c56f98SSadaf Ebrahimi        if (mode == 0) {
865*62c56f98SSadaf Ebrahimi            /* Choose randomly between reclaim and feed */
866*62c56f98SSadaf Ebrahimi            rand_op = rand() % 2;
867*62c56f98SSadaf Ebrahimi
868*62c56f98SSadaf Ebrahimi            if (rand_op == 0) {
869*62c56f98SSadaf Ebrahimi                /* Reclaim */
870*62c56f98SSadaf Ebrahimi                ret = mbedtls_mps_reader_reclaim(&rd, NULL);
871*62c56f98SSadaf Ebrahimi
872*62c56f98SSadaf Ebrahimi                if (ret == 0) {
873*62c56f98SSadaf Ebrahimi                    TEST_ASSERT(cur_chunk != NULL);
874*62c56f98SSadaf Ebrahimi                    mbedtls_free(cur_chunk);
875*62c56f98SSadaf Ebrahimi                    cur_chunk = NULL;
876*62c56f98SSadaf Ebrahimi                }
877*62c56f98SSadaf Ebrahimi                reclaimed = 1;
878*62c56f98SSadaf Ebrahimi            } else {
879*62c56f98SSadaf Ebrahimi                /* Feed reader with a random chunk */
880*62c56f98SSadaf Ebrahimi                unsigned char *tmp = NULL;
881*62c56f98SSadaf Ebrahimi                size_t tmp_size;
882*62c56f98SSadaf Ebrahimi                if (cur_out_chunk == (unsigned) num_out_chunks) {
883*62c56f98SSadaf Ebrahimi                    continue;
884*62c56f98SSadaf Ebrahimi                }
885*62c56f98SSadaf Ebrahimi
886*62c56f98SSadaf Ebrahimi                tmp_size = (rand() % max_chunk_size) + 1;
887*62c56f98SSadaf Ebrahimi                TEST_CALLOC(tmp, tmp_size);
888*62c56f98SSadaf Ebrahimi
889*62c56f98SSadaf Ebrahimi                TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL, tmp, tmp_size) == 0);
890*62c56f98SSadaf Ebrahimi                ret = mbedtls_mps_reader_feed(&rd, tmp, tmp_size);
891*62c56f98SSadaf Ebrahimi
892*62c56f98SSadaf Ebrahimi                if (ret == 0 || ret == MBEDTLS_ERR_MPS_READER_NEED_MORE) {
893*62c56f98SSadaf Ebrahimi                    cur_out_chunk++;
894*62c56f98SSadaf Ebrahimi                    memcpy(outgoing + out_pos, tmp, tmp_size);
895*62c56f98SSadaf Ebrahimi                    out_pos += tmp_size;
896*62c56f98SSadaf Ebrahimi                }
897*62c56f98SSadaf Ebrahimi
898*62c56f98SSadaf Ebrahimi                if (ret == 0) {
899*62c56f98SSadaf Ebrahimi                    TEST_ASSERT(cur_chunk == NULL);
900*62c56f98SSadaf Ebrahimi                    cur_chunk = tmp;
901*62c56f98SSadaf Ebrahimi                } else {
902*62c56f98SSadaf Ebrahimi                    mbedtls_free(tmp);
903*62c56f98SSadaf Ebrahimi                }
904*62c56f98SSadaf Ebrahimi
905*62c56f98SSadaf Ebrahimi            }
906*62c56f98SSadaf Ebrahimi
907*62c56f98SSadaf Ebrahimi            /* Randomly switch to consumption mode if reclaim
908*62c56f98SSadaf Ebrahimi             * was called at least once. */
909*62c56f98SSadaf Ebrahimi            if (reclaimed == 1 && rand() % 3 == 0) {
910*62c56f98SSadaf Ebrahimi                in_fetch = 0;
911*62c56f98SSadaf Ebrahimi                mode = 1;
912*62c56f98SSadaf Ebrahimi            }
913*62c56f98SSadaf Ebrahimi        } else {
914*62c56f98SSadaf Ebrahimi            /* Choose randomly between get tolerating fewer data,
915*62c56f98SSadaf Ebrahimi             * get not tolerating fewer data, and commit. */
916*62c56f98SSadaf Ebrahimi            rand_op = rand() % 3;
917*62c56f98SSadaf Ebrahimi            if (rand_op == 0 || rand_op == 1) {
918*62c56f98SSadaf Ebrahimi                mbedtls_mps_size_t get_size, real_size;
919*62c56f98SSadaf Ebrahimi                unsigned char *chunk_get;
920*62c56f98SSadaf Ebrahimi                get_size = (rand() % max_request) + 1;
921*62c56f98SSadaf Ebrahimi                if (rand_op == 0) {
922*62c56f98SSadaf Ebrahimi                    ret = mbedtls_mps_reader_get(&rd, get_size, &chunk_get,
923*62c56f98SSadaf Ebrahimi                                                 &real_size);
924*62c56f98SSadaf Ebrahimi                } else {
925*62c56f98SSadaf Ebrahimi                    real_size = get_size;
926*62c56f98SSadaf Ebrahimi                    ret = mbedtls_mps_reader_get(&rd, get_size, &chunk_get, NULL);
927*62c56f98SSadaf Ebrahimi                }
928*62c56f98SSadaf Ebrahimi
929*62c56f98SSadaf Ebrahimi                /* Check if output is in accordance with what was written */
930*62c56f98SSadaf Ebrahimi                if (ret == 0) {
931*62c56f98SSadaf Ebrahimi                    memcpy(incoming + in_commit + in_fetch,
932*62c56f98SSadaf Ebrahimi                           chunk_get, real_size);
933*62c56f98SSadaf Ebrahimi                    TEST_ASSERT(memcmp(incoming + in_commit + in_fetch,
934*62c56f98SSadaf Ebrahimi                                       outgoing + in_commit + in_fetch,
935*62c56f98SSadaf Ebrahimi                                       real_size) == 0);
936*62c56f98SSadaf Ebrahimi                    in_fetch += real_size;
937*62c56f98SSadaf Ebrahimi                }
938*62c56f98SSadaf Ebrahimi            } else if (rand_op == 2) { /* Commit */
939*62c56f98SSadaf Ebrahimi                ret = mbedtls_mps_reader_commit(&rd);
940*62c56f98SSadaf Ebrahimi                if (ret == 0) {
941*62c56f98SSadaf Ebrahimi                    in_commit += in_fetch;
942*62c56f98SSadaf Ebrahimi                    in_fetch = 0;
943*62c56f98SSadaf Ebrahimi                }
944*62c56f98SSadaf Ebrahimi            }
945*62c56f98SSadaf Ebrahimi
946*62c56f98SSadaf Ebrahimi            /* Randomly switch back to preparation */
947*62c56f98SSadaf Ebrahimi            if (rand() % 3 == 0) {
948*62c56f98SSadaf Ebrahimi                reclaimed = 0;
949*62c56f98SSadaf Ebrahimi                mode = 0;
950*62c56f98SSadaf Ebrahimi            }
951*62c56f98SSadaf Ebrahimi        }
952*62c56f98SSadaf Ebrahimi    }
953*62c56f98SSadaf Ebrahimi
954*62c56f98SSadaf Ebrahimi    /* Cleanup */
955*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
956*62c56f98SSadaf Ebrahimi    mbedtls_free(incoming);
957*62c56f98SSadaf Ebrahimi    mbedtls_free(outgoing);
958*62c56f98SSadaf Ebrahimi    mbedtls_free(acc);
959*62c56f98SSadaf Ebrahimi    mbedtls_free(cur_chunk);
960*62c56f98SSadaf Ebrahimi}
961*62c56f98SSadaf Ebrahimi/* END_CASE */
962*62c56f98SSadaf Ebrahimi
963*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
964*62c56f98SSadaf Ebrahimivoid mbedtls_reader_inconsistent_usage(int option)
965*62c56f98SSadaf Ebrahimi{
966*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the MPS reader
967*62c56f98SSadaf Ebrahimi     * in the following situation:
968*62c56f98SSadaf Ebrahimi     * - The consumer asks for more data than what's available
969*62c56f98SSadaf Ebrahimi     * - The reader is paused and receives more data from the
970*62c56f98SSadaf Ebrahimi     *   producer until the original read request can be fulfilled.
971*62c56f98SSadaf Ebrahimi     * - The consumer does not repeat the original request but
972*62c56f98SSadaf Ebrahimi     *   requests data in a different way.
973*62c56f98SSadaf Ebrahimi     *
974*62c56f98SSadaf Ebrahimi     * The reader does not guarantee that inconsistent read requests
975*62c56f98SSadaf Ebrahimi     * after pausing will succeed, and this test triggers some cases
976*62c56f98SSadaf Ebrahimi     * where the request fails.
977*62c56f98SSadaf Ebrahimi     */
978*62c56f98SSadaf Ebrahimi
979*62c56f98SSadaf Ebrahimi    unsigned char bufA[100], bufB[100];
980*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
981*62c56f98SSadaf Ebrahimi    unsigned char acc[40];
982*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
983*62c56f98SSadaf Ebrahimi    int success = 0;
984*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufA); i++) {
985*62c56f98SSadaf Ebrahimi        bufA[i] = (unsigned char) i;
986*62c56f98SSadaf Ebrahimi    }
987*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(bufB); i++) {
988*62c56f98SSadaf Ebrahimi        bufB[i] = ~((unsigned char) i);
989*62c56f98SSadaf Ebrahimi    }
990*62c56f98SSadaf Ebrahimi
991*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
992*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, acc, sizeof(acc));
993*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufA, sizeof(bufA)) == 0);
994*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
995*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 80, &tmp, NULL) == 0);
996*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
997*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) == 0);
998*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 20, &tmp, NULL) ==
999*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_OUT_OF_DATA);
1000*62c56f98SSadaf Ebrahimi    /* Preparation */
1001*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
1002*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, bufB, sizeof(bufB)) == 0);
1003*62c56f98SSadaf Ebrahimi    /* Consumption */
1004*62c56f98SSadaf Ebrahimi    switch (option) {
1005*62c56f98SSadaf Ebrahimi        case 0:
1006*62c56f98SSadaf Ebrahimi            /* Ask for buffered data in a single chunk, no commit */
1007*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 30, &tmp, NULL) == 0);
1008*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 20, bufA + 80, 20);
1009*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 20, 10, bufB, 10);
1010*62c56f98SSadaf Ebrahimi            success = 1;
1011*62c56f98SSadaf Ebrahimi            break;
1012*62c56f98SSadaf Ebrahimi
1013*62c56f98SSadaf Ebrahimi        case 1:
1014*62c56f98SSadaf Ebrahimi            /* Ask for buffered data in a single chunk, with commit */
1015*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 30, &tmp, NULL) == 0);
1016*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 20, bufA + 80, 20);
1017*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 20, 10, bufB, 10);
1018*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1019*62c56f98SSadaf Ebrahimi            success = 1;
1020*62c56f98SSadaf Ebrahimi            break;
1021*62c56f98SSadaf Ebrahimi
1022*62c56f98SSadaf Ebrahimi        case 2:
1023*62c56f98SSadaf Ebrahimi            /* Ask for more than was requested when pausing, #1 */
1024*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 31, &tmp, NULL) ==
1025*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS);
1026*62c56f98SSadaf Ebrahimi            break;
1027*62c56f98SSadaf Ebrahimi
1028*62c56f98SSadaf Ebrahimi        case 3:
1029*62c56f98SSadaf Ebrahimi            /* Ask for more than was requested when pausing #2 */
1030*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, (mbedtls_mps_size_t) -1, &tmp, NULL) ==
1031*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS);
1032*62c56f98SSadaf Ebrahimi            break;
1033*62c56f98SSadaf Ebrahimi
1034*62c56f98SSadaf Ebrahimi        case 4:
1035*62c56f98SSadaf Ebrahimi            /* Asking for buffered data in different
1036*62c56f98SSadaf Ebrahimi             * chunks than before CAN fail. */
1037*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1038*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 15, bufA + 80, 15);
1039*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 10, &tmp, NULL) ==
1040*62c56f98SSadaf Ebrahimi                        MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS);
1041*62c56f98SSadaf Ebrahimi            break;
1042*62c56f98SSadaf Ebrahimi
1043*62c56f98SSadaf Ebrahimi        case 5:
1044*62c56f98SSadaf Ebrahimi            /* Asking for buffered data different chunks
1045*62c56f98SSadaf Ebrahimi             * than before NEED NOT fail - no commits */
1046*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1047*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 15, bufA + 80, 15);
1048*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1049*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 5, bufA + 95, 5);
1050*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 5, 10, bufB, 10);
1051*62c56f98SSadaf Ebrahimi            success = 1;
1052*62c56f98SSadaf Ebrahimi            break;
1053*62c56f98SSadaf Ebrahimi
1054*62c56f98SSadaf Ebrahimi        case 6:
1055*62c56f98SSadaf Ebrahimi            /* Asking for buffered data different chunks
1056*62c56f98SSadaf Ebrahimi             * than before NEED NOT fail - intermediate commit */
1057*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1058*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 15, bufA + 80, 15);
1059*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1060*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1061*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 5, bufA + 95, 5);
1062*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 5, 10, bufB, 10);
1063*62c56f98SSadaf Ebrahimi            success = 1;
1064*62c56f98SSadaf Ebrahimi            break;
1065*62c56f98SSadaf Ebrahimi
1066*62c56f98SSadaf Ebrahimi        case 7:
1067*62c56f98SSadaf Ebrahimi            /* Asking for buffered data different chunks
1068*62c56f98SSadaf Ebrahimi             * than before NEED NOT fail - end commit */
1069*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1070*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 15, bufA + 80, 15);
1071*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1072*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 5, bufA + 95, 5);
1073*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 5, 10, bufB, 10);
1074*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1075*62c56f98SSadaf Ebrahimi            success = 1;
1076*62c56f98SSadaf Ebrahimi            break;
1077*62c56f98SSadaf Ebrahimi
1078*62c56f98SSadaf Ebrahimi        case 8:
1079*62c56f98SSadaf Ebrahimi            /* Asking for buffered data different chunks
1080*62c56f98SSadaf Ebrahimi             * than before NEED NOT fail - intermediate & end commit */
1081*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1082*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 15, bufA + 80, 15);
1083*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_get(&rd, 15, &tmp, NULL) == 0);
1084*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1085*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp, 5, bufA + 95, 5);
1086*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(tmp + 5, 10, bufB, 10);
1087*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1088*62c56f98SSadaf Ebrahimi            success = 1;
1089*62c56f98SSadaf Ebrahimi            break;
1090*62c56f98SSadaf Ebrahimi
1091*62c56f98SSadaf Ebrahimi        default:
1092*62c56f98SSadaf Ebrahimi            TEST_ASSERT(0);
1093*62c56f98SSadaf Ebrahimi            break;
1094*62c56f98SSadaf Ebrahimi    }
1095*62c56f98SSadaf Ebrahimi
1096*62c56f98SSadaf Ebrahimi    if (success == 1) {
1097*62c56f98SSadaf Ebrahimi        /* In all succeeding cases, fetch the rest of the second buffer. */
1098*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mps_reader_get(&rd, 90, &tmp, NULL) == 0);
1099*62c56f98SSadaf Ebrahimi        TEST_MEMORY_COMPARE(tmp, 90, bufB + 10, 90);
1100*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1101*62c56f98SSadaf Ebrahimi
1102*62c56f98SSadaf Ebrahimi        /* Wrapup */
1103*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
1104*62c56f98SSadaf Ebrahimi    }
1105*62c56f98SSadaf Ebrahimi
1106*62c56f98SSadaf Ebrahimi    /* Wrapup */
1107*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
1108*62c56f98SSadaf Ebrahimi}
1109*62c56f98SSadaf Ebrahimi/* END_CASE */
1110*62c56f98SSadaf Ebrahimi
1111*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */
1112*62c56f98SSadaf Ebrahimivoid mbedtls_mps_reader_feed_empty()
1113*62c56f98SSadaf Ebrahimi{
1114*62c56f98SSadaf Ebrahimi    /* This test exercises the behaviour of the reader when it is
1115*62c56f98SSadaf Ebrahimi     * fed with a NULL buffer. */
1116*62c56f98SSadaf Ebrahimi    unsigned char buf[100];
1117*62c56f98SSadaf Ebrahimi    unsigned char *tmp;
1118*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader rd;
1119*62c56f98SSadaf Ebrahimi    for (size_t i = 0; (unsigned) i < sizeof(buf); i++) {
1120*62c56f98SSadaf Ebrahimi        buf[i] = (unsigned char) i;
1121*62c56f98SSadaf Ebrahimi    }
1122*62c56f98SSadaf Ebrahimi
1123*62c56f98SSadaf Ebrahimi    /* Preparation (lower layer) */
1124*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_init(&rd, NULL, 0);
1125*62c56f98SSadaf Ebrahimi
1126*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, NULL, sizeof(buf)) ==
1127*62c56f98SSadaf Ebrahimi                MBEDTLS_ERR_MPS_READER_INVALID_ARG);
1128*62c56f98SSadaf Ebrahimi
1129*62c56f98SSadaf Ebrahimi    /* Subsequent feed-calls should still succeed. */
1130*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_feed(&rd, buf, sizeof(buf)) == 0);
1131*62c56f98SSadaf Ebrahimi
1132*62c56f98SSadaf Ebrahimi    /* Consumption (upper layer) */
1133*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_get(&rd, 100, &tmp, NULL) == 0);
1134*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(tmp, 100, buf, 100);
1135*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_commit(&rd) == 0);
1136*62c56f98SSadaf Ebrahimi
1137*62c56f98SSadaf Ebrahimi    /* Wrapup */
1138*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mps_reader_reclaim(&rd, NULL) == 0);
1139*62c56f98SSadaf Ebrahimi    mbedtls_mps_reader_free(&rd);
1140*62c56f98SSadaf Ebrahimi}
1141*62c56f98SSadaf Ebrahimi/* END_CASE */
1142