Merge remote-tracking branch 'public/pr/2291' into development

This commit is contained in:
Simon Butcher 2018-12-20 12:02:11 +00:00
commit decf2f5c2c
4 changed files with 418 additions and 84 deletions

View File

@ -118,7 +118,8 @@ typedef void mbedtls_ecdsa_restart_ctx;
* \brief This function computes the ECDSA signature of a * \brief This function computes the ECDSA signature of a
* previously-hashed message. * previously-hashed message.
* *
* \note The deterministic version is usually preferred. * \note The deterministic version implemented in
* mbedtls_ecdsa_sign_det() is usually preferred.
* *
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated * bitlength of the group order, then the hash is truncated
@ -128,14 +129,22 @@ typedef void mbedtls_ecdsa_restart_ctx;
* *
* \see ecp.h * \see ecp.h
* *
* \param grp The ECP group. * \param grp The context for the elliptic curve to use.
* \param r The first output integer. * This must be initialized and have group parameters
* \param s The second output integer. * set, for example through mbedtls_ecp_group_load().
* \param d The private signing key. * \param r The MPI context in which to store the first part
* \param buf The message hash. * the signature. This must be initialized.
* \param blen The length of \p buf. * \param s The MPI context in which to store the second part
* \param f_rng The RNG function. * the signature. This must be initialized.
* \param p_rng The RNG context. * \param d The private signing key. This must be initialized.
* \param buf The content to be signed. This is usually the hash of
* the original data to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \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 parameter.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX * \return An \c MBEDTLS_ERR_ECP_XXX
@ -162,21 +171,29 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
* *
* \see ecp.h * \see ecp.h
* *
* \param grp The ECP group. * \param grp The context for the elliptic curve to use.
* \param r The first output integer. * This must be initialized and have group parameters
* \param s The second output integer. * set, for example through mbedtls_ecp_group_load().
* \param d The private signing key. * \param r The MPI context in which to store the first part
* \param buf The message hash. * the signature. This must be initialized.
* \param blen The length of \p buf. * \param s The MPI context in which to store the second part
* \param md_alg The MD algorithm used to hash the message. * the signature. This must be initialized.
* \param d The private signing key. This must be initialized
* and setup, for example through mbedtls_ecp_gen_privkey().
* \param buf The hashed content to be signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param md_alg The hash algorithm used to hash the original data.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
* error code on failure. * error code on failure.
*/ */
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, mbedtls_mpi *s, const mbedtls_mpi *d,
mbedtls_md_type_t md_alg ); const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/** /**
@ -191,12 +208,19 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
* *
* \see ecp.h * \see ecp.h
* *
* \param grp The ECP group. * \param grp The ECP group to use.
* \param buf The message hash. * This must be initialized and have group parameters
* \param blen The length of \p buf. * set, for example through mbedtls_ecp_group_load().
* \param Q The public key to use for verification. * \param buf The hashed content that was signed. This must be a readable
* buffer of length \p blen Bytes. It may be \c NULL if
* \p blen is zero.
* \param blen The length of \p buf in Bytes.
* \param Q The public key to use for verification. This must be
* initialized and setup.
* \param r The first integer of the signature. * \param r The first integer of the signature.
* This must be initialized.
* \param s The second integer of the signature. * \param s The second integer of the signature.
* This must be initialized.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the signature
@ -205,8 +229,9 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
* error code on failure for any other reason. * error code on failure for any other reason.
*/ */
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen, const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s); const mbedtls_ecp_point *Q, const mbedtls_mpi *r,
const mbedtls_mpi *s);
/** /**
* \brief This function computes the ECDSA signature and writes it * \brief This function computes the ECDSA signature and writes it
@ -223,11 +248,6 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
* of the Digital Signature Algorithm (DSA) and Elliptic * of the Digital Signature Algorithm (DSA) and Elliptic
* Curve Digital Signature Algorithm (ECDSA)</em>. * Curve Digital Signature Algorithm (ECDSA)</em>.
* *
* \note The \p sig buffer must be at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
*
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group * defined in <em>Standards for Efficient Cryptography Group
@ -236,20 +256,32 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
* *
* \see ecp.h * \see ecp.h
* *
* \param ctx The ECDSA context. * \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message. * \param md_alg The message digest that was used to hash the message.
* \param hash The message hash. * \param hash The message hash to be signed. This must be a readable
* \param hlen The length of the hash. * buffer of length \p blen Bytes.
* \param sig The buffer that holds the signature. * \param hlen The length of the hash \p hash in Bytes.
* \param slen The length of the signature written. * \param sig The buffer to which to write the signature. This must be a
* \param f_rng The RNG function. * writable buffer of length at least twice as large as the
* \param p_rng The RNG context. * size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
* \c MBEDTLS_ERR_ASN1_XXX error code on failure. * \c MBEDTLS_ERR_ASN1_XXX error code on failure.
*/ */
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hlen, const unsigned char *hash, size_t hlen,
unsigned char *sig, size_t *slen, unsigned char *sig, size_t *slen,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
@ -265,15 +297,28 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t
* but it can return early and restart according to the limit * but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking. * set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
* *
* \param ctx The ECDSA context. * \param ctx The ECDSA context to use. This must be initialized
* and have a group and private key bound to it, for example
* via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param md_alg The message digest that was used to hash the message. * \param md_alg The message digest that was used to hash the message.
* \param hash The message hash. * \param hash The message hash to be signed. This must be a readable
* \param hlen The length of the hash. * buffer of length \p blen Bytes.
* \param sig The buffer that holds the signature. * \param hlen The length of the hash \p hash in Bytes.
* \param slen The length of the signature written. * \param sig The buffer to which to write the signature. This must be a
* \param f_rng The RNG function. * writable buffer of length at least twice as large as the
* \param p_rng The RNG context. * size of the curve used, plus 9. For example, 73 Bytes if
* \param rs_ctx The restart context (NULL disables restart). * a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
* it is unused and may be set to \c NULL.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@ -309,11 +354,6 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
* \warning It is not thread-safe to use the same context in * \warning It is not thread-safe to use the same context in
* multiple threads. * multiple threads.
* *
* \note The \p sig buffer must be at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if a
* 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
*
* \note If the bitlength of the message hash is larger than the * \note If the bitlength of the message hash is larger than the
* bitlength of the group order, then the hash is truncated as * bitlength of the group order, then the hash is truncated as
* defined in <em>Standards for Efficient Cryptography Group * defined in <em>Standards for Efficient Cryptography Group
@ -325,12 +365,20 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
* \deprecated Superseded by mbedtls_ecdsa_write_signature() in * \deprecated Superseded by mbedtls_ecdsa_write_signature() in
* Mbed TLS version 2.0 and later. * Mbed TLS version 2.0 and later.
* *
* \param ctx The ECDSA context. * \param ctx The ECDSA context to use. This must be initialized
* \param hash The message hash. * and have a group and private key bound to it, for example
* \param hlen The length of the hash. * via mbedtls_ecdsa_genkey() or mbedtls_ecdsa_from_keypair().
* \param sig The buffer that holds the signature. * \param hash The message hash to be signed. This must be a readable
* \param slen The length of the signature written. * buffer of length \p blen Bytes.
* \param md_alg The MD algorithm used to hash the message. * \param hlen The length of the hash \p hash in Bytes.
* \param sig The buffer to which to write the signature. This must be a
* writable buffer of length at least twice as large as the
* size of the curve used, plus 9. For example, 73 Bytes if
* a 256-bit curve is used. A buffer length of
* #MBEDTLS_ECDSA_MAX_LEN is always safe.
* \param slen The address at which to store the actual length of
* the signature written. Must not be \c NULL.
* \param md_alg The message digest that was used to hash the message.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or * \return An \c MBEDTLS_ERR_ECP_XXX, \c MBEDTLS_ERR_MPI_XXX or
@ -355,11 +403,14 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
* *
* \see ecp.h * \see ecp.h
* *
* \param ctx The ECDSA context. * \param ctx The ECDSA context to use. This must be initialized
* \param hash The message hash. * and have a group and public key bound to it.
* \param hlen The size of the hash. * \param hash The message hash that was signed. This must be a readable
* \param sig The signature to read and verify. * buffer of length \p size Bytes.
* \param slen The size of \p sig. * \param hlen The size of the hash \p hash.
* \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
@ -382,12 +433,17 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
* but it can return early and restart according to the limit * but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking. * set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
* *
* \param ctx The ECDSA context. * \param ctx The ECDSA context to use. This must be initialized
* \param hash The message hash. * and have a group and public key bound to it.
* \param hlen The size of the hash. * \param hash The message hash that was signed. This must be a readable
* \param sig The signature to read and verify. * buffer of length \p size Bytes.
* \param slen The size of \p sig. * \param hlen The size of the hash \p hash.
* \param rs_ctx The restart context (NULL disables restart). * \param sig The signature to read and verify. This must be a readable
* buffer of length \p slen Bytes.
* \param slen The size of \p sig in Bytes.
* \param rs_ctx The restart context to use. This may be \c NULL to disable
* restarting. If it is not \c NULL, it must point to an
* initialized restart context.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid. * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
@ -409,10 +465,12 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
* \see ecp.h * \see ecp.h
* *
* \param ctx The ECDSA context to store the keypair in. * \param ctx The ECDSA context to store the keypair in.
* This must be initialized.
* \param gid The elliptic curve to use. One of the various * \param gid The elliptic curve to use. One of the various
* \c MBEDTLS_ECP_DP_XXX macros depending on configuration. * \c MBEDTLS_ECP_DP_XXX macros depending on configuration.
* \param f_rng The RNG function. * \param f_rng The RNG function to use. This must not be \c NULL.
* \param p_rng The RNG context. * \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 \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure. * \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
@ -421,40 +479,55 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
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 sets an ECDSA context from an EC key pair. * \brief This function sets up an ECDSA context from an EC key pair.
* *
* \see ecp.h * \see ecp.h
* *
* \param ctx The ECDSA context to set. * \param ctx The ECDSA context to setup. This must be initialized.
* \param key The EC key to use. * \param key The EC key to use. This must be initialized and hold
* a private-public key pair or a public key. In the former
* case, the ECDSA context may be used for signature creation
* and verification after this call. In the latter case, it
* may be used for signature verification.
* *
* \return \c 0 on success. * \return \c 0 on success.
* \return An \c MBEDTLS_ERR_ECP_XXX code on failure. * \return An \c MBEDTLS_ERR_ECP_XXX code on failure.
*/ */
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ); int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx,
const mbedtls_ecp_keypair *key );
/** /**
* \brief This function initializes an ECDSA context. * \brief This function initializes an ECDSA context.
* *
* \param ctx The ECDSA context to initialize. * \param ctx The ECDSA context to initialize.
* This must not be \c NULL.
*/ */
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ); void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx );
/** /**
* \brief This function frees an ECDSA context. * \brief This function frees an ECDSA context.
* *
* \param ctx The ECDSA context to free. * \param ctx The ECDSA context to free. This may be \c NULL,
* in which case this function does nothing. If it
* is not \c NULL, it must be initialized.
*/ */
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ); void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx );
#if defined(MBEDTLS_ECP_RESTARTABLE) #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_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ); void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_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 does nothing. If it
* is not \c NULL, it must be initialized.
*/ */
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ); void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx );
#endif /* MBEDTLS_ECP_RESTARTABLE */ #endif /* MBEDTLS_ECP_RESTARTABLE */

