Merge remote-tracking branch 'restricted/pr/551' into development
* restricted/pr/551:
ECP: Clarify test descriptions
ECP: remove extra whitespaces
Fix ECDH secret export for Mongomery curves
Improve ECP test names
Make ecp_get_type public
Add more tests for ecp_read_key
ECP: Catch unsupported import/export
Improve documentation of mbedtls_ecp_read_key
Fix typo in ECP module
Remove unnecessary cast from ECP test
Improve mbedtls_ecp_point_read_binary tests
Add Montgomery points to ecp_point_write_binary
ECDH: Add test vectors for Curve25519
Add little endian export to Bignum
Add mbedtls_ecp_read_key
Add Montgomery points to ecp_point_read_binary
Add little endian import to Bignum
diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h
index a54c18e..c4d7686 100644
--- a/include/mbedtls/bignum.h
+++ b/include/mbedtls/bignum.h
@@ -490,8 +490,24 @@
size_t buflen );
/**
- * \brief Export an MPI into unsigned big endian binary data
- * of fixed size.
+ * \brief Import X from unsigned binary data, little endian
+ *
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param buf The input buffer. This must be a readable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The length of the input buffer \p p in Bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
+ const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief Export X into unsigned binary data, big endian.
+ * Always fills the whole buffer, which will start with zeros
+ * if the number is smaller.
*
* \param X The source MPI. This must point to an initialized MPI.
* \param buf The output buffer. This must be a writable buffer of length
@@ -507,6 +523,24 @@
size_t buflen );
/**
+ * \brief Export X into unsigned binary data, little endian.
+ * Always fills the whole buffer, which will end with zeros
+ * if the number is smaller.
+ *
+ * \param X The source MPI. This must point to an initialized MPI.
+ * \param buf The output buffer. This must be a writable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The size of the output buffer \p buf in Bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
+ * large enough to hold the value of \p X.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
+ unsigned char *buf, size_t buflen );
+
+/**
* \brief Perform a left-shift on an MPI: X <<= count
*
* \param X The MPI to shift. This must point to an initialized MPI.
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 065a4cc..0b2504e 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -99,6 +99,16 @@
*/
#define MBEDTLS_ECP_DP_MAX 12
+/*
+ * Curve types
+ */
+typedef enum
+{
+ MBEDTLS_ECP_TYPE_NONE = 0,
+ MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
+ MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
+} mbedtls_ecp_curve_type;
+
/**
* Curve information, for use by other modules.
*/
@@ -417,6 +427,11 @@
int mbedtls_ecp_restart_is_enabled( void );
#endif /* MBEDTLS_ECP_RESTARTABLE */
+/*
+ * Get the type of a curve
+ */
+mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp );
+
/**
* \brief This function retrieves the information defined in
* mbedtls_ecp_curve_info() for all supported curves in order
@@ -626,6 +641,9 @@
* \param P The point to export. This must be initialized.
* \param format The point format. This must be either
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * (For groups without these formats, this parameter is
+ * ignored. But it still has to be either of the above
+ * values.)
* \param olen The address at which to store the length of
* the output in Bytes. This must not be \c NULL.
* \param buf The output buffer. This must be a writable buffer
@@ -635,11 +653,14 @@
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
* is too small to hold the point.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ * or the export for the given group is not implemented.
* \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
- int format, size_t *olen,
- unsigned char *buf, size_t buflen );
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *P,
+ int format, size_t *olen,
+ unsigned char *buf, size_t buflen );
/**
* \brief This function imports a point from unsigned binary data.
@@ -660,8 +681,8 @@
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
- * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
- * is not implemented.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the
+ * given group is not implemented.
*/
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P,
@@ -1094,6 +1115,26 @@
void *p_rng );
/**
+ * \brief This function reads an elliptic curve private key.
+ *
+ * \param grp_id The ECP group identifier.
+ * \param key The destination key.
+ * \param buf The the buffer containing the binary representation of the
+ * key. (Big endian integer for Weierstrass curves, byte
+ * string for Montgomery curves.)
+ * \param buflen The length of the buffer in bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is
+ * invalid.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
+ * the group is not implemented.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+ const unsigned char *buf, size_t buflen );
+/**
* \brief This function checks that the keypair objects
* \p pub and \p prv have the same group and the
* same public point, and that the private key in
diff --git a/library/bignum.c b/library/bignum.c
index 47e4529..592aa2e 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -814,6 +814,39 @@
}
/*
+ * Import X from unsigned binary data, little endian
+ */
+int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
+ const unsigned char *buf, size_t buflen )
+{
+ int ret;
+ size_t i;
+ size_t const limbs = CHARS_TO_LIMBS( buflen );
+
+ /* Ensure that target MPI has exactly the necessary number of limbs */
+ if( X->n != limbs )
+ {
+ mbedtls_mpi_free( X );
+ mbedtls_mpi_init( X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
+ }
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+
+ for( i = 0; i < buflen; i++ )
+ X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
+
+cleanup:
+
+ /*
+ * This function is also used to import keys. However, wiping the buffers
+ * upon failure is not necessary because failure only can happen before any
+ * input is copied.
+ */
+ return( ret );
+}
+
+/*
* Import X from unsigned binary data, big endian
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
@@ -847,10 +880,54 @@
cleanup:
+ /*
+ * This function is also used to import keys. However, wiping the buffers
+ * upon failure is not necessary because failure only can happen before any
+ * input is copied.
+ */
return( ret );
}
/*
+ * Export X into unsigned binary data, little endian
+ */
+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 );
+}
+
+/*
* Export X into unsigned binary data, big endian
*/
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
diff --git a/library/ecdh.c b/library/ecdh.c
index c572687..eecae91 100644
--- a/library/ecdh.c
+++ b/library/ecdh.c
@@ -637,6 +637,10 @@
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
+
+ if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
+
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
}
diff --git a/library/ecp.c b/library/ecp.c
index ecea591..c3c5ce5 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -364,16 +364,6 @@
#endif
/*
- * Curve types: internal for now, might be exposed later
- */
-typedef enum
-{
- ECP_TYPE_NONE = 0,
- ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
- ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
-} ecp_curve_type;
-
-/*
* List of supported curves:
* - internal ID
* - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
@@ -522,15 +512,15 @@
/*
* Get the type of a curve
*/
-static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
+mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp )
{
if( grp->G.X.p == NULL )
- return( ECP_TYPE_NONE );
+ return( MBEDTLS_ECP_TYPE_NONE );
if( grp->G.Y.p == NULL )
- return( ECP_TYPE_MONTGOMERY );
+ return( MBEDTLS_ECP_TYPE_MONTGOMERY );
else
- return( ECP_TYPE_SHORT_WEIERSTRASS );
+ return( MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS );
}
/*
@@ -729,14 +719,14 @@
}
/*
- * Export a point into unsigned binary data (SEC1 2.3.3)
+ * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748)
*/
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P,
int format, size_t *olen,
unsigned char *buf, size_t buflen )
{
- int ret = 0;
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
size_t plen;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( P != NULL );
@@ -745,56 +735,71 @@
ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
format == MBEDTLS_ECP_PF_COMPRESSED );
- /*
- * Common case: P == 0
- */
- if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
- {
- if( buflen < 1 )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
-
- buf[0] = 0x00;
- *olen = 1;
-
- return( 0 );
- }
-
plen = mbedtls_mpi_size( &grp->P );
- if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+#if defined(ECP_MONTGOMERY)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
- *olen = 2 * plen + 1;
-
+ *olen = plen;
if( buflen < *olen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- buf[0] = 0x04;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) );
}
- else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+#endif
+#if defined(ECP_SHORTWEIERSTRASS)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
- *olen = plen + 1;
+ /*
+ * Common case: P == 0
+ */
+ if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
+ {
+ if( buflen < 1 )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- if( buflen < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+ buf[0] = 0x00;
+ *olen = 1;
- buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ return( 0 );
+ }
+
+ if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+ {
+ *olen = 2 * plen + 1;
+
+ if( buflen < *olen )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+ buf[0] = 0x04;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+ }
+ else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+ {
+ *olen = plen + 1;
+
+ if( buflen < *olen )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+ buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ }
}
+#endif
cleanup:
return( ret );
}
/*
- * Import a point from unsigned binary data (SEC1 2.3.4)
+ * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748)
*/
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt,
const unsigned char *buf, size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
size_t plen;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( pt != NULL );
@@ -803,25 +808,47 @@
if( ilen < 1 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( buf[0] == 0x00 )
- {
- if( ilen == 1 )
- return( mbedtls_ecp_set_zero( pt ) );
- else
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
-
plen = mbedtls_mpi_size( &grp->P );
- if( buf[0] != 0x04 )
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#if defined(ECP_MONTGOMERY)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ if( plen != ilen )
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( ilen != 2 * plen + 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &pt->X, buf, plen ) );
+ mbedtls_mpi_free( &pt->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ if( grp->id == MBEDTLS_ECP_DP_CURVE25519 )
+ /* Set most significant bit to 0 as prescribed in RFC7748 §5 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ }
+#endif
+#if defined(ECP_SHORTWEIERSTRASS)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ if( buf[0] == 0x00 )
+ {
+ if( ilen == 1 )
+ return( mbedtls_ecp_set_zero( pt ) );
+ else
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ }
+
+ if( buf[0] != 0x04 )
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+
+ if( ilen != 2 * plen + 1 )
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y,
+ buf + 1 + plen, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ }
+#endif
cleanup:
return( ret );
@@ -2357,11 +2384,11 @@
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
#endif
#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
#endif
@@ -2500,7 +2527,7 @@
ECP_VALIDATE_RET( n != NULL );
ECP_VALIDATE_RET( Q != NULL );
- if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
mbedtls_ecp_point_init( &mP );
@@ -2620,11 +2647,11 @@
return( MBEDTLS_ERR_ECP_INVALID_KEY );
#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
return( ecp_check_pubkey_mx( grp, pt ) );
#endif
#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( ecp_check_pubkey_sw( grp, pt ) );
#endif
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -2640,7 +2667,7 @@
ECP_VALIDATE_RET( d != NULL );
#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/* see RFC 7748 sec. 5 para. 5 */
if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
@@ -2656,7 +2683,7 @@
}
#endif /* ECP_MONTGOMERY */
#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/* see SEC1 3.2 */
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
@@ -2688,7 +2715,7 @@
n_size = ( grp->nbits + 7 ) / 8;
#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/* [M225] page 5 */
size_t b;
@@ -2716,7 +2743,7 @@
#endif /* ECP_MONTGOMERY */
#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
int count = 0;
@@ -2809,6 +2836,75 @@
return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
}
+#define ECP_CURVE25519_KEY_SIZE 32
+/*
+ * Read a private key.
+ */
+int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+ const unsigned char *buf, size_t buflen )
+{
+ int ret = 0;
+
+ ECP_VALIDATE_RET( key != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+
+ if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
+ return( ret );
+
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+#if defined(ECP_MONTGOMERY)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ /*
+ * If it is Curve25519 curve then mask the key as mandated by RFC7748
+ */
+ if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
+ {
+ if( buflen != ECP_CURVE25519_KEY_SIZE )
+ return MBEDTLS_ERR_ECP_INVALID_KEY;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
+
+ /* Set the three least significant bits to 0 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) );
+
+ /* Set the most significant bit to 0 */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( &key->d,
+ ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 )
+ );
+
+ /* Set the second most significant bit to 1 */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( &key->d,
+ ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 )
+ );
+ }
+ else
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+ }
+
+#endif
+#if defined(ECP_SHORTWEIERSTRASS)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) );
+
+ MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) );
+ }
+
+#endif
+cleanup:
+
+ if( ret != 0 )
+ mbedtls_mpi_free( &key->d );
+
+ return( ret );
+}
+
/*
* Check a public-private key pair
*/
diff --git a/tests/suites/test_suite_ecdh.data b/tests/suites/test_suite_ecdh.data
index af25359..fb4a232 100644
--- a/tests/suites/test_suite_ecdh.data
+++ b/tests/suites/test_suite_ecdh.data
@@ -88,6 +88,18 @@
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_SECP256R1:"c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53":"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":1:"d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de"
+ecdh calc_secret: ours first (Alice), curve25519 (rfc 7748)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_CURVE25519:"77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":"de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":0:"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+
+ecdh calc_secret: theirs first (Alice), curve25519 (rfc 7748)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_CURVE25519:"77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a":"de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f":1:"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+
+ecdh calc_secret: ours first (Bob), curve25519 (rfc 7748)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecdh_exchange_calc_secret:MBEDTLS_ECP_DP_CURVE25519:"5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb":"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":0:"4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+
ECDH get_params with mismatched groups: our BP256R1, their SECP256R1
depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_BP256R1_ENABLED
ecdh_exchange_get_params_fail:MBEDTLS_ECP_DP_BP256R1:"1234567812345678123456781234567812345678123456781234567812345678":MBEDTLS_ECP_DP_SECP256R1:"04dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3":0:MBEDTLS_ERR_ECP_BAD_INPUT_DATA
diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function
index 1a33d81..d6bed7f 100644
--- a/tests/suites/test_suite_ecdh.function
+++ b/tests/suites/test_suite_ecdh.function
@@ -22,10 +22,9 @@
rnd_pseudo_info *rnd_info )
{
int ok = 0;
- TEST_ASSERT( mbedtls_ecp_group_load( &ecp->grp, grp_id ) == 0 );
- TEST_ASSERT( mbedtls_mpi_read_binary( &ecp->d,
- private_key->x,
- private_key->len ) == 0 );
+ TEST_ASSERT( mbedtls_ecp_read_key( grp_id, ecp,
+ private_key->x,
+ private_key->len ) == 0 );
TEST_ASSERT( mbedtls_ecp_check_privkey( &ecp->grp, &ecp->d ) == 0 );
/* Calculate the public key from the private key. */
TEST_ASSERT( mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d,
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index 30d5ec6..8653366 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -88,6 +88,14 @@
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
ecp_write_binary:MBEDTLS_ECP_DP_SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"93112b28345b7d1d7799611e49bea9d8290cb2d7afe1f9f3":"01":MBEDTLS_ECP_PF_COMPRESSED:"0348d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":25:0
+ECP write binary #10 (Montgomery, buffer just fits)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_binary:MBEDTLS_ECP_DP_CURVE25519:"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff":"0":"1":MBEDTLS_ECP_PF_COMPRESSED:"ffeeddccbbaa00998877665544332211ffeeddccbbaa00998877665544332211":32:0
+
+ECP write binary #11 (Montgomery, buffer too small)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_write_binary:MBEDTLS_ECP_DP_CURVE25519:"11223344556677889900aabbccddeeff11223344556677889900aabbccddeeff":"0":"1":MBEDTLS_ECP_PF_COMPRESSED:"ffeeddccbbaa00998877665544332211ffeeddccbbaa00998877665544332211":31:MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
+
ECP read binary #1 (zero, invalid ilen)
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
ecp_read_binary:MBEDTLS_ECP_DP_SECP192R1:"0000":"01":"01":"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
@@ -112,6 +120,30 @@
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
ecp_read_binary:MBEDTLS_ECP_DP_SECP192R1:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":0
+ECP read binary #7 (Curve25519, OK)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":0
+
+ECP read binary #8 (Curve25519, masked first bit)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4efa":"7a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":0
+
+ECP read binary #9 (Curve25519, too short)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"20f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f020":"0":"1":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
+ECP read binary #10 (Curve25519, non-canonical)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"0":"1":0
+
+ECP read binary #11 (Curve25519, masked non-canonical)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":"0":"1":0
+
+ECP read binary #12 (Curve25519, too long)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ecp_read_binary:MBEDTLS_ECP_DP_CURVE25519:"8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a00":"6a4e9baa8ea9a4ebf41a38260d3abf0d5af73eb4dc7d8b7454a7308909f02085":"0":"1":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+
ECP tls read point #1 (zero, invalid length byte)
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
mbedtls_ecp_tls_read_point:MBEDTLS_ECP_DP_SECP192R1:"0200":"01":"01":"00":MBEDTLS_ERR_ECP_BAD_INPUT_DATA
@@ -244,6 +276,68 @@
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
mbedtls_ecp_gen_key:MBEDTLS_ECP_DP_SECP192R1
+ECP read key #1 (short weierstrass, too small)
+depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"00":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP read key #2 (short weierstrass, smallest)
+depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"01":0
+
+ECP read key #3 (short weierstrass, biggest)
+depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830":0
+
+ECP read key #4 (short weierstrass, too big)
+depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_SECP192R1:"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP read key #5 (Curve25519, most significant bit set)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"000000000000000000000000000000000000000000000000000000000000000C":0
+
+ECP read key #6 (Curve25519, second most significant bit unset)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":0
+
+ECP read key #7 (Curve25519, msb OK)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0000000000000000000000000000000000000000000000000000000000000004":0
+
+ECP read key #8 (Curve25519, bit 0 set)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"1000000000000000000000000000000000000000000000000000000000000000":0
+
+ECP read key #9 (Curve25519, bit 1 set)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"2000000000000000000000000000000000000000000000000000000000000004":0
+
+ECP read key #10 (Curve25519, bit 2 set)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"4000000000000000000000000000000000000000000000000000000000000004":0
+
+ECP read key #11 (Curve25519, OK)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":0
+
+ECP read key #12 (Curve25519, too long)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"00000000000000000000000000000000000000000000000000000000000000000C":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP read key #13 (Curve25519, not long enough)
+depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3":MBEDTLS_ERR_ECP_INVALID_KEY
+
+ECP read key #14 (Curve448, not supported)
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE448:"FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
+
+ECP read key #15 (Curve25519, not supported)
+depends_on:!MBEDTLS_ECP_DP_CURVE25519_ENABLED
+mbedtls_ecp_read_key:MBEDTLS_ECP_DP_CURVE25519:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
+
+ECP read key #15 (invalid curve)
+mbedtls_ecp_read_key:INT_MAX:"8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7":MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
+
ECP mod p192 small (more than 192 bits, less limbs than 2 * 192 bits)
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
ecp_fast_mod:MBEDTLS_ECP_DP_SECP192R1:"0100000000000103010000000000010201000000000001010100000000000100"
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index 0b2e029..7eeea28 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -762,8 +762,18 @@
if( ret == 0 )
{
TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.X, &X ) == 0 );
- TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Y, &Y ) == 0 );
- TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Z, &Z ) == 0 );
+ if( mbedtls_ecp_get_type( &grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, 0 ) == 0 );
+ TEST_ASSERT( P.Y.p == NULL );
+ TEST_ASSERT( mbedtls_mpi_cmp_int( &Z, 1 ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_cmp_int( &P.Z, 1 ) == 0 );
+ }
+ else
+ {
+ TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Y, &Y ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_cmp_mpi( &P.Z, &Z ) == 0 );
+ }
}
exit:
@@ -1008,6 +1018,28 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void mbedtls_ecp_read_key( int grp_id, data_t* in_key, int expected )
+{
+ int ret = 0;
+ mbedtls_ecp_keypair key;
+
+ mbedtls_ecp_keypair_init( &key );
+
+ ret = mbedtls_ecp_read_key( grp_id, &key, in_key->x, in_key->len );
+ TEST_ASSERT( ret == expected );
+
+ if( expected == 0 )
+ {
+ ret = mbedtls_ecp_check_privkey( &key.grp, &key.d );
+ TEST_ASSERT( ret == 0 );
+ }
+
+exit:
+ mbedtls_ecp_keypair_free( &key );
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void ecp_selftest( )
{
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 8b5f97d..f2be148 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -58,6 +58,9 @@
Base test mbedtls_mpi_read_binary #1
mbedtls_mpi_read_binary:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924"
+Base test mbedtls_mpi_read_binary_le #1
+mbedtls_mpi_read_binary_le:"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":10:"219946662473865722255717126709915431768051735954189829340600976826409773245337023925691629251672268961177825243440202069039100741562168093042339401187848509859789949044607421190014088260008793380554914226244485299326152319899746569"
+
Base test mbedtls_mpi_write_binary #1
mbedtls_mpi_write_binary:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":"0941379d00fed1491fe15df284dfde4a142f68aa8d412023195cee66883e6290ffe703f4ea5963bf212713cee46b107c09182b5edcd955adac418bf4918e2889af48e1099d513830cec85c26ac1e158b52620e33ba8692f893efbb2f958b4424":200:0
@@ -67,6 +70,15 @@
Test mbedtls_mpi_write_binary #2 (Buffer too small)
mbedtls_mpi_write_binary:16:"123123123123123123123123123":"23123123123123123123123123":13:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+Base test mbedtls_mpi_write_binary_le #1
+mbedtls_mpi_write_binary_le:10:"56125680981752282334141896320372489490613963693556392520816017892111350604111697682705498319512049040516698827829292076808006940873974979584527073481012636016353913462376755556720019831187364993587901952757307830896531678727717924":"24448b952fbbef93f89286ba330e62528b151eac265cc8ce3038519d09e148af89288e91f48b41acad55d9dc5e2b18097c106be4ce132721bf6359eaf403e7ff90623e8866ee5c192320418daa682f144adedf84f25de11f49d1fe009d374109":200:0
+
+Test mbedtls_mpi_write_binary_le #1 (Buffer just fits)
+mbedtls_mpi_write_binary_le:16:"123123123123123123123123123":"2331122331122331122331122301":14:0
+
+Test mbedtls_mpi_write_binary_le #2 (Buffer too small)
+mbedtls_mpi_write_binary_le:16:"123123123123123123123123123":"23311223311223311223311223":13:MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL
+
Base test mbedtls_mpi_read_file #1
mbedtls_mpi_read_file:10:"data_files/mpi_10":"01f55332c3a48b910f9942f6c914e58bef37a47ee45cb164a5b6b8d1006bf59a059c21449939ebebfdf517d2e1dbac88010d7b1f141e997bd6801ddaec9d05910f4f2de2b2c4d714e2c14a72fc7f17aa428d59c531627f09":0
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index d1fa5a4..67894e6 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -313,14 +313,33 @@
void mbedtls_mpi_read_binary( data_t * buf, int radix_A, char * input_A )
{
mbedtls_mpi X;
- unsigned char str[1000];
+ char str[1000];
size_t len;
mbedtls_mpi_init( &X );
TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
- TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, (char *) str, sizeof( str ), &len ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
+ TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
+
+exit:
+ mbedtls_mpi_free( &X );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void mbedtls_mpi_read_binary_le( data_t * buf, int radix_A, char * input_A )
+{
+ mbedtls_mpi X;
+ char str[1000];
+ size_t len;
+
+ mbedtls_mpi_init( &X );
+
+
+ TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
+ TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
exit:
@@ -359,6 +378,37 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void mbedtls_mpi_write_binary_le( int radix_X, char * input_X,
+ data_t * input_A, int output_size,
+ int result )
+{
+ mbedtls_mpi X;
+ unsigned char buf[1000];
+ size_t buflen;
+
+ memset( buf, 0x00, 1000 );
+
+ mbedtls_mpi_init( &X );
+
+ TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == 0 );
+
+ buflen = mbedtls_mpi_size( &X );
+ if( buflen > (size_t) output_size )
+ buflen = (size_t) output_size;
+
+ TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
+ if( result == 0)
+ {
+
+ TEST_ASSERT( hexcmp( buf, input_A->x, buflen, input_A->len ) == 0 );
+ }
+
+exit:
+ mbedtls_mpi_free( &X );
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
void mbedtls_mpi_read_file( int radix_X, char * input_file,
data_t * input_A, int result )