Added ecp_read_binary().
diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h
index cd4dd9b..189e3f2 100644
--- a/include/polarssl/ecp.h
+++ b/include/polarssl/ecp.h
@@ -218,7 +218,7 @@
/**
* \brief Export a point into unsigned binary data
*
- * \param grp Group the point belongs to
+ * \param grp Group to which the point should belong
* \param P Point to export
* \param format Point format, should be a POLARSSL_ECP_PF_XXX macro
* \param olen Length of the actual ouput
@@ -231,6 +231,25 @@
size_t *olen, unsigned char *buf, size_t buflen );
/**
+ * \brief Import a point from unsigned binary data
+ *
+ * \param grp Group to which the point should belong
+ * \param P Point to import
+ * \param format Point format, must be POLARSSL_ECP_PF_UNCOMPRESSED for now
+ * \param buf Input buffer
+ * \param ilen Actual length of input
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_ECP_GENERIC if input is invalid
+ * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ *
+ * \note This function does NOT check that the point actually
+ * belongs to the given group, see ecp_check_pubkey() for
+ * that.
+ */
+int ecp_read_binary( const ecp_group *grp, ecp_point *P, int format,
+ const unsigned char *buf, size_t ilen );
+/**
* \brief Set a group using well-known domain parameters
*
* \param grp Destination group
diff --git a/library/ecp.c b/library/ecp.c
index 6501fbe..dd913be 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -229,6 +229,33 @@
}
/*
+ * Import a point from unsigned binary data (SEC1 2.3.4)
+ */
+int ecp_read_binary( const ecp_group *grp, ecp_point *P, int format,
+ const unsigned char *buf, size_t ilen ) {
+ int ret;
+ size_t plen;
+
+ if( format != POLARSSL_ECP_PF_UNCOMPRESSED )
+ return( POLARSSL_ERR_ECP_GENERIC );
+
+ if( ilen == 1 && buf[0] == 0x00 )
+ return( ecp_set_zero( P ) );
+
+ plen = mpi_size( &grp-> P );
+
+ if( ilen != 2 * plen + 1 || buf[0] != 0x04 )
+ return( POLARSSL_ERR_ECP_GENERIC );
+
+ MPI_CHK( mpi_read_binary( &P->X, buf + 1, plen ) );
+ MPI_CHK( mpi_read_binary( &P->Y, buf + 1 + plen, plen ) );
+ MPI_CHK( mpi_lset( &P->Z, 1 ) );
+
+cleanup:
+ return( ret );
+}
+
+/*
* Wrapper around fast quasi-modp functions, with fall-back to mpi_mod_mpi.
* See the documentation of struct ecp_group.
*/
diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data
index e84ac04..605af82 100644
--- a/tests/suites/test_suite_ecp.data
+++ b/tests/suites/test_suite_ecp.data
@@ -163,6 +163,27 @@
ECP write binary #7 (odd, compressed, buffer just fits)
ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"93112b28345b7d1d7799611e49bea9d8290cb2d7afe1f9f3":"01":COMPRESSED:"0348d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":25:0
+ECP read binary #0 (invalid format)
+ecp_read_binary:SECP192R1:"00":UNKNOWN:"01":"01":"00":POLARSSL_ERR_ECP_GENERIC
+
+ECP read binary #1 (zero, invalid ilen)
+ecp_read_binary:SECP192R1:"0000":UNCOMPRESSED:"01":"01":"00":POLARSSL_ERR_ECP_GENERIC
+
+ECP read binary #2 (zero, invalid first byte)
+ecp_read_binary:SECP192R1:"01":UNCOMPRESSED:"01":"01":"00":POLARSSL_ERR_ECP_GENERIC
+
+ECP read binary #3 (zero, OK)
+ecp_read_binary:SECP192R1:"00":UNCOMPRESSED:"01":"01":"00":0
+
+ECP read binary #4 (non-zero, invalid ilen)
+ecp_read_binary:SECP192R1:"04001122":UNCOMPRESSED:"01":"01":"00":POLARSSL_ERR_ECP_GENERIC
+
+ECP read binary #5 (non-zero, invalid first byte)
+ecp_read_binary:SECP192R1:"0548d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":UNCOMPRESSED:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":POLARSSL_ERR_ECP_GENERIC
+
+ECP read binary #6 (non-zero, OK)
+ecp_read_binary:SECP192R1:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":UNCOMPRESSED:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":0
+
ECP mod p192 readable
ecp_fast_mod:SECP192R1:"000000000000010500000000000001040000000000000103000000000000010200000000000001010000000000000100"
diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function
index b273a70..fdd3da2 100644
--- a/tests/suites/test_suite_ecp.function
+++ b/tests/suites/test_suite_ecp.function
@@ -258,6 +258,44 @@
END_CASE
BEGIN_CASE
+ecp_read_binary:id:input:format:x:y:z:ret
+{
+ ecp_group grp;
+ ecp_point P;
+ mpi X, Y, Z;
+ int ilen;
+ unsigned char buf[256];
+
+ memset( buf, 0, sizeof( buf ) );
+
+ ecp_group_init( &grp ); ecp_point_init( &P );
+ mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
+
+ TEST_ASSERT( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_{id} ) == 0 );
+
+ TEST_ASSERT( mpi_read_string( &X, 16, {x} ) == 0 );
+ TEST_ASSERT( mpi_read_string( &Y, 16, {y} ) == 0 );
+ TEST_ASSERT( mpi_read_string( &Z, 16, {z} ) == 0 );
+
+ ilen = unhexify( buf, {input} );
+
+#define POLARSSL_ECP_PF_UNKNOWN -1
+ TEST_ASSERT( ecp_read_binary( &grp, &P, POLARSSL_ECP_PF_{format},
+ buf, ilen ) == {ret} );
+
+ if( {ret} == 0 )
+ {
+ TEST_ASSERT( mpi_cmp_mpi( &P.X, &X ) == 0 );
+ TEST_ASSERT( mpi_cmp_mpi( &P.Y, &Y ) == 0 );
+ TEST_ASSERT( mpi_cmp_mpi( &P.Z, &Z ) == 0 );
+ }
+
+ ecp_group_free( &grp ); ecp_point_free( &P );
+ mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
+}
+END_CASE
+
+BEGIN_CASE
ecp_selftest:
{
TEST_ASSERT( ecp_self_test( 0 ) == 0 );