View File

@ -50,6 +50,14 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#include "mbedtls/platform_util.h"
/* Parameter validation macros based on platform_util.h */
#define ECDSA_VALIDATE_RET( cond ) \
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
#define ECDSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
#if defined(MBEDTLS_ECP_RESTARTABLE) #if defined(MBEDTLS_ECP_RESTARTABLE)
/* /*
@ -377,6 +385,13 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
ECDSA_VALIDATE_RET( grp != NULL );
ECDSA_VALIDATE_RET( r != NULL );
ECDSA_VALIDATE_RET( s != NULL );
ECDSA_VALIDATE_RET( d != NULL );
ECDSA_VALIDATE_RET( f_rng != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
return( ecdsa_sign_restartable( grp, r, s, d, buf, blen, return( ecdsa_sign_restartable( grp, r, s, d, buf, blen,
f_rng, p_rng, NULL ) ); f_rng, p_rng, NULL ) );
} }
@ -456,6 +471,12 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi
const mbedtls_mpi *d, const unsigned char *buf, size_t blen, const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
mbedtls_md_type_t md_alg ) mbedtls_md_type_t md_alg )
{ {
ECDSA_VALIDATE_RET( grp != NULL );
ECDSA_VALIDATE_RET( r != NULL );
ECDSA_VALIDATE_RET( s != NULL );
ECDSA_VALIDATE_RET( d != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) ); return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg, NULL ) );
} }
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@ -574,9 +595,17 @@ cleanup:
* Verify ECDSA signature of hashed message * Verify ECDSA signature of hashed message
*/ */
int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen, const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s) const mbedtls_ecp_point *Q,
const mbedtls_mpi *r,
const mbedtls_mpi *s)
{ {
ECDSA_VALIDATE_RET( grp != NULL );
ECDSA_VALIDATE_RET( Q != NULL );
ECDSA_VALIDATE_RET( r != NULL );
ECDSA_VALIDATE_RET( s != NULL );
ECDSA_VALIDATE_RET( buf != NULL || blen == 0 );
return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) ); return( ecdsa_verify_restartable( grp, buf, blen, Q, r, s, NULL ) );
} }
#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ #endif /* !MBEDTLS_ECDSA_VERIFY_ALT */
@ -618,6 +647,10 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
{ {
int ret; int ret;
mbedtls_mpi r, s; mbedtls_mpi r, s;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
ECDSA_VALIDATE_RET( sig != NULL );
ECDSA_VALIDATE_RET( slen != NULL );
mbedtls_mpi_init( &r ); mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s ); mbedtls_mpi_init( &s );
@ -652,12 +685,17 @@ cleanup:
/* /*
* Compute and write signature * Compute and write signature
*/ */
int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen, mbedtls_md_type_t md_alg,
unsigned char *sig, size_t *slen, const unsigned char *hash, size_t hlen,
int (*f_rng)(void *, unsigned char *, size_t), unsigned char *sig, size_t *slen,
void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{ {
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
ECDSA_VALIDATE_RET( sig != NULL );
ECDSA_VALIDATE_RET( slen != NULL );
return( mbedtls_ecdsa_write_signature_restartable( return( mbedtls_ecdsa_write_signature_restartable(
ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) ); ctx, md_alg, hash, hlen, sig, slen, f_rng, p_rng, NULL ) );
} }
@ -669,6 +707,10 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx,
unsigned char *sig, size_t *slen, unsigned char *sig, size_t *slen,
mbedtls_md_type_t md_alg ) mbedtls_md_type_t md_alg )
{ {
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
ECDSA_VALIDATE_RET( sig != NULL );
ECDSA_VALIDATE_RET( slen != NULL );
return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen, return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen,
NULL, NULL ) ); NULL, NULL ) );
} }
@ -681,6 +723,9 @@ int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx,
const unsigned char *hash, size_t hlen, const unsigned char *hash, size_t hlen,
const unsigned char *sig, size_t slen ) const unsigned char *sig, size_t slen )
{ {
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
ECDSA_VALIDATE_RET( sig != NULL );
return( mbedtls_ecdsa_read_signature_restartable( return( mbedtls_ecdsa_read_signature_restartable(
ctx, hash, hlen, sig, slen, NULL ) ); ctx, hash, hlen, sig, slen, NULL ) );
} }
@ -698,6 +743,9 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *end = sig + slen; const unsigned char *end = sig + slen;
size_t len; size_t len;
mbedtls_mpi r, s; mbedtls_mpi r, s;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
ECDSA_VALIDATE_RET( sig != NULL );
mbedtls_mpi_init( &r ); mbedtls_mpi_init( &r );
mbedtls_mpi_init( &s ); mbedtls_mpi_init( &s );
@ -752,6 +800,9 @@ cleanup:
int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{ {
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( f_rng != NULL );
return( mbedtls_ecp_group_load( &ctx->grp, gid ) || return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
} }
@ -763,6 +814,8 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
{ {
int ret; int ret;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( key != NULL );
if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ||
@ -779,6 +832,8 @@ int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_ke
*/ */
void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ) void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
{ {
ECDSA_VALIDATE( ctx != NULL );
mbedtls_ecp_keypair_init( ctx ); mbedtls_ecp_keypair_init( ctx );
} }
@ -787,6 +842,9 @@ void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx )
*/ */
void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ) void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
{ {
if( ctx == NULL )
return;
mbedtls_ecp_keypair_free( ctx ); mbedtls_ecp_keypair_free( ctx );
} }
@ -796,6 +854,8 @@ void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx )
*/ */
void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx ) void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
{ {
ECDSA_VALIDATE( ctx != NULL );
mbedtls_ecp_restart_init( &ctx->ecp ); mbedtls_ecp_restart_init( &ctx->ecp );
ctx->ver = NULL; ctx->ver = NULL;
@ -810,6 +870,9 @@ void mbedtls_ecdsa_restart_init( mbedtls_ecdsa_restart_ctx *ctx )
*/ */
void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx ) void mbedtls_ecdsa_restart_free( mbedtls_ecdsa_restart_ctx *ctx )
{ {
if( ctx == NULL )
return;
mbedtls_ecp_restart_free( &ctx->ecp ); mbedtls_ecp_restart_free( &ctx->ecp );
ecdsa_restart_ver_free( ctx->ver ); ecdsa_restart_ver_free( ctx->ver );

View File

@ -1,3 +1,6 @@
ECDSA Parameter validation
ecdsa_invalid_param:
ECDSA primitive random #1 ECDSA primitive random #1
depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED
ecdsa_prim_random:MBEDTLS_ECP_DP_SECP192R1 ecdsa_prim_random:MBEDTLS_ECP_DP_SECP192R1

View File

@ -7,6 +7,201 @@
* END_DEPENDENCIES * END_DEPENDENCIES
*/ */
/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
void ecdsa_invalid_param( )
{
mbedtls_ecdsa_context ctx;
mbedtls_ecp_keypair key;
mbedtls_ecp_group grp;
mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
mbedtls_ecp_point P;
mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
mbedtls_mpi m;
size_t slen;
unsigned char buf[42] = { 0 };
TEST_INVALID_PARAM( mbedtls_ecdsa_init( NULL ) );
TEST_VALID_PARAM( mbedtls_ecdsa_free( NULL ) );
#if defined(MBEDTLS_ECP_RESTARTABLE)
TEST_INVALID_PARAM( mbedtls_ecdsa_restart_init( NULL ) );
TEST_VALID_PARAM( mbedtls_ecdsa_restart_free( NULL ) );
#endif /* MBEDTLS_ECP_RESTARTABLE */
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign( NULL, &m, &m, &m,
buf, sizeof( buf ),
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign( &grp, NULL, &m, &m,
buf, sizeof( buf ),
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign( &grp, &m, NULL, &m,
buf, sizeof( buf ),
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign( &grp, &m, &m, NULL,
buf, sizeof( buf ),
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign( &grp, &m, &m, &m,
NULL, sizeof( buf ),
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign( &grp, &m, &m, &m,
buf, sizeof( buf ),
NULL, NULL ) );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign_det( NULL, &m, &m, &m,
buf, sizeof( buf ),
valid_md ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign_det( &grp, NULL, &m, &m,
buf, sizeof( buf ),
valid_md ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign_det( &grp, &m, NULL, &m,
buf, sizeof( buf ),
valid_md ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign_det( &grp, &m, &m, NULL,
buf, sizeof( buf ),
valid_md ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_sign_det( &grp, &m, &m, &m,
NULL, sizeof( buf ),
valid_md ) );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_verify( NULL,
buf, sizeof( buf ),
&P, &m, &m ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_verify( &grp,
NULL, sizeof( buf ),
&P, &m, &m ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_verify( &grp,
buf, sizeof( buf ),
NULL, &m, &m ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_verify( &grp,
buf, sizeof( buf ),
&P, NULL, &m ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_verify( &grp,
buf, sizeof( buf ),
&P, &m, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature( NULL,
valid_md,
buf, sizeof( buf ),
buf, &slen,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature( &ctx,
valid_md,
NULL, sizeof( buf ),
buf, &slen,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature( &ctx,
valid_md,
buf, sizeof( buf ),
NULL, &slen,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature( &ctx,
valid_md,
buf, sizeof( buf ),
buf, NULL,
rnd_std_rand,
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature_restartable( NULL,
valid_md,
buf, sizeof( buf ),
buf, &slen,
rnd_std_rand,
NULL, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature_restartable( &ctx,
valid_md,
NULL, sizeof( buf ),
buf, &slen,
rnd_std_rand,
NULL, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature_restartable( &ctx,
valid_md,
buf, sizeof( buf ),
NULL, &slen,
rnd_std_rand,
NULL, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_write_signature_restartable( &ctx,
valid_md,
buf, sizeof( buf ),
buf, NULL,
rnd_std_rand,
NULL, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_read_signature( NULL,
buf, sizeof( buf ),
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_read_signature( &ctx,
NULL, sizeof( buf ),
buf, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_read_signature( &ctx,
buf, sizeof( buf ),
NULL, sizeof( buf ) ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_read_signature_restartable( NULL,
buf, sizeof( buf ),
buf, sizeof( buf ),
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_read_signature_restartable( &ctx,
NULL, sizeof( buf ),
buf, sizeof( buf ),
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_read_signature_restartable( &ctx,
buf, sizeof( buf ),
NULL, sizeof( buf ),
NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_genkey( NULL, valid_group,
rnd_std_rand, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_genkey( &ctx, valid_group,
NULL, NULL ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_from_keypair( NULL, &key ) );
TEST_INVALID_PARAM_RET( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
mbedtls_ecdsa_from_keypair( &ctx, NULL ) );
exit:
return;
}
/* END_CASE */
/* BEGIN_CASE */ /* BEGIN_CASE */
void ecdsa_prim_random( int id ) void ecdsa_prim_random( int id )
{ {