diff --git a/include/polarssl/ecp.h b/include/polarssl/ecp.h index a875d7ec8..cd4dd9b27 100644 --- a/include/polarssl/ecp.h +++ b/include/polarssl/ecp.h @@ -115,6 +115,12 @@ ecp_group; */ #define POLARSSL_ECP_WINDOW_SIZE 7 /**< Maximum NAF width used. */ +/* + * Point formats + */ +#define POLARSSL_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */ +#define POLARSSL_ECP_PF_COMPRESSED 1 /**< Compressed point format */ + #ifdef __cplusplus extern "C" { #endif @@ -210,17 +216,18 @@ int ecp_group_read_string( ecp_group *grp, int radix, const char *gx, const char *gy, const char *n); /** - * \brief Export a point into unsigned binary data, uncompressed + * \brief Export a point into unsigned binary data * * \param grp Group the point belongs to * \param P Point to export + * \param format Point format, should be a POLARSSL_ECP_PF_XXX macro * \param olen Length of the actual ouput * \param buf Output buffer * \param buflen Length of the output buffer * * \return 0 if successful, or POLARSSL_ERR_ECP_GENERIC */ -int ecp_write_binary( const ecp_group *grp, const ecp_point *P, +int ecp_write_binary( const ecp_group *grp, const ecp_point *P, int format, size_t *olen, unsigned char *buf, size_t buflen ); /** diff --git a/library/ecp.c b/library/ecp.c index 854da58c8..6501fbe9f 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -174,16 +174,20 @@ cleanup: } /* - * Export a point into unsigned binary data, uncompressed format (SEC1 2.3.3) + * Export a point into unsigned binary data (SEC1 2.3.3) */ -int ecp_write_binary( const ecp_group *grp, const ecp_point *P, +int ecp_write_binary( const ecp_group *grp, const ecp_point *P, int format, size_t *olen, unsigned char *buf, size_t buflen ) { int ret; size_t plen; + if( format != POLARSSL_ECP_PF_UNCOMPRESSED && + format != POLARSSL_ECP_PF_COMPRESSED ) + return( POLARSSL_ERR_ECP_GENERIC ); + /* - * Case P == 0 + * Common case: P == 0 */ if( mpi_cmp_int( &P->Z, 0 ) == 0 ) { @@ -197,14 +201,28 @@ int ecp_write_binary( const ecp_group *grp, const ecp_point *P, } plen = mpi_size( &grp->P ); - *olen = 2 * plen + 1; - if( buflen < *olen ) - return( POLARSSL_ERR_ECP_GENERIC ); + if( format == POLARSSL_ECP_PF_UNCOMPRESSED ) + { + *olen = 2 * plen + 1; - buf[0] = 0x04; - MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); - MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + if( buflen < *olen ) + return( POLARSSL_ERR_ECP_GENERIC ); + + buf[0] = 0x04; + MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); + MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + } + else if( format == POLARSSL_ECP_PF_COMPRESSED ) + { + *olen = plen + 1; + + if( buflen < *olen ) + return( POLARSSL_ERR_ECP_GENERIC ); + + buf[0] = 0x02 + mpi_get_bit( &P->Y, 0 ); + MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); + } cleanup: return( ret ); diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 20ae3cd68..e84ac045e 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -133,17 +133,35 @@ ecp_small_check_pub:0:2:1:0 ECP small check pubkey #10 ecp_small_check_pub:10:25:1:POLARSSL_ERR_ECP_GENERIC -ECP write binary #1 (zero, buffer just fits) -ecp_write_binary:SECP192R1:"01":"01":"00":"00":1:0 +ECP write binary #0 (zero, bad format) +ecp_write_binary:SECP192R1:"01":"01":"00":UNKNOWN:"00":1:POLARSSL_ERR_ECP_GENERIC + +ECP write binary #1 (zero, uncompressed, buffer just fits) +ecp_write_binary:SECP192R1:"01":"01":"00":UNCOMPRESSED:"00":1:0 ECP write binary #2 (zero, buffer too small) -ecp_write_binary:SECP192R1:"01":"01":"00":"00":0:POLARSSL_ERR_ECP_GENERIC +ecp_write_binary:SECP192R1:"01":"01":"00":UNCOMPRESSED:"00":0:POLARSSL_ERR_ECP_GENERIC -ECP write binary #3 (non-zero, buffer just fits) -ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":49:0 +ECP write binary #3 (non-zero, uncompressed, buffer just fits) +ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":UNCOMPRESSED:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":49:0 -ECP write binary #4 (non-zero, buffer too small) -ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":48:POLARSSL_ERR_ECP_GENERIC +ECP write binary #4 (non-zero, uncompressed, buffer too small) +ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":UNCOMPRESSED:"0448d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc99336ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":48:POLARSSL_ERR_ECP_GENERIC + +ECP write binary #5 (zero, compressed, buffer just fits) +ecp_write_binary:SECP192R1:"01":"01":"00":COMPRESSED:"00":1:0 + +ECP write binary #6 (zero, buffer too small) +ecp_write_binary:SECP192R1:"01":"01":"00":COMPRESSED:"00":0:POLARSSL_ERR_ECP_GENERIC + +ECP write binary #7 (even, compressed, buffer just fits) +ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":COMPRESSED:"0248d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":25:0 + +ECP write binary #8 (even, compressed, buffer too small) +ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"6ceed4d7cba482e288669ee1b6415626d6f34d28501e060c":"01":COMPRESSED:"0248d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":24:POLARSSL_ERR_ECP_GENERIC + +ECP write binary #7 (odd, compressed, buffer just fits) +ecp_write_binary:SECP192R1:"48d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":"93112b28345b7d1d7799611e49bea9d8290cb2d7afe1f9f3":"01":COMPRESSED:"0348d8082a3a1e3112bc03a8ef2f6d40d0a77a6f8e00cc9933":25: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 1e50499b8..b273a70a1 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -225,7 +225,7 @@ ecp_fast_mod:id:N END_CASE BEGIN_CASE -ecp_write_binary:id:x:y:z:out:blen:ret +ecp_write_binary:id:x:y:z:format:out:blen:ret { ecp_group grp; ecp_point P; @@ -243,13 +243,13 @@ ecp_write_binary:id:x:y:z:out:blen:ret TEST_ASSERT( mpi_read_string( &P.Y, 16, {y} ) == 0 ); TEST_ASSERT( mpi_read_string( &P.Z, 16, {z} ) == 0 ); - TEST_ASSERT( ecp_write_binary( &grp, &P, &olen, buf, {blen} ) == {ret} ); +#define POLARSSL_ECP_PF_UNKNOWN -1 + TEST_ASSERT( ecp_write_binary( &grp, &P, POLARSSL_ECP_PF_{format}, + &olen, buf, {blen} ) == {ret} ); if( {ret} == 0 ) { - TEST_ASSERT( olen == strlen({out}) / 2 ); - - hexify( str, buf, {blen} ); + hexify( str, buf, olen ); TEST_ASSERT( strcasecmp( (char *) str, {out} ) == 0 ); }