Skip to content

Commit 57773d4

Browse files
committed
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
2 parents 0ea3377 + 54ba3eb commit 57773d4

File tree

11 files changed

+532
-81
lines changed

11 files changed

+532
-81
lines changed

include/mbedtls/bignum.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,8 +490,24 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
490490
size_t buflen );
491491

492492
/**
493-
* \brief Export an MPI into unsigned big endian binary data
494-
* of fixed size.
493+
* \brief Import X from unsigned binary data, little endian
494+
*
495+
* \param X The destination MPI. This must point to an initialized MPI.
496+
* \param buf The input buffer. This must be a readable buffer of length
497+
* \p buflen Bytes.
498+
* \param buflen The length of the input buffer \p p in Bytes.
499+
*
500+
* \return \c 0 if successful.
501+
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
502+
* \return Another negative error code on different kinds of failure.
503+
*/
504+
int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
505+
const unsigned char *buf, size_t buflen );
506+
507+
/**
508+
* \brief Export X into unsigned binary data, big endian.
509+
* Always fills the whole buffer, which will start with zeros
510+
* if the number is smaller.
495511
*
496512
* \param X The source MPI. This must point to an initialized MPI.
497513
* \param buf The output buffer. This must be a writable buffer of length
@@ -506,6 +522,24 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
506522
int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf,
507523
size_t buflen );
508524

525+
/**
526+
* \brief Export X into unsigned binary data, little endian.
527+
* Always fills the whole buffer, which will end with zeros
528+
* if the number is smaller.
529+
*
530+
* \param X The source MPI. This must point to an initialized MPI.
531+
* \param buf The output buffer. This must be a writable buffer of length
532+
* \p buflen Bytes.
533+
* \param buflen The size of the output buffer \p buf in Bytes.
534+
*
535+
* \return \c 0 if successful.
536+
* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
537+
* large enough to hold the value of \p X.
538+
* \return Another negative error code on different kinds of failure.
539+
*/
540+
int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
541+
unsigned char *buf, size_t buflen );
542+
509543
/**
510544
* \brief Perform a left-shift on an MPI: X <<= count
511545
*

include/mbedtls/ecp.h

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ typedef enum
9999
*/
100100
#define MBEDTLS_ECP_DP_MAX 12
101101

102+
/*
103+
* Curve types
104+
*/
105+
typedef enum
106+
{
107+
MBEDTLS_ECP_TYPE_NONE = 0,
108+
MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
109+
MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
110+
} mbedtls_ecp_curve_type;
111+
102112
/**
103113
* Curve information, for use by other modules.
104114
*/
@@ -417,6 +427,11 @@ void mbedtls_ecp_set_max_ops( unsigned max_ops );
417427
int mbedtls_ecp_restart_is_enabled( void );
418428
#endif /* MBEDTLS_ECP_RESTARTABLE */
419429

430+
/*
431+
* Get the type of a curve
432+
*/
433+
mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp );
434+
420435
/**
421436
* \brief This function retrieves the information defined in
422437
* mbedtls_ecp_curve_info() for all supported curves in order
@@ -626,6 +641,9 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
626641
* \param P The point to export. This must be initialized.
627642
* \param format The point format. This must be either
628643
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
644+
* (For groups without these formats, this parameter is
645+
* ignored. But it still has to be either of the above
646+
* values.)
629647
* \param olen The address at which to store the length of
630648
* the output in Bytes. This must not be \c NULL.
631649
* \param buf The output buffer. This must be a writable buffer
@@ -635,11 +653,14 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
635653
* \return \c 0 on success.
636654
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
637655
* is too small to hold the point.
656+
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
657+
* or the export for the given group is not implemented.
638658
* \return Another negative error code on other kinds of failure.
639659
*/
640-
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
641-
int format, size_t *olen,
642-
unsigned char *buf, size_t buflen );
660+
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
661+
const mbedtls_ecp_point *P,
662+
int format, size_t *olen,
663+
unsigned char *buf, size_t buflen );
643664

