Merge pull request #6208 from AndrzejKurek/tls-tests-no-md-structured
Remove the dependency on MD from TLS 1.2 tests
diff --git a/ChangeLog.d/fix-ctr-drbg-may-free-invalid-aes-context.txt b/ChangeLog.d/fix-ctr-drbg-may-free-invalid-aes-context.txt
new file mode 100644
index 0000000..fe62c28
--- /dev/null
+++ b/ChangeLog.d/fix-ctr-drbg-may-free-invalid-aes-context.txt
@@ -0,0 +1,4 @@
+Bugfix
+ * Fix mbedtls_ctr_drbg_free() on an initialized but unseeded context. When
+ MBEDTLS_AES_ALT is enabled, it could call mbedtls_aes_free() on an
+ uninitialized context.
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index ac8b7c0..0c1790d 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -918,7 +918,7 @@
* \note To prevent timing attacks, this function
* executes the exact same sequence of base-field
* operations for any valid \p m. It avoids any if-branch or
- * array index depending on the value of \p m. If also uses
+ * array index depending on the value of \p m. It also uses
* \p f_rng to randomize some intermediate results.
*
* \param grp The ECP group to use.
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index fd2391d..e9487b2 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -2018,6 +2018,9 @@
* Enable the multi-precision integer library.
*
* Module: library/bignum.c
+ * library/bignum_core.c
+ * library/bignum_mod.c
+ * library/bignum_mod_raw.c
* Caller: library/dhm.c
* library/ecp.c
* library/ecdsa.c
@@ -2683,7 +2686,7 @@
* above to be specified at runtime or compile time respectively.
*
* \note This abstraction layer must be enabled on Windows (including MSYS2)
- * as other module rely on it for a fixed snprintf implementation.
+ * as other modules rely on it for a fixed snprintf implementation.
*
* Module: library/platform.c
* Caller: Most other .c files
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index bcf9072..3d820a5 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -4736,7 +4736,7 @@
*
* \note When this function returns #MBEDTLS_ERR_SSL_WANT_WRITE/READ,
* it must be called later with the *same* arguments,
- * until it returns a value greater that or equal to 0. When
+ * until it returns a value greater than or equal to 0. When
* the function returns #MBEDTLS_ERR_SSL_WANT_WRITE there may be
* some partial data in the output buffer, however this is not
* yet sent.
diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h
index 98fd287..b8a8a24 100644
--- a/include/mbedtls/ssl_ticket.h
+++ b/include/mbedtls/ssl_ticket.h
@@ -34,6 +34,10 @@
#include "mbedtls/ssl.h"
#include "mbedtls/cipher.h"
+#if defined(MBEDTLS_HAVE_TIME)
+#include "mbedtls/platform_time.h"
+#endif
+
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#endif
@@ -56,7 +60,9 @@
{
unsigned char MBEDTLS_PRIVATE(name)[MBEDTLS_SSL_TICKET_KEY_NAME_BYTES];
/*!< random key identifier */
- uint32_t MBEDTLS_PRIVATE(generation_time); /*!< key generation timestamp (seconds) */
+#if defined(MBEDTLS_HAVE_TIME)
+ mbedtls_time_t MBEDTLS_PRIVATE(generation_time); /*!< key generation timestamp (seconds) */
+#endif
#if !defined(MBEDTLS_USE_PSA_CRYPTO)
mbedtls_cipher_context_t MBEDTLS_PRIVATE(ctx); /*!< context for auth enc/decryption */
#else
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index ed58a9e..378cfb4 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -18,6 +18,9 @@
asn1write.c
base64.c
bignum.c
+ bignum_core.c
+ bignum_mod.c
+ bignum_mod_raw.c
camellia.c
ccm.c
chacha20.c
diff --git a/library/Makefile b/library/Makefile
index 2f58f66..85cea6b 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -83,6 +83,9 @@
asn1write.o \
base64.o \
bignum.o \
+ bignum_core.o \
+ bignum_mod.o \
+ bignum_mod_raw.o \
camellia.o \
ccm.o \
chacha20.o \
diff --git a/library/bignum.c b/library/bignum.c
index 55325b4..acf620f 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -39,6 +39,7 @@
#include "mbedtls/bignum.h"
#include "bignum_internal.h"
+#include "bignum_core.h"
#include "bn_mul.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
@@ -62,19 +63,8 @@
#define MPI_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
-#define biL (ciL << 3) /* bits in limb */
-#define biH (ciL << 2) /* half limb size */
-
#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
-/*
- * Convert between bits/chars and number of limbs
- * Divide first in order to avoid potential overflows
- */
-#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
-#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
-
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
{
@@ -303,10 +293,6 @@
return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
}
-/* Get a specific byte, without range checks. */
-#define GET_BYTE( X, i ) \
- ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
-
/*
* Set a bit to a specific value of 0 or 1
*/
@@ -353,40 +339,11 @@
}
/*
- * Count leading zero bits in a given integer
- */
-static size_t mbedtls_clz( const mbedtls_mpi_uint x )
-{
- size_t j;
- mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
-
- for( j = 0; j < biL; j++ )
- {
- if( x & mask ) break;
-
- mask >>= 1;
- }
-
- return j;
-}
-
-/*
* Return the number of bits
*/
size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
{
- size_t i, j;
-
- if( X->n == 0 )
- return( 0 );
-
- for( i = X->n - 1; i > 0; i-- )
- if( X->p[i] != 0 )
- break;
-
- j = biL - mbedtls_clz( X->p[i] );
-
- return( ( i * biL ) + j );
+ return( mbedtls_mpi_core_bitlen( X->p, X->n ) );
}
/*
@@ -693,97 +650,6 @@
}
#endif /* MBEDTLS_FS_IO */
-
-/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
- * into the storage form used by mbedtls_mpi. */
-
-static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
-{
- uint8_t i;
- unsigned char *x_ptr;
- mbedtls_mpi_uint tmp = 0;
-
- for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
- {
- tmp <<= CHAR_BIT;
- tmp |= (mbedtls_mpi_uint) *x_ptr;
- }
-
- return( tmp );
-}
-
-static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
-{
-#if defined(__BYTE_ORDER__)
-
-/* Nothing to do on bigendian systems. */
-#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
- return( x );
-#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
-
-#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
-
-/* For GCC and Clang, have builtins for byte swapping. */
-#if defined(__GNUC__) && defined(__GNUC_PREREQ)
-#if __GNUC_PREREQ(4,3)
-#define have_bswap
-#endif
-#endif
-
-#if defined(__clang__) && defined(__has_builtin)
-#if __has_builtin(__builtin_bswap32) && \
- __has_builtin(__builtin_bswap64)
-#define have_bswap
-#endif
-#endif
-
-#if defined(have_bswap)
- /* The compiler is hopefully able to statically evaluate this! */
- switch( sizeof(mbedtls_mpi_uint) )
- {
- case 4:
- return( __builtin_bswap32(x) );
- case 8:
- return( __builtin_bswap64(x) );
- }
-#endif
-#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
-#endif /* __BYTE_ORDER__ */
-
- /* Fall back to C-based reordering if we don't know the byte order
- * or we couldn't use a compiler-specific builtin. */
- return( mpi_uint_bigendian_to_host_c( x ) );
-}
-
-static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
-{
- mbedtls_mpi_uint *cur_limb_left;
- mbedtls_mpi_uint *cur_limb_right;
- if( limbs == 0 )
- return;
-
- /*
- * Traverse limbs and
- * - adapt byte-order in each limb
- * - swap the limbs themselves.
- * For that, simultaneously traverse the limbs from left to right
- * and from right to left, as long as the left index is not bigger
- * than the right index (it's not a problem if limbs is odd and the
- * indices coincide in the last iteration).
- */
- for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
- cur_limb_left <= cur_limb_right;
- cur_limb_left++, cur_limb_right-- )
- {
- mbedtls_mpi_uint tmp;
- /* Note that if cur_limb_left == cur_limb_right,
- * this code effectively swaps the bytes only once. */
- tmp = mpi_uint_bigendian_to_host( *cur_limb_left );
- *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right );
- *cur_limb_right = tmp;
- }
-}
-
/*
* Import X from unsigned binary data, little endian
*
@@ -794,14 +660,12 @@
const unsigned char *buf, size_t buflen )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t i;
- size_t const limbs = CHARS_TO_LIMBS( buflen );
+ const size_t limbs = CHARS_TO_LIMBS( buflen );
/* Ensure that target MPI has exactly the necessary number of limbs */
MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
- for( i = 0; i < buflen; i++ )
- X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
+ MBEDTLS_MPI_CHK( mbedtls_mpi_core_read_le( X->p, X->n, buf, buflen ) );
cleanup:
@@ -822,9 +686,7 @@
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t const limbs = CHARS_TO_LIMBS( buflen );
- size_t const overhead = ( limbs * ciL ) - buflen;
- unsigned char *Xp;
+ const size_t limbs = CHARS_TO_LIMBS( buflen );
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
@@ -832,15 +694,7 @@
/* Ensure that target MPI has exactly the necessary number of limbs */
MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
- /* Avoid calling `memcpy` with NULL source or destination argument,
- * even if buflen is 0. */
- if( buflen != 0 )
- {
- Xp = (unsigned char*) X->p;
- memcpy( Xp + overhead, buf, buflen );
-
- mpi_bigendian_to_host( X->p, limbs );
- }
+ MBEDTLS_MPI_CHK( mbedtls_mpi_core_read_be( X->p, X->n, buf, buflen ) );
cleanup:
@@ -858,37 +712,7 @@
int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
unsigned char *buf, size_t buflen )
{
- size_t stored_bytes = X->n * ciL;
- size_t bytes_to_copy;
- size_t i;
-
- if( stored_bytes < buflen )
- {
- bytes_to_copy = stored_bytes;
- }
- else
- {
- bytes_to_copy = buflen;
-
- /* The output buffer is smaller than the allocated size of X.
- * However X may fit if its leading bytes are zero. */
- for( i = bytes_to_copy; i < stored_bytes; i++ )
- {
- if( GET_BYTE( X, i ) != 0 )
- return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
- }
- }
-
- for( i = 0; i < bytes_to_copy; i++ )
- buf[i] = GET_BYTE( X, i );
-
- if( stored_bytes < buflen )
- {
- /* Write trailing 0 bytes */
- memset( buf + stored_bytes, 0, buflen - stored_bytes );
- }
-
- return( 0 );
+ return( mbedtls_mpi_core_write_le( X->p, X->n, buf, buflen ) );
}
/*
@@ -897,44 +721,7 @@
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
unsigned char *buf, size_t buflen )
{
- size_t stored_bytes;
- size_t bytes_to_copy;
- unsigned char *p;
- size_t i;
-
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
-
- stored_bytes = X->n * ciL;
-
- if( stored_bytes < buflen )
- {
- /* There is enough space in the output buffer. Write initial
- * null bytes and record the position at which to start
- * writing the significant bytes. In this case, the execution
- * trace of this function does not depend on the value of the
- * number. */
- bytes_to_copy = stored_bytes;
- p = buf + buflen - stored_bytes;
- memset( buf, 0, buflen - stored_bytes );
- }
- else
- {
- /* The output buffer is smaller than the allocated size of X.
- * However X may fit if its leading bytes are zero. */
- bytes_to_copy = buflen;
- p = buf;
- for( i = bytes_to_copy; i < stored_bytes; i++ )
- {
- if( GET_BYTE( X, i ) != 0 )
- return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
- }
- }
-
- for( i = 0; i < bytes_to_copy; i++ )
- p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
-
- return( 0 );
+ return( mbedtls_mpi_core_write_be( X->p, X->n, buf, buflen ) );
}
/*
@@ -1545,7 +1332,7 @@
/*
* Normalize the divisor, d, and dividend, u0, u1
*/
- s = mbedtls_clz( d );
+ s = mbedtls_mpi_core_clz( d );
d = d << s;
u1 = u1 << s;
@@ -2334,7 +2121,7 @@
memset( X->p, 0, overhead );
memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
- mpi_bigendian_to_host( X->p, limbs );
+ mbedtls_mpi_core_bigendian_to_host( X->p, limbs );
cleanup:
return( ret );
@@ -2352,7 +2139,7 @@
void *p_rng )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t const limbs = CHARS_TO_LIMBS( size );
+ const size_t limbs = CHARS_TO_LIMBS( size );
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( f_rng != NULL );
diff --git a/library/bignum_core.c b/library/bignum_core.c
new file mode 100644
index 0000000..8e89766
--- /dev/null
+++ b/library/bignum_core.c
@@ -0,0 +1,294 @@
+/*
+ * Core bignum functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include <string.h>
+
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "bignum_core.h"
+
+size_t mbedtls_mpi_core_clz( mbedtls_mpi_uint a )
+{
+ size_t j;
+ mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
+
+ for( j = 0; j < biL; j++ )
+ {
+ if( a & mask ) break;
+
+ mask >>= 1;
+ }
+
+ return( j );
+}
+
+size_t mbedtls_mpi_core_bitlen( const mbedtls_mpi_uint *A, size_t A_limbs )
+{
+ size_t i, j;
+
+ if( A_limbs == 0 )
+ return( 0 );
+
+ for( i = A_limbs - 1; i > 0; i-- )
+ if( A[i] != 0 )
+ break;
+
+ j = biL - mbedtls_mpi_core_clz( A[i] );
+
+ return( ( i * biL ) + j );
+}
+
+/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
+ * into the storage form used by mbedtls_mpi. */
+static mbedtls_mpi_uint mpi_bigendian_to_host_c( mbedtls_mpi_uint a )
+{
+ uint8_t i;
+ unsigned char *a_ptr;
+ mbedtls_mpi_uint tmp = 0;
+
+ for( i = 0, a_ptr = (unsigned char *) &a; i < ciL; i++, a_ptr++ )
+ {
+ tmp <<= CHAR_BIT;
+ tmp |= (mbedtls_mpi_uint) *a_ptr;
+ }
+
+ return( tmp );
+}
+
+static mbedtls_mpi_uint mpi_bigendian_to_host( mbedtls_mpi_uint a )
+{
+#if defined(__BYTE_ORDER__)
+
+/* Nothing to do on bigendian systems. */
+#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
+ return( a );
+#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
+
+#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
+
+/* For GCC and Clang, have builtins for byte swapping. */
+#if defined(__GNUC__) && defined(__GNUC_PREREQ)
+#if __GNUC_PREREQ(4,3)
+#define have_bswap
+#endif
+#endif
+
+#if defined(__clang__) && defined(__has_builtin)
+#if __has_builtin(__builtin_bswap32) && \
+ __has_builtin(__builtin_bswap64)
+#define have_bswap
+#endif
+#endif
+
+#if defined(have_bswap)
+ /* The compiler is hopefully able to statically evaluate this! */
+ switch( sizeof(mbedtls_mpi_uint) )
+ {
+ case 4:
+ return( __builtin_bswap32(a) );
+ case 8:
+ return( __builtin_bswap64(a) );
+ }
+#endif
+#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
+#endif /* __BYTE_ORDER__ */
+
+ /* Fall back to C-based reordering if we don't know the byte order
+ * or we couldn't use a compiler-specific builtin. */
+ return( mpi_bigendian_to_host_c( a ) );
+}
+
+void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
+ size_t A_limbs )
+{
+ mbedtls_mpi_uint *cur_limb_left;
+ mbedtls_mpi_uint *cur_limb_right;
+ if( A_limbs == 0 )
+ return;
+
+ /*
+ * Traverse limbs and
+ * - adapt byte-order in each limb
+ * - swap the limbs themselves.
+ * For that, simultaneously traverse the limbs from left to right
+ * and from right to left, as long as the left index is not bigger
+ * than the right index (it's not a problem if limbs is odd and the
+ * indices coincide in the last iteration).
+ */
+ for( cur_limb_left = A, cur_limb_right = A + ( A_limbs - 1 );
+ cur_limb_left <= cur_limb_right;
+ cur_limb_left++, cur_limb_right-- )
+ {
+ mbedtls_mpi_uint tmp;
+ /* Note that if cur_limb_left == cur_limb_right,
+ * this code effectively swaps the bytes only once. */
+ tmp = mpi_bigendian_to_host( *cur_limb_left );
+ *cur_limb_left = mpi_bigendian_to_host( *cur_limb_right );
+ *cur_limb_right = tmp;
+ }
+}
+
+int mbedtls_mpi_core_read_le( mbedtls_mpi_uint *X,
+ size_t X_limbs,
+ const unsigned char *input,
+ size_t input_length )
+{
+ const size_t limbs = CHARS_TO_LIMBS( input_length );
+
+ if( X_limbs < limbs )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+
+ if( X != NULL )
+ {
+ memset( X, 0, X_limbs * ciL );
+
+ for( size_t i = 0; i < input_length; i++ )
+ {
+ size_t offset = ( ( i % ciL ) << 3 );
+ X[i / ciL] |= ( (mbedtls_mpi_uint) input[i] ) << offset;
+ }
+ }
+
+ return( 0 );
+}
+
+int mbedtls_mpi_core_read_be( mbedtls_mpi_uint *X,
+ size_t X_limbs,
+ const unsigned char *input,
+ size_t input_length )
+{
+ const size_t limbs = CHARS_TO_LIMBS( input_length );
+
+ if( X_limbs < limbs )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+
+ /* If X_limbs is 0, input_length must also be 0 (from previous test).
+ * Nothing to do. */
+ if( X_limbs == 0 )
+ return( 0 );
+
+ memset( X, 0, X_limbs * ciL );
+
+ /* memcpy() with (NULL, 0) is undefined behaviour */
+ if( input_length != 0 )
+ {
+ size_t overhead = ( X_limbs * ciL ) - input_length;
+ unsigned char *Xp = (unsigned char *) X;
+ memcpy( Xp + overhead, input, input_length );
+ }
+
+ mbedtls_mpi_core_bigendian_to_host( X, X_limbs );
+
+ return( 0 );
+}
+
+int mbedtls_mpi_core_write_le( const mbedtls_mpi_uint *A,
+ size_t A_limbs,
+ unsigned char *output,
+ size_t output_length )
+{
+ size_t stored_bytes = A_limbs * ciL;
+ size_t bytes_to_copy;
+
+ if( stored_bytes < output_length )
+ {
+ bytes_to_copy = stored_bytes;
+ }
+ else
+ {
+ bytes_to_copy = output_length;
+
+ /* The output buffer is smaller than the allocated size of A.
+ * However A may fit if its leading bytes are zero. */
+ for( size_t i = bytes_to_copy; i < stored_bytes; i++ )
+ {
+ if( GET_BYTE( A, i ) != 0 )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+ }
+
+ for( size_t i = 0; i < bytes_to_copy; i++ )
+ output[i] = GET_BYTE( A, i );
+
+ if( stored_bytes < output_length )
+ {
+ /* Write trailing 0 bytes */
+ memset( output + stored_bytes, 0, output_length - stored_bytes );
+ }
+
+ return( 0 );
+}
+
+int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *X,
+ size_t X_limbs,
+ unsigned char *output,
+ size_t output_length )
+{
+ size_t stored_bytes;
+ size_t bytes_to_copy;
+ unsigned char *p;
+
+ stored_bytes = X_limbs * ciL;
+
+ if( stored_bytes < output_length )
+ {
+ /* There is enough space in the output buffer. Write initial
+ * null bytes and record the position at which to start
+ * writing the significant bytes. In this case, the execution
+ * trace of this function does not depend on the value of the
+ * number. */
+ bytes_to_copy = stored_bytes;
+ p = output + output_length - stored_bytes;
+ memset( output, 0, output_length - stored_bytes );
+ }
+ else
+ {
+ /* The output buffer is smaller than the allocated size of X.
+ * However X may fit if its leading bytes are zero. */
+ bytes_to_copy = output_length;
+ p = output;
+ for( size_t i = bytes_to_copy; i < stored_bytes; i++ )
+ {
+ if( GET_BYTE( X, i ) != 0 )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+ }
+
+ for( size_t i = 0; i < bytes_to_copy; i++ )
+ p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
+
+ return( 0 );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
diff --git a/library/bignum_core.h b/library/bignum_core.h
new file mode 100644
index 0000000..434f52b
--- /dev/null
+++ b/library/bignum_core.h
@@ -0,0 +1,158 @@
+/**
+ * Core bignum functions
+ *
+ * This interface should only be used by the legacy bignum module (bignum.h)
+ * and the modular bignum modules (bignum_mod.c, bignum_mod_raw.c). All other
+ * modules should use the high-level modular bignum interface (bignum_mod.h)
+ * or the legacy bignum interface (bignum.h).
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_BIGNUM_CORE_H
+#define MBEDTLS_BIGNUM_CORE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+/** Count leading zero bits in a given integer.
+ *
+ * \param a Integer to count leading zero bits.
+ *
+ * \return The number of leading zero bits in \p a.
+ */
+size_t mbedtls_mpi_core_clz( mbedtls_mpi_uint a );
+
+/** Return the minimum number of bits required to represent the value held
+ * in the MPI.
+ *
+ * \note This function returns 0 if all the limbs of \p A are 0.
+ *
+ * \param[in] A The address of the MPI.
+ * \param A_limbs The number of limbs of \p A.
+ *
+ * \return The number of bits in \p A.
+ */
+size_t mbedtls_mpi_core_bitlen( const mbedtls_mpi_uint *A, size_t A_limbs );
+
+/** Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
+ * into the storage form used by mbedtls_mpi.
+ *
+ * \param[in,out] A The address of the MPI.
+ * \param A_limbs The number of limbs of \p A.
+ */
+void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint *A,
+ size_t A_limbs );
+
+/** Import X from unsigned binary data, little-endian.
+ *
+ * The MPI needs to have enough limbs to store the full value (including any
+ * most significant zero bytes in the input).
+ *
+ * \param[out] X The address of the MPI.
+ * \param X_limbs The number of limbs of \p X.
+ * \param[in] input The input buffer to import from.
+ * \param input_length The length bytes of \p input.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
+ * large enough to hold the value in \p input.
+ */
+int mbedtls_mpi_core_read_le( mbedtls_mpi_uint *X,
+ size_t X_limbs,
+ const unsigned char *input,
+ size_t input_length );
+
+/** Import X from unsigned binary data, big-endian.
+ *
+ * The MPI needs to have enough limbs to store the full value (including any
+ * most significant zero bytes in the input).
+ *
+ * \param[out] X The address of the MPI.
+ * May only be #NULL if \X_limbs is 0 and \p input_length
+ * is 0.
+ * \param X_limbs The number of limbs of \p X.
+ * \param[in] input The input buffer to import from.
+ * May only be #NULL if \p input_length is 0.
+ * \param input_length The length in bytes of \p input.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
+ * large enough to hold the value in \p input.
+ */
+int mbedtls_mpi_core_read_be( mbedtls_mpi_uint *X,
+ size_t X_limbs,
+ const unsigned char *input,
+ size_t input_length );
+
+/** Export A into unsigned binary data, little-endian.
+ *
+ * \note If \p output is shorter than \p A the export is still successful if the
+ * value held in \p A fits in the buffer (that is, if enough of the most
+ * significant bytes of \p A are 0).
+ *
+ * \param[in] A The address of the MPI.
+ * \param A_limbs The number of limbs of \p A.
+ * \param[out] output The output buffer to export to.
+ * \param output_length The length in bytes of \p output.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
+ * large enough to hold the value of \p A.
+ */
+int mbedtls_mpi_core_write_le( const mbedtls_mpi_uint *A,
+ size_t A_limbs,
+ unsigned char *output,
+ size_t output_length );
+
+/** Export A into unsigned binary data, big-endian.
+ *
+ * \note If \p output is shorter than \p A the export is still successful if the
+ * value held in \p A fits in the buffer (that is, if enough of the most
+ * significant bytes of \p A are 0).
+ *
+ * \param[in] A The address of the MPI.
+ * \param A_limbs The number of limbs of \p A.
+ * \param[out] output The output buffer to export to.
+ * \param output_length The length in bytes of \p output.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
+ * large enough to hold the value of \p A.
+ */
+int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A,
+ size_t A_limbs,
+ unsigned char *output,
+ size_t output_length );
+
+#define ciL ( sizeof(mbedtls_mpi_uint) ) /* chars in limb */
+#define biL ( ciL << 3 ) /* bits in limb */
+#define biH ( ciL << 2 ) /* half limb size */
+
+/*
+ * Convert between bits/chars and number of limbs
+ * Divide first in order to avoid potential overflows
+ */
+#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
+#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
+/* Get a specific byte, without range checks. */
+#define GET_BYTE( X, i ) \
+ ( ( (X)[(i) / ciL] >> ( ( (i) % ciL ) * 8 ) ) & 0xff )
+
+#endif /* MBEDTLS_BIGNUM_CORE_H */
diff --git a/library/bignum_mod.c b/library/bignum_mod.c
new file mode 100644
index 0000000..de28093
--- /dev/null
+++ b/library/bignum_mod.c
@@ -0,0 +1,152 @@
+/**
+ * Modular bignum functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include <string.h>
+
+#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/bignum.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "bignum_core.h"
+#include "bignum_mod.h"
+#include "bignum_mod_raw.h"
+#include "constant_time_internal.h"
+
+int mbedtls_mpi_mod_residue_setup( mbedtls_mpi_mod_residue *r,
+ const mbedtls_mpi_mod_modulus *m,
+ mbedtls_mpi_uint *p,
+ size_t p_limbs )
+{
+ if( p_limbs < m->limbs || !mbedtls_mpi_core_lt_ct( m->p, p, p_limbs ) )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+ r->limbs = m->limbs;
+ r->p = p;
+
+ return( 0 );
+}
+
+void mbedtls_mpi_mod_residue_release( mbedtls_mpi_mod_residue *r )
+{
+ if ( r == NULL )
+ return;
+
+ r->limbs = 0;
+ r->p = NULL;
+}
+
+void mbedtls_mpi_mod_modulus_init( mbedtls_mpi_mod_modulus *m )
+{
+ if ( m == NULL )
+ return;
+
+ m->p = NULL;
+ m->limbs = 0;
+ m->bits = 0;
+ m->ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
+ m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+}
+
+void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m )
+{
+ if ( m == NULL )
+ return;
+
+ switch( m->int_rep )
+ {
+ case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
+ mbedtls_free( m->rep.mont );
+ break;
+ case MBEDTLS_MPI_MOD_REP_OPT_RED:
+ mbedtls_free( m->rep.ored );
+ break;
+ case MBEDTLS_MPI_MOD_REP_INVALID:
+ break;
+ }
+
+ m->p = NULL;
+ m->limbs = 0;
+ m->bits = 0;
+ m->ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
+ m->int_rep = MBEDTLS_MPI_MOD_REP_INVALID;
+}
+
+int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
+ const mbedtls_mpi_uint *p,
+ size_t p_limbs,
+ mbedtls_mpi_mod_ext_rep ext_rep,
+ mbedtls_mpi_mod_rep_selector int_rep )
+{
+ int ret = 0;
+
+ m->p = p;
+ m->limbs = p_limbs;
+ m->bits = mbedtls_mpi_core_bitlen( p, p_limbs );
+
+ switch( ext_rep )
+ {
+ case MBEDTLS_MPI_MOD_EXT_REP_LE:
+ case MBEDTLS_MPI_MOD_EXT_REP_BE:
+ m->ext_rep = ext_rep;
+ break;
+ default:
+ ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ goto exit;
+ }
+
+ switch( int_rep )
+ {
+ case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
+ m->int_rep = int_rep;
+ m->rep.mont = NULL;
+ break;
+ case MBEDTLS_MPI_MOD_REP_OPT_RED:
+ m->int_rep = int_rep;
+ m->rep.ored = NULL;
+ break;
+ default:
+ ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ goto exit;
+ }
+
+exit:
+
+ if( ret != 0 )
+ {
+ mbedtls_mpi_mod_modulus_free( m );
+ }
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
diff --git a/library/bignum_mod.h b/library/bignum_mod.h
new file mode 100644
index 0000000..9d28bc7
--- /dev/null
+++ b/library/bignum_mod.h
@@ -0,0 +1,143 @@
+/**
+ * Modular bignum functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_BIGNUM_MOD_H
+#define MBEDTLS_BIGNUM_MOD_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+/* Skip 1 as it is slightly easier to accidentally pass to functions. */
+typedef enum
+{
+ MBEDTLS_MPI_MOD_REP_INVALID = 0,
+ MBEDTLS_MPI_MOD_REP_MONTGOMERY = 2,
+ MBEDTLS_MPI_MOD_REP_OPT_RED
+} mbedtls_mpi_mod_rep_selector;
+
+/* Make mbedtls_mpi_mod_rep_selector and mbedtls_mpi_mod_ext_rep disjoint to
+ * make it easier to catch when they are accidentally swapped. */
+typedef enum
+{
+ MBEDTLS_MPI_MOD_EXT_REP_INVALID = 0,
+ MBEDTLS_MPI_MOD_EXT_REP_LE = 8,
+ MBEDTLS_MPI_MOD_EXT_REP_BE
+} mbedtls_mpi_mod_ext_rep;
+
+typedef struct
+{
+ mbedtls_mpi_uint *p;
+ size_t limbs;
+} mbedtls_mpi_mod_residue;
+
+typedef void *mbedtls_mpi_mont_struct;
+typedef void *mbedtls_mpi_opt_red_struct;
+
+typedef struct {
+ const mbedtls_mpi_uint *p;
+ size_t limbs; // number of limbs
+ size_t bits; // bitlen of p
+ mbedtls_mpi_mod_ext_rep ext_rep; // signals external representation (eg. byte order)
+ mbedtls_mpi_mod_rep_selector int_rep; // selector to signal the active member of the union
+ union rep
+ {
+ mbedtls_mpi_mont_struct mont;
+ mbedtls_mpi_opt_red_struct ored;
+ } rep;
+} mbedtls_mpi_mod_modulus;
+
+/** Setup a residue structure.
+ *
+ * \param[out] r The address of residue to setup. The size is determined by
+ * \p m.
+ * (In particular, it must have at least as many limbs as the
+ * modulus \p m.)
+ * \param[in] m The address of the modulus related to \p r.
+ * \param[in] p The address of the limb array storing the value of \p r.
+ * The memory pointed to by \p p will be used by \p r and must
+ * not be modified in any way until after
+ * mbedtls_mpi_mod_residue_release() is called.
+ * \param p_limbs The number of limbs of \p p.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the
+ * limbs in \p m or if \p p is not less than \p m.
+ */
+int mbedtls_mpi_mod_residue_setup( mbedtls_mpi_mod_residue *r,
+ const mbedtls_mpi_mod_modulus *m,
+ mbedtls_mpi_uint *p,
+ size_t p_limbs );
+
+/** Unbind elements of a residue structure.
+ *
+ * This function removes the reference to the limb array that was passed to
+ * mbedtls_mpi_mod_residue_setup() to make it safe to free or use again.
+ *
+ * This function invalidates \p r and it must not be used until after
+ * mbedtls_mpi_mod_residue_setup() is called on it again.
+ *
+ * \param[out] r The address of residue to release.
+ */
+void mbedtls_mpi_mod_residue_release( mbedtls_mpi_mod_residue *r );
+
+/** Initialize a modulus structure.
+ *
+ * \param[out] m The address of the modulus structure to initialize.
+ */
+void mbedtls_mpi_mod_modulus_init( mbedtls_mpi_mod_modulus *m );
+
+/** Setup a modulus structure.
+ *
+ * \param[out] m The address of the modulus structure to populate.
+ * \param[in] p The address of the limb array storing the value of \p m.
+ * The memory pointed to by \p p will be used by \p m and must
+ * not be modified in any way until after
+ * mbedtls_mpi_mod_modulus_free() is called.
+ * \param p_limbs The number of limbs of \p p.
+ * \param ext_rep The external representation to be used for residues
+ * associated with \p m (see #mbedtls_mpi_mod_ext_rep).
+ * \param int_rep The internal representation to be used for residues
+ * associated with \p m (see #mbedtls_mpi_mod_rep_selector).
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep or \p int_rep is
+ * invalid.
+ */
+int mbedtls_mpi_mod_modulus_setup( mbedtls_mpi_mod_modulus *m,
+ const mbedtls_mpi_uint *p,
+ size_t p_limbs,
+ mbedtls_mpi_mod_ext_rep ext_rep,
+ mbedtls_mpi_mod_rep_selector int_rep );
+
+/** Free elements of a modulus structure.
+ *
+ * This function frees any memory allocated by mbedtls_mpi_mod_modulus_setup().
+ *
+ * \warning This function does not free the limb array passed to
+ * mbedtls_mpi_mod_modulus_setup() only removes the reference to it,
+ * making it safe to free or to use it again.
+ *
+ * \param[in,out] m The address of the modulus structure to free.
+ */
+void mbedtls_mpi_mod_modulus_free( mbedtls_mpi_mod_modulus *m );
+
+#endif /* MBEDTLS_BIGNUM_MOD_H */
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
new file mode 100644
index 0000000..8c89b2c
--- /dev/null
+++ b/library/bignum_mod_raw.c
@@ -0,0 +1,97 @@
+/*
+ * Low-level modular bignum functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#include <string.h>
+
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "bignum_core.h"
+#include "bignum_mod_raw.h"
+#include "bignum_mod.h"
+#include "constant_time_internal.h"
+
+int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
+ const mbedtls_mpi_mod_modulus *m,
+ const unsigned char *input,
+ size_t input_length )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ switch( m->ext_rep )
+ {
+ case MBEDTLS_MPI_MOD_EXT_REP_LE:
+ ret = mbedtls_mpi_core_read_le( X, m->limbs,
+ input, input_length );
+ break;
+ case MBEDTLS_MPI_MOD_EXT_REP_BE:
+ ret = mbedtls_mpi_core_read_be( X, m->limbs,
+ input, input_length );
+ break;
+ default:
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ }
+
+ if( ret != 0 )
+ goto cleanup;
+
+ if( !mbedtls_mpi_core_lt_ct( X, m->p, m->limbs ) )
+ {
+ ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ goto cleanup;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_mod_modulus *m,
+ unsigned char *output,
+ size_t output_length )
+{
+ switch( m->ext_rep )
+ {
+ case MBEDTLS_MPI_MOD_EXT_REP_LE:
+ return( mbedtls_mpi_core_write_le( A, m->limbs,
+ output, output_length ) );
+ case MBEDTLS_MPI_MOD_EXT_REP_BE:
+ return( mbedtls_mpi_core_write_be( A, m->limbs,
+ output, output_length ) );
+ default:
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ }
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
diff --git a/library/bignum_mod_raw.h b/library/bignum_mod_raw.h
new file mode 100644
index 0000000..7b3a0c1
--- /dev/null
+++ b/library/bignum_mod_raw.h
@@ -0,0 +1,79 @@
+/**
+ * Low-level modular bignum functions
+ *
+ * This interface should only be used by the higher-level modular bignum
+ * module (bignum_mod.c) and the ECP module (ecp.c, ecp_curves.c). All other
+ * modules should use the high-level modular bignum interface (bignum_mod.h)
+ * or the legacy bignum interface (bignum.h).
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_BIGNUM_MOD_RAW_H
+#define MBEDTLS_BIGNUM_MOD_RAW_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#include "bignum_mod.h"
+
+/** Import X from unsigned binary data.
+ *
+ * The MPI needs to have enough limbs to store the full value (including any
+ * most significant zero bytes in the input).
+ *
+ * \param[out] X The address of the MPI. The size is determined by \p m.
+ * (In particular, it must have at least as many limbs as
+ * the modulus \p m.)
+ * \param[in] m The address of the modulus related to \p X.
+ * \param[in] input The input buffer to import from.
+ * \param input_length The length in bytes of \p input.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't
+ * large enough to hold the value in \p input.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
+ * of \p m is invalid or \p X is not less than \p m.
+ */
+int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
+ const mbedtls_mpi_mod_modulus *m,
+ const unsigned char *input,
+ size_t input_length );
+
+/** Export A into unsigned binary data.
+ *
+ * \param[in] A The address of the MPI. The size is determined by \p m.
+ * (In particular, it must have at least as many limbs as
+ * the modulus \p m.)
+ * \param[in] m The address of the modulus related to \p A.
+ * \param[out] output The output buffer to export to.
+ * \param output_length The length in bytes of \p output.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't
+ * large enough to hold the value of \p A.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation
+ * of \p m is invalid.
+ */
+int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_mod_modulus *m,
+ unsigned char *output,
+ size_t output_length );
+
+#endif /* MBEDTLS_BIGNUM_MOD_RAW_H */
diff --git a/library/constant_time.c b/library/constant_time.c
index 0dc723a..8980701 100644
--- a/library/constant_time.c
+++ b/library/constant_time.c
@@ -742,6 +742,50 @@
}
/*
+ * Compare unsigned values in constant time
+ */
+unsigned mbedtls_mpi_core_lt_ct( const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *B,
+ size_t limbs )
+{
+ unsigned ret, cond, done;
+
+ /* The value of any of these variables is either 0 or 1 for the rest of
+ * their scope. */
+ ret = cond = done = 0;
+
+ for( size_t i = limbs; i > 0; i-- )
+ {
+ /*
+ * If B[i - 1] < A[i - 1] then A < B is false and the result must
+ * remain 0.
+ *
+ * Again even if we can make a decision, we just mark the result and
+ * the fact that we are done and continue looping.
+ */
+ cond = mbedtls_ct_mpi_uint_lt( B[i - 1], A[i - 1] );
+ done |= cond;
+
+ /*
+ * If A[i - 1] < B[i - 1] then A < B is true.
+ *
+ * Again even if we can make a decision, we just mark the result and
+ * the fact that we are done and continue looping.
+ */
+ cond = mbedtls_ct_mpi_uint_lt( A[i - 1], B[i - 1] );
+ ret |= cond & ( 1 - done );
+ done |= cond;
+ }
+
+ /*
+ * If all the limbs were equal, then the numbers are equal, A < B is false
+ * and leaving the result 0 is correct.
+ */
+
+ return( ret );
+}
+
+/*
* Compare signed values in constant time
*/
int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X,
diff --git a/library/constant_time_internal.h b/library/constant_time_internal.h
index 9466bc3..fc24ae5 100644
--- a/library/constant_time_internal.h
+++ b/library/constant_time_internal.h
@@ -129,6 +129,23 @@
unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
const mbedtls_mpi_uint y );
+/**
+ * \brief Check if one unsigned MPI is less than another in constant
+ * time.
+ *
+ * \param A The left-hand MPI. This must point to an array of limbs
+ * with the same allocated length as \p B.
+ * \param B The right-hand MPI. This must point to an array of limbs
+ * with the same allocated length as \p A.
+ * \param limbs The number of limbs in \p A and \p B.
+ *
+ * \return The result of the comparison:
+ * \c 1 if \p A is less than \p B.
+ * \c 0 if \p A is greater than or equal to \p B.
+ */
+unsigned mbedtls_mpi_core_lt_ct( const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *B,
+ size_t limbs);
#endif /* MBEDTLS_BIGNUM_C */
/** Choose between two integer values without branches.
diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c
index 43f490e..8919c78 100644
--- a/library/ctr_drbg.c
+++ b/library/ctr_drbg.c
@@ -51,6 +51,7 @@
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
+ mbedtls_aes_init( &ctx->aes_ctx );
/* Indicate that the entropy nonce length is not set explicitly.
* See mbedtls_ctr_drbg_set_nonce_len(). */
ctx->reseed_counter = -1;
@@ -448,8 +449,6 @@
mbedtls_mutex_init( &ctx->mutex );
#endif
- mbedtls_aes_init( &ctx->aes_ctx );
-
ctx->f_entropy = f_entropy;
ctx->p_entropy = p_entropy;
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 28c4d3e..359686a 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -79,7 +79,7 @@
#endif
#if defined(MBEDTLS_HAVE_TIME)
- key->generation_time = (uint32_t) mbedtls_time( NULL );
+ key->generation_time = mbedtls_time( NULL );
#endif
if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 )
@@ -122,15 +122,15 @@
#else
if( ctx->ticket_lifetime != 0 )
{
- uint32_t current_time = (uint32_t) mbedtls_time( NULL );
- uint32_t key_time = ctx->keys[ctx->active].generation_time;
+ mbedtls_time_t current_time = mbedtls_time( NULL );
+ mbedtls_time_t key_time = ctx->keys[ctx->active].generation_time;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
#endif
if( current_time >= key_time &&
- current_time - key_time < ctx->ticket_lifetime )
+ (uint64_t) ( current_time - key_time ) < ctx->ticket_lifetime )
{
return( 0 );
}
@@ -204,7 +204,7 @@
ctx->ticket_lifetime = lifetime;
memcpy( key->name, name, TICKET_KEY_NAME_BYTES );
#if defined(MBEDTLS_HAVE_TIME)
- key->generation_time = (uint32_t) mbedtls_time( NULL );
+ key->generation_time = mbedtls_time( NULL );
#endif
return 0;
}
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 7a1f588..435d772 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -4927,7 +4927,14 @@
*/
int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id )
{
- uint16_t tls_id = mbedtls_ecp_curve_info_from_grp_id( grp_id )->tls_id;
+ const mbedtls_ecp_curve_info *grp_info =
+ mbedtls_ecp_curve_info_from_grp_id( grp_id );
+
+ if ( grp_info == NULL )
+ return -1;
+
+ uint16_t tls_id = grp_info->tls_id;
+
return mbedtls_ssl_check_curve_tls_id( ssl, tls_id );
}
#endif /* MBEDTLS_ECP_C */
@@ -6570,14 +6577,27 @@
/* If certificate uses an EC key, make sure the curve is OK.
* This is a public key, so it can't be opaque, so can_do() is a good
* enough check to ensure pk_ec() is safe to use here. */
- if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
- mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
+ if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) )
{
- ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
+ /* and in the unlikely case the above assumption no longer holds
+ * we are making sure that pk_ec() here does not return a NULL
+ */
+ const mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *pk );
+ if( ec == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_pk_ec() returned NULL" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
- if( ret == 0 )
- ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
+ if( mbedtls_ssl_check_curve( ssl, ec->grp.id ) != 0 )
+ {
+ ssl->session_negotiate->verify_result |=
+ MBEDTLS_X509_BADCERT_BAD_KEY;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
+ if( ret == 0 )
+ ret = MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
+ }
}
}
#endif /* MBEDTLS_ECP_C */
diff --git a/programs/fuzz/fuzz_privkey.c b/programs/fuzz/fuzz_privkey.c
index 56795d2..81ea1bc 100644
--- a/programs/fuzz/fuzz_privkey.c
+++ b/programs/fuzz/fuzz_privkey.c
@@ -11,9 +11,9 @@
//4 Kb should be enough for every bug ;-)
#define MAX_LEN 0x1000
-#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_CTR_DRBG_C)
+#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_CTR_DRBG_C) && defined(MBEDTLS_ENTROPY_C)
const char *pers = "fuzz_privkey";
-#endif // MBEDTLS_PK_PARSE_C && MBEDTLS_CTR_DRBG_C
+#endif // MBEDTLS_PK_PARSE_C && MBEDTLS_CTR_DRBG_C && MBEDTLS_ENTROPY_C
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
#if defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_CTR_DRBG_C) && defined(MBEDTLS_ENTROPY_C)
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 2e9713b..7139fde 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1878,7 +1878,7 @@
# but is already disabled in the default config
loc_accel_flags="$loc_accel_flags $( echo "$loc_accel_list" | sed 's/[^ ]* */-DMBEDTLS_PSA_ACCEL_&/g' )"
- make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" tests
+ make CFLAGS="$ASAN_CFLAGS -Werror -I../tests/include -I../tests -I../../tests -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_TEST_LIBTESTDRIVER1 $loc_accel_flags" LDFLAGS="-ltestdriver1 $ASAN_CFLAGS" all
# There's a risk of something getting re-enabled via config_psa.h;
# make sure it did not happen.
diff --git a/tests/scripts/check_names.py b/tests/scripts/check_names.py
index 96117a2..e204487 100755
--- a/tests/scripts/check_names.py
+++ b/tests/scripts/check_names.py
@@ -58,8 +58,9 @@
# Naming patterns to check against. These are defined outside the NameCheck
# class for ease of modification.
-MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
-CONSTANTS_PATTERN = MACRO_PATTERN
+PUBLIC_MACRO_PATTERN = r"^(MBEDTLS|PSA)_[0-9A-Z_]*[0-9A-Z]$"
+INTERNAL_MACRO_PATTERN = r"^[0-9A-Za-z_]*[0-9A-Z]$"
+CONSTANTS_PATTERN = PUBLIC_MACRO_PATTERN
IDENTIFIER_PATTERN = r"^(mbedtls|psa)_[0-9a-z_]*[0-9a-z]$"
class Match(): # pylint: disable=too-few-public-methods
@@ -249,14 +250,17 @@
.format(str(self.excluded_files))
)
- all_macros = self.parse_macros([
+ all_macros = {"public": [], "internal": []}
+ all_macros["public"] = self.parse_macros([
"include/mbedtls/*.h",
"include/psa/*.h",
- "library/*.h",
- "tests/include/test/drivers/*.h",
"3rdparty/everest/include/everest/everest.h",
"3rdparty/everest/include/everest/x25519.h"
])
+ all_macros["internal"] = self.parse_macros([
+ "library/*.h",
+ "tests/include/test/drivers/*.h",
+ ])
enum_consts = self.parse_enum_consts([
"include/mbedtls/*.h",
"library/*.h",
@@ -284,20 +288,25 @@
# Remove identifier macros like mbedtls_printf or mbedtls_calloc
identifiers_justname = [x.name for x in identifiers]
- actual_macros = []
- for macro in all_macros:
- if macro.name not in identifiers_justname:
- actual_macros.append(macro)
+ actual_macros = {"public": [], "internal": []}
+ for scope in actual_macros:
+ for macro in all_macros[scope]:
+ if macro.name not in identifiers_justname:
+ actual_macros[scope].append(macro)
self.log.debug("Found:")
# Aligns the counts on the assumption that none exceeds 4 digits
- self.log.debug(" {:4} Total Macros".format(len(all_macros)))
- self.log.debug(" {:4} Non-identifier Macros".format(len(actual_macros)))
+ for scope in actual_macros:
+ self.log.debug(" {:4} Total {} Macros"
+ .format(len(all_macros[scope]), scope))
+ self.log.debug(" {:4} {} Non-identifier Macros"
+ .format(len(actual_macros[scope]), scope))
self.log.debug(" {:4} Enum Constants".format(len(enum_consts)))
self.log.debug(" {:4} Identifiers".format(len(identifiers)))
self.log.debug(" {:4} Exported Symbols".format(len(symbols)))
return {
- "macros": actual_macros,
+ "public_macros": actual_macros["public"],
+ "internal_macros": actual_macros["internal"],
"enum_consts": enum_consts,
"identifiers": identifiers,
"symbols": symbols,
@@ -741,7 +750,8 @@
problems += self.check_symbols_declared_in_header()
pattern_checks = [
- ("macros", MACRO_PATTERN),
+ ("public_macros", PUBLIC_MACRO_PATTERN),
+ ("internal_macros", INTERNAL_MACRO_PATTERN),
("enum_consts", CONSTANTS_PATTERN),
("identifiers", IDENTIFIER_PATTERN)
]
@@ -825,7 +835,10 @@
all_caps_names = {
match.name
for match
- in self.parse_result["macros"] + self.parse_result["enum_consts"]}
+ in self.parse_result["public_macros"] +
+ self.parse_result["internal_macros"] +
+ self.parse_result["enum_consts"]
+ }
typo_exclusion = re.compile(r"XXX|__|_$|^MBEDTLS_.*CONFIG_FILE$|"
r"MBEDTLS_TEST_LIBTESTDRIVER*")
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index f29dcab..7573f95 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -82,6 +82,308 @@
Test mpi_write_string #10 (Negative hex with odd number of digits)
mpi_read_write_string:16:"-1":16:"":3:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+Test mbedtls_mpi_core_io functions with null pointers
+mbedtls_mpi_core_io_null
+
+Test mbedtls_mpi_core_io_be #1 (Buffer and limbs just fit, input limb-aligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:24:0:0
+
+Test mbedtls_mpi_core_io_be #2 (Buffer and limbs just fit, input unaligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:24:0:0
+
+Test mbedtls_mpi_core_io_be #3 (Buffer just fits, extra limbs, input limb-aligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:28:0:0
+
+Test mbedtls_mpi_core_io_be #4 (Buffer just fits, extra limbs, input unaligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:28:0:0
+
+Test mbedtls_mpi_core_io_be #5 (Extra limbs, buffer aligned to extra limbs, input limb-aligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":112:28:0:0
+
+Test mbedtls_mpi_core_io_be #6 (Extra limbs, buffer aligned to extra limbs, input unaligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":112:28:0:0
+
+Test mbedtls_mpi_core_io_be #7 (Buffer and limbs just fit, input limb-aligned with leading zeroes)
+mbedtls_mpi_core_io_be:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":88:24:0:0
+
+Test mbedtls_mpi_core_io_be #8 (Buffer and limbs just fit, input unaligned with leading zeroes)
+mbedtls_mpi_core_io_be:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":86:24:0:0
+
+Test mbedtls_mpi_core_io_be #9 (Buffer just fits, extra limbs, input limb-aligned with leading zeroes)
+mbedtls_mpi_core_io_be:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":88:28:0:0
+
+Test mbedtls_mpi_core_io_be #10 (Buffer just fits, extra limbs, input unaligned with leading zeroes)
+mbedtls_mpi_core_io_be:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":86:28:0:0
+
+Test mbedtls_mpi_core_io_be #11 (Zero)
+mbedtls_mpi_core_io_be:"00":1:1:0:0
+
+Test mbedtls_mpi_core_io_be #12 (Zero, empty output)
+mbedtls_mpi_core_io_be:"00":0:1:0:0
+
+Test mbedtls_mpi_core_io_be #13 (Zero, empty input)
+mbedtls_mpi_core_io_be:"":1:1:0:0
+
+Test mbedtls_mpi_core_io_be #14 (One)
+mbedtls_mpi_core_io_be:"01":1:1:0:0
+
+Test mbedtls_mpi_core_io_be #15 (One limb, 32 bit)
+depends_on:MBEDTLS_HAVE_INT32
+mbedtls_mpi_core_io_be:"ff000000":4:1:0:0
+
+Test mbedtls_mpi_core_io_be #16 (One limb, 64 bit)
+depends_on:MBEDTLS_HAVE_INT64
+mbedtls_mpi_core_io_be:"ff00000000000000":8:2:0:0
+
+Test mbedtls_mpi_core_io_be #17 (not enough limbs, input limb-aligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:22:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_core_io_be #18 (not enough limbs, input unaligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:22:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_core_io_be #19 (buffer too small, input limb-aligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":95:24:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_core_io_be #20 (buffer too small, input unaligned)
+mbedtls_mpi_core_io_be:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":93:24:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_core_io_be #21 (Buffer and limbs fit, input unaligned, odd number of limbs)
+mbedtls_mpi_core_io_be:"00de4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":82:21:0:0
+
+Test mbedtls_mpi_core_io_le #1 (Buffer and limbs just fit, input limb-aligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:24:0:0
+
+Test mbedtls_mpi_core_io_le #2 (Buffer and limbs just fit, input unaligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:24:0:0
+
+Test mbedtls_mpi_core_io_le #3 (Buffer just fits, extra limbs, input limb-aligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:28:0:0
+
+Test mbedtls_mpi_core_io_le #4 (Buffer just fits, extra limbs, input unaligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:28:0:0
+
+Test mbedtls_mpi_core_io_le #5 (Extra limbs, buffer aligned to extra limbs, input limb-aligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":112:28:0:0
+
+Test mbedtls_mpi_core_io_le #6 (Extra limbs, buffer aligned to extra limbs, input unaligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":112:28:0:0
+
+Test mbedtls_mpi_core_io_le #7 (Buffer and limbs just fit, input limb-aligned with leading zeroes)
+mbedtls_mpi_core_io_le:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b44240000000000000000":88:24:0:0
+
+Test mbedtls_mpi_core_io_le #8 (Buffer and limbs just fit, input unaligned with leading zeroes)
+mbedtls_mpi_core_io_le:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b0000000000000000":86:24:0:0
+
+Test mbedtls_mpi_core_io_le #9 (Buffer just fits, extra limbs, input limb-aligned with leading zeroes)
+mbedtls_mpi_core_io_le:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b44240000000000000000":88:28:0:0
+
+Test mbedtls_mpi_core_io_le #10 (Buffer just fits, extra limbs, input unaligned with leading zeroes)
+mbedtls_mpi_core_io_le:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b0000000000000000":86:28:0:0
+
+Test mbedtls_mpi_core_io_le #11 (Zero)
+mbedtls_mpi_core_io_le:"00":1:1:0:0
+
+Test mbedtls_mpi_core_io_le #12 (Zero, empty output)
+mbedtls_mpi_core_io_le:"00":0:1:0:0
+
+Test mbedtls_mpi_core_io_le #13 (Zero, empty input)
+mbedtls_mpi_core_io_le:"":1:1:0:0
+
+Test mbedtls_mpi_core_io_le #14 (One)
+mbedtls_mpi_core_io_le:"01":1:1:0:0
+
+Test mbedtls_mpi_core_io_le #15 (One limb)
+depends_on:MBEDTLS_HAVE_INT32
+mbedtls_mpi_core_io_le:"000000ff":4:1:0:0
+
+Test mbedtls_mpi_core_io_le #16 (One limb)
+depends_on:MBEDTLS_HAVE_INT64
+mbedtls_mpi_core_io_le:"00000000000000ff":8:2:0:0
+
+Test mbedtls_mpi_core_io_le #17 (not enough limbs, input limb-aligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:22:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_core_io_le #18 (not enough limbs, input unaligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:22:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_core_io_le #19 (buffer too small, input limb-aligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":95:24:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_core_io_le #20 (buffer too small, input unaligned)
+mbedtls_mpi_core_io_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":93:24:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_core_io_le #21 (Buffer and limbs fit, input unaligned, odd number of limbs)
+mbedtls_mpi_core_io_le:"de4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b442400":82:21:0:0
+
+Test mbedtls_mpi_mod_raw_io #1 BE (Buffer and limbs just fit, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:24:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #1 LE (Buffer and limbs just fit, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:24:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #2 BE (Buffer and limbs just fit, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:24:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #2 LE (Buffer and limbs just fit, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:24:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #3 BE (Buffer just fits, extra limbs, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:28:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #3 LE (Buffer just fits, extra limbs, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:28:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #4 BE (Buffer just fits, extra limbs, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:28:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #4 LE (Buffer just fits, extra limbs, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:28:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #5 BE (Extra limbs, buffer aligned to extra limbs, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":112:28:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #5 LE (Extra limbs, buffer aligned to extra limbs, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":112:28:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #6 BE (Extra limbs, buffer aligned to extra limbs, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":112:28:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #6 LE (Extra limbs, buffer aligned to extra limbs, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":112:28:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #7 BE (Buffer and limbs just fit, input limb-aligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":88:24:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #7 LE (Buffer and limbs just fit, input limb-aligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b44240000000000000000":88:24:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #8 BE (Buffer and limbs just fit, input unaligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":86:24:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #8 LE (Buffer and limbs just fit, input unaligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b0000000000000000":86:24:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #9 BE (Buffer just fits, extra limbs, input limb-aligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":88:28:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #9 LE (Buffer just fits, extra limbs, input limb-aligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b44240000000000000000":88:28:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #10 BE (Buffer just fits, extra limbs, input unaligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"00000000000000001fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":86:28:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #10 LE (Buffer just fits, extra limbs, input unaligned with leading zeroes)
+mbedtls_mpi_mod_raw_io:"1fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b0000000000000000":86:28:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #11 BE (Zero)
+mbedtls_mpi_mod_raw_io:"00":1:1:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #11 LE (Zero)
+mbedtls_mpi_mod_raw_io:"00":1:1:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #12 BE (Zero, empty output)
+mbedtls_mpi_mod_raw_io:"00":0:1:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #12 LE (Zero, empty output)
+mbedtls_mpi_mod_raw_io:"00":0:1:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #13 BE (Zero, empty input)
+mbedtls_mpi_mod_raw_io:"":1:1:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #13 LE (Zero, empty input)
+mbedtls_mpi_mod_raw_io:"":1:1:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #14 BE (One)
+mbedtls_mpi_mod_raw_io:"01":1:1:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #14 LE (One)
+mbedtls_mpi_mod_raw_io:"01":1:1:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #14 BE (One limb)
+mbedtls_mpi_mod_raw_io:"ff00000000000000":8:2:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #14 LE (One limb)
+mbedtls_mpi_mod_raw_io:"00000000000000ff":8:2:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #15 BE (One limb)
+depends_on:MBEDTLS_HAVE_INT32
+mbedtls_mpi_mod_raw_io:"000000ff":4:1:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #15 LE (One limb)
+depends_on:MBEDTLS_HAVE_INT32
+mbedtls_mpi_mod_raw_io:"000000ff":4:1:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #16 BE (One limb)
+depends_on:MBEDTLS_HAVE_INT64
+mbedtls_mpi_mod_raw_io:"00000000000000ff":8:2:MBEDTLS_MPI_MOD_EXT_REP_BE:0:0
+
+Test mbedtls_mpi_mod_raw_io #16 LE (One limb)
+depends_on:MBEDTLS_HAVE_INT64
+mbedtls_mpi_mod_raw_io:"00000000000000ff":8:2:MBEDTLS_MPI_MOD_EXT_REP_LE:0:0
+
+Test mbedtls_mpi_mod_raw_io #17 BE (not enough limbs, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:22:MBEDTLS_MPI_MOD_EXT_REP_BE:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_mod_raw_io #17 LE (not enough limbs, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":96:22:MBEDTLS_MPI_MOD_EXT_REP_LE:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_mod_raw_io #18 BE (not enough limbs, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:22:MBEDTLS_MPI_MOD_EXT_REP_BE:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_mod_raw_io #18 LE (not enough limbs, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":94:22:MBEDTLS_MPI_MOD_EXT_REP_LE:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:0
+
+Test mbedtls_mpi_mod_raw_io #19 BE (buffer too small, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":95:24:MBEDTLS_MPI_MOD_EXT_REP_BE:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_mod_raw_io #19 LE (buffer too small, input limb-aligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":95:24:MBEDTLS_MPI_MOD_EXT_REP_LE:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_mod_raw_io #20 BE (buffer too small, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":93:24:MBEDTLS_MPI_MOD_EXT_REP_BE:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_mod_raw_io #20 LE (buffer too small, input unaligned)
+mbedtls_mpi_mod_raw_io:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b":93:24:MBEDTLS_MPI_MOD_EXT_REP_LE:0:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
+Test mbedtls_mpi_mod_raw_io #21 BE (modulus is equal to input)
+mbedtls_mpi_mod_raw_io:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":1024:256:MBEDTLS_MPI_MOD_EXT_REP_BE:MBEDTLS_ERR_MPI_BAD_INPUT_DATA:0
+
+Test mbedtls_mpi_mod_raw_io #21 LE (modulus is equal to input)
+mbedtls_mpi_mod_raw_io:"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":1024:256:MBEDTLS_MPI_MOD_EXT_REP_LE:MBEDTLS_ERR_MPI_BAD_INPUT_DATA:0
+
+Test mbedtls_mpi_mod_raw_io #22 (reading with invalid endianness)
+mbedtls_mpi_mod_raw_io:"":1:1:MBEDTLS_MPI_MOD_EXT_REP_INVALID:MBEDTLS_ERR_MPI_BAD_INPUT_DATA:0
+
+Test mbedtls_mpi_mod_raw_io #22 (writing with invalid endianness)
+mbedtls_mpi_mod_raw_io:"":1:1:MBEDTLS_MPI_MOD_EXT_REP_INVALID:0:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_mod_setup #1 (Both representations invalid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_INVALID:MBEDTLS_MPI_MOD_REP_INVALID:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_mod_setup #2 (Internal representation invalid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_LE:MBEDTLS_MPI_MOD_REP_INVALID:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_mod_setup #3 (Internal representation invalid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_BE:MBEDTLS_MPI_MOD_REP_INVALID:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_mod_setup #4 (External representation invalid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_INVALID:MBEDTLS_MPI_MOD_REP_MONTGOMERY:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_mod_setup #5 (External representation invalid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_INVALID:MBEDTLS_MPI_MOD_REP_OPT_RED:MBEDTLS_ERR_MPI_BAD_INPUT_DATA
+
+Test mbedtls_mpi_mod_setup #6 (Both representations valid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_BE:MBEDTLS_MPI_MOD_REP_OPT_RED:0
+
+Test mbedtls_mpi_mod_setup #7 (Both representations valid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_BE:MBEDTLS_MPI_MOD_REP_MONTGOMERY:0
+
+Test mbedtls_mpi_mod_setup #8 (Both representations valid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_LE:MBEDTLS_MPI_MOD_REP_OPT_RED:0
+
+Test mbedtls_mpi_mod_setup #9 (Both representations valid)
+mbedtls_mpi_mod_setup:MBEDTLS_MPI_MOD_EXT_REP_LE:MBEDTLS_MPI_MOD_REP_MONTGOMERY:0
+
Base test mbedtls_mpi_read_binary #1
mbedtls_mpi_read_binary:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":"0941379D00FED1491FE15DF284DFDE4A142F68AA8D412023195CEE66883E6290FFE703F4EA5963BF212713CEE46B107C09182B5EDCD955ADAC418BF4918E2889AF48E1099D513830CEC85C26AC1E158B52620E33BA8692F893EFBB2F958B4424"
@@ -292,6 +594,93 @@
Test mbedtls_mpi_cmp_mpi: large negative < 0 (1 limb)
mbedtls_mpi_cmp_mpi:"-1230000000000000000":"0":-1
+mbedtls_mpi_core_lt_ct: x=y (1 limb)
+mpi_core_lt_ct:"02B5":"02B5":0
+
+mbedtls_mpi_core_lt_ct: x>y (1 limb)
+mpi_core_lt_ct:"02B5":"02B4":0
+
+mbedtls_mpi_core_lt_ct: x<y (1 limb)
+mpi_core_lt_ct:"02B5":"02B6":1
+
+mbedtls_mpi_core_lt_ct: x=y (0 limbs)
+mpi_core_lt_ct:"":"":0
+
+mbedtls_mpi_core_lt_ct: x>y (63 bit x, y first byte greater)
+mpi_core_lt_ct:"7FFFFFFFFFFFFFFF":"FF":0
+
+mbedtls_mpi_core_lt_ct: x<y (63 bit y, x first byte greater)
+mpi_core_lt_ct:"FF":"7FFFFFFFFFFFFFFF":1
+
+mbedtls_mpi_core_lt_ct: x>y (64 bit x, y=x-1)
+mpi_core_lt_ct:"8000000000000000":"7FFFFFFFFFFFFFFF":0
+
+mbedtls_mpi_core_lt_ct: x<y (64 bit y, x=y-1)
+mpi_core_lt_ct:"7FFFFFFFFFFFFFFF":"8000000000000000":1
+
+mbedtls_mpi_core_lt_ct: x>y (64 bit x, y=1)
+mpi_core_lt_ct:"8000000000000000":"01":0
+
+mbedtls_mpi_core_lt_ct: x<y (64 bit y, x=1)
+mpi_core_lt_ct:"01":"8000000000000000":1
+
+mbedtls_mpi_core_lt_ct: x>y (64 bit x, y=0)
+mpi_core_lt_ct:"8000000000000000":"00":0
+
+mbedtls_mpi_core_lt_ct: x<y (64 bit y, x=0)
+mpi_core_lt_ct:"00":"8000000000000000":1
+
+mbedtls_mpi_core_lt_ct: x>y (64 bit x, first bytes equal)
+mpi_core_lt_ct:"FFFFFFFFFFFFFFFF":"FF":0
+
+mbedtls_mpi_core_lt_ct: x<y (64 bit y, first bytes equal)
+mpi_core_lt_ct:"FF":"FFFFFFFFFFFFFFFF":1
+
+mbedtls_mpi_core_lt_ct: x>y (31 bit x, y first byte greater)
+mpi_core_lt_ct:"7FFFFFFF":"FF":0
+
+mbedtls_mpi_core_lt_ct: x<y (31 bit y, x first byte greater)
+mpi_core_lt_ct:"FF":"7FFFFFFF":1
+
+mbedtls_mpi_core_lt_ct: x>y (32 bit x, y=x-1)
+mpi_core_lt_ct:"80000000":"7FFFFFFF":0
+
+mbedtls_mpi_core_lt_ct: x<y (32 bit y, x=y-1)
+mpi_core_lt_ct:"7FFFFFFF":"80000000":1
+
+mbedtls_mpi_core_lt_ct: x>y (32 bit x, y=1)
+mpi_core_lt_ct:"80000000":"01":0
+
+mbedtls_mpi_core_lt_ct: x<y (32 bit y, x=1)
+mpi_core_lt_ct:"01":"80000000":1
+
+mbedtls_mpi_core_lt_ct: x>y (32 bit x, y=0)
+mpi_core_lt_ct:"80000000":"00":0
+
+mbedtls_mpi_core_lt_ct: x<y (32 bit y, x=0)
+mpi_core_lt_ct:"00":"80000000":1
+
+mbedtls_mpi_core_lt_ct: x>y (32 bit x, first bytes equal)
+mpi_core_lt_ct:"FFFFFFFF":"FF":0
+
+mbedtls_mpi_core_lt_ct: x<y (32 bit y, first bytes equal)
+mpi_core_lt_ct:"FF":"FFFFFFFF":1
+
+mbedtls_mpi_core_lt_ct: x<y, zero vs non-zero MS limb
+mpi_core_lt_ct:"00FFFFFFFFFFFFFFFF":"01FFFFFFFFFFFFFFFF":1
+
+mbedtls_mpi_core_lt_ct: x>y, equal MS limbs
+mpi_core_lt_ct:"EEFFFFFFFFFFFFFFFF":"EEFFFFFFFFFFFFFFF1":0
+
+mbedtls_mpi_core_lt_ct: x=y (multi-limb)
+mpi_core_lt_ct:"EEFFFFFFFFFFFFFFFF":"EEFFFFFFFFFFFFFFFF":0
+
+mbedtls_mpi_core_lt_ct: x<y (alternating limbs)
+mpi_core_lt_ct:"11FFFFFFFFFFFFFFFF":"FF1111111111111111":1
+
+mbedtls_mpi_core_lt_ct: x>y (alternating limbs)
+mpi_core_lt_ct:"FF1111111111111111":"11FFFFFFFFFFFFFFFF":0
+
Base test mbedtls_mpi_lt_mpi_ct #1
mbedtls_mpi_lt_mpi_ct:1:"2B5":1:"2B5":0:0
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index 2694a44..dae3262 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -1,6 +1,11 @@
/* BEGIN_HEADER */
#include "mbedtls/bignum.h"
#include "mbedtls/entropy.h"
+#include "bignum_core.h"
+#include "bignum_mod.h"
+#include "bignum_mod_raw.h"
+#include "constant_time_internal.h"
+#include "test/constant_flow.h"
#if MBEDTLS_MPI_MAX_BITS > 792
#define MPI_MAX_BITS_LARGER_THAN_792
@@ -197,6 +202,273 @@
/* END_CASE */
/* BEGIN_CASE */
+void mbedtls_mpi_core_io_null()
+{
+ mbedtls_mpi_uint X = 0;
+ int ret;
+
+ ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+ ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+
+ ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+ ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+
+ ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+ ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+
+ ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+ ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
+ TEST_EQUAL( ret, 0 );
+
+exit:
+ ;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_core_io_be( data_t *input, int nb_int, int nx_32_int, int iret,
+ int oret )
+{
+ if( iret != 0 )
+ TEST_ASSERT( oret == 0 );
+
+ TEST_ASSERT( 0 <= nb_int );
+ size_t nb = nb_int;
+
+ unsigned char buf[1024];
+ TEST_ASSERT( nb <= sizeof( buf ) );
+
+ /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
+ * to halve the number of limbs to have the same size. */
+ size_t nx;
+ TEST_ASSERT( 0 <= nx_32_int );
+ if( sizeof( mbedtls_mpi_uint ) == 8 )
+ nx = nx_32_int / 2 + nx_32_int % 2;
+ else
+ nx = nx_32_int;
+
+ mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
+ TEST_ASSERT( nx <= sizeof( X ) / sizeof( X[0] ) );
+
+ int ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
+ TEST_EQUAL( ret, iret );
+
+ if( iret == 0 )
+ {
+ ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
+ TEST_EQUAL( ret, oret );
+ }
+
+ if( ( iret == 0 ) && ( oret == 0 ) )
+ {
+ if( nb > input->len )
+ {
+ size_t leading_zeroes = nb - input->len;
+ TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
+ for( size_t i = 0; i < leading_zeroes; i++ )
+ TEST_EQUAL( buf[i], 0 );
+ }
+ else
+ {
+ size_t leading_zeroes = input->len - nb;
+ TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
+ for( size_t i = 0; i < leading_zeroes; i++ )
+ TEST_EQUAL( input->x[i], 0 );
+ }
+ }
+
+exit:
+ ;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_32_int, int iret,
+ int oret )
+{
+ if( iret != 0 )
+ TEST_ASSERT( oret == 0 );
+
+ TEST_ASSERT( 0 <= nb_int );
+ size_t nb = nb_int;
+
+ unsigned char buf[1024];
+ TEST_ASSERT( nb <= sizeof( buf ) );
+
+ /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
+ * to halve the number of limbs to have the same size. */
+ size_t nx;
+ TEST_ASSERT( 0 <= nx_32_int );
+ if( sizeof( mbedtls_mpi_uint ) == 8 )
+ nx = nx_32_int / 2 + nx_32_int % 2;
+ else
+ nx = nx_32_int;
+
+ mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
+ TEST_ASSERT( nx <= sizeof( X ) / sizeof( X[0] ) );
+
+ int ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
+ TEST_EQUAL( ret, iret );
+
+ if( iret == 0 )
+ {
+ ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
+ TEST_EQUAL( ret, oret );
+ }
+
+ if( ( iret == 0 ) && ( oret == 0 ) )
+ {
+ if( nb > input->len )
+ {
+ TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
+ for( size_t i = input->len; i < nb; i++ )
+ TEST_EQUAL( buf[i], 0 );
+ }
+ else
+ {
+ TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
+ for( size_t i = nb; i < input->len; i++ )
+ TEST_EQUAL( input->x[i], 0 );
+ }
+ }
+
+exit:
+ ;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_mod_setup( int ext_rep, int int_rep, int iret )
+{
+ #define MLIMBS 8
+ mbedtls_mpi_uint mp[MLIMBS];
+ mbedtls_mpi_mod_modulus m;
+ int ret;
+
+ memset( mp, 0xFF, sizeof(mp) );
+
+ mbedtls_mpi_mod_modulus_init( &m );
+ ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, ext_rep, int_rep );
+ TEST_EQUAL( ret, iret );
+
+ /* Address sanitiser should catch if we try to free mp */
+ mbedtls_mpi_mod_modulus_free( &m );
+
+ /* Make sure that the modulus doesn't have reference to mp anymore */
+ TEST_ASSERT( m.p != mp );
+
+exit:
+ /* It should be safe to call an mbedtls free several times */
+ mbedtls_mpi_mod_modulus_free( &m );
+
+ #undef MLIMBS
+}
+/* END_CASE */
+
+
+/* BEGIN_CASE */
+void mbedtls_mpi_mod_raw_io( data_t *input, int nb_int, int nx_32_int,
+ int iendian, int iret, int oret )
+{
+ if( iret != 0 )
+ TEST_ASSERT( oret == 0 );
+
+ TEST_ASSERT( 0 <= nb_int );
+ size_t nb = nb_int;
+
+ unsigned char buf[1024];
+ TEST_ASSERT( nb <= sizeof( buf ) );
+
+ /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
+ * to halve the number of limbs to have the same size. */
+ size_t nx;
+ TEST_ASSERT( 0 <= nx_32_int );
+ if( sizeof( mbedtls_mpi_uint ) == 8 )
+ nx = nx_32_int / 2 + nx_32_int % 2;
+ else
+ nx = nx_32_int;
+
+ mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
+ TEST_ASSERT( nx <= sizeof( X ) / sizeof( X[0] ) );
+
+ int endian;
+ if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
+ endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
+ else
+ endian = iendian;
+
+ mbedtls_mpi_mod_modulus m;
+ mbedtls_mpi_mod_modulus_init( &m );
+ mbedtls_mpi_uint init[sizeof( X ) / sizeof( X[0] )];
+ memset( init, 0xFF, sizeof( init ) );
+ int ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, endian,
+ MBEDTLS_MPI_MOD_REP_MONTGOMERY );
+ TEST_EQUAL( ret, 0 );
+
+ if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
+ m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
+
+ ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len );
+ TEST_EQUAL( ret, iret );
+
+ if( iret == 0 )
+ {
+ if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
+ m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
+
+ ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb );
+ TEST_EQUAL( ret, oret );
+ }
+
+ if( ( iret == 0 ) && ( oret == 0 ) )
+ {
+ if( nb > input->len )
+ {
+ if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
+ {
+ size_t leading_zeroes = nb - input->len;
+ TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
+ for( size_t i = 0; i < leading_zeroes; i++ )
+ TEST_EQUAL( buf[i], 0 );
+ }
+ else
+ {
+ TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
+ for( size_t i = input->len; i < nb; i++ )
+ TEST_EQUAL( buf[i], 0 );
+ }
+ }
+ else
+ {
+ if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
+ {
+ size_t leading_zeroes = input->len - nb;
+ TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
+ for( size_t i = 0; i < leading_zeroes; i++ )
+ TEST_EQUAL( input->x[i], 0 );
+ }
+ else
+ {
+ TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
+ for( size_t i = nb; i < input->len; i++ )
+ TEST_EQUAL( input->x[i], 0 );
+ }
+ }
+ }
+
+exit:
+ mbedtls_mpi_mod_modulus_free( &m );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
{
mbedtls_mpi X;
@@ -456,6 +728,42 @@
/* END_CASE */
/* BEGIN_CASE */
+void mpi_core_lt_ct( data_t * input_X, data_t * input_Y, int input_ret )
+{
+ #define MAX_LEN 64
+ mbedtls_mpi_uint X[MAX_LEN];
+ mbedtls_mpi_uint Y[MAX_LEN];
+ unsigned exp_ret = input_ret;
+ unsigned ret;
+ size_t len = CHARS_TO_LIMBS(
+ input_X->len > input_Y->len ? input_X->len : input_Y->len );
+
+ TEST_ASSERT( len <= MAX_LEN );
+
+ TEST_ASSERT( mbedtls_mpi_core_read_be( X, len, input_X->x, input_X->len )
+ == 0 );
+ TEST_ASSERT( mbedtls_mpi_core_read_be( Y, len, input_Y->x, input_Y->len )
+ == 0 );
+
+ TEST_CF_SECRET( X, len * sizeof( mbedtls_mpi_uint ) );
+ TEST_CF_SECRET( Y, len * sizeof( mbedtls_mpi_uint ) );
+
+ ret = mbedtls_mpi_core_lt_ct( X, Y, len );
+
+ TEST_CF_PUBLIC( X, len * sizeof( mbedtls_mpi_uint ) );
+ TEST_CF_PUBLIC( Y, len * sizeof( mbedtls_mpi_uint ) );
+ TEST_CF_PUBLIC( &ret, sizeof( ret ) );
+
+ TEST_EQUAL( ret, exp_ret );
+
+exit:
+ ;
+
+ #undef MAX_LEN
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
int size_Y, char * input_Y,
int input_ret, int input_err )