2022-07-18 23:02:33 +02:00
|
|
|
/**
|
2022-08-19 13:09:17 +02:00
|
|
|
* Modular bignum functions
|
2022-07-18 23:02:33 +02:00
|
|
|
*
|
|
|
|
* Copyright The Mbed TLS Contributors
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
|
|
* not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_BIGNUM_C)
|
|
|
|
|
2022-07-18 23:09:45 +02:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "mbedtls/platform_util.h"
|
2022-07-18 23:02:33 +02:00
|
|
|
#include "mbedtls/error.h"
|
|
|
|
#include "mbedtls/bignum.h"
|
|
|
|
|
2022-07-19 14:42:07 +02:00
|
|
|
#include "mbedtls/platform.h"
|
|
|
|
|
2022-08-09 14:44:53 +02:00
|
|
|
#include "bignum_core.h"
|
|
|
|
#include "bignum_mod.h"
|
|
|
|
#include "bignum_mod_raw.h"
|
|
|
|
#include "constant_time_internal.h"
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
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)
|
2022-07-18 23:02:33 +02:00
|
|
|
{
|
2023-01-11 15:19:00 +01:00
|
|
|
if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) {
|
2023-01-11 14:50:10 +01:00
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
}
|
2022-07-18 23:02:33 +02:00
|
|
|
|
2023-01-11 15:19:00 +01:00
|
|
|
r->limbs = N->limbs;
|
2022-07-25 12:31:02 +02:00
|
|
|
r->p = p;
|
2022-07-18 23:02:33 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
return 0;
|
2022-07-18 23:02:33 +02:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r)
|
2022-08-02 17:22:18 +02:00
|
|
|
{
|
2023-01-11 14:50:10 +01:00
|
|
|
if (r == NULL) {
|
2022-08-02 17:22:18 +02:00
|
|
|
return;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-08-02 17:22:18 +02:00
|
|
|
|
2022-08-12 18:09:12 +02:00
|
|
|
r->limbs = 0;
|
2022-08-02 17:22:18 +02:00
|
|
|
r->p = NULL;
|
|
|
|
}
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N)
|
2022-07-18 23:02:33 +02:00
|
|
|
{
|
2023-01-11 15:25:14 +01:00
|
|
|
if (N == NULL) {
|
2022-07-18 23:02:33 +02:00
|
|
|
return;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-07-18 23:02:33 +02:00
|
|
|
|
2023-01-11 15:25:14 +01:00
|
|
|
N->p = NULL;
|
|
|
|
N->limbs = 0;
|
|
|
|
N->bits = 0;
|
|
|
|
N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
2022-07-18 23:02:33 +02:00
|
|
|
}
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N)
|
2022-07-18 23:02:33 +02:00
|
|
|
{
|
2023-01-11 15:38:34 +01:00
|
|
|
if (N == NULL) {
|
2022-07-18 23:02:33 +02:00
|
|
|
return;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-07-18 23:02:33 +02:00
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
switch (N->int_rep) {
|
2022-07-19 14:42:07 +02:00
|
|
|
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
2023-01-11 16:42:46 +01:00
|
|
|
if (N->rep.mont.rr != NULL) {
|
|
|
|
mbedtls_platform_zeroize((mbedtls_mpi_uint *) N->rep.mont.rr,
|
|
|
|
N->limbs * sizeof(mbedtls_mpi_uint));
|
|
|
|
mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr);
|
2023-01-11 15:38:34 +01:00
|
|
|
N->rep.mont.rr = NULL;
|
2022-10-27 16:58:02 +02:00
|
|
|
}
|
2023-01-11 15:38:34 +01:00
|
|
|
N->rep.mont.mm = 0;
|
2022-10-27 13:22:22 +02:00
|
|
|
break;
|
2022-07-19 14:42:07 +02:00
|
|
|
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
2023-01-11 16:42:46 +01:00
|
|
|
mbedtls_free(N->rep.ored);
|
2022-08-11 15:58:29 +02:00
|
|
|
break;
|
|
|
|
case MBEDTLS_MPI_MOD_REP_INVALID:
|
2022-07-19 14:42:07 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-01-11 15:38:34 +01:00
|
|
|
N->p = NULL;
|
|
|
|
N->limbs = 0;
|
|
|
|
N->bits = 0;
|
|
|
|
N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
|
2022-07-18 23:02:33 +02:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
static int set_mont_const_square(const mbedtls_mpi_uint **X,
|
|
|
|
const mbedtls_mpi_uint *A,
|
|
|
|
size_t limbs)
|
2022-10-11 12:28:24 +02:00
|
|
|
{
|
|
|
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
|
|
mbedtls_mpi N;
|
|
|
|
mbedtls_mpi RR;
|
2022-10-27 16:58:02 +02:00
|
|
|
*X = NULL;
|
2022-10-11 12:28:24 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_init(&N);
|
|
|
|
mbedtls_mpi_init(&RR);
|
2022-10-11 12:28:24 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) {
|
2022-10-11 12:28:24 +02:00
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-10-11 12:28:24 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
if (mbedtls_mpi_grow(&N, limbs)) {
|
2022-10-11 12:28:24 +02:00
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-10-11 12:28:24 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs);
|
2022-10-27 13:22:22 +02:00
|
|
|
|
2022-10-27 16:58:02 +02:00
|
|
|
ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N);
|
2022-10-11 12:28:24 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
if (ret == 0) {
|
2022-10-27 16:58:02 +02:00
|
|
|
*X = RR.p;
|
|
|
|
RR.p = NULL;
|
|
|
|
}
|
2022-10-11 12:28:24 +02:00
|
|
|
|
|
|
|
cleanup:
|
|
|
|
mbedtls_mpi_free(&N);
|
|
|
|
mbedtls_mpi_free(&RR);
|
2023-01-11 14:50:10 +01:00
|
|
|
ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0;
|
|
|
|
return ret;
|
2022-10-11 12:28:24 +02:00
|
|
|
}
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,
|
|
|
|
const mbedtls_mpi_uint *p,
|
|
|
|
size_t p_limbs,
|
|
|
|
mbedtls_mpi_mod_rep_selector int_rep)
|
2022-07-18 23:02:33 +02:00
|
|
|
{
|
2022-07-19 14:42:07 +02:00
|
|
|
int ret = 0;
|
|
|
|
|
2023-01-11 15:33:21 +01:00
|
|
|
N->p = p;
|
|
|
|
N->limbs = p_limbs;
|
2023-01-11 16:42:46 +01:00
|
|
|
N->bits = mbedtls_mpi_core_bitlen(p, p_limbs);
|
2022-07-18 23:02:33 +02:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
switch (int_rep) {
|
2022-07-19 14:42:07 +02:00
|
|
|
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
2023-01-11 15:33:21 +01:00
|
|
|
N->int_rep = int_rep;
|
2023-01-11 16:42:46 +01:00
|
|
|
N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p);
|
|
|
|
ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs);
|
2022-10-11 12:28:24 +02:00
|
|
|
break;
|
2022-07-19 14:42:07 +02:00
|
|
|
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
2023-01-11 15:33:21 +01:00
|
|
|
N->int_rep = int_rep;
|
|
|
|
N->rep.ored = NULL;
|
2022-08-11 15:58:29 +02:00
|
|
|
break;
|
2022-07-19 14:42:07 +02:00
|
|
|
default:
|
|
|
|
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
if (ret != 0) {
|
|
|
|
mbedtls_mpi_mod_modulus_free(N);
|
2022-07-19 14:42:07 +02:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
return ret;
|
2022-07-18 23:02:33 +02:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
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)
|
2022-12-13 10:51:37 +01:00
|
|
|
{
|
2023-01-11 14:50:10 +01:00
|
|
|
if (N->limbs == 0) {
|
2022-12-13 10:51:37 +01:00
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-12-13 10:51:37 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
2022-12-13 10:51:37 +01:00
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-12-13 10:51:37 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL);
|
|
|
|
if (T == NULL) {
|
2022-12-13 10:51:37 +01:00
|
|
|
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-12-13 10:51:37 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T);
|
2022-12-13 10:51:37 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_free(T);
|
2022-12-13 10:51:37 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
return 0;
|
2022-12-13 10:51:37 +01:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
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)
|
2022-12-01 15:27:37 +01:00
|
|
|
{
|
2023-01-11 14:50:10 +01:00
|
|
|
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
}
|
2022-12-01 15:27:37 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N);
|
2022-11-02 15:35:17 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
return 0;
|
2022-12-01 15:27:37 +01:00
|
|
|
}
|
2022-12-13 11:46:39 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
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)
|
2022-12-13 12:57:57 +01:00
|
|
|
{
|
|
|
|
/* Input already in Montgomery form, so there's little to do */
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_raw_inv_prime(X->p, A->p,
|
|
|
|
N->p, N->limbs,
|
|
|
|
N->rep.mont.rr,
|
|
|
|
working_memory);
|
|
|
|
return 0;
|
2022-12-13 12:57:57 +01:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
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)
|
2022-12-13 12:57:57 +01:00
|
|
|
{
|
|
|
|
/* Need to convert input into Montgomery form */
|
|
|
|
|
|
|
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
|
|
|
|
|
|
mbedtls_mpi_mod_modulus Nmont;
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_modulus_init(&Nmont);
|
2022-12-13 12:57:57 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs,
|
|
|
|
MBEDTLS_MPI_MOD_REP_MONTGOMERY));
|
2022-12-13 12:57:57 +01:00
|
|
|
|
|
|
|
/* We'll use X->p to hold the Montgomery form of the input A->p */
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs,
|
|
|
|
Nmont.rep.mont.mm, Nmont.rep.mont.rr,
|
|
|
|
working_memory);
|
2022-12-13 12:57:57 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_raw_inv_prime(X->p, X->p,
|
|
|
|
Nmont.p, Nmont.limbs,
|
|
|
|
Nmont.rep.mont.rr,
|
|
|
|
working_memory);
|
2022-12-13 12:57:57 +01:00
|
|
|
|
|
|
|
/* And convert back from Montgomery form */
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs,
|
|
|
|
Nmont.rep.mont.mm, working_memory);
|
2022-12-13 12:57:57 +01:00
|
|
|
|
|
|
|
cleanup:
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_modulus_free(&Nmont);
|
|
|
|
return ret;
|
2022-12-13 12:57:57 +01:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,
|
|
|
|
const mbedtls_mpi_mod_residue *A,
|
|
|
|
const mbedtls_mpi_mod_modulus *N)
|
2022-12-13 11:46:39 +01:00
|
|
|
{
|
2023-01-11 14:50:10 +01:00
|
|
|
if (X->limbs != N->limbs || A->limbs != N->limbs) {
|
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
}
|
2022-12-13 11:46:39 +01:00
|
|
|
|
|
|
|
/* Zero has the same value regardless of Montgomery form or not */
|
2023-01-11 14:50:10 +01:00
|
|
|
if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) {
|
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
}
|
2022-12-13 11:46:39 +01:00
|
|
|
|
|
|
|
size_t working_limbs =
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs);
|
2022-12-13 11:46:39 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs,
|
|
|
|
sizeof(mbedtls_mpi_uint));
|
|
|
|
if (working_memory == NULL) {
|
|
|
|
return MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
|
|
|
}
|
2022-12-13 11:46:39 +01:00
|
|
|
|
2022-12-13 12:57:57 +01:00
|
|
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
2022-12-13 11:46:39 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
switch (N->int_rep) {
|
2022-12-13 12:57:57 +01:00
|
|
|
case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
|
2023-01-11 14:50:10 +01:00
|
|
|
ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory);
|
2022-12-13 12:57:57 +01:00
|
|
|
break;
|
|
|
|
case MBEDTLS_MPI_MOD_REP_OPT_RED:
|
2023-01-11 14:50:10 +01:00
|
|
|
ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory);
|
2022-12-13 12:57:57 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
break;
|
2022-12-13 11:46:39 +01:00
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
mbedtls_platform_zeroize(working_memory,
|
|
|
|
working_limbs * sizeof(mbedtls_mpi_uint));
|
|
|
|
mbedtls_free(working_memory);
|
2022-12-13 11:46:39 +01:00
|
|
|
|
2022-12-13 12:57:57 +01:00
|
|
|
return ret;
|
2022-12-13 11:46:39 +01:00
|
|
|
}
|
2022-11-02 15:35:17 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
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)
|
2022-11-29 13:25:05 +01:00
|
|
|
{
|
2023-01-11 14:50:10 +01:00
|
|
|
if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) {
|
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
}
|
2022-11-29 13:25:05 +01:00
|
|
|
|
|
|
|
mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N);
|
2022-11-02 15:35:17 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
return 0;
|
2022-11-29 13:25:05 +01:00
|
|
|
}
|
2022-11-02 15:35:17 +01:00
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
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)
|
2022-12-07 22:59:27 +01:00
|
|
|
{
|
2023-01-11 14:50:10 +01:00
|
|
|
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);
|
2022-12-07 22:59:27 +01:00
|
|
|
}
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
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)
|
2022-11-10 15:40:38 +01:00
|
|
|
{
|
|
|
|
int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
|
|
|
|
2022-11-26 15:28:50 +01:00
|
|
|
/* Do our best to check if r and m have been set up */
|
2023-01-11 16:02:59 +01:00
|
|
|
if (r->limbs == 0 || N->limbs == 0) {
|
2022-11-26 15:28:50 +01:00
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2023-01-11 16:02:59 +01:00
|
|
|
if (r->limbs != N->limbs) {
|
2022-11-10 15:40:38 +01:00
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-11-10 15:40:38 +01:00
|
|
|
|
2023-01-11 16:02:59 +01:00
|
|
|
ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep);
|
2023-01-11 14:50:10 +01:00
|
|
|
if (ret != 0) {
|
2022-11-10 15:40:38 +01:00
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-11-10 15:40:38 +01:00
|
|
|
|
2023-01-11 16:02:59 +01:00
|
|
|
r->limbs = N->limbs;
|
2022-11-24 12:04:11 +01:00
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N);
|
2022-11-10 15:40:38 +01:00
|
|
|
|
|
|
|
cleanup:
|
2023-01-11 14:50:10 +01:00
|
|
|
return ret;
|
2022-11-10 15:40:38 +01:00
|
|
|
}
|
|
|
|
|
2023-01-11 16:42:46 +01:00
|
|
|
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)
|
2022-11-10 15:40:38 +01:00
|
|
|
{
|
2022-11-26 15:28:50 +01:00
|
|
|
/* Do our best to check if r and m have been set up */
|
2023-01-11 16:16:18 +01:00
|
|
|
if (r->limbs == 0 || N->limbs == 0) {
|
2023-03-27 15:49:24 +02:00
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2023-01-11 16:16:18 +01:00
|
|
|
if (r->limbs != N->limbs) {
|
2023-03-27 15:49:24 +02:00
|
|
|
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-11-10 15:40:38 +01:00
|
|
|
|
2023-03-27 15:49:24 +02:00
|
|
|
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;
|
|
|
|
|
2023-01-11 16:16:18 +01:00
|
|
|
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
|
2023-03-27 15:49:24 +02:00
|
|
|
|
|
|
|
working_memory = mbedtls_calloc(r->limbs, sizeof(mbedtls_mpi_uint));
|
|
|
|
|
|
|
|
if (working_memory == NULL) {
|
|
|
|
ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
|
2022-11-26 16:39:02 +01:00
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-11-10 15:40:38 +01:00
|
|
|
|
2023-03-27 15:49:24 +02:00
|
|
|
memcpy(working_memory, r->p, working_memory_len);
|
2022-11-10 15:40:38 +01:00
|
|
|
|
2023-03-27 15:49:24 +02:00
|
|
|
ret = mbedtls_mpi_mod_raw_from_mont_rep(working_memory, N);
|
|
|
|
if (ret != 0) {
|
|
|
|
goto cleanup;
|
2023-01-11 14:50:10 +01:00
|
|
|
}
|
2022-11-28 11:27:14 +01:00
|
|
|
}
|
2022-11-26 16:39:02 +01:00
|
|
|
|
2023-03-27 15:49:24 +02:00
|
|
|
ret = mbedtls_mpi_mod_raw_write(working_memory, N, buf, buflen, ext_rep);
|
|
|
|
|
2022-11-10 15:40:38 +01:00
|
|
|
cleanup:
|
2022-11-26 16:39:02 +01:00
|
|
|
|
2023-03-27 15:49:24 +02:00
|
|
|
if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY &&
|
|
|
|
working_memory != NULL) {
|
|
|
|
|
|
|
|
mbedtls_platform_zeroize(working_memory, working_memory_len);
|
|
|
|
mbedtls_free(working_memory);
|
|
|
|
}
|
|
|
|
|
2023-01-11 14:50:10 +01:00
|
|
|
return ret;
|
2022-11-10 15:40:38 +01:00
|
|
|
}
|
2022-11-02 15:35:17 +01:00
|
|
|
|
2022-07-18 23:02:33 +02:00
|
|
|
#endif /* MBEDTLS_BIGNUM_C */
|