Move the quasi reduction fixing function to bignum_mod_raw

Rename the function to 'fix_quasi_reduction' to better suite its functionality.
Also changed the name prefix to suite for the new module.

Signed-off-by: Gabor Mezei <gabor.mezei@arm.com>
This commit is contained in:
Gabor Mezei 2023-01-23 16:13:43 +01:00
parent 7e14c66c4d
commit aaa1d2a276
No known key found for this signature in database
GPG Key ID: F072ACA227ACD71D
14 changed files with 149 additions and 296 deletions

View File

@ -128,6 +128,21 @@ void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X,
N->rep.mont.mm, T);
}
MBEDTLS_STATIC_TESTABLE
int mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *N)
{
if (N->limbs == 0) {
return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
}
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
return 0;
}
/* END MERGE SLOT 2 */
/* BEGIN MERGE SLOT 3 */

View File

@ -1,8 +1,8 @@
/**
* \file ecp_internal.h
* \file bignum_mod_raw_invasive.h
*
* \brief Function declarations for internal functions of elliptic curve
* point arithmetic.
* \brief Function declarations for invasive functions of Low-level
* modular bignum.
*/
/**
* Copyright The Mbed TLS Contributors
@ -21,8 +21,8 @@
* limitations under the License.
*/
#ifndef MBEDTLS_ECP_INTERNAL_H
#define MBEDTLS_ECP_INTERNAL_H
#ifndef MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H
#define MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H
#include "common.h"
#include "mbedtls/bignum.h"
@ -40,7 +40,8 @@
* \return \c 0 if successful.
* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p N is invalid.
*/
int mbedtls_ecp_quasi_reduction(mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *N);
MBEDTLS_STATIC_TESTABLE
int mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *N);
#endif /* MBEDTLS_ECP_INTERNAL_H */
#endif /* MBEDTLS_BIGNUM_MOD_RAW_INVASIVE_H */

View File

