diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index e7f3131740..eb372cf1fd 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -203,6 +203,12 @@ extern "C" { * \brief MPI structure */ typedef struct mbedtls_mpi { + /** Pointer to limbs. + * + * This may be \c NULL if \c n is 0. + */ + mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); + /** Sign: -1 if the mpi is negative, 1 otherwise. * * The number 0 must be represented with `s = +1`. Although many library @@ -214,16 +220,19 @@ typedef struct mbedtls_mpi { * Note that this implies that calloc() or `... = {0}` does not create * a valid MPI representation. You must call mbedtls_mpi_init(). */ - int MBEDTLS_PRIVATE(s); + signed short MBEDTLS_PRIVATE(s); /** Total number of limbs in \c p. */ - size_t MBEDTLS_PRIVATE(n); - - /** Pointer to limbs. - * - * This may be \c NULL if \c n is 0. + unsigned short MBEDTLS_PRIVATE(n); + /* Make sure that MBEDTLS_MPI_MAX_LIMBS fits in n. + * Use the same limit value on all platforms so that we don't have to + * think about different behavior on the rare platforms where + * unsigned short can store values larger than the minimum required by + * the C language, which is 65535. */ - mbedtls_mpi_uint *MBEDTLS_PRIVATE(p); +#if MBEDTLS_MPI_MAX_LIMBS > 65535 +#error "MBEDTLS_MPI_MAX_LIMBS > 65535 is not supported" +#endif } mbedtls_mpi; diff --git a/library/bignum.c b/library/bignum.c index 36effaf8da..5b9293293e 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -114,7 +114,9 @@ int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs) mbedtls_free(X->p); } - X->n = nblimbs; + /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS + * fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */ + X->n = (unsigned short) nblimbs; X->p = p; } @@ -162,7 +164,9 @@ int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs) mbedtls_free(X->p); } - X->n = i; + /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS + * fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */ + X->n = (unsigned short) i; X->p = p; return 0; @@ -1574,8 +1578,8 @@ static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N, { mbedtls_mpi_uint z = 1; mbedtls_mpi U; - - U.n = U.s = (int) z; + U.n = 1; + U.s = 1; U.p = &z; mpi_montmul(A, &U, N, mm, T); diff --git a/library/ecp.c b/library/ecp.c index b13cac0393..049a1e0151 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -2932,9 +2932,9 @@ int mbedtls_ecp_muladd(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) -#define ECP_MPI_INIT(s, n, p) { s, (n), (mbedtls_mpi_uint *) (p) } +#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } #define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x) + ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) /* * Constants for the two points other than 0, 1, -1 (mod p) in * https://cr.yp.to/ecdh.html#validate diff --git a/library/ecp_curves.c b/library/ecp_curves.c index a4fa663a56..3d3ec60f94 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -44,15 +44,15 @@ #define ECP_VALIDATE(cond) \ MBEDTLS_INTERNAL_VALIDATE(cond) -#define ECP_MPI_INIT(s, n, p) { s, (n), (mbedtls_mpi_uint *) (p) } +#define ECP_MPI_INIT(_p, _n) { .p = (mbedtls_mpi_uint *) (_p), .s = 1, .n = (_n) } #define ECP_MPI_INIT_ARRAY(x) \ - ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x) + ECP_MPI_INIT(x, sizeof(x) / sizeof(mbedtls_mpi_uint)) #define ECP_POINT_INIT_XY_Z0(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(1, 0, NULL) } + ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(NULL, 0) } #define ECP_POINT_INIT_XY_Z1(x, y) { \ - ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(1, 1, mpi_one) } + ECP_MPI_INIT_ARRAY(x), ECP_MPI_INIT_ARRAY(y), ECP_MPI_INIT(mpi_one, 1) } #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ @@ -4512,12 +4512,13 @@ static const mbedtls_ecp_point brainpoolP512r1_T[32] = { defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) /* * Create an MPI from embedded constants - * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint)) + * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint) and + * len < 1048576) */ static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len) { X->s = 1; - X->n = len / sizeof(mbedtls_mpi_uint); + X->n = (unsigned short) (len / sizeof(mbedtls_mpi_uint)); X->p = (mbedtls_mpi_uint *) p; } #endif diff --git a/tests/suites/test_suite_bignum_random.function b/tests/suites/test_suite_bignum_random.function index e4db3d7acc..34221a796e 100644 --- a/tests/suites/test_suite_bignum_random.function +++ b/tests/suites/test_suite_bignum_random.function @@ -312,8 +312,8 @@ void mpi_random_many(int min, char *bound_hex, int iterations) /* Temporarily use a legacy MPI for analysis, because the * necessary auxiliary functions don't exist yet in core. */ - mbedtls_mpi B = { 1, limbs, upper_bound }; - mbedtls_mpi R = { 1, limbs, result }; + mbedtls_mpi B = { .s = 1, .n = limbs, .p = upper_bound }; + mbedtls_mpi R = { .s = 1, .n = limbs, .p = result }; TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) < 0); TEST_ASSERT(mbedtls_mpi_cmp_int(&R, min) >= 0);