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 */ 28void 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 69exit: 70 mbedtls_mps_reader_free(&rd); 71} 72/* END_CASE */ 73 74/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 75void 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 125exit: 126 mbedtls_mps_reader_free(&rd); 127} 128/* END_CASE */ 129 130/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 131void 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 178exit: 179 mbedtls_mps_reader_free(&rd); 180} 181/* END_CASE */ 182 183/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 184void 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 227exit: 228 mbedtls_mps_reader_free(&rd); 229} 230/* END_CASE */ 231 232/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 233void 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 262exit: 263 mbedtls_mps_reader_free(&rd); 264} 265/* END_CASE */ 266 267/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 268void 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 310exit: 311 mbedtls_mps_reader_free(&rd); 312} 313/* END_CASE */ 314 315/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 316void 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 347exit: 348 mbedtls_mps_reader_free(&rd); 349} 350/* END_CASE */ 351 352/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 353void 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 474exit: 475 mbedtls_mps_reader_free(&rd); 476} 477/* END_CASE */ 478 479/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 480void 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 580exit: 581 mbedtls_mps_reader_free(&rd); 582} 583/* END_CASE */ 584 585 586/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 587void 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 643exit: 644 mbedtls_mps_reader_free(&rd); 645} 646/* END_CASE */ 647 648/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 649void 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 */ 685void 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 816exit: 817 mbedtls_mps_reader_free(&rd); 818} 819/* END_CASE */ 820 821/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER:MBEDTLS_MPS_STATE_VALIDATION */ 822void 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 973exit: 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 */ 984void 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 1126exit: 1127 /* Wrapup */ 1128 mbedtls_mps_reader_free(&rd); 1129} 1130/* END_CASE */ 1131 1132/* BEGIN_CASE depends_on:TEST_SUITE_MPS_READER */ 1133void 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 1161exit: 1162 mbedtls_mps_reader_free(&rd); 1163} 1164/* END_CASE */ 1165