test_suite_mps.function 43 KB

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