diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 1a027d6aa3..d42f093cfa 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4575,6 +4575,7 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); #endif #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) static int ecp_mod_p224(mbedtls_mpi *); +static int ecp_mod_p224_raw(mbedtls_mpi_uint *Np, size_t Nn); #endif #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) static int ecp_mod_p256(mbedtls_mpi *); @@ -4951,6 +4952,176 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn) #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ 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 Nn +#define A(j) Np[j] +#define STORE32 Np[i] = cur; +#define STORE0 Np[i] = 0; + +#else /* 64 bit */ + +#define MAX32 Nn * 2 +#define A(j) (j) % 2 ? (uint32_t) (Np[(j) / 2] >> 32) : \ + (uint32_t) (Np[(j) / 2]) +#define STORE32 \ + if (i % 2) { \ + Np[i/2] &= 0x00000000FFFFFFFF; \ + Np[i/2] |= (uint64_t) (cur) << 32; \ + } else { \ + Np[i/2] &= 0xFFFFFFFF00000000; \ + Np[i/2] |= (uint32_t) cur; \ + } + +#define STORE0 \ + if (i % 2) { \ + Np[i/2] &= 0x00000000FFFFFFFF; \ + } else { \ + Np[i/2] &= 0xFFFFFFFF00000000; \ + } + +#endif + +static inline int8_t extract_carry(int64_t cur) +{ + return (int8_t) (cur >> 32); +} + +#define ADD(j) cur += A(j) +#define SUB(j) cur -= A(j) + +#define ADD_CARRY(cc) cur += (cc) +#define SUB_CARRY(cc) cur -= (cc) + +#define ADD_LAST ADD_CARRY(last_c) +#define SUB_LAST SUB_CARRY(last_c) + +/* + * Helpers for the main 'loop' + */ +#define INIT(b) \ + int8_t c = 0, last_c; \ + int64_t cur; \ + size_t i = 0; \ + LOAD32; + +#define NEXT \ + c = extract_carry(cur); \ + STORE32; i++; LOAD32; \ + ADD_CARRY(c); + +#define RESET \ + c = extract_carry(cur); \ + last_c = c; \ + STORE32; i = 0; LOAD32; \ + c = 0; \ + +#define LAST \ + c = extract_carry(cur); \ + STORE32; i++; \ + if (c != 0) \ + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; \ + while (i < MAX32) { STORE0; i++; } + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +static int ecp_mod_p224(mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + size_t expected_width = 2 * ((224 + biL - 1) / biL); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); + ret = ecp_mod_p224_raw(N->p, expected_width); +cleanup: + return ret; +} + +static int ecp_mod_p224_raw(mbedtls_mpi_uint *Np, size_t Nn) +{ + if (Nn != 2 * ((224 + biL - 1) / biL)) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + INIT(224); + + SUB( 7); SUB(11); NEXT; // A0 += -A7 - A11 + SUB( 8); SUB(12); NEXT; // A1 += -A8 - A12 + SUB( 9); SUB(13); NEXT; // A2 += -A9 - A13 + SUB(10); ADD( 7); ADD(11); NEXT; // A3 += -A10 + A7 + A11 + SUB(11); ADD( 8); ADD(12); NEXT; // A4 += -A11 + A8 + A12 + SUB(12); ADD( 9); ADD(13); NEXT; // A5 += -A12 + A9 + A13 + SUB(13); ADD(10); // A6 += -A13 + A10 + + RESET; + + SUB_LAST; NEXT; // A0 + NEXT; // A1 + NEXT; // A2 + ADD_LAST; NEXT; // A3 + NEXT; // A4 + NEXT; // A5 + // A6 + + RESET; + + SUB_LAST; NEXT; // A0 + NEXT; // A1 + NEXT; // A2 + ADD_LAST; NEXT; // A3 + NEXT; // A4 + NEXT; // A5 + // A6 + + LAST; + + return 0; +} + +#endif /* MBEDTLS_ECP_DP_SECP224R1_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_SECP256R1_ENABLED) || \ + 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: @@ -5071,27 +5242,6 @@ void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits) N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw; } -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) -/* - * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) - */ -static int ecp_mod_p224(mbedtls_mpi *N) -{ - INIT(224); - - SUB(7); SUB(11); NEXT; // A0 += -A7 - A11 - SUB(8); SUB(12); NEXT; // A1 += -A8 - A12 - SUB(9); SUB(13); NEXT; // A2 += -A9 - A13 - SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11 - SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12 - SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13 - SUB(13); ADD(10); LAST; // A6 += -A13 + A10 - -cleanup: - return ret; -} -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ - #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) /* * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) @@ -5186,8 +5336,7 @@ cleanup: #undef NEXT #undef LAST -#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || - MBEDTLS_ECP_DP_SECP256R1_ENABLED || +#endif /* 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 3d1321c525..19d516f9b4 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -32,8 +32,7 @@ #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C) -#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) /* Preconditions: * - bits is a multiple of 64 or is 224 diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 4e74d9b8eb..a38720c348 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -8,8 +8,7 @@ #include "bignum_mod_raw_invasive.h" #if defined(MBEDTLS_TEST_HOOKS) && \ - (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ - defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + (defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)) #define HAVE_FIX_NEGATIVE #endif