Extract Secp224r1 from the prototype
Signed-off-by: Gabor Mezei <gabor.mezei@arm.com>
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index 1a027d6..d42f093 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -4575,6 +4575,7 @@
#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 @@
#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 @@
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 @@
#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 3d1321c..19d516f 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 4e74d9b..a38720c 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