From ebffa7995bc17a71f7bc068a4afbade976485e9d Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 14 Dec 2018 15:07:50 +0000 Subject: [PATCH 01/12] Document parameter preconditions in ECP module --- include/mbedtls/ecp.h | 370 +++++++++++++++++++++++++++--------------- 1 file changed, 239 insertions(+), 131 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 1c372980e..9f4c3e55c 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -497,24 +497,37 @@ void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); /** * \brief This function frees the components of an ECP group. - * \param grp The group to free. + * + * \param grp The group to free. This may be \c NULL, in which + * case this function is a no-op. If it is not \c NULL, + * it must point to an initialized ECP group. */ void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); /** * \brief This function frees the components of a key pair. - * \param key The key pair to free. + * + * \param key The key pair to free. This may be \c NULL, in which + * case this function is a no-op. If it is not \c NULL, + * it must point to an initialized ECP key pair. */ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); #if defined(MBEDTLS_ECP_RESTARTABLE) /** - * \brief Initialize a restart context + * \brief Initialize a restart context. + * + * \param ctx The restart context to initialize. This must + * not be \c NULL. */ void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ); /** - * \brief Free the components of a restart context + * \brief Free the components of a restart context. + * + * \param ctx The restart context to free. This may be \c NULL, in which + * case this function is a no-op. If it is not \c NULL, + * it must point to an initialized restart context. */ void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); #endif /* MBEDTLS_ECP_RESTARTABLE */ @@ -523,11 +536,12 @@ void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); * \brief This function copies the contents of point \p Q into * point \p P. * - * \param P The destination point. - * \param Q The source point. + * \param P The destination point. This must be initialized. + * \param Q The source point. This must be initialized. * * \return \c 0 on success. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code for other kinds of failure. */ int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); @@ -535,31 +549,35 @@ int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); * \brief This function copies the contents of group \p src into * group \p dst. * - * \param dst The destination group. - * \param src The source group. + * \param dst The destination group. This must be initialized. + * \param src The source group. This must be initialized. * * \return \c 0 on success. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ); +int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, + const mbedtls_ecp_group *src ); /** - * \brief This function sets a point to zero. + * \brief This function sets a point to the point at infinity. * - * \param pt The point to set. + * \param pt The point to set. This must be initialized. * * \return \c 0 on success. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ); /** - * \brief This function checks if a point is zero. + * \brief This function checks if a point is the point at infinity. * - * \param pt The point to test. + * \param pt The point to test. This must be initialized. * * \return \c 1 if the point is zero. * \return \c 0 if the point is non-zero. + * \return A negative error code on failure. */ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); @@ -569,8 +587,8 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); * \note This assumes that the points are normalized. Otherwise, * they may compare as "not equal" even if they are. * - * \param P The first point to compare. - * \param Q The second point to compare. + * \param P The first point to compare. This must be initialized. + * \param Q The second point to compare. This must be initialized. * * \return \c 0 if the points are equal. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the points are not equal. @@ -582,7 +600,7 @@ int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, * \brief This function imports a non-zero point from two ASCII * strings. * - * \param P The destination point. + * \param P The destination point. This must be initialized. * \param radix The numeric base of the input. * \param x The first affine coordinate, as a null-terminated string. * \param y The second affine coordinate, as a null-terminated string. @@ -597,15 +615,21 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, * \brief This function exports a point into unsigned binary data. * * \param grp The group to which the point should belong. - * \param P The point to export. - * \param format The point format. Should be an \c MBEDTLS_ECP_PF_XXX macro. - * \param olen The length of the output. - * \param buf The output buffer. - * \param buflen The length of the output buffer. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \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. + * \param olen The address at which to store the length of + * the output in Bytes. + * \param buf The output buffer. This must be a writable buffer + * of length \p buflen Bytes. + * \param buflen The length of the output buffer \p buf in Bytes. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA - * or #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer + * is too small to hold the point. + * \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, @@ -619,19 +643,23 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ * for that. * * \param grp The group to which the point should belong. - * \param P The point to import. - * \param buf The input buffer. - * \param ilen The length of the input. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param P The destination context to import the point to. + * This must be initialized. + * \param buf The input buffer. This must be a readable buffer + * of length \p ilen Bytes. + * \param ilen The length of the input buffer \p buf in Bytes. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. + * \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. - * */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, - const unsigned char *buf, size_t ilen ); +int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P, + const unsigned char *buf, size_t ilen ); /** * \brief This function imports a point from a TLS ECPoint record. @@ -639,7 +667,9 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_poi * \note On function return, \p *buf is updated to point immediately * after the ECPoint record. * - * \param grp The ECP group used. + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). * \param pt The destination point. * \param buf The address of the pointer to the start of the input buffer. * \param len The length of the buffer. @@ -649,99 +679,122 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_poi * failure. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, - const unsigned char **buf, size_t len ); +int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char **buf, size_t len ); /** - * \brief This function exports a point as a TLS ECPoint record. + * \brief This function exports a point as a TLS ECPoint record + * defined in RFC 4492, Section 5.4. * - * \param grp The ECP group used. - * \param pt The point format to export to. The point format is an - * \c MBEDTLS_ECP_PF_XXX constant. - * \param format The export format. - * \param olen The length of the data written. - * \param buf The buffer to write to. - * \param blen The length of the buffer. + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The point to be exported. This must be initialized. + * \param format The point format to use. This must be either + * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. + * \param olen The address at which to store the length in Bytes + * of the data written. + * \param buf The target buffer. This must be a writable buffer of + * length \p blen Bytes. + * \param blen The length of the target buffer \p buf in Bytes. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA or - * #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the target buffer + * is too small to hold the exported point. + * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, - int format, size_t *olen, - unsigned char *buf, size_t blen ); +int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ); /** - * \brief This function sets a group using standardized domain parameters. + * \brief This function sets up an ECP group context + * from a standardized set of domain parameters. * * \note The index should be a value of the NamedCurve enum, * as defined in RFC-4492: Elliptic Curve Cryptography * (ECC) Cipher Suites for Transport Layer Security (TLS), * usually in the form of an \c MBEDTLS_ECP_DP_XXX macro. * - * \param grp The destination group. + * \param grp The group context to setup. This must be initialized. * \param id The identifier of the domain parameter set to load. * - * \return \c 0 on success, - * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization failure. - * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups. - + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p id doesn't + * correspond to a known group. + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); /** - * \brief This function sets a group from a TLS ECParameters record. + * \brief This function sets up an ECP group context from a TLS + * ECParameters record as defined in RFC 4492, Section 5.4. * - * \note \p buf is updated to point right after the ECParameters - * record on exit. + * \note The read pointer \p buf is updated to point right after + * the ECParameters record on exit. * - * \param grp The destination group. + * \param grp The group context to setup. This must be initialized. * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the buffer. + * \param len The length of the input buffer \c *buf in Bytes. * * \return \c 0 on success. - * \return An \c MBEDTLS_ERR_MPI_XXX error code on initialization - * failure. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognised. + * recognized. + * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len ); +int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, + const unsigned char **buf, size_t len ); /** - * \brief This function reads a group from a TLS ECParameters record. + * \brief This function extracts an elliptic curve group ID from a + * TLS ECParameters record as defined in RFC 4492, Section 5.4. * - * \note \p buf is updated to point right after the ECParameters - * record on exit. + * \note The read pointer \p buf is updated to point right after + * the ECParameters record on exit. * - * \param grp Output parameter to hold the group id. + * \param grp The address at which to store the group id. + * This must not be \c NULL. * \param buf The address of the pointer to the start of the input buffer. - * \param len The length of the buffer. + * \param len The length of the input buffer \c *buf in Bytes. * * \return \c 0 on success. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid. * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the group is not - * recognised. + * recognized. + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, - const unsigned char **buf, size_t len ); + const unsigned char **buf, + size_t len ); /** - * \brief This function writes the TLS ECParameters record for a group. + * \brief This function exports an elliptic curve as a TLS + * ECParameters record as defined in RFC 4492, Section 5.4. * - * \param grp The ECP group used. - * \param olen The number of Bytes written. - * \param buf The buffer to write to. - * \param blen The length of the buffer. + * \param grp The ECP group to be exported. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param olen The address at which to store the number of Bytes written. + * This must not be \c NULL. + * \param buf The buffer to write to. This must be a writable buffer + * of length \p blen Bytes. + * \param blen The length of the output buffer \p buf in Bytes. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure. + * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output + * buffer is too small to hold the exported group. + * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, - unsigned char *buf, size_t blen ); +int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, + size_t *olen, + unsigned char *buf, size_t blen ); /** - * \brief This function performs multiplication of a point by - * an integer: \p R = \p m * \p P. + * \brief This function performs a scalaar multiplication of a point + * by an integer: \p R = \p m * \p P. * * It is not thread-safe to use same group in multiple threads. * @@ -755,17 +808,22 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, * targeting these results. We recommend always providing * a non-NULL \p f_rng. The overhead is negligible. * - * \param grp The ECP group. - * \param R The destination point. - * \param m The integer by which to multiply. - * \param P The point to multiply. - * \param f_rng The RNG function. - * \param p_rng The RNG context. + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply. This must be initialized. + * \param P The point to multiply. This must be initialized. + * \param f_rng The RNG function. This may be \c NULL if randomization + * of intermediate results isn't desired (discouraged). + * \param p_rng The RNG context to be passed to \p p_rng. * * \return \c 0 on success. * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m is not a valid private * key, or \p P is not a valid public key. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, @@ -781,12 +839,16 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * it can return early and restart according to the limit set * with \c mbedtls_ecp_set_max_ops() to reduce blocking. * - * \param grp The ECP group. - * \param R The destination point. - * \param m The integer by which to multiply. - * \param P The point to multiply. - * \param f_rng The RNG function. - * \param p_rng The RNG context. + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. + * \param m The integer by which to multiply. This must be initialized. + * \param P The point to multiply. This must be initialized. + * \param f_rng The RNG function. This may be \c NULL if randomization + * of intermediate results isn't desired (discouraged). + * \param p_rng The RNG context to be passed to \p p_rng. * \param rs_ctx The restart context (NULL disables restart). * * \return \c 0 on success. @@ -795,6 +857,7 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, @@ -810,18 +873,25 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * \note In contrast to mbedtls_ecp_mul(), this function does not * guarantee a constant execution flow and timing. * - * \param grp The ECP group. - * \param R The destination point. + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. * \param m The integer by which to multiply \p P. - * \param P The point to multiply by \p m. + * This must be initialized. + * \param P The point to multiply by \p m. This must be initialized. * \param n The integer by which to multiply \p Q. + * This must be initialized. * \param Q The point to be multiplied by \p n. + * This must be initialized. * * \return \c 0 on success. * \return #MBEDTLS_ERR_ECP_INVALID_KEY if \p m or \p n are not * valid private keys, or \p P or \p Q are not valid public * keys. * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, @@ -838,12 +908,18 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * but it can return early and restart according to the limit * set with \c mbedtls_ecp_set_max_ops() to reduce blocking. * - * \param grp The ECP group. - * \param R The destination point. + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param R The point in which to store the result of the calculation. + * This must be initialized. * \param m The integer by which to multiply \p P. - * \param P The point to multiply by \p m. + * This must be initialized. + * \param P The point to multiply by \p m. This must be initialized. * \param n The integer by which to multiply \p Q. + * This must be initialized. * \param Q The point to be multiplied by \p n. + * This must be initialized. * \param rs_ctx The restart context (NULL disables restart). * * \return \c 0 on success. @@ -853,6 +929,7 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure. * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return Another negative error code on other kinds of failure. */ int mbedtls_ecp_muladd_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, @@ -877,38 +954,51 @@ int mbedtls_ecp_muladd_restartable( * structures, such as ::mbedtls_ecdh_context or * ::mbedtls_ecdsa_context. * - * \param grp The curve the point should lie on. - * \param pt The point to check. + * \param grp The ECP group the point should belong to. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param pt The point to check. This must be initialized. * * \return \c 0 if the point is a valid public key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY on failure. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not + * a valid public key for the given curve. + * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ); +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt ); /** - * \brief This function checks that an \p mbedtls_mpi is a valid private - * key for this curve. + * \brief This function checks that an \p mbedtls_mpi is a + * valid private key for this curve. * * \note This function uses bare components rather than an * ::mbedtls_ecp_keypair structure to ease use with other * structures, such as ::mbedtls_ecdh_context or * ::mbedtls_ecdsa_context. * - * \param grp The group used. - * \param d The integer to check. + * \param grp The ECP group the private key should belong to. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The integer to check. This must be initialized. * * \return \c 0 if the point is a valid private key. - * \return #MBEDTLS_ERR_ECP_INVALID_KEY on failure. + * \return #MBEDTLS_ERR_ECP_INVALID_KEY if the point is not a valid + * private key for the given curve. + * \return Another negative error code on other kinds of failure. */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ); +int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, + const mbedtls_mpi *d ); /** * \brief This function generates a private key. * - * \param grp The ECP group. - * \param d The destination MPI (secret part). - * \param f_rng The RNG function. - * \param p_rng The RNG parameter. + * \param grp The ECP group to generate a private key for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param d The destination MPI (secret part). This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG parameter to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context argument. * * \return \c 0 on success. * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code @@ -928,22 +1018,29 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, * structures, such as ::mbedtls_ecdh_context or * ::mbedtls_ecdsa_context. * - * \param grp The ECP group. - * \param G The chosen base point. + * \param grp The ECP group to generate a key pair for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param G The base point to use. This must be initialized + * and belong to \p grp. It replaces the default base + * point \c grp->G used by mbedtls_ecp_gen_keypair(). * \param d The destination MPI (secret part). + * This must be initialized. * \param Q The destination point (public part). - * \param f_rng The RNG function. - * \param p_rng The RNG context. + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. * * \return \c 0 on success. * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code * on failure. */ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, - const mbedtls_ecp_point *G, - mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); /** * \brief This function generates an ECP keypair. @@ -953,34 +1050,42 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, * structures, such as ::mbedtls_ecdh_context or * ::mbedtls_ecdsa_context. * - * \param grp The ECP group. + * \param grp The ECP group to generate a key pair for. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). * \param d The destination MPI (secret part). + * This must be initialized. * \param Q The destination point (public part). - * \param f_rng The RNG function. - * \param p_rng The RNG context. + * This must be initialized. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. * * \return \c 0 on success. * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code * on failure. */ -int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); +int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, + mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); /** * \brief This function generates an ECP key. * * \param grp_id The ECP group identifier. - * \param key The destination key. - * \param f_rng The RNG function. - * \param p_rng The RNG context. + * \param key The destination key. This must be initialized. + * \param f_rng The RNG function to use. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may + * be \c NULL if \p f_rng doesn't need a context argument. * * \return \c 0 on success. * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code * on failure. */ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); /** * \brief This function checks that the keypair objects @@ -988,16 +1093,19 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, * same public point, and that the private key in * \p prv is consistent with the public key. * - * \param pub The keypair structure holding the public key. - * If it contains a private key, that part is ignored. + * \param pub The keypair structure holding the public key. This + * must be initialized. If it contains a private key, that + * part is ignored. * \param prv The keypair structure holding the full keypair. + * This must be initialized. * * \return \c 0 on success, meaning that the keys are valid and match. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the keys are invalid or do not match. * \return An \c MBEDTLS_ERR_ECP_XXX or an \c MBEDTLS_ERR_MPI_XXX * error code on calculation failure. */ -int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ); +int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, + const mbedtls_ecp_keypair *prv ); #if defined(MBEDTLS_SELF_TEST) From 4f8e8e5805d8ed09efa79cc4dea537b31a22bb68 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 14 Dec 2018 15:08:03 +0000 Subject: [PATCH 02/12] Implement parameter validation for ECP module --- library/ecp.c | 140 ++++++++++++++++++++++++++++++++++++------- library/ecp_curves.c | 8 +++ 2 files changed, 125 insertions(+), 23 deletions(-) diff --git a/library/ecp.c b/library/ecp.c index 7fefb4c16..229b28eaf 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -86,6 +86,12 @@ #if !defined(MBEDTLS_ECP_ALT) +/* Parameter validation macros based on platform_util.h */ +#define ECP_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) +#define ECP_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else @@ -268,6 +274,8 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp, mbedtls_ecp_restart_ctx *rs_ctx, unsigned ops ) { + ECP_VALIDATE_RET( grp != NULL ); + if( rs_ctx != NULL && ecp_max_ops != 0 ) { /* scale depending on curve size: the chosen reference is 256-bit, @@ -526,8 +534,7 @@ static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp ) */ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) { - if( pt == NULL ) - return; + ECP_VALIDATE( pt != NULL ); mbedtls_mpi_init( &pt->X ); mbedtls_mpi_init( &pt->Y ); @@ -539,8 +546,7 @@ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) */ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) { - if( grp == NULL ) - return; + ECP_VALIDATE( grp != NULL ); grp->id = MBEDTLS_ECP_DP_NONE; mbedtls_mpi_init( &grp->P ); @@ -564,8 +570,7 @@ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) */ void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ) { - if( key == NULL ) - return; + ECP_VALIDATE( key != NULL ); mbedtls_ecp_group_init( &key->grp ); mbedtls_mpi_init( &key->d ); @@ -633,6 +638,8 @@ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ) int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) { int ret; + ECP_VALIDATE_RET( P != NULL ); + ECP_VALIDATE_RET( Q != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) ); @@ -647,7 +654,10 @@ cleanup: */ int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ) { - return mbedtls_ecp_group_load( dst, src->id ); + ECP_VALIDATE_RET( dst != NULL ); + ECP_VALIDATE_RET( src != NULL ); + + return( mbedtls_ecp_group_load( dst, src->id ) ); } /* @@ -656,6 +666,7 @@ int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ) { int ret; + ECP_VALIDATE_RET( pt != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) ); @@ -670,6 +681,8 @@ cleanup: */ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) { + ECP_VALIDATE_RET( pt != NULL ); + return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); } @@ -679,6 +692,9 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) { + ECP_VALIDATE_RET( P != NULL ); + ECP_VALIDATE_RET( Q != NULL ); + if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 && mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 && mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 ) @@ -696,6 +712,9 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, const char *x, const char *y ) { int ret; + ECP_VALIDATE_RET( P != NULL ); + ECP_VALIDATE_RET( x != NULL ); + ECP_VALIDATE_RET( y != NULL ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) ); @@ -708,16 +727,19 @@ cleanup: /* * Export a point into unsigned binary data (SEC1 2.3.3) */ -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 ) { int ret = 0; size_t plen; - - if( format != MBEDTLS_ECP_PF_UNCOMPRESSED && - format != MBEDTLS_ECP_PF_COMPRESSED ) - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( P != NULL ); + ECP_VALIDATE_RET( olen != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || + format == MBEDTLS_ECP_PF_COMPRESSED ); /* * Common case: P == 0 @@ -764,11 +786,15 @@ cleanup: /* * Import a point from unsigned binary data (SEC1 2.3.4) */ -int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, - const unsigned char *buf, size_t ilen ) +int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char *buf, size_t ilen ) { int ret; size_t plen; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( pt != NULL ); + ECP_VALIDATE_RET( buf != NULL ); if( ilen < 1 ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); @@ -803,11 +829,16 @@ cleanup: * opaque point <1..2^8-1>; * } ECPoint; */ -int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, - const unsigned char **buf, size_t buf_len ) +int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, + const unsigned char **buf, size_t buf_len ) { unsigned char data_len; const unsigned char *buf_start; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( pt != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + ECP_VALIDATE_RET( *buf != NULL ); /* * We must have at least two bytes (1 for length, at least one for data) @@ -825,7 +856,7 @@ int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point buf_start = *buf; *buf += data_len; - return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ); + return( mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ) ); } /* @@ -839,6 +870,12 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp unsigned char *buf, size_t blen ) { int ret; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( pt != NULL ); + ECP_VALIDATE_RET( olen != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED || + format == MBEDTLS_ECP_PF_COMPRESSED ); /* * buffer length must be at least one, for our length byte @@ -867,11 +904,14 @@ int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, { int ret; mbedtls_ecp_group_id grp_id; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + ECP_VALIDATE_RET( *buf != NULL ); if( ( ret = mbedtls_ecp_tls_read_group_id( &grp_id, buf, len ) ) != 0 ) return( ret ); - return mbedtls_ecp_group_load( grp, grp_id ); + return( mbedtls_ecp_group_load( grp, grp_id ) ); } /* @@ -883,6 +923,9 @@ int mbedtls_ecp_tls_read_group_id( mbedtls_ecp_group_id *grp, { uint16_t tls_id; const mbedtls_ecp_curve_info *curve_info; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + ECP_VALIDATE_RET( *buf != NULL ); /* * We expect at least three bytes (see below) @@ -918,6 +961,9 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, unsigned char *buf, size_t blen ) { const mbedtls_ecp_curve_info *curve_info; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( buf != NULL ); + ECP_VALIDATE_RET( olen != NULL ); if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); @@ -2276,6 +2322,10 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, #if defined(MBEDTLS_ECP_INTERNAL_ALT) char is_grp_capable = 0; #endif + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( R != NULL ); + ECP_VALIDATE_RET( m != NULL ); + ECP_VALIDATE_RET( P != NULL ); #if defined(MBEDTLS_ECP_RESTARTABLE) /* reset ops count for this call if top-level */ @@ -2333,6 +2383,10 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( R != NULL ); + ECP_VALIDATE_RET( m != NULL ); + ECP_VALIDATE_RET( P != NULL ); return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) ); } @@ -2435,6 +2489,12 @@ int mbedtls_ecp_muladd_restartable( #if defined(MBEDTLS_ECP_INTERNAL_ALT) char is_grp_capable = 0; #endif + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( R != NULL ); + ECP_VALIDATE_RET( m != NULL ); + ECP_VALIDATE_RET( P != NULL ); + ECP_VALIDATE_RET( n != NULL ); + ECP_VALIDATE_RET( Q != NULL ); if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); @@ -2517,6 +2577,12 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) { + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( R != NULL ); + ECP_VALIDATE_RET( m != NULL ); + ECP_VALIDATE_RET( P != NULL ); + ECP_VALIDATE_RET( n != NULL ); + ECP_VALIDATE_RET( Q != NULL ); return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) ); } @@ -2539,8 +2605,12 @@ static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_ /* * Check that a point is valid as a public key */ -int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, + const mbedtls_ecp_point *pt ) { + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( pt != NULL ); + /* Must use affine coordinates */ if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) return( MBEDTLS_ERR_ECP_INVALID_KEY ); @@ -2559,8 +2629,12 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_po /* * Check that an mbedtls_mpi is valid as a private key */ -int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ) +int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, + const mbedtls_mpi *d ) { + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( d != NULL ); + #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) { @@ -2601,7 +2675,13 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp, void *p_rng ) { int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - size_t n_size = ( grp->nbits + 7 ) / 8; + size_t n_size; + + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( d != NULL ); + ECP_VALIDATE_RET( f_rng != NULL ); + + n_size = ( grp->nbits + 7 ) / 8; #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) @@ -2680,6 +2760,11 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, void *p_rng ) { int ret; + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( d != NULL ); + ECP_VALIDATE_RET( G != NULL ); + ECP_VALIDATE_RET( Q != NULL ); + ECP_VALIDATE_RET( f_rng != NULL ); MBEDTLS_MPI_CHK( mbedtls_ecp_gen_privkey( grp, d, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); @@ -2696,6 +2781,11 @@ int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { + ECP_VALIDATE_RET( grp != NULL ); + ECP_VALIDATE_RET( d != NULL ); + ECP_VALIDATE_RET( Q != NULL ); + ECP_VALIDATE_RET( f_rng != NULL ); + return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) ); } @@ -2706,6 +2796,8 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; + ECP_VALIDATE_RET( key != NULL ); + ECP_VALIDATE_RET( f_rng != NULL ); if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) return( ret ); @@ -2721,6 +2813,8 @@ int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ec int ret; mbedtls_ecp_point Q; mbedtls_ecp_group grp; + ECP_VALIDATE_RET( pub != NULL ); + ECP_VALIDATE_RET( prv != NULL ); if( pub->grp.id == MBEDTLS_ECP_DP_NONE || pub->grp.id != prv->grp.id || diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 68e2441ae..731621dc3 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -28,11 +28,18 @@ #if defined(MBEDTLS_ECP_C) #include "mbedtls/ecp.h" +#include "mbedtls/platform_util.h" #include #if !defined(MBEDTLS_ECP_ALT) +/* Parameter validation macros based on platform_util.h */ +#define ECP_VALIDATE_RET( cond ) \ + MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) +#define ECP_VALIDATE( cond ) \ + MBEDTLS_INTERNAL_VALIDATE( cond ) + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -746,6 +753,7 @@ cleanup: */ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) { + ECP_VALIDATE_RET( grp != NULL ); mbedtls_ecp_group_free( grp ); grp->id = id; From 12dff0352b5ede23986e835561544ad09effde7e Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 14 Dec 2018 15:08:13 +0000 Subject: [PATCH 03/12] Test parameter validation for ECP module --- tests/suites/test_suite_ecp.data | 7 +- tests/suites/test_suite_ecp.function | 309 +++++++++++++++++++++++++++ 2 files changed, 312 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 321a1b497..1b46306fa 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1,3 +1,6 @@ +ECP invalid params +ecp_invalid_param: + ECP curve info #1 depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED mbedtls_ecp_curve_info:MBEDTLS_ECP_DP_BP512R1:28:512:"brainpoolP512r1" @@ -46,10 +49,6 @@ ECP check pubkey Koblitz #2 (coordinate not affine) depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED ecp_check_pub:MBEDTLS_ECP_DP_SECP224K1:"E2000000000000BB3A13D43B323337383935321F0603551D":"100101FF040830060101FF02010A30220603551D0E041B04636FC0C0":"101":MBEDTLS_ERR_ECP_INVALID_KEY -ECP write binary #0 (zero, bad format) -depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED -ecp_write_binary:MBEDTLS_ECP_DP_SECP192R1:"01":"01":"00":ECP_PF_UNKNOWN:"00":1:MBEDTLS_ERR_ECP_BAD_INPUT_DATA - ECP write binary #1 (zero, uncompressed, buffer just fits) depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED ecp_write_binary:MBEDTLS_ECP_DP_SECP192R1:"01":"01":"00":MBEDTLS_ECP_PF_UNCOMPRESSED:"00":1:0 diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 65c487ef8..94ba8cbe0 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -13,6 +13,315 @@ * END_DEPENDENCIES */ +/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */ +void ecp_invalid_param( ) +{ + mbedtls_ecp_group grp; + mbedtls_ecp_keypair kp; + mbedtls_ecp_point P; + mbedtls_mpi m; + const char *x = "deadbeef"; + int valid_fmt = MBEDTLS_ECP_PF_UNCOMPRESSED; + int invalid_fmt = 42; + size_t olen; + unsigned char buf[42] = { 0 }; + const unsigned char *null_buf = NULL; + mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1; + + TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) ); + TEST_INVALID_PARAM( mbedtls_ecp_keypair_init( NULL ) ); + TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) ); + + TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); + TEST_VALID_PARAM( mbedtls_ecp_keypair_free( NULL ) ); + TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + TEST_INVALID_PARAM( mbedtls_ecp_restart_init( NULL ) ); + TEST_VALID_PARAM( mbedtls_ecp_restart_free( NULL ) ); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_copy( NULL, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_copy( &P, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_group_copy( NULL, &grp ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_group_copy( &grp, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_set_zero( NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_is_zero( NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_cmp( NULL, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_cmp( &P, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_read_string( NULL, 2, + x, x ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_read_string( &P, 2, + NULL, x ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_read_string( &P, 2, + x, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_write_binary( NULL, &P, + valid_fmt, + &olen, + buf, sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_write_binary( &grp, NULL, + valid_fmt, + &olen, + buf, sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_write_binary( &grp, &P, + invalid_fmt, + &olen, + buf, sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_write_binary( &grp, &P, + valid_fmt, + NULL, + buf, sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_write_binary( &grp, &P, + valid_fmt, + &olen, + NULL, sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_read_binary( NULL, &P, buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_read_binary( &grp, NULL, buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_point_read_binary( &grp, &P, NULL, + sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_point( NULL, &P, + (const unsigned char **) &buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_point( &grp, NULL, + (const unsigned char **) &buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_point( &grp, &P, &null_buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_point( &grp, &P, NULL, + sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_point( NULL, &P, + valid_fmt, + &olen, + buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_point( &grp, NULL, + valid_fmt, + &olen, + buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_point( &grp, &P, + invalid_fmt, + &olen, + buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_point( &grp, &P, + valid_fmt, + NULL, + buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_point( &grp, &P, + valid_fmt, + &olen, + NULL, + sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_group_load( NULL, valid_group ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_group( NULL, + (const unsigned char **) &buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_group( &grp, NULL, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_group( &grp, &null_buf, + sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_group_id( NULL, + (const unsigned char **) &buf, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_group_id( &valid_group, NULL, + sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_read_group_id( &valid_group, + &null_buf, + sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_group( NULL, &olen, + buf, sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_group( &grp, NULL, + buf, sizeof( buf ) ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_tls_write_group( &grp, &olen, + NULL, sizeof( buf ) ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul( NULL, &P, &m, &P, + rnd_std_rand, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul( &grp, NULL, &m, &P, + rnd_std_rand, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul( &grp, &P, NULL, &P, + rnd_std_rand, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul( &grp, &P, &m, NULL, + rnd_std_rand, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul_restartable( NULL, &P, &m, &P, + rnd_std_rand, NULL , NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul_restartable( &grp, NULL, &m, &P, + rnd_std_rand, NULL , NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul_restartable( &grp, &P, NULL, &P, + rnd_std_rand, NULL , NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_mul_restartable( &grp, &P, &m, NULL, + rnd_std_rand, NULL , NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd( NULL, &P, &m, &P, + &m, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd( &grp, NULL, &m, &P, + &m, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd( &grp, &P, NULL, &P, + &m, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd( &grp, &P, &m, NULL, + &m, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd( &grp, &P, &m, &P, + NULL, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd( &grp, &P, &m, &P, + &m, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd_restartable( NULL, &P, &m, &P, + &m, &P, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd_restartable( &grp, NULL, &m, &P, + &m, &P, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd_restartable( &grp, &P, NULL, &P, + &m, &P, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd_restartable( &grp, &P, &m, NULL, + &m, &P, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd_restartable( &grp, &P, &m, &P, + NULL, &P, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_muladd_restartable( &grp, &P, &m, &P, + &m, NULL, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_check_pubkey( NULL, &P ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_check_pubkey( &grp, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_check_privkey( NULL, &m ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_check_privkey( &grp, NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair_base( NULL, &P, + &m, &P, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair_base( &grp, NULL, + &m, &P, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair_base( &grp, &P, + NULL, &P, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair_base( &grp, &P, + &m, NULL, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair_base( &grp, &P, + &m, &P, + NULL, + NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair( NULL, + &m, &P, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair( &grp, + NULL, &P, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair( &grp, + &m, NULL, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_keypair( &grp, + &m, &P, + NULL, + NULL ) ); + + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_key( valid_group, NULL, + rnd_std_rand, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_key( valid_group, &kp, + NULL, NULL ) ); + +exit: + return; +} +/* END_CASE */ + /* BEGIN_CASE */ void mbedtls_ecp_curve_info( int id, int tls_id, int size, char * name ) { From 5edcfa529fed02a77b529e533e218520d4f97799 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 12:49:55 +0000 Subject: [PATCH 04/12] Improve ECP documentation --- include/mbedtls/ecp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 9f4c3e55c..06a3ce575 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -621,7 +621,7 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, * \param format The point format. This must be either * #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED. * \param olen The address at which to store the length of - * the output in Bytes. + * the output in Bytes. This must not be \c NULL. * \param buf The output buffer. This must be a writable buffer * of length \p buflen Bytes. * \param buflen The length of the output buffer \p buf in Bytes. @@ -793,7 +793,7 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, unsigned char *buf, size_t blen ); /** - * \brief This function performs a scalaar multiplication of a point + * \brief This function performs a scalar multiplication of a point * by an integer: \p R = \p m * \p P. * * It is not thread-safe to use same group in multiple threads. From 57b684f9d1032ff437cca48c73f14d7bea7e244d Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 12:50:02 +0000 Subject: [PATCH 05/12] Add separate test for xxx_free() functions in ECP module --- tests/suites/test_suite_ecp.data | 3 +++ tests/suites/test_suite_ecp.function | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 1b46306fa..30d5ec6f1 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1,3 +1,6 @@ +ECP valid params +ecp_valid_param: + ECP invalid params ecp_invalid_param: diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 94ba8cbe0..49ab870ac 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -13,6 +13,22 @@ * END_DEPENDENCIES */ +/* BEGIN_CASE */ +void ecp_valid_param( ) +{ + TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); + TEST_VALID_PARAM( mbedtls_ecp_keypair_free( NULL ) ); + TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); + +#if defined(MBEDTLS_ECP_RESTARTABLE) + TEST_VALID_PARAM( mbedtls_ecp_restart_free( NULL ) ); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + +exit: + return; +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */ void ecp_invalid_param( ) { @@ -32,13 +48,8 @@ void ecp_invalid_param( ) TEST_INVALID_PARAM( mbedtls_ecp_keypair_init( NULL ) ); TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) ); - TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); - TEST_VALID_PARAM( mbedtls_ecp_keypair_free( NULL ) ); - TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); - #if defined(MBEDTLS_ECP_RESTARTABLE) TEST_INVALID_PARAM( mbedtls_ecp_restart_init( NULL ) ); - TEST_VALID_PARAM( mbedtls_ecp_restart_free( NULL ) ); #endif /* MBEDTLS_ECP_RESTARTABLE */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, From 486f1b33d72f960f7cb8b9fbd36d992a26697692 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 13:00:34 +0000 Subject: [PATCH 06/12] Improve wording in ECP documentation --- include/mbedtls/ecp.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 06a3ce575..de3a343cb 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -499,8 +499,8 @@ void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ); * \brief This function frees the components of an ECP group. * * \param grp The group to free. This may be \c NULL, in which - * case this function is a no-op. If it is not \c NULL, - * it must point to an initialized ECP group. + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized ECP group. */ void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); @@ -508,8 +508,8 @@ void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ); * \brief This function frees the components of a key pair. * * \param key The key pair to free. This may be \c NULL, in which - * case this function is a no-op. If it is not \c NULL, - * it must point to an initialized ECP key pair. + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized ECP key pair. */ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ); @@ -526,8 +526,8 @@ void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ); * \brief Free the components of a restart context. * * \param ctx The restart context to free. This may be \c NULL, in which - * case this function is a no-op. If it is not \c NULL, - * it must point to an initialized restart context. + * case this function returns immediately. If it is not + * \c NULL, it must point to an initialized restart context. */ void mbedtls_ecp_restart_free( mbedtls_ecp_restart_ctx *ctx ); #endif /* MBEDTLS_ECP_RESTARTABLE */ From 80f71689eeb83366ac4492f8aad0e05b85faae33 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 23:44:43 +0000 Subject: [PATCH 07/12] Add parameter validation to mbedtls_ecp_restart_init() --- library/ecp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/ecp.c b/library/ecp.c index 229b28eaf..beab9c4c3 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -244,6 +244,7 @@ static void ecp_restart_ma_free( mbedtls_ecp_restart_muladd_ctx *ctx ) */ void mbedtls_ecp_restart_init( mbedtls_ecp_restart_ctx *ctx ) { + ECP_VALIDATE( ctx != NULL ); ctx->ops_done = 0; ctx->depth = 0; ctx->rsm = NULL; From 807c107c3c9f4d742324552fe8d5e6a1e1f526c8 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 23:45:14 +0000 Subject: [PATCH 08/12] Fix typos in ECP test suite --- tests/suites/test_suite_ecp.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 49ab870ac..40a037ec0 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -16,7 +16,7 @@ /* BEGIN_CASE */ void ecp_valid_param( ) { - TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); + TEST_VALID_PARAM( mbedtls_ecp_group_free( NULL ) ); TEST_VALID_PARAM( mbedtls_ecp_keypair_free( NULL ) ); TEST_VALID_PARAM( mbedtls_ecp_point_free( NULL ) ); @@ -46,7 +46,7 @@ void ecp_invalid_param( ) TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) ); TEST_INVALID_PARAM( mbedtls_ecp_keypair_init( NULL ) ); - TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) ); + TEST_INVALID_PARAM( mbedtls_ecp_group_init( NULL ) ); #if defined(MBEDTLS_ECP_RESTARTABLE) TEST_INVALID_PARAM( mbedtls_ecp_restart_init( NULL ) ); From 0a4fa9b1fb0819fc65ccaba18dd2608024c8472e Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 23:45:29 +0000 Subject: [PATCH 09/12] Add parameter validation test for mbedtls_ecp_check_budget() --- tests/suites/test_suite_ecp.function | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index 40a037ec0..de61022b1 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -43,6 +43,7 @@ void ecp_invalid_param( ) unsigned char buf[42] = { 0 }; const unsigned char *null_buf = NULL; mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1; + mbedtls_ecp_restart_ctx restart_ctx; TEST_INVALID_PARAM( mbedtls_ecp_point_init( NULL ) ); TEST_INVALID_PARAM( mbedtls_ecp_keypair_init( NULL ) ); @@ -50,6 +51,7 @@ void ecp_invalid_param( ) #if defined(MBEDTLS_ECP_RESTARTABLE) TEST_INVALID_PARAM( mbedtls_ecp_restart_init( NULL ) ); + TEST_INVALID_PARAM( mbedtls_ecp_check_budget( NULL, &restart_ctx, 42 ) ); #endif /* MBEDTLS_ECP_RESTARTABLE */ TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, From 549e455a423576881139d5ecaa8f9ad6738bb74a Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 23:45:43 +0000 Subject: [PATCH 10/12] Add parameter validation test for mbedtls_ecp_gen_privkey() --- tests/suites/test_suite_ecp.function | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index de61022b1..b6253feef 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -64,6 +64,22 @@ void ecp_invalid_param( ) TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, mbedtls_ecp_group_copy( &grp, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_privkey( NULL, + &m, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_privkey( &grp, + NULL, + rnd_std_rand, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_gen_privkey( &grp, + &m, + NULL, + NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, mbedtls_ecp_set_zero( NULL ) ); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, From b7a04a785176512f32805e9901e30a76fbb68a50 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 23:50:21 +0000 Subject: [PATCH 11/12] Fix mbedtls_ecp_curve_info_from_name() for NULL input --- library/ecp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/ecp.c b/library/ecp.c index beab9c4c3..ecea5910e 100644 --- a/library/ecp.c +++ b/library/ecp.c @@ -505,6 +505,9 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name { const mbedtls_ecp_curve_info *curve_info; + if( name == NULL ) + return( NULL ); + for( curve_info = mbedtls_ecp_curve_list(); curve_info->grp_id != MBEDTLS_ECP_DP_NONE; curve_info++ ) From 195953503843911ab8fad3bc06d44795eb0795d6 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 18 Dec 2018 23:54:04 +0000 Subject: [PATCH 12/12] Add parameter validation test for mbedtls_ecp_check_pub_priv() --- tests/suites/test_suite_ecp.function | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index b6253feef..606ddd22a 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -287,6 +287,11 @@ void ecp_invalid_param( ) TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, mbedtls_ecp_check_pubkey( &grp, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_check_pub_priv( NULL, &kp ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, + mbedtls_ecp_check_pub_priv( &kp, NULL ) ); + TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA, mbedtls_ecp_check_privkey( NULL, &m ) ); TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,