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