test_suite_mps.function 44 KB

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