Convert curve 448 to use ecp core functions

Signed-off-by: Paul Elliott <paul.elliott@arm.com>
diff --git a/library/ecp_curves.c b/library/ecp_curves.c
index b07753a..094b25c 100644
--- a/library/ecp_curves.c
+++ b/library/ecp_curves.c
@@ -22,6 +22,7 @@
 #if defined(MBEDTLS_ECP_LIGHT)
 
 #include "mbedtls/ecp.h"
+#include "mbedtls/platform.h"
 #include "mbedtls/platform_util.h"
 #include "mbedtls/error.h"
 
@@ -4608,7 +4609,7 @@
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 static int ecp_mod_p448(mbedtls_mpi *);
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p448(mbedtls_mpi *);
+int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *, size_t);
 #endif
 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
 static int ecp_mod_p192k1(mbedtls_mpi *);
@@ -5455,7 +5456,18 @@
 
 static int ecp_mod_p448(mbedtls_mpi *N)
 {
-    return mbedtls_ecp_mod_p448(N);
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+    size_t expected_width = 2 * ((448 + biL - 1) / biL);
+
+    /* This is required as some tests and use cases do not pass in a Bignum of
+     * the correct size, and expect the growth to be done automatically, which
+     * will no longer happen. */
+    MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width));
+
+    ret = mbedtls_ecp_mod_p448(N->p, N->n);
+
+cleanup:
+    return ret;
 }
 
 /*
@@ -5470,56 +5482,82 @@
  * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
  */
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p448(mbedtls_mpi *N)
+int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *N, size_t N_limbs)
 {
-    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     size_t i;
-    mbedtls_mpi M, Q;
-    mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
+    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
 
-    if (N->n <= P448_WIDTH) {
+    if (N_limbs <= P448_WIDTH) {
         return 0;
     }
 
-    /* M = A1 */
-    M.s = 1;
-    M.n = N->n - (P448_WIDTH);
-    if (M.n > P448_WIDTH) {
+    size_t M_limbs = N_limbs - (P448_WIDTH);
+    size_t Q_limbs = M_limbs;
+
+    if (M_limbs > P448_WIDTH) {
         /* Shouldn't be called with N larger than 2^896! */
         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
     }
-    M.p = Mp;
-    memset(Mp, 0, sizeof(Mp));
-    memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint));
 
-    /* N = A0 */
-    for (i = P448_WIDTH; i < N->n; i++) {
-        N->p[i] = 0;
+    /* Extra limb for carry below. */
+    M_limbs++;
+
+    mbedtls_mpi_uint *M = mbedtls_calloc(M_limbs, ciL);
+
+    if (M == NULL) {
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
     }
 
-    /* N += A1 */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
+    /* M = A1 */
+    memset(M, 0, (M_limbs * ciL));
+
+    /* Do not copy into the overflow limb, as this would read past the end of
+     * N. */
+    memcpy(M, N + P448_WIDTH, ((M_limbs - 1) * ciL));
+
+    /* N = A0 */
+    for (i = P448_WIDTH; i < N_limbs; i++) {
+        N[i] = 0;
+    }
+
+    /* N += A1 - Carry here dealt with by oversize M and N. */
+    (void) mbedtls_mpi_core_add(N, N, M, M_limbs);
 
     /* Q = B1, N += B1 */
-    Q = M;
-    Q.p = Qp;
-    memcpy(Qp, Mp, sizeof(Qp));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q));
+    mbedtls_mpi_uint *Q = mbedtls_calloc(Q_limbs, ciL);
+
+    if (Q == NULL) {
+        ret =  MBEDTLS_ERR_ECP_ALLOC_FAILED;
+        goto cleanup;
+    }
+
+    memcpy(Q, M, (Q_limbs * ciL));
+
+    mbedtls_mpi_core_shift_r(Q, Q_limbs, 224);
+
+    /* No carry here - only max 224 bits */
+    (void) mbedtls_mpi_core_add(N, N, Q, Q_limbs);
 
     /* M = (B0 + B1) * 2^224, N += M */
     if (sizeof(mbedtls_mpi_uint) > 4) {
-        Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
+        M[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
     }
-    for (i = P224_WIDTH_MAX; i < M.n; ++i) {
-        Mp[i] = 0;
+    for (i = P224_WIDTH_MAX; i < M_limbs; ++i) {
+        M[i] = 0;
     }
-    MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q));
-    M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
-    MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224));
-    MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
+
+    (void) mbedtls_mpi_core_add(M, M, Q, Q_limbs);
+
+    /* Shifted carry bit from the addition is dealt with by oversize M */
+    mbedtls_mpi_core_shift_l(M, M_limbs, 224);
+    (void) mbedtls_mpi_core_add(N, N, M, M_limbs);
+
+    ret = 0;
 
 cleanup:
+    mbedtls_free(M);
+    mbedtls_free(Q);
+
     return ret;
 }
 #endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h
index 68187ac..4cf4f6e 100644
--- a/library/ecp_invasive.h
+++ b/library/ecp_invasive.h
@@ -196,7 +196,7 @@
 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
 
 MBEDTLS_STATIC_TESTABLE
-int mbedtls_ecp_mod_p448(mbedtls_mpi *N);
+int mbedtls_ecp_mod_p448(mbedtls_mpi_uint *N, size_t N_limbs);
 
 #endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
 
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index f034d6f..95aaef2 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -1499,7 +1499,7 @@
     TEST_LE_U(X.n, 2 * limbs);
     TEST_EQUAL(res.n, limbs);
 
-    TEST_EQUAL(mbedtls_ecp_mod_p448(&X), 0);
+    TEST_EQUAL(mbedtls_ecp_mod_p448(X.p, X.n), 0);
     TEST_EQUAL(mbedtls_mpi_mod_mpi(&X, &X, &N), 0);
     TEST_LE_U(mbedtls_mpi_core_bitlen(X.p, X.n), 448);
     ASSERT_COMPARE(X.p, bytes, res.p, bytes);