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