mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-03-20 19:21:09 +01:00
Gracefully handle A_limbs > N_limbs and test it
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
This commit is contained in:
@@ -1123,12 +1123,15 @@ void mbedtls_mpi_core_gcd_modinv_odd(mbedtls_mpi_uint *G,
|
||||
* We only write to G (aka v) after reading from inputs (A and N), which
|
||||
* allows aliasing, except with N when I != NULL, as then we'll be operating
|
||||
* mod N on q and r later - see the public documentation.
|
||||
*
|
||||
* Also avoid possible UB with memcpy when src == dst.
|
||||
*/
|
||||
if (A_limbs > N_limbs) {
|
||||
/* Violating this precondition should not result in memory errors. */
|
||||
A_limbs = N_limbs;
|
||||
}
|
||||
memcpy(u, A, A_limbs * ciL);
|
||||
memset((char *) u + A_limbs * ciL, 0, (N_limbs - A_limbs) * ciL);
|
||||
|
||||
/* Avoid possible UB with memcpy when src == dst. */
|
||||
if (v != N) {
|
||||
memcpy(v, N, N_limbs * ciL);
|
||||
}
|
||||
|
||||
@@ -832,7 +832,7 @@ void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
|
||||
* When I != NULL (computing the modular inverse), G or I may alias A
|
||||
* but none of them may alias N (the modulus).
|
||||
*
|
||||
* If any precondition is not met, output values are unspecified.
|
||||
* If any of the above preconditions is not met, output values are unspecified.
|
||||
*
|
||||
* \param[out] G The GCD of \p A and \p N.
|
||||
* Must have the same number of limbs as \p N.
|
||||
|
||||
@@ -1531,6 +1531,110 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void mpi_core_gcd_modinv_odd_preconditions()
|
||||
{
|
||||
/*
|
||||
* The purpose of this test function is to ensure that the function doesn't
|
||||
* crash (but just outputs garbage) when preconditions are not met.
|
||||
*/
|
||||
|
||||
mbedtls_mpi_uint two_limbs[2];
|
||||
mbedtls_mpi_uint one_limb[1];
|
||||
mbedtls_mpi_uint *G = NULL, *I = NULL, *T = NULL;
|
||||
|
||||
/* Large enough for all calls below */
|
||||
TEST_CALLOC(G, 2);
|
||||
TEST_CALLOC(I, 2);
|
||||
TEST_CALLOC(T, 5 * 2);
|
||||
|
||||
/*
|
||||
* Input values
|
||||
*/
|
||||
|
||||
/* N is not odd */
|
||||
two_limbs[0] = 2; // N = 2^n + 2
|
||||
two_limbs[1] = 1;
|
||||
one_limb[0] = 42; // A = 42
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, one_limb, 1, two_limbs, 2, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, one_limb, 1, two_limbs, 2, T);
|
||||
|
||||
/* A > N */
|
||||
two_limbs[0] = 3; // N = 3
|
||||
two_limbs[1] = 0;
|
||||
one_limb[0] = 42; // A = 42
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, one_limb, 1, two_limbs, 2, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, one_limb, 1, two_limbs, 2, T);
|
||||
|
||||
/* A_limbs > N_limbs (but A <= N) */
|
||||
one_limb[0] = 5; // N = 5
|
||||
two_limbs[0] = 3; // A = 3
|
||||
two_limbs[1] = 0;
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, two_limbs, 2, one_limb, 1, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, two_limbs, 2, one_limb, 1, T);
|
||||
|
||||
/* A_limbs > N_limbs (and A > N) */
|
||||
one_limb[0] = 5; // N = 5
|
||||
two_limbs[0] = 7; // A = 7
|
||||
two_limbs[1] = 0;
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, two_limbs, 2, one_limb, 1, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, two_limbs, 2, one_limb, 1, T);
|
||||
|
||||
/* I != NULL but N is 1 */
|
||||
two_limbs[0] = 1; // N = 1
|
||||
two_limbs[1] = 0;
|
||||
one_limb[0] = 1; // A = 1
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, two_limbs, 2, one_limb, 1, T);
|
||||
|
||||
/*
|
||||
* Aliasing
|
||||
*/
|
||||
|
||||
/* Now use valid values for remaining tests */
|
||||
two_limbs[0] = 1; // N = 2^n + 1
|
||||
two_limbs[1] = 1;
|
||||
one_limb[0] = 42; // A = 42
|
||||
|
||||
/* A aliased to N */
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, two_limbs, 2, two_limbs, 2, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, two_limbs, 2, two_limbs, 2, T);
|
||||
|
||||
/* G aliased to A and N */
|
||||
memcpy(G, two_limbs, 2 * sizeof(mbedtls_mpi_uint));
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, G, 2, G, 2, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, G, 2, G, 2, T);
|
||||
|
||||
/* I != NULL, G aliased to N */
|
||||
memcpy(G, two_limbs, 2 * sizeof(mbedtls_mpi_uint));
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, two_limbs, 2, G, 2, T);
|
||||
|
||||
/* I != NULL, I aliased to N */
|
||||
memcpy(I, two_limbs, 2 * sizeof(mbedtls_mpi_uint));
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, two_limbs, 2, I, 2, T);
|
||||
|
||||
/* I aliased to A and N */
|
||||
memcpy(I, two_limbs, 2 * sizeof(mbedtls_mpi_uint));
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, I, 2, I, 2, T);
|
||||
|
||||
/*
|
||||
* Not specific to this function
|
||||
*/
|
||||
|
||||
/* A_limbs = 0 */
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, one_limb, 0, two_limbs, 2, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, one_limb, 0, two_limbs, 2, T);
|
||||
|
||||
/* A_limbs = N_limbs = 0 */
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, NULL, one_limb, 0, two_limbs, 0, T);
|
||||
mbedtls_mpi_core_gcd_modinv_odd(G, I, one_limb, 0, two_limbs, 0, T);
|
||||
|
||||
exit:
|
||||
mbedtls_free(G);
|
||||
mbedtls_free(I);
|
||||
mbedtls_free(T);
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
|
||||
void mpi_core_div2_mod_odd(char *input_X, char *input_N, char *input_exp_X)
|
||||
{
|
||||
|
||||
@@ -535,6 +535,9 @@ mpi_core_gcd_modinv_odd:"7f2405d6de7db80a7bc":"1a84113636607520200d":"1":"15f158
|
||||
GCD-modinv (almost) max iterations
|
||||
mpi_core_gcd_modinv_odd:"8000000000000000":"b26eb5721a2cb24c36acb4550b176671":"1":"77e1dd63583a6b3c8deefe7737862c89"
|
||||
|
||||
GCD-modinv preconditions not met
|
||||
mpi_core_gcd_modinv_odd_preconditions:
|
||||
|
||||
Div2 mod odd: even value
|
||||
mpi_core_div2_mod_odd:"4":"7":"2"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user