summaryrefslogtreecommitdiffstats
path: root/thirdparty/mbedtls/library/bignum_mod.c
diff options
context:
space:
mode:
authorLyuma <xn.lyuma@gmail.com>2023-09-24 20:04:06 -0700
committerFabio Alessandrelli <fabio.alessandrelli@gmail.com>2024-04-10 21:19:22 +0200
commit40fa684c181d3138d8f86c70e5933fb0b3dcbac8 (patch)
tree4d104dfb95341e96ac2d98f9a9e3a85c5b7e55ca /thirdparty/mbedtls/library/bignum_mod.c
parent6c579280630715ff7da8310d405ef34194847294 (diff)
downloadredot-engine-40fa684c181d3138d8f86c70e5933fb0b3dcbac8.tar.gz
mbedTLS: Update to new LTS v3.6.0
Keep module compatibility with mbedtls 2.x (old LTS branch). A patch has been added to allow compiling after removing all the `psa_*` files from the library folder (will look into upstreaming it). Note: mbedTLS 3.6 finally enabled TLSv1.3 by default, but it requires some module changes, and to enable PSA crypto (new "standard" API specification), so it might be best done in a separate commit/PR.
Diffstat (limited to 'thirdparty/mbedtls/library/bignum_mod.c')
-rw-r--r--thirdparty/mbedtls/library/bignum_mod.c394
1 files changed, 394 insertions, 0 deletions
diff --git a/thirdparty/mbedtls/library/bignum_mod.c b/thirdparty/mbedtls/library/bignum_mod.c
new file mode 100644
index 0000000000..dfd332a703
--- /dev/null
+++ b/thirdparty/mbedtls/library/bignum_mod.c
@@ -0,0 +1,394 @@
+/**
+ * Modular bignum functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
+
+#include <string.h>
+
+#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/bignum.h"
+
+#include "mbedtls/platform.h"
+
+#include "bignum_core.h"
+#include "bignum_mod.h"
+#include "bignum_mod_raw.h"
+#include "constant_time_internal.h"
+
+int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,
+ const mbedtls_mpi_mod_modulus *N,
+ mbedtls_mpi_uint *p,
+ size_t p_limbs)
+{
+ if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ r->limbs = N->limbs;
+ r->p = p;
+
+ return 0;
+}
+
+void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r)
+{
+ if (r == NULL) {
+ return;
+ }
+
+ r->limbs = 0;
+ r->p = NULL;
+}
+
+void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
+{
+ if (N == NULL) {
+ return;
+ }
+
+ N->p = NULL;
+ N->limbs = 0;
+ N->bits = 0;
+ N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+}
+
+void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
+{
+ if (N == NULL) {
+ return;
+ }
+
+ switch (N->int_rep) {
+ case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
+ if (N->rep.mont.rr != NULL) {
+ mbedtls_zeroize_and_free((mbedtls_mpi_uint *) N->rep.mont.rr,
+ N->limbs * sizeof(mbedtls_mpi_uint));
+ N->rep.mont.rr = NULL;
+ }
+ N->rep.mont.mm = 0;
+ break;
+ case MBEDTLS_MPI_MOD_REP_OPT_RED:
+ N->rep.ored.modp = NULL;
+ break;
+ case MBEDTLS_MPI_MOD_REP_INVALID:
+ break;
+ }
+
+ N->p = NULL;
+ N->limbs = 0;
+ N->bits = 0;
+ N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+}
+
+static int set_mont_const_square(const mbedtls_mpi_uint **X,
+ const mbedtls_mpi_uint *A,
+ size_t limbs)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi N;
+ mbedtls_mpi RR;
+ *X = NULL;
+
+ mbedtls_mpi_init(&N);
+ mbedtls_mpi_init(&RR);
+
+ if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) {
+ goto cleanup;
+ }
+
+ if (mbedtls_mpi_grow(&N, limbs)) {
+ goto cleanup;
+ }
+
+ memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs);
+
+ ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
+
+ if (ret == 0) {
+ *X = RR.p;
+ RR.p = NULL;
+ }
+
+cleanup:
+ mbedtls_mpi_free(&N);
+ mbedtls_mpi_free(&RR);
+ ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0;
+ return ret;
+}
+
+static inline void standard_modulus_setup(mbedtls_mpi_mod_modulus *N,
+ const mbedtls_mpi_uint *p,
+ size_t p_limbs,
+ mbedtls_mpi_mod_rep_selector int_rep)
+{
+ N->p = p;
+ N->limbs = p_limbs;
+ N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
+ N->int_rep = int_rep;
+}
+
+int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
+ const mbedtls_mpi_uint *p,
+ size_t p_limbs)
+{
+ int ret = 0;
+ standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_MONTGOMERY);
+ N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
+ ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
+
+ if (ret != 0) {
+ mbedtls_mpi_mod_modulus_free(N);
+ }
+
+ return ret;
+}
+
+int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N,
+ const mbedtls_mpi_uint *p,
+ size_t p_limbs,
+ mbedtls_mpi_modp_fn modp)
+{
+ standard_modulus_setup(N, p, p_limbs, MBEDTLS_MPI_MOD_REP_OPT_RED);
+ N->rep.ored.modp = modp;
+ return 0;
+}
+
+int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_residue *B,
+ const mbedtls_mpi_mod_modulus *N)
+{
+ if (N->limbs == 0) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL);
+ if (T == NULL) {
+ return MBEDTLS_ERR_MPI_ALLOC_FAILED;
+ }
+
+ mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T);
+
+ mbedtls_free(T);
+
+ return 0;
+}
+
+int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_residue *B,
+ const mbedtls_mpi_mod_modulus *N)
+{
+ if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N);
+
+ return 0;
+}
+
+static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_modulus *N,
+ mbedtls_mpi_uint *working_memory)
+{
+ /* Input already in Montgomery form, so there's little to do */
+ mbedtls_mpi_mod_raw_inv_prime(X->p, A->p,
+ N->p, N->limbs,
+ N->rep.mont.rr,
+ working_memory);
+ return 0;
+}
+
+static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_modulus *N,
+ mbedtls_mpi_uint *working_memory)
+{
+ /* Need to convert input into Montgomery form */
+
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ mbedtls_mpi_mod_modulus Nmont;
+ mbedtls_mpi_mod_modulus_init(&Nmont);
+
+ MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs));
+
+ /* We'll use X->p to hold the Montgomery form of the input A->p */
+ mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs,
+ Nmont.rep.mont.mm, Nmont.rep.mont.rr,
+ working_memory);
+
+ mbedtls_mpi_mod_raw_inv_prime(X->p, X->p,
+ Nmont.p, Nmont.limbs,
+ Nmont.rep.mont.rr,
+ working_memory);
+
+ /* And convert back from Montgomery form */
+
+ mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs,
+ Nmont.rep.mont.mm, working_memory);
+
+cleanup:
+ mbedtls_mpi_mod_modulus_free(&Nmont);
+ return ret;
+}
+
+int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_modulus *N)
+{
+ if (X->limbs != N->limbs || A->limbs != N->limbs) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ /* Zero has the same value regardless of Montgomery form or not */
+ if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ size_t working_limbs =
+ mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs);
+
+ mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs,
+ sizeof(mbedtls_mpi_uint));
+ if (working_memory == NULL) {
+ return MBEDTLS_ERR_MPI_ALLOC_FAILED;
+ }
+
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ switch (N->int_rep) {
+ case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
+ ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory);
+ break;
+ case MBEDTLS_MPI_MOD_REP_OPT_RED:
+ ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory);
+ break;
+ default:
+ ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ break;
+ }
+
+ mbedtls_zeroize_and_free(working_memory,
+ working_limbs * sizeof(mbedtls_mpi_uint));
+
+ return ret;
+}
+
+int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X,
+ const mbedtls_mpi_mod_residue *A,
+ const mbedtls_mpi_mod_residue *B,
+ const mbedtls_mpi_mod_modulus *N)
+{
+ if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N);
+
+ return 0;
+}
+
+int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X,
+ mbedtls_mpi_uint min,
+ const mbedtls_mpi_mod_modulus *N,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng)
+{
+ if (X->limbs != N->limbs) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+ return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng);
+}
+
+int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,
+ const mbedtls_mpi_mod_modulus *N,
+ const unsigned char *buf,
+ size_t buflen,
+ mbedtls_mpi_mod_ext_rep ext_rep)
+{
+ int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+ /* Do our best to check if r and m have been set up */
+ if (r->limbs == 0 || N->limbs == 0) {
+ goto cleanup;
+ }
+ if (r->limbs != N->limbs) {
+ goto cleanup;
+ }
+
+ ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
+ if (ret != 0) {
+ goto cleanup;
+ }
+
+ r->limbs = N->limbs;
+
+ ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
+
+cleanup:
+ return ret;
+}
+
+int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,
+ const mbedtls_mpi_mod_modulus *N,
+ unsigned char *buf,
+ size_t buflen,
+ mbedtls_mpi_mod_ext_rep ext_rep)
+{
+ /* Do our best to check if r and m have been set up */
+ if (r->limbs == 0 || N->limbs == 0) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+ if (r->limbs != N->limbs) {
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ }
+
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi_uint *working_memory = r->p;
+ size_t working_memory_len = sizeof(mbedtls_mpi_uint) * r->limbs;
+
+ if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
+
+ working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint));
+
+ if (working_memory == NULL) {
+ ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+ goto cleanup;
+ }
+
+ memcpy(working_memory, r->p, working_memory_len);
+
+ ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N);
+ if (ret != 0) {
+ goto cleanup;
+ }
+ }
+
+ ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep);
+
+cleanup:
+
+ if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
+ working_memory != NULL) {
+
+ mbedtls_zeroize_and_free(working_memory, working_memory_len);
+ }
+
+ return ret;
+}
+
+#endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */