quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

test_suite_mps.function (44515B)


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