test_suite_bignum_mod.function 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. /* BEGIN_HEADER */
  2. #include "mbedtls/bignum.h"
  3. #include "mbedtls/entropy.h"
  4. #include "bignum_mod.h"
  5. #include "bignum_mod_raw.h"
  6. #include "constant_time_internal.h"
  7. #include "test/constant_flow.h"
  8. #define TEST_COMPARE_MPI_RESIDUES(a, b) \
  9. ASSERT_COMPARE((a).p, (a).limbs * sizeof(mbedtls_mpi_uint), \
  10. (b).p, (b).limbs * sizeof(mbedtls_mpi_uint))
  11. static int test_read_modulus(mbedtls_mpi_mod_modulus *m,
  12. mbedtls_mpi_mod_rep_selector int_rep,
  13. char *input)
  14. {
  15. mbedtls_mpi_uint *p = NULL;
  16. size_t limbs;
  17. int ret = mbedtls_test_read_mpi_core(&p, &limbs, input);
  18. if (ret != 0) {
  19. return ret;
  20. }
  21. return mbedtls_mpi_mod_modulus_setup(m, p, limbs, int_rep);
  22. }
  23. static int test_read_residue(mbedtls_mpi_mod_residue *r,
  24. const mbedtls_mpi_mod_modulus *m,
  25. char *input,
  26. int skip_limbs_and_value_checks)
  27. {
  28. mbedtls_mpi_uint *p = NULL;
  29. size_t limbs;
  30. int ret = mbedtls_test_read_mpi_core(&p, &limbs, input);
  31. if (ret != 0) {
  32. return ret;
  33. }
  34. if (skip_limbs_and_value_checks) {
  35. r->p = p;
  36. r->limbs = limbs;
  37. return 0;
  38. }
  39. /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */
  40. return mbedtls_mpi_mod_residue_setup(r, m, p, limbs);
  41. }
  42. /* END_HEADER */
  43. /* BEGIN_DEPENDENCIES
  44. * depends_on:MBEDTLS_BIGNUM_C
  45. * END_DEPENDENCIES
  46. */
  47. /* BEGIN_CASE */
  48. void mpi_mod_setup(int int_rep, int iret)
  49. {
  50. #define MLIMBS 8
  51. mbedtls_mpi_uint mp[MLIMBS];
  52. mbedtls_mpi_mod_modulus m;
  53. int ret;
  54. memset(mp, 0xFF, sizeof(mp));
  55. mbedtls_mpi_mod_modulus_init(&m);
  56. ret = mbedtls_mpi_mod_modulus_setup(&m, mp, MLIMBS, int_rep);
  57. TEST_EQUAL(ret, iret);
  58. /* Only test if the constants have been set-up */
  59. if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
  60. /* Test that the consts have been calculated */
  61. TEST_ASSERT(m.rep.mont.rr != NULL);
  62. TEST_ASSERT(m.rep.mont.mm != 0);
  63. }
  64. /* Address sanitiser should catch if we try to free mp */
  65. mbedtls_mpi_mod_modulus_free(&m);
  66. /* Make sure that the modulus doesn't have reference to mp anymore */
  67. TEST_ASSERT(m.p != mp);
  68. /* Only test if the constants have been set-up */
  69. if (ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
  70. /* Verify the data and pointers allocated have been properly wiped */
  71. TEST_ASSERT(m.rep.mont.rr == NULL);
  72. TEST_ASSERT(m.rep.mont.mm == 0);
  73. }
  74. exit:
  75. /* It should be safe to call an mbedtls free several times */
  76. mbedtls_mpi_mod_modulus_free(&m);
  77. #undef MLIMBS
  78. }
  79. /* END_CASE */
  80. /* BEGIN MERGE SLOT 1 */
  81. /* END MERGE SLOT 1 */
  82. /* BEGIN MERGE SLOT 2 */
  83. /* BEGIN_CASE */
  84. void mpi_mod_mul(char *input_A,
  85. char *input_B,
  86. char *input_N,
  87. char *result)
  88. {
  89. mbedtls_mpi_uint *X = NULL;
  90. mbedtls_mpi_mod_residue rA = { NULL, 0 };
  91. mbedtls_mpi_mod_residue rB = { NULL, 0 };
  92. mbedtls_mpi_mod_residue rR = { NULL, 0 };
  93. mbedtls_mpi_mod_residue rX = { NULL, 0 };
  94. mbedtls_mpi_mod_modulus m;
  95. mbedtls_mpi_mod_modulus_init(&m);
  96. TEST_EQUAL(test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N),
  97. 0);
  98. TEST_EQUAL(test_read_residue(&rA, &m, input_A, 0), 0);
  99. TEST_EQUAL(test_read_residue(&rB, &m, input_B, 0), 0);
  100. TEST_EQUAL(test_read_residue(&rR, &m, result, 0), 0);
  101. const size_t limbs = m.limbs;
  102. const size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
  103. TEST_EQUAL(rA.limbs, limbs);
  104. TEST_EQUAL(rB.limbs, limbs);
  105. TEST_EQUAL(rR.limbs, limbs);
  106. ASSERT_ALLOC(X, limbs);
  107. TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0);
  108. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), 0);
  109. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  110. /* alias X to A */
  111. memcpy(rX.p, rA.p, bytes);
  112. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rB, &m), 0);
  113. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  114. /* alias X to B */
  115. memcpy(rX.p, rB.p, bytes);
  116. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rX, &m), 0);
  117. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  118. /* A == B: alias A and B */
  119. if (memcmp(rA.p, rB.p, bytes) == 0) {
  120. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA, &m), 0);
  121. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  122. /* X, A, B all aliased together */
  123. memcpy(rX.p, rA.p, bytes);
  124. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rX, &m), 0);
  125. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  126. }
  127. /* A != B: test B * A */
  128. else {
  129. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rA, &m), 0);
  130. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  131. /* B * A: alias X to A */
  132. memcpy(rX.p, rA.p, bytes);
  133. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rB, &rX, &m), 0);
  134. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  135. /* B + A: alias X to B */
  136. memcpy(rX.p, rB.p, bytes);
  137. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rX, &rA, &m), 0);
  138. ASSERT_COMPARE(rX.p, bytes, rR.p, bytes);
  139. }
  140. exit:
  141. mbedtls_free(rA.p);
  142. mbedtls_free(rB.p);
  143. mbedtls_free(rR.p);
  144. mbedtls_free(X);
  145. mbedtls_free((mbedtls_mpi_uint *) m.p);
  146. mbedtls_mpi_mod_modulus_free(&m);
  147. }
  148. /* END_CASE */
  149. /* BEGIN_CASE */
  150. void mpi_mod_mul_neg(char *input_A,
  151. char *input_B,
  152. char *input_N,
  153. char *result,
  154. int exp_ret)
  155. {
  156. mbedtls_mpi_uint *X = NULL;
  157. mbedtls_mpi_mod_residue rA = { NULL, 0 };
  158. mbedtls_mpi_mod_residue rB = { NULL, 0 };
  159. mbedtls_mpi_mod_residue rR = { NULL, 0 };
  160. mbedtls_mpi_mod_residue rX = { NULL, 0 };
  161. mbedtls_mpi_mod_modulus m;
  162. mbedtls_mpi_mod_modulus_init(&m);
  163. mbedtls_mpi_mod_modulus fake_m;
  164. mbedtls_mpi_mod_modulus_init(&fake_m);
  165. TEST_EQUAL(test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N),
  166. 0);
  167. TEST_EQUAL(test_read_residue(&rA, &m, input_A, 1), 0);
  168. TEST_EQUAL(test_read_residue(&rB, &m, input_B, 1), 0);
  169. TEST_EQUAL(test_read_residue(&rR, &m, result, 1), 0);
  170. const size_t limbs = m.limbs;
  171. ASSERT_ALLOC(X, limbs);
  172. TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rX, &m, X, limbs), 0);
  173. rX.limbs = rR.limbs;
  174. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &m), exp_ret);
  175. /* Check when m is not initialized */
  176. TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rB, &fake_m),
  177. MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
  178. exit:
  179. mbedtls_free(rA.p);
  180. mbedtls_free(rB.p);
  181. mbedtls_free(rR.p);
  182. mbedtls_free(X);
  183. mbedtls_free((mbedtls_mpi_uint *) m.p);
  184. mbedtls_mpi_mod_modulus_free(&m);
  185. mbedtls_mpi_mod_modulus_free(&fake_m);
  186. }
  187. /* END_CASE */
  188. /* END MERGE SLOT 2 */
  189. /* BEGIN MERGE SLOT 3 */
  190. /* BEGIN_CASE */
  191. void mpi_mod_sub(char *input_N,
  192. char *input_A, char *input_B,
  193. char *input_D, int expected_ret)
  194. {
  195. mbedtls_mpi_mod_residue a = { NULL, 0 };
  196. mbedtls_mpi_mod_residue b = { NULL, 0 };
  197. mbedtls_mpi_mod_residue d = { NULL, 0 };
  198. mbedtls_mpi_mod_residue x = { NULL, 0 };
  199. mbedtls_mpi_uint *X_raw = NULL;
  200. mbedtls_mpi_mod_modulus m;
  201. mbedtls_mpi_mod_modulus_init(&m);
  202. TEST_EQUAL(0,
  203. test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N));
  204. /* test_read_residue() normally checks that inputs have the same number of
  205. * limbs as the modulus. For negative testing we can ask it to skip this
  206. * with a non-zero final parameter. */
  207. TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0));
  208. TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0));
  209. TEST_EQUAL(0, test_read_residue(&d, &m, input_D, expected_ret != 0));
  210. size_t limbs = m.limbs;
  211. size_t bytes = limbs * sizeof(*X_raw);
  212. if (expected_ret == 0) {
  213. /* Negative test with too many limbs in output */
  214. ASSERT_ALLOC(X_raw, limbs + 1);
  215. x.p = X_raw;
  216. x.limbs = limbs + 1;
  217. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  218. mbedtls_mpi_mod_sub(&x, &a, &b, &m));
  219. mbedtls_free(X_raw);
  220. X_raw = NULL;
  221. /* Negative test with too few limbs in output */
  222. if (limbs > 1) {
  223. ASSERT_ALLOC(X_raw, limbs - 1);
  224. x.p = X_raw;
  225. x.limbs = limbs - 1;
  226. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  227. mbedtls_mpi_mod_sub(&x, &a, &b, &m));
  228. mbedtls_free(X_raw);
  229. X_raw = NULL;
  230. }
  231. /* Negative testing with too many/too few limbs in a and b is covered by
  232. * manually-written test cases with expected_ret != 0. */
  233. }
  234. ASSERT_ALLOC(X_raw, limbs);
  235. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs));
  236. /* a - b => Correct result, or expected error */
  237. TEST_EQUAL(expected_ret, mbedtls_mpi_mod_sub(&x, &a, &b, &m));
  238. if (expected_ret != 0) {
  239. goto exit;
  240. }
  241. TEST_COMPARE_MPI_RESIDUES(x, d);
  242. /* a - b: alias x to a => Correct result */
  243. memcpy(x.p, a.p, bytes);
  244. TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &b, &m));
  245. TEST_COMPARE_MPI_RESIDUES(x, d);
  246. /* a - b: alias x to b => Correct result */
  247. memcpy(x.p, b.p, bytes);
  248. TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &x, &m));
  249. TEST_COMPARE_MPI_RESIDUES(x, d);
  250. if (memcmp(a.p, b.p, bytes) == 0) {
  251. /* a == b: alias a and b */
  252. /* a - a => Correct result */
  253. TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &a, &a, &m));
  254. TEST_COMPARE_MPI_RESIDUES(x, d);
  255. /* a - a: x, a, b all aliased together => Correct result */
  256. memcpy(x.p, a.p, bytes);
  257. TEST_EQUAL(0, mbedtls_mpi_mod_sub(&x, &x, &x, &m));
  258. TEST_COMPARE_MPI_RESIDUES(x, d);
  259. }
  260. exit:
  261. mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
  262. mbedtls_mpi_mod_modulus_free(&m);
  263. mbedtls_free(a.p);
  264. mbedtls_free(b.p);
  265. mbedtls_free(d.p);
  266. mbedtls_free(X_raw);
  267. }
  268. /* END_CASE */
  269. /* BEGIN_CASE */
  270. void mpi_mod_inv_mont(char *input_N,
  271. char *input_A, char *input_I,
  272. int expected_ret)
  273. {
  274. mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
  275. mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
  276. mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
  277. mbedtls_mpi_uint *X_raw = NULL;
  278. mbedtls_mpi_mod_modulus N;
  279. mbedtls_mpi_mod_modulus_init(&N);
  280. TEST_EQUAL(0,
  281. test_read_modulus(&N, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N));
  282. /* test_read_residue() normally checks that inputs have the same number of
  283. * limbs as the modulus. For negative testing we can ask it to skip this
  284. * with a non-zero final parameter. */
  285. TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0));
  286. TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0));
  287. size_t limbs = N.limbs;
  288. size_t bytes = limbs * sizeof(*X_raw);
  289. ASSERT_ALLOC(X_raw, limbs);
  290. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs));
  291. TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N));
  292. if (expected_ret == 0) {
  293. TEST_COMPARE_MPI_RESIDUES(x, i);
  294. /* a^-1: alias x to a => Correct result */
  295. memcpy(x.p, a.p, bytes);
  296. TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N));
  297. TEST_COMPARE_MPI_RESIDUES(x, i);
  298. }
  299. exit:
  300. mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
  301. mbedtls_mpi_mod_modulus_free(&N);
  302. mbedtls_free(a.p);
  303. mbedtls_free(i.p);
  304. mbedtls_free(X_raw);
  305. }
  306. /* END_CASE */
  307. /* BEGIN_CASE */
  308. void mpi_mod_inv_non_mont(char *input_N,
  309. char *input_A, char *input_I,
  310. int expected_ret)
  311. {
  312. mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
  313. mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
  314. mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
  315. mbedtls_mpi_uint *X_raw = NULL;
  316. mbedtls_mpi_mod_modulus N;
  317. mbedtls_mpi_mod_modulus_init(&N);
  318. TEST_EQUAL(0,
  319. test_read_modulus(&N, MBEDTLS_MPI_MOD_REP_OPT_RED, input_N));
  320. /* test_read_residue() normally checks that inputs have the same number of
  321. * limbs as the modulus. For negative testing we can ask it to skip this
  322. * with a non-zero final parameter. */
  323. TEST_EQUAL(0, test_read_residue(&a, &N, input_A, expected_ret != 0));
  324. TEST_EQUAL(0, test_read_residue(&i, &N, input_I, expected_ret != 0));
  325. size_t limbs = N.limbs;
  326. size_t bytes = limbs * sizeof(*X_raw);
  327. ASSERT_ALLOC(X_raw, limbs);
  328. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &N, X_raw, limbs));
  329. TEST_EQUAL(expected_ret, mbedtls_mpi_mod_inv(&x, &a, &N));
  330. if (expected_ret == 0) {
  331. TEST_COMPARE_MPI_RESIDUES(x, i);
  332. /* a^-1: alias x to a => Correct result */
  333. memcpy(x.p, a.p, bytes);
  334. TEST_EQUAL(0, mbedtls_mpi_mod_inv(&x, &x, &N));
  335. TEST_COMPARE_MPI_RESIDUES(x, i);
  336. }
  337. exit:
  338. mbedtls_free((void *) N.p); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
  339. mbedtls_mpi_mod_modulus_free(&N);
  340. mbedtls_free(a.p);
  341. mbedtls_free(i.p);
  342. mbedtls_free(X_raw);
  343. }
  344. /* END_CASE */
  345. /* END MERGE SLOT 3 */
  346. /* BEGIN MERGE SLOT 4 */
  347. /* END MERGE SLOT 4 */
  348. /* BEGIN MERGE SLOT 5 */
  349. /* BEGIN_CASE */
  350. void mpi_mod_add(char *input_N,
  351. char *input_A, char *input_B,
  352. char *input_S, int expected_ret)
  353. {
  354. mbedtls_mpi_mod_residue a = { NULL, 0 };
  355. mbedtls_mpi_mod_residue b = { NULL, 0 };
  356. mbedtls_mpi_mod_residue s = { NULL, 0 };
  357. mbedtls_mpi_mod_residue x = { NULL, 0 };
  358. mbedtls_mpi_uint *X_raw = NULL;
  359. mbedtls_mpi_mod_modulus m;
  360. mbedtls_mpi_mod_modulus_init(&m);
  361. TEST_EQUAL(0,
  362. test_read_modulus(&m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N));
  363. /* test_read_residue() normally checks that inputs have the same number of
  364. * limbs as the modulus. For negative testing we can ask it to skip this
  365. * with a non-zero final parameter. */
  366. TEST_EQUAL(0, test_read_residue(&a, &m, input_A, expected_ret != 0));
  367. TEST_EQUAL(0, test_read_residue(&b, &m, input_B, expected_ret != 0));
  368. TEST_EQUAL(0, test_read_residue(&s, &m, input_S, expected_ret != 0));
  369. size_t limbs = m.limbs;
  370. size_t bytes = limbs * sizeof(*X_raw);
  371. if (expected_ret == 0) {
  372. /* Negative test with too many limbs in output */
  373. ASSERT_ALLOC(X_raw, limbs + 1);
  374. x.p = X_raw;
  375. x.limbs = limbs + 1;
  376. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  377. mbedtls_mpi_mod_add(&x, &a, &b, &m));
  378. mbedtls_free(X_raw);
  379. X_raw = NULL;
  380. /* Negative test with too few limbs in output */
  381. if (limbs > 1) {
  382. ASSERT_ALLOC(X_raw, limbs - 1);
  383. x.p = X_raw;
  384. x.limbs = limbs - 1;
  385. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  386. mbedtls_mpi_mod_add(&x, &a, &b, &m));
  387. mbedtls_free(X_raw);
  388. X_raw = NULL;
  389. }
  390. /* Negative testing with too many/too few limbs in a and b is covered by
  391. * manually-written test cases with oret != 0. */
  392. }
  393. /* Allocate correct number of limbs for X_raw */
  394. ASSERT_ALLOC(X_raw, limbs);
  395. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&x, &m, X_raw, limbs));
  396. /* A + B => Correct result or expected error */
  397. TEST_EQUAL(expected_ret, mbedtls_mpi_mod_add(&x, &a, &b, &m));
  398. if (expected_ret != 0) {
  399. goto exit;
  400. }
  401. TEST_COMPARE_MPI_RESIDUES(x, s);
  402. /* a + b: alias x to a => Correct result */
  403. memcpy(x.p, a.p, bytes);
  404. TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &b, &m));
  405. TEST_COMPARE_MPI_RESIDUES(x, s);
  406. /* a + b: alias x to b => Correct result */
  407. memcpy(x.p, b.p, bytes);
  408. TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &x, &m));
  409. TEST_COMPARE_MPI_RESIDUES(x, s);
  410. if (memcmp(a.p, b.p, bytes) == 0) {
  411. /* a == b: alias a and b */
  412. /* a + a => Correct result */
  413. TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &a, &a, &m));
  414. TEST_COMPARE_MPI_RESIDUES(x, s);
  415. /* a + a: x, a, b all aliased together => Correct result */
  416. memcpy(x.p, a.p, bytes);
  417. TEST_EQUAL(0, mbedtls_mpi_mod_add(&x, &x, &x, &m));
  418. TEST_COMPARE_MPI_RESIDUES(x, s);
  419. }
  420. exit:
  421. mbedtls_free((void *) m.p); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
  422. mbedtls_mpi_mod_modulus_free(&m);
  423. mbedtls_free(a.p);
  424. mbedtls_free(b.p);
  425. mbedtls_free(s.p);
  426. mbedtls_free(X_raw);
  427. }
  428. /* END_CASE */
  429. /* END MERGE SLOT 5 */
  430. /* BEGIN MERGE SLOT 6 */
  431. /* END MERGE SLOT 6 */
  432. /* BEGIN MERGE SLOT 7 */
  433. /* BEGIN_CASE */
  434. void mpi_residue_setup(char *input_N, char *input_R, int ret)
  435. {
  436. mbedtls_mpi_uint *N = NULL;
  437. mbedtls_mpi_uint *R = NULL;
  438. size_t n_limbs, r_limbs;
  439. mbedtls_mpi_mod_modulus m;
  440. mbedtls_mpi_mod_residue r;
  441. mbedtls_mpi_mod_modulus_init(&m);
  442. /* Allocate the memory for intermediate data structures */
  443. TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
  444. TEST_EQUAL(0, mbedtls_test_read_mpi_core(&R, &r_limbs, input_R));
  445. TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs,
  446. MBEDTLS_MPI_MOD_REP_MONTGOMERY));
  447. TEST_EQUAL(ret, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs));
  448. if (ret == 0) {
  449. TEST_EQUAL(r.limbs, r_limbs);
  450. TEST_ASSERT(r.p == R);
  451. }
  452. exit:
  453. mbedtls_mpi_mod_modulus_free(&m);
  454. mbedtls_free(N);
  455. mbedtls_free(R);
  456. }
  457. /* END_CASE */
  458. /* BEGIN_CASE */
  459. void mpi_mod_io_neg(char *input_N, data_t *buf, int ret)
  460. {
  461. mbedtls_mpi_uint *N = NULL;
  462. mbedtls_mpi_uint *R = NULL;
  463. mbedtls_mpi_mod_modulus m;
  464. mbedtls_mpi_mod_residue r = { NULL, 0 };
  465. mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
  466. mbedtls_mpi_mod_modulus_init(&m);
  467. size_t n_limbs;
  468. TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
  469. size_t r_limbs = n_limbs;
  470. ASSERT_ALLOC(R, r_limbs);
  471. /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */
  472. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  473. mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
  474. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  475. mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
  476. /* Set up modulus and test with residue->p == NULL */
  477. TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs,
  478. MBEDTLS_MPI_MOD_REP_MONTGOMERY));
  479. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  480. mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
  481. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  482. mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
  483. /* Do the rest of the tests with a residue set up with the input data */
  484. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, r_limbs));
  485. /* Fail for r_limbs < m->limbs */
  486. r.limbs--;
  487. TEST_ASSERT(r.limbs < m.limbs);
  488. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  489. mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
  490. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  491. mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
  492. r.limbs++;
  493. /* Fail for r_limbs > m->limbs */
  494. m.limbs--;
  495. TEST_ASSERT(r.limbs > m.limbs);
  496. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  497. mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
  498. TEST_EQUAL(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
  499. mbedtls_mpi_mod_write(&r, &m, buf->x, buf->len, endian));
  500. m.limbs++;
  501. /* Test the read */
  502. TEST_EQUAL(ret, mbedtls_mpi_mod_read(&r, &m, buf->x, buf->len, endian));
  503. /* Test write overflow only when the representation is large and read is successful */
  504. if (r.limbs > 1 && ret == 0) {
  505. TEST_EQUAL(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL,
  506. mbedtls_mpi_mod_write(&r, &m, buf->x, 1, endian));
  507. }
  508. exit:
  509. mbedtls_mpi_mod_residue_release(&r);
  510. mbedtls_mpi_mod_modulus_free(&m);
  511. mbedtls_free(N);
  512. mbedtls_free(R);
  513. }
  514. /* END_CASE */
  515. /* BEGIN_CASE */
  516. void mpi_mod_io(char *input_N, data_t *input_A, int endian)
  517. {
  518. mbedtls_mpi_uint *N = NULL;
  519. mbedtls_mpi_uint *R = NULL;
  520. mbedtls_mpi_uint *R_COPY = NULL;
  521. unsigned char *obuf = NULL;
  522. unsigned char *ref_buf = NULL;
  523. mbedtls_mpi_mod_modulus m;
  524. mbedtls_mpi_mod_residue r;
  525. mbedtls_mpi_mod_residue r_copy;
  526. size_t n_limbs, n_bytes, a_bytes;
  527. mbedtls_mpi_mod_modulus_init(&m);
  528. /* Read inputs */
  529. TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
  530. n_bytes = n_limbs * sizeof(mbedtls_mpi_uint);
  531. a_bytes = input_A->len;
  532. /* Allocate the memory for intermediate data structures */
  533. ASSERT_ALLOC(R, n_bytes);
  534. ASSERT_ALLOC(R_COPY, n_bytes);
  535. /* Test that input's size is not greater to modulo's */
  536. TEST_LE_U(a_bytes, n_bytes);
  537. /* Init Structures */
  538. TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs,
  539. MBEDTLS_MPI_MOD_REP_MONTGOMERY));
  540. /* Enforcing p_limbs >= m->limbs */
  541. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r, &m, R, n_limbs));
  542. TEST_EQUAL(0, mbedtls_mpi_mod_read(&r, &m, input_A->x, input_A->len,
  543. endian));
  544. /* Read a copy for checking that writing didn't change the value of r */
  545. TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&r_copy, &m,
  546. R_COPY, n_limbs));
  547. TEST_EQUAL(0, mbedtls_mpi_mod_read(&r_copy, &m, input_A->x, input_A->len,
  548. endian));
  549. /* Get number of bytes without leading zeroes */
  550. size_t a_bytes_trimmed = a_bytes;
  551. while (a_bytes_trimmed > 0) {
  552. unsigned char *r_byte_array = (unsigned char *) r.p;
  553. if (r_byte_array[--a_bytes_trimmed] != 0) {
  554. break;
  555. }
  556. }
  557. a_bytes_trimmed++;
  558. /* Test write with three output buffer sizes: tight, same as input and
  559. * longer than the input */
  560. size_t obuf_sizes[3];
  561. const size_t obuf_sizes_len = sizeof(obuf_sizes) / sizeof(obuf_sizes[0]);
  562. obuf_sizes[0] = a_bytes_trimmed;
  563. obuf_sizes[1] = a_bytes;
  564. obuf_sizes[2] = a_bytes + 8;
  565. for (size_t i = 0; i < obuf_sizes_len; i++) {
  566. ASSERT_ALLOC(obuf, obuf_sizes[i]);
  567. TEST_EQUAL(0, mbedtls_mpi_mod_write(&r, &m, obuf, obuf_sizes[i], endian));
  568. /* Make sure that writing didn't corrupt the value of r */
  569. ASSERT_COMPARE(r.p, r.limbs, r_copy.p, r_copy.limbs);
  570. /* Set up reference output for checking the result */
  571. ASSERT_ALLOC(ref_buf, obuf_sizes[i]);
  572. switch (endian) {
  573. case MBEDTLS_MPI_MOD_EXT_REP_LE:
  574. memcpy(ref_buf, input_A->x, a_bytes_trimmed);
  575. break;
  576. case MBEDTLS_MPI_MOD_EXT_REP_BE:
  577. {
  578. size_t a_offset = input_A->len - a_bytes_trimmed;
  579. size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed;
  580. memcpy(ref_buf + ref_offset, input_A->x + a_offset,
  581. a_bytes_trimmed);
  582. }
  583. break;
  584. default:
  585. TEST_ASSERT(0);
  586. }
  587. /* Check the result */
  588. ASSERT_COMPARE(obuf, obuf_sizes[i], ref_buf, obuf_sizes[i]);
  589. mbedtls_free(ref_buf);
  590. ref_buf = NULL;
  591. mbedtls_free(obuf);
  592. obuf = NULL;
  593. }
  594. exit:
  595. mbedtls_mpi_mod_modulus_free(&m);
  596. mbedtls_free(N);
  597. mbedtls_free(R);
  598. mbedtls_free(R_COPY);
  599. mbedtls_free(obuf);
  600. }
  601. /* END_CASE */
  602. /* END MERGE SLOT 7 */
  603. /* BEGIN MERGE SLOT 8 */
  604. /* END MERGE SLOT 8 */
  605. /* BEGIN MERGE SLOT 9 */
  606. /* END MERGE SLOT 9 */
  607. /* BEGIN MERGE SLOT 10 */
  608. /* END MERGE SLOT 10 */