From 6fb105fb2e70ad6a47ccbd1c1c9bfea4be0755b2 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Wed, 22 Feb 2023 15:28:20 +0000 Subject: [PATCH] ecp_curves: Ported prototypes Signed-off-by: Minos Galanakis --- library/ecp_curves.c | 212 +++++++++++++---------------------------- library/ecp_invasive.h | 21 ++++ 2 files changed, 85 insertions(+), 148 deletions(-) diff --git a/library/ecp_curves.c b/library/ecp_curves.c index db21d7d8cf..179016b5d4 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4585,6 +4585,8 @@ int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs); #endif #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) static int ecp_mod_p384(mbedtls_mpi *); +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *N_p, size_t N_n); #endif #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) static int ecp_mod_p521(mbedtls_mpi *); @@ -5181,160 +5183,34 @@ int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs) #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ -#undef LOAD32 -#undef MAX32 -#undef A -#undef STORE32 -#undef STORE0 -#undef ADD -#undef SUB -#undef ADD_CARRY -#undef SUB_CARRY -#undef ADD_LAST -#undef SUB_LAST -#undef INIT -#undef NEXT -#undef RESET -#undef LAST - -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || - MBEDTLS_ECP_DP_SECP384R1_ENABLED */ - -#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) -/* - * The reader is advised to first understand ecp_mod_p192() since the same - * general structure is used here, but with additional complications: - * (1) chunks of 32 bits, and (2) subtractions. - */ - -/* - * For these primes, we need to handle data in chunks of 32 bits. - * This makes it more complicated if we use 64 bits limbs in MPI, - * which prevents us from using a uniform access method as for p192. - * - * So, we define a mini abstraction layer to access 32 bit chunks, - * load them in 'cur' for work, and store them back from 'cur' when done. - * - * While at it, also define the size of N in terms of 32-bit chunks. - */ -#define LOAD32 cur = A(i); - -#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ - -#define MAX32 N->n -#define A(j) N->p[j] -#define STORE32 N->p[i] = cur; - -#else /* 64-bit */ - -#define MAX32 N->n * 2 -#define A(j) (j) % 2 ? (uint32_t) (N->p[(j)/2] >> 32) : \ - (uint32_t) (N->p[(j)/2]) -#define STORE32 \ - if (i % 2) { \ - N->p[i/2] &= 0x00000000FFFFFFFF; \ - N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ - } else { \ - N->p[i/2] &= 0xFFFFFFFF00000000; \ - N->p[i/2] |= (mbedtls_mpi_uint) cur; \ - } - -#endif /* sizeof( mbedtls_mpi_uint ) */ - -/* - * Helpers for addition and subtraction of chunks, with signed carry. - */ -static inline void add32(uint32_t *dst, uint32_t src, signed char *carry) -{ - *dst += src; - *carry += (*dst < src); -} - -static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry) -{ - *carry -= (*dst < src); - *dst -= src; -} - -#define ADD(j) add32(&cur, A(j), &c); -#define SUB(j) sub32(&cur, A(j), &c); - -/* - * Helpers for the main 'loop' - */ -#define INIT(b) \ - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = (b); \ - /* N is the size of the product of two b-bit numbers, plus one */ \ - /* limb for fix_negative */ \ - MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, (b) * 2 / biL + 1)); \ - LOAD32; - -#define NEXT \ - STORE32; i++; LOAD32; \ - cc = c; c = 0; \ - if (cc < 0) \ - sub32(&cur, -cc, &c); \ - else \ - add32(&cur, cc, &c); \ - -#define LAST \ - STORE32; i++; \ - cur = c > 0 ? c : 0; STORE32; \ - cur = 0; while (++i < MAX32) { STORE32; } \ - if (c < 0) mbedtls_ecp_fix_negative(N, c, bits); - -/* - * If the result is negative, we get it in the form - * c * 2^bits + N, with c negative and N positive shorter than 'bits' - */ -MBEDTLS_STATIC_TESTABLE -void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits) -{ - size_t i; - - /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so - * set the absolute value to 0xfff...fff - N. There is no carry - * since we're subtracting from all-bits-one. */ - for (i = 0; i <= bits / 8 / sizeof(mbedtls_mpi_uint); i++) { - N->p[i] = ~(mbedtls_mpi_uint) 0 - N->p[i]; - } - /* Add 1, taking care of the carry. */ - i = 0; - do { - ++N->p[i]; - } while (N->p[i++] == 0 && i <= bits / 8 / sizeof(mbedtls_mpi_uint)); - /* Invert the sign. - * Now N = N0 - 2^bits where N0 is the initial value of N. */ - N->s = -1; - - /* Add |c| * 2^bits to the absolute value. Since c and N are - * negative, this adds c * 2^bits. */ - mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c; -#if defined(MBEDTLS_HAVE_INT64) - if (bits == 224) { - msw <<= 32; - } -#endif - N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw; -} - #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) /* * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) */ static int ecp_mod_p384(mbedtls_mpi *N) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t expected_width = 2 * ((384 + biL - 1) / biL); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); + ret = mbedtls_ecp_mod_p384_raw(N->p, expected_width); +cleanup: + return ret; +} + +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs) +{ + if (X_limbs != 2*((384 + biL - 1)/biL)) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + INIT(384); ADD(12); ADD(21); ADD(20); SUB(23); NEXT; // A0 ADD(13); ADD(22); ADD(23); - SUB(12); SUB(20); NEXT; // A2 + SUB(12); SUB(20); NEXT; // A1 ADD(14); ADD(23); SUB(13); SUB(21); NEXT; // A2 @@ -5364,22 +5240,62 @@ static int ecp_mod_p384(mbedtls_mpi *N) SUB(21); NEXT; // A10 ADD(23); ADD(20); ADD(19); - SUB(22); LAST; // A11 + SUB(22); // A11 -cleanup: - return ret; + RESET; + + ADD_LAST; NEXT; // A0 + SUB_LAST; NEXT; // A1 + NEXT; // A2 + ADD_LAST; NEXT; // A3 + ADD_LAST; NEXT; // A4 + NEXT; // A5 + NEXT; // A6 + NEXT; // A7 + NEXT; // A8 + NEXT; // A9 + NEXT; // A10 + // A11 + + RESET; + + ADD_LAST; NEXT; // A0 + SUB_LAST; NEXT; // A1 + NEXT; // A2 + ADD_LAST; NEXT; // A3 + ADD_LAST; NEXT; // A4 + NEXT; // A5 + NEXT; // A6 + NEXT; // A7 + NEXT; // A8 + NEXT; // A9 + NEXT; // A10 + // A11 + + LAST; + + return 0; } #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ -#undef A #undef LOAD32 -#undef STORE32 #undef MAX32 +#undef A +#undef STORE32 +#undef STORE0 +#undef ADD +#undef SUB +#undef ADD_CARRY +#undef SUB_CARRY +#undef ADD_LAST +#undef SUB_LAST #undef INIT #undef NEXT +#undef RESET #undef LAST -#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED || +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || + MBEDTLS_ECP_DP_SECP256R1_ENABLED || MBEDTLS_ECP_DP_SECP384R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index cb16d23728..501152c038 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -160,6 +160,27 @@ int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs); #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + +/** Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + * + * \param[in,out] X The address of the MPI to be converted. + * Must have exact limb size of `(766 / biL) + 1`. + * Upon return holds the reduced value which is + * in range `0 <= X < 2 * N` (where N is the modulus). + * The bitlength of the reduced value is the same as + * that of the modulus (384 bits). + * \param[in] X_limbs The length of \p N in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p N_n does not have + * twice as many limbs as the modulus. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + /** Initialise a modulus with hard-coded const curve data. * * \note The caller is responsible for the \p N modulus' memory.