644665
/**
645666
* \brief This function imports a point from unsigned binary data.
@@ -660,8 +681,8 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_
660681
* \return \c 0 on success.
661682
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
662683
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
663-
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
664-
* is not implemented.
684+
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the
685+
* given group is not implemented.
665686
*/
666687
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
667688
mbedtls_ecp_point *P,
@@ -1093,6 +1114,26 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
10931114
int (*f_rng)(void *, unsigned char *, size_t),
10941115
void *p_rng );
10951116

1117+
/**
1118+
* \brief This function reads an elliptic curve private key.
1119+
*
1120+
* \param grp_id The ECP group identifier.
1121+
* \param key The destination key.
1122+
* \param buf The the buffer containing the binary representation of the
1123+
* key. (Big endian integer for Weierstrass curves, byte
1124+
* string for Montgomery curves.)
1125+
* \param buflen The length of the buffer in bytes.
1126+
*
1127+
* \return \c 0 on success.
1128+
* \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is
1129+
* invalid.
1130+
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
1131+
* \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
1132+
* the group is not implemented.
1133+
* \return Another negative error code on different kinds of failure.
1134+
*/
1135+
int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
1136+
const unsigned char *buf, size_t buflen );
10961137
/**
10971138
* \brief This function checks that the keypair objects
10981139
* \p pub and \p prv have the same group and the

library/bignum.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,39 @@ static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
813813
}
814814
}
815815

816+
/*
817+
* Import X from unsigned binary data, little endian
818+
*/
819+
int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
820+
const unsigned char *buf, size_t buflen )
821+
{
822+
int ret;
823+
size_t i;
824+
size_t const limbs = CHARS_TO_LIMBS( buflen );
825+
826+
/* Ensure that target MPI has exactly the necessary number of limbs */
827+
if( X->n != limbs )
828+
{
829+
mbedtls_mpi_free( X );
830+
mbedtls_mpi_init( X );
831+
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
832+
}
833+
834+
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
835+
836+
for( i = 0; i < buflen; i++ )
837+
X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
838+
839+
cleanup:
840+
841+
/*
842+
* This function is also used to import keys. However, wiping the buffers
843+
* upon failure is not necessary because failure only can happen before any
844+
* input is copied.
845+
*/
846+
return( ret );
847+
}
848+
816849
/*
817850
* Import X from unsigned binary data, big endian
818851
*/
@@ -847,9 +880,53 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
847880

848881
cleanup:
849882

883+
/*
884+
* This function is also used to import keys. However, wiping the buffers
885+
* upon failure is not necessary because failure only can happen before any
886+
* input is copied.
887+
*/
850888
return( ret );
851889
}
852890

891+
/*
892+
* Export X into unsigned binary data, little endian
893+
*/
894+
int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
895+
unsigned char *buf, size_t buflen )
896+
{
897+
size_t stored_bytes = X->n * ciL;
898+
size_t bytes_to_copy;
899+
size_t i;
900+
901+
if( stored_bytes < buflen )
902+
{
903+
bytes_to_copy = stored_bytes;
904+
}
905+
else
906+
{
907+
bytes_to_copy = buflen;
908+
909+
/* The output buffer is smaller than the allocated size of X.
910+
* However X may fit if its leading bytes are zero. */
911+
for( i = bytes_to_copy; i < stored_bytes; i++ )
912+
{
913+
if( GET_BYTE( X, i ) != 0 )
914+
return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
915+
}
916+
}
917+
918+
for( i = 0; i < bytes_to_copy; i++ )
919+
buf[i] = GET_BYTE( X, i );
920+
921+
if( stored_bytes < buflen )
922+
{
923+
/* Write trailing 0 bytes */
924+
memset( buf + stored_bytes, 0, buflen - stored_bytes );
925+
}
926+
927+
return( 0 );
928+
}
929+
853930
/*
854931
* Export X into unsigned binary data, big endian
855932
*/

library/ecdh.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,10 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
637637
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
638638

639639
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
640+
641+
if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
642+
return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
643+
640644
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
641645
}
642646

0 commit comments

Comments
 (0)