@ -79,7 +79,6 @@
#include "bn_mul.h"
#include "ecp_invasive.h"
#include "ecp_internal.h"
#include "bignum_core.h"
#include <string.h>
@ -1031,20 +1030,6 @@ cleanup:
return ret;
}
int mbedtls_ecp_quasi_reduction(mbedtls_mpi_uint *X,
const mbedtls_mpi_mod_modulus *N)
{
if (N->limbs == 0) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
(void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
return 0;
}
/*
* Fast mod-p functions expect their argument to be in the 0..p^2 range.
*

View File

@ -51,6 +51,33 @@ class BignumModRawSub(bignum_common.ModOperationCommon,
result = (self.int_a - self.int_b) % self.int_n
return [self.format_result(result)]
class BignumModRawFixQuasiReduction(bignum_common.ModOperationCommon,
BignumModRawTarget):
"""Test cases for ecp quasi_reduction()."""
symbol = "-"
test_function = "mpi_mod_raw_fix_quasi_reduction"
test_name = "mbedtls_mpi_mod_raw_fix_quasi_reduction"
input_style = "fixed"
arity = 1
# Extend the default values with n < x < 2n
input_values = bignum_common.ModOperationCommon.input_values + [
"73",
"ebeddd7b4fefae8755bbfb9c181a73347096b3ec70d1a021",
("1f4e1d074d0b50e8d8818f9a9e5df9959f902bb955fd24fd3d791175226ad8c1"
"fcb6d59fa41a3dcb25412009e5e356eb65b50ca67782285290420b45b32f0d63"
"7c9ee549a52ad8d631ba4945435c9aec77227ec59faff878b71b920a3d631929"
"d636c9a409d6ffdcd95e2568e128596811fb9ade15e69f6efd509381ebbf3599")
] # type: List[str]
def result(self) -> List[str]:
result = self.int_a % self.int_n
return [self.format_result(result)]
@property
def is_valid(self) -> bool:
return bool(self.int_a < 2 * self.int_n)
class BignumModRawMul(bignum_common.ModOperationCommon,
BignumModRawTarget):
"""Test cases for bignum mpi_mod_raw_mul()."""

View File

@ -1,52 +0,0 @@
"""Framework classes for generation of ecp test cases."""
# 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.
from typing import List
from . import test_data_generation
from . import ecp_common
class EcpTarget(test_data_generation.BaseTarget):
#pylint: disable=abstract-method, too-few-public-methods
"""Target for ecp test case generation."""
target_basename = 'test_suite_ecp.generated'
class EcpQuasiReduction(ecp_common.EcpOperationCommon,
EcpTarget):
"""Test cases for ecp quasi_reduction()."""
symbol = "-"
test_function = "ecp_quasi_reduction"
test_name = "mbedtls_ecp_quasi_reduction"
input_style = "fixed"
arity = 1
# Extend the default values with n < x < 2n
input_values = ecp_common.EcpOperationCommon.input_values + [
"73",
"ebeddd7b4fefae8755bbfb9c181a73347096b3ec70d1a021",
("1f4e1d074d0b50e8d8818f9a9e5df9959f902bb955fd24fd3d791175226ad8c1"
"fcb6d59fa41a3dcb25412009e5e356eb65b50ca67782285290420b45b32f0d63"
"7c9ee549a52ad8d631ba4945435c9aec77227ec59faff878b71b920a3d631929"
"d636c9a409d6ffdcd95e2568e128596811fb9ade15e69f6efd509381ebbf3599")
] # type: List[str]
def result(self) -> List[str]:
result = self.int_a % self.int_n
return [self.format_result(result)]
@property
def is_valid(self) -> bool:
return bool(self.int_a < 2 * self.int_n)

View File

@ -1,22 +0,0 @@
"""Common features for ecp in test generation framework."""
# 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.
from . import bignum_common
class EcpOperationCommon(bignum_common.ModOperationCommon):
#pylint: disable=abstract-method
"""Target for ecp test case generation."""
pass

View File

@ -29,18 +29,6 @@ execute_process(
string(REGEX REPLACE "[^;]*/" ""
base_bignum_generated_data_files "${base_bignum_generated_data_files}")
execute_process(
COMMAND
${MBEDTLS_PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_ecp_tests.py
--list-for-cmake
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}/..
OUTPUT_VARIABLE
base_ecp_generated_data_files)
string(REGEX REPLACE "[^;]*/" ""
base_ecp_generated_data_files "${base_ecp_generated_data_files}")
execute_process(
COMMAND
${MBEDTLS_PYTHON_EXECUTABLE}
@ -64,9 +52,6 @@ set(psa_generated_data_files "")
foreach(file ${base_bignum_generated_data_files})
list(APPEND bignum_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
foreach(file ${base_ecp_generated_data_files})
list(APPEND ecp_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
foreach(file ${base_psa_generated_data_files})
list(APPEND psa_generated_data_files ${CMAKE_CURRENT_BINARY_DIR}/suites/${file})
endforeach()
@ -87,7 +72,6 @@ if(GEN_FILES)
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_core.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_mod_raw.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_mod.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/ecp.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_case.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_data_generation.py
)

View File

@ -73,13 +73,6 @@ GENERATED_BIGNUM_DATA_FILES := $(patsubst tests/%,%,$(shell \
ifeq ($(GENERATED_BIGNUM_DATA_FILES),FAILED)
$(error "$(PYTHON) scripts/generate_bignum_tests.py --list" failed)
endif
GENERATED_ECP_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) scripts/generate_ecp_tests.py --list || \
echo FAILED \
))
ifeq ($(GENERATED_ECP_DATA_FILES),FAILED)
$(error "$(PYTHON) scripts/generate_ecp_tests.py --list" failed)
endif
GENERATED_PSA_DATA_FILES := $(patsubst tests/%,%,$(shell \
$(PYTHON) scripts/generate_psa_tests.py --list || \
echo FAILED \
@ -87,7 +80,7 @@ GENERATED_PSA_DATA_FILES := $(patsubst tests/%,%,$(shell \
ifeq ($(GENERATED_PSA_DATA_FILES),FAILED)
$(error "$(PYTHON) scripts/generate_psa_tests.py --list" failed)
endif
GENERATED_FILES := $(GENERATED_PSA_DATA_FILES) $(GENERATED_ECP_DATA_FILES) $(GENERATED_BIGNUM_DATA_FILES)
GENERATED_FILES := $(GENERATED_PSA_DATA_FILES) $(GENERATED_BIGNUM_DATA_FILES)
generated_files: $(GENERATED_FILES)
# generate_bignum_tests.py and generate_psa_tests.py spend more time analyzing
@ -96,7 +89,7 @@ generated_files: $(GENERATED_FILES)
# It's rare not to want all the outputs. So always generate all of its outputs.
# Use an intermediate phony dependency so that parallel builds don't run
# a separate instance of the recipe for each output file.
.SECONDARY: generated_bignum_test_data generated_ecp_test_data generated_psa_test_data
.SECONDARY: generated_bignum_test_data generated_psa_test_data
$(GENERATED_BIGNUM_DATA_FILES): generated_bignum_test_data
generated_bignum_test_data: scripts/generate_bignum_tests.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_common.py
@ -109,17 +102,6 @@ generated_bignum_test_data:
echo " Gen $(GENERATED_BIGNUM_DATA_FILES)"
$(PYTHON) scripts/generate_bignum_tests.py
$(GENERATED_ECP_DATA_FILES): generated_ecp_test_data
generated_ecp_test_data: scripts/generate_ecp_tests.py
generated_ecp_test_data: ../scripts/mbedtls_dev/bignum_common.py
generated_ecp_test_data: ../scripts/mbedtls_dev/ecp_common.py
generated_ecp_test_data: ../scripts/mbedtls_dev/ecp.py
generated_ecp_test_data: ../scripts/mbedtls_dev/test_case.py
generated_ecp_test_data: ../scripts/mbedtls_dev/test_data_generation.py
generated_ecp_test_data:
echo " Gen $(GENERATED_ECP_DATA_FILES)"
$(PYTHON) scripts/generate_ecp_tests.py
$(GENERATED_PSA_DATA_FILES): generated_psa_test_data
generated_psa_test_data: scripts/generate_psa_tests.py
generated_psa_test_data: ../scripts/mbedtls_dev/crypto_knowledge.py

View File

@ -137,5 +137,4 @@ check scripts/generate_ssl_debug_helpers.py library/ssl_debug_helpers_generated.
check scripts/generate_visualc_files.pl visualc/VS2013
check scripts/generate_psa_constants.py programs/psa/psa_constant_names_generated.c
check tests/scripts/generate_bignum_tests.py $(tests/scripts/generate_bignum_tests.py --list)
check tests/scripts/generate_ecp_tests.py $(tests/scripts/generate_ecp_tests.py --list)
check tests/scripts/generate_psa_tests.py $(tests/scripts/generate_psa_tests.py --list)

View File

@ -1,68 +0,0 @@
#!/usr/bin/env python3
"""Generate test data for ecp functions.
With no arguments, generate all test data. With non-option arguments,
generate only the specified files.
Class structure:
Child classes of test_data_generation.BaseTarget (file targets) represent an output
file. These indicate where test cases will be written to, for all subclasses of
this target. Multiple file targets should not reuse a `target_basename`.
Each subclass derived from a file target can either be:
- A concrete class, representing a test function, which generates test cases.
- An abstract class containing shared methods and attributes, not associated
with a test function.
Both concrete and abstract subclasses can be derived from, to implement
additional test cases (see BignumCmp and BignumCmpAbs for examples of deriving
from abstract and concrete classes).
Adding test case generation for a function:
A subclass representing the test function should be added, deriving from a
file target such as BignumTarget. This test class must set/implement the
following:
- test_function: the function name from the associated .function file.
- test_name: a descriptive name or brief summary to refer to the test
function.
- arguments(): a method to generate the list of arguments required for the
test_function.
- generate_function_tests(): a method to generate TestCases for the function.
This should create instances of the class with required input data, and
call `.create_test_case()` to yield the TestCase.
Additional details and other attributes/methods are given in the documentation
of BaseTarget in test_data_generation.py.
"""
# 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.
import sys
import scripts_path # pylint: disable=unused-import
from mbedtls_dev import test_data_generation
# Import modules containing additional test classes
# Test function classes in these modules will be registered by
# the framework
from mbedtls_dev import ecp # pylint: disable=unused-import
if __name__ == '__main__':
# Use the section of the docstring relevant to the CLI as description
test_data_generation.main(sys.argv[1:], "\n".join(__doc__.splitlines()[:4]))

View File

@ -179,6 +179,9 @@ mpi_mod_raw_cond_swap:"000000001111111122222222333333334444444455555555666666667
mbedtls_mpi_mod_raw_cond_swap: copy half of the limbs
mpi_mod_raw_cond_swap:"00000000FFFFFFFF55555555AAAAAAAA":"FEDCBA9876543210FEDCBA9876543210":8
Bignum mod raw quasi-reduction: uninitialized modulus
mpi_mod_raw_fix_quasi_reduction_neg:"11":"12":"1"
# BEGIN MERGE SLOT 1
# END MERGE SLOT 1

View File

@ -6,6 +6,8 @@
#include "constant_time_internal.h"
#include "test/constant_flow.h"
#include "bignum_mod_raw_invasive.h"
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@ -338,6 +340,96 @@ exit:
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_mod_raw_fix_quasi_reduction(char *input_N,
char *input_A,
char *result)
{
mbedtls_mpi_uint *A = NULL;
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *res = NULL;
size_t limbs_A;
size_t limbs_N;
size_t limbs_res;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init(&m);
TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
size_t limbs = limbs_N;
size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
TEST_EQUAL(limbs_A, limbs);
TEST_EQUAL(limbs_res, limbs);
TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
&m, N, limbs,
MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
TEST_EQUAL(mbedtls_mpi_mod_raw_fix_quasi_reduction(A, &m), 0);
ASSERT_COMPARE(A, bytes, res, bytes);
exit:
mbedtls_free(A);
mbedtls_free(res);
mbedtls_mpi_mod_modulus_free(&m);
mbedtls_free(N);
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_mod_raw_fix_quasi_reduction_neg(char *input_N,
char *input_A,
char *result)
{
mbedtls_mpi_uint *A = NULL;
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *res = NULL;
size_t limbs_A;
size_t limbs_N;
size_t limbs_res;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init(&m);
mbedtls_mpi_mod_modulus fake_m;
mbedtls_mpi_mod_modulus_init(&fake_m);
TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
size_t limbs = limbs_N;
size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
TEST_EQUAL(limbs_A, limbs);
TEST_EQUAL(limbs_res, limbs);
TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
&m, N, limbs,
MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
TEST_EQUAL(mbedtls_mpi_mod_raw_fix_quasi_reduction(A, &m), 0);
ASSERT_COMPARE(A, bytes, res, bytes);
/* Check when m is not initialized */
TEST_EQUAL(mbedtls_mpi_mod_raw_fix_quasi_reduction(A, &fake_m),
MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
exit:
mbedtls_free(A);
mbedtls_free(res);
mbedtls_mpi_mod_modulus_free(&fake_m);
mbedtls_mpi_mod_modulus_free(&m);
mbedtls_free(N);
}
/* END_CASE */
/* BEGIN_CASE */
void mpi_mod_raw_mul(char *input_A,
char *input_B,

View File

@ -1038,6 +1038,3 @@ ecp_check_order:MBEDTLS_ECP_DP_SECP256K1:"fffffffffffffffffffffffffffffffebaaedc
ECP check order for CURVE448
depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED
ecp_check_order:MBEDTLS_ECP_DP_CURVE448:"3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3"
ECP quasi-reduction: uninitialized modulus
ecp_quasi_reduction_neg:"11":"12":"1"

View File

@ -2,8 +2,8 @@
#include "mbedtls/ecp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/ecdh.h"
#include "ecp_invasive.h"
#include "ecp_internal.h"
#if defined(MBEDTLS_TEST_HOOKS) && \
(defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
@ -1295,93 +1295,3 @@ exit:
mbedtls_mpi_free(&expected_n);
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_quasi_reduction(char *input_N,
char *input_A,
char *result)
{
mbedtls_mpi_uint *A = NULL;
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *res = NULL;
size_t limbs_A;
size_t limbs_N;
size_t limbs_res;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init(&m);
TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
size_t limbs = limbs_N;
size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
TEST_EQUAL(limbs_A, limbs);
TEST_EQUAL(limbs_res, limbs);
TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
&m, N, limbs,
MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
TEST_EQUAL(mbedtls_ecp_quasi_reduction(A, &m), 0);
ASSERT_COMPARE(A, bytes, res, bytes);
exit:
mbedtls_free(A);
mbedtls_free(res);
mbedtls_mpi_mod_modulus_free(&m);
mbedtls_free(N);
}
/* END_CASE */
/* BEGIN_CASE */
void ecp_quasi_reduction_neg(char *input_N,
char *input_A,
char *result)
{
mbedtls_mpi_uint *A = NULL;
mbedtls_mpi_uint *N = NULL;
mbedtls_mpi_uint *res = NULL;
size_t limbs_A;
size_t limbs_N;
size_t limbs_res;
mbedtls_mpi_mod_modulus m;
mbedtls_mpi_mod_modulus_init(&m);
mbedtls_mpi_mod_modulus fake_m;
mbedtls_mpi_mod_modulus_init(&fake_m);
TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
size_t limbs = limbs_N;
size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
TEST_EQUAL(limbs_A, limbs);
TEST_EQUAL(limbs_res, limbs);
TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
&m, N, limbs,
MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0);
TEST_EQUAL(mbedtls_ecp_quasi_reduction(A, &m), 0);
ASSERT_COMPARE(A, bytes, res, bytes);
/* Check when m is not initialized */
TEST_EQUAL(mbedtls_ecp_quasi_reduction(A, &fake_m),
MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
exit:
mbedtls_free(A);
mbedtls_free(res);
mbedtls_mpi_mod_modulus_free(&fake_m);
mbedtls_mpi_mod_modulus_free(&m);
mbedtls_free(N);
}
/* END_CASE */