bignum_mod.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /**
  2. * Modular bignum functions
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. #include "common.h"
  20. #if defined(MBEDTLS_BIGNUM_C)
  21. #include <string.h>
  22. #include "mbedtls/platform_util.h"
  23. #include "mbedtls/error.h"
  24. #include "mbedtls/bignum.h"
  25. #include "mbedtls/platform.h"
  26. #include "bignum_core.h"
  27. #include "bignum_mod.h"
  28. #include "bignum_mod_raw.h"
  29. #include "constant_time_internal.h"
  30. int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
  31. const mbedtls_mpi_mod_modulus *N,
  32. mbedtls_mpi_uint *p,
  33. size_t p_limbs)
  34. {
  35. if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
  36. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  37. }
  38. r->limbs = N->limbs;
  39. r->p = p;
  40. return 0;
  41. }
  42. void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r)
  43. {
  44. if (r == NULL) {
  45. return;
  46. }
  47. r->limbs = 0;
  48. r->p = NULL;
  49. }
  50. void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
  51. {
  52. if (N == NULL) {
  53. return;
  54. }
  55. N->p = NULL;
  56. N->limbs = 0;
  57. N->bits = 0;
  58. N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
  59. }
  60. void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
  61. {
  62. if (N == NULL) {
  63. return;
  64. }
  65. switch (N->int_rep) {
  66. case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
  67. if (N->rep.mont.rr != NULL) {
  68. mbedtls_platform_zeroize((mbedtls_mpi_uint *) N->rep.mont.rr,
  69. N->limbs * sizeof(mbedtls_mpi_uint));
  70. mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr);
  71. N->rep.mont.rr = NULL;
  72. }
  73. N->rep.mont.mm = 0;
  74. break;
  75. case MBEDTLS_MPI_MOD_REP_OPT_RED:
  76. mbedtls_free(N->rep.ored);
  77. break;
  78. case MBEDTLS_MPI_MOD_REP_INVALID:
  79. break;
  80. }
  81. N->p = NULL;
  82. N->limbs = 0;
  83. N->bits = 0;
  84. N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
  85. }
  86. static int set_mont_const_square(const mbedtls_mpi_uint **X,
  87. const mbedtls_mpi_uint *A,
  88. size_t limbs)
  89. {
  90. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  91. mbedtls_mpi N;
  92. mbedtls_mpi RR;
  93. *X = NULL;
  94. mbedtls_mpi_init(&N);
  95. mbedtls_mpi_init(&RR);
  96. if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) {
  97. goto cleanup;
  98. }
  99. if (mbedtls_mpi_grow(&N, limbs)) {
  100. goto cleanup;
  101. }
  102. memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs);
  103. ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
  104. if (ret == 0) {
  105. *X = RR.p;
  106. RR.p = NULL;
  107. }
  108. cleanup:
  109. mbedtls_mpi_free(&N);
  110. mbedtls_mpi_free(&RR);
  111. ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0;
  112. return ret;
  113. }
  114. int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
  115. const mbedtls_mpi_uint *p,
  116. size_t p_limbs,
  117. mbedtls_mpi_mod_rep_selector int_rep)
  118. {
  119. int ret = 0;
  120. N->p = p;
  121. N->limbs = p_limbs;
  122. N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
  123. switch (int_rep) {
  124. case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
  125. N->int_rep = int_rep;
  126. N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
  127. ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
  128. break;
  129. case MBEDTLS_MPI_MOD_REP_OPT_RED:
  130. N->int_rep = int_rep;
  131. N->rep.ored = NULL;
  132. break;
  133. default:
  134. ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  135. goto exit;
  136. }
  137. exit:
  138. if (ret != 0) {
  139. mbedtls_mpi_mod_modulus_free(N);
  140. }
  141. return ret;
  142. }
  143. /* BEGIN MERGE SLOT 1 */
  144. /* END MERGE SLOT 1 */
  145. /* BEGIN MERGE SLOT 2 */
  146. int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X,
  147. const mbedtls_mpi_mod_residue *A,
  148. const mbedtls_mpi_mod_residue *B,
  149. const mbedtls_mpi_mod_modulus *N)
  150. {
  151. if (N->limbs == 0) {
  152. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  153. }
  154. if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
  155. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  156. }
  157. mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL);
  158. if (T == NULL) {
  159. return MBEDTLS_ERR_MPI_ALLOC_FAILED;
  160. }
  161. mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T);
  162. mbedtls_free(T);
  163. return 0;
  164. }
  165. /* END MERGE SLOT 2 */
  166. /* BEGIN MERGE SLOT 3 */
  167. int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X,
  168. const mbedtls_mpi_mod_residue *A,
  169. const mbedtls_mpi_mod_residue *B,
  170. const mbedtls_mpi_mod_modulus *N)
  171. {
  172. if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
  173. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  174. }
  175. mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N);
  176. return 0;
  177. }
  178. static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X,
  179. const mbedtls_mpi_mod_residue *A,
  180. const mbedtls_mpi_mod_modulus *N,
  181. mbedtls_mpi_uint *working_memory)
  182. {
  183. /* Input already in Montgomery form, so there's little to do */
  184. mbedtls_mpi_mod_raw_inv_prime(X->p, A->p,
  185. N->p, N->limbs,
  186. N->rep.mont.rr,
  187. working_memory);
  188. return 0;
  189. }
  190. static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X,
  191. const mbedtls_mpi_mod_residue *A,
  192. const mbedtls_mpi_mod_modulus *N,
  193. mbedtls_mpi_uint *working_memory)
  194. {
  195. /* Need to convert input into Montgomery form */
  196. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  197. mbedtls_mpi_mod_modulus Nmont;
  198. mbedtls_mpi_mod_modulus_init(&Nmont);
  199. MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs,
  200. MBEDTLS_MPI_MOD_REP_MONTGOMERY));
  201. /* We'll use X->p to hold the Montgomery form of the input A->p */
  202. mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs,
  203. Nmont.rep.mont.mm, Nmont.rep.mont.rr,
  204. working_memory);
  205. mbedtls_mpi_mod_raw_inv_prime(X->p, X->p,
  206. Nmont.p, Nmont.limbs,
  207. Nmont.rep.mont.rr,
  208. working_memory);
  209. /* And convert back from Montgomery form */
  210. mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs,
  211. Nmont.rep.mont.mm, working_memory);
  212. cleanup:
  213. mbedtls_mpi_mod_modulus_free(&Nmont);
  214. return ret;
  215. }
  216. int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
  217. const mbedtls_mpi_mod_residue *A,
  218. const mbedtls_mpi_mod_modulus *N)
  219. {
  220. if (X->limbs != N->limbs || A->limbs != N->limbs) {
  221. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  222. }
  223. /* Zero has the same value regardless of Montgomery form or not */
  224. if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) {
  225. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  226. }
  227. size_t working_limbs =
  228. mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs);
  229. mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs,
  230. sizeof(mbedtls_mpi_uint));
  231. if (working_memory == NULL) {
  232. return MBEDTLS_ERR_MPI_ALLOC_FAILED;
  233. }
  234. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  235. switch (N->int_rep) {
  236. case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
  237. ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory);
  238. break;
  239. case MBEDTLS_MPI_MOD_REP_OPT_RED:
  240. ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory);
  241. break;
  242. default:
  243. ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  244. break;
  245. }
  246. mbedtls_platform_zeroize(working_memory,
  247. working_limbs * sizeof(mbedtls_mpi_uint));
  248. mbedtls_free(working_memory);
  249. return ret;
  250. }
  251. /* END MERGE SLOT 3 */
  252. /* BEGIN MERGE SLOT 4 */
  253. /* END MERGE SLOT 4 */
  254. /* BEGIN MERGE SLOT 5 */
  255. int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X,
  256. const mbedtls_mpi_mod_residue *A,
  257. const mbedtls_mpi_mod_residue *B,
  258. const mbedtls_mpi_mod_modulus *N)
  259. {
  260. if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
  261. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  262. }
  263. mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N);
  264. return 0;
  265. }
  266. /* END MERGE SLOT 5 */
  267. /* BEGIN MERGE SLOT 6 */
  268. int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X,
  269. mbedtls_mpi_uint min,
  270. const mbedtls_mpi_mod_modulus *N,
  271. int (*f_rng)(void *, unsigned char *, size_t),
  272. void *p_rng)
  273. {
  274. if (X->limbs != N->limbs) {
  275. return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  276. }
  277. return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng);
  278. }
  279. /* END MERGE SLOT 6 */
  280. /* BEGIN MERGE SLOT 7 */
  281. int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
  282. const mbedtls_mpi_mod_modulus *N,
  283. const unsigned char *buf,
  284. size_t buflen,
  285. mbedtls_mpi_mod_ext_rep ext_rep)
  286. {
  287. int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  288. /* Do our best to check if r and m have been set up */
  289. if (r->limbs == 0 || N->limbs == 0) {
  290. goto cleanup;
  291. }
  292. if (r->limbs != N->limbs) {
  293. goto cleanup;
  294. }
  295. ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
  296. if (ret != 0) {
  297. goto cleanup;
  298. }
  299. r->limbs = N->limbs;
  300. ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
  301. cleanup:
  302. return ret;
  303. }
  304. int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
  305. const mbedtls_mpi_mod_modulus *N,
  306. unsigned char *buf,
  307. size_t buflen,
  308. mbedtls_mpi_mod_ext_rep ext_rep)
  309. {
  310. int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
  311. /* Do our best to check if r and m have been set up */
  312. if (r->limbs == 0 || N->limbs == 0) {
  313. goto cleanup;
  314. }
  315. if (r->limbs != N->limbs) {
  316. goto cleanup;
  317. }
  318. if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
  319. ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, N);
  320. if (ret != 0) {
  321. goto cleanup;
  322. }
  323. }
  324. ret = mbedtls_mpi_mod_raw_write(r->p, N, buf, buflen, ext_rep);
  325. if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
  326. /* If this fails, the value of r is corrupted and we want to return
  327. * this error (as opposed to the error code from the write above) to
  328. * let the caller know. If it succeeds, we want to return the error
  329. * code from write above. */
  330. int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, N);
  331. if (ret == 0) {
  332. ret = conv_ret;
  333. }
  334. }
  335. cleanup:
  336. return ret;
  337. }
  338. /* END MERGE SLOT 7 */
  339. /* BEGIN MERGE SLOT 8 */
  340. /* END MERGE SLOT 8 */
  341. /* BEGIN MERGE SLOT 9 */
  342. /* END MERGE SLOT 9 */
  343. /* BEGIN MERGE SLOT 10 */
  344. /* END MERGE SLOT 10 */
  345. #endif /* MBEDTLS_BIGNUM_C */