diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h index e208da232..92f43ac77 100644 --- a/include/mbedtls/pk.h +++ b/include/mbedtls/pk.h @@ -359,12 +359,18 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, * \param hash Hash of the message to sign * \param hash_len Hash length or 0 (see notes) * \param sig Place to write the signature - * \param sig_len Number of bytes written + * \param sig_len Number of bytes written to sig * \param f_rng RNG function * \param p_rng RNG parameter * * \return 0 on success, or a type-specific error code. * + * \note The signature buffer \c sig must be of appropriate size + * which can be calculated with \c mbedtls_pk_signature_size. + * Depending on the algorithm, the value returned in + * \c sig_len may be less or equal to the value returned by + * \c mbedtls_pk_signature_size. + * * \note For RSA keys, the default padding type is PKCS#1 v1.5. * There is no interface in the PK module to make RSASSA-PSS * signatures yet. @@ -380,6 +386,15 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +/** + * \brief Calculate the size of a signature made with this key. + * + * \param ctx PK context to use + * + * \return Maximum size in bytes of a signature made with this key. + */ +size_t mbedtls_pk_signature_size( const mbedtls_pk_context *ctx ); + /** * \brief Decrypt message (including padding if relevant). * diff --git a/include/mbedtls/pk_internal.h b/include/mbedtls/pk_internal.h index 592eb4b06..4823294e8 100644 --- a/include/mbedtls/pk_internal.h +++ b/include/mbedtls/pk_internal.h @@ -82,7 +82,10 @@ struct mbedtls_pk_info_t /** Interface with the debug module */ void (*debug_func)( const void *ctx, mbedtls_pk_debug_item *items ); + /** Signature size */ + size_t (*signature_size_func)( const void *ctx ); }; + #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /* Container for RSA-alt */ typedef struct diff --git a/library/pk.c b/library/pk.c index 9037646de..b48f4d90c 100644 --- a/library/pk.c +++ b/library/pk.c @@ -342,6 +342,20 @@ size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) ); } +/* + * Maximum signature size + */ +size_t mbedtls_pk_signature_size( const mbedtls_pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->signature_size_func == NULL ) + return( ( ctx->pk_info->get_bitlen( ctx->pk_ctx ) + 7 ) / 8 ); + else + return( ctx->pk_info->signature_size_func( ctx->pk_ctx ) ); +} + /* * Export debug information */ diff --git a/library/pk_wrap.c b/library/pk_wrap.c index 55be5954e..0d8aee1fc 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -195,6 +195,7 @@ const mbedtls_pk_info_t mbedtls_rsa_info = { rsa_alloc_wrap, rsa_free_wrap, rsa_debug, + NULL, }; #endif /* MBEDTLS_RSA_C */ @@ -262,6 +263,12 @@ static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, return( ret ); } +static size_t ecdsa_signature_size( const void *ctx_arg ) +{ + const mbedtls_ecp_keypair *ctx = ctx_arg; + return( MBEDTLS_ECDSA_MAX_SIG_LEN( ctx->grp.pbits ) ); +} + #endif /* MBEDTLS_ECDSA_C */ static int eckey_check_pair( const void *pub, const void *prv ) @@ -311,6 +318,11 @@ const mbedtls_pk_info_t mbedtls_eckey_info = { eckey_alloc_wrap, eckey_free_wrap, eckey_debug, +#if defined(MBEDTLS_ECDSA_C) + ecdsa_signature_size, +#else + NULL, +#endif }; /* @@ -336,6 +348,7 @@ const mbedtls_pk_info_t mbedtls_eckeydh_info = { eckey_alloc_wrap, /* Same underlying key structure */ eckey_free_wrap, /* Same underlying key structure */ eckey_debug, /* Same underlying key structure */ + NULL, }; #endif /* MBEDTLS_ECP_C */ @@ -400,6 +413,7 @@ const mbedtls_pk_info_t mbedtls_ecdsa_info = { ecdsa_alloc_wrap, ecdsa_free_wrap, eckey_debug, /* Compatible key structures */ + ecdsa_signature_size, }; #endif /* MBEDTLS_ECDSA_C */ @@ -519,6 +533,7 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = { rsa_alt_alloc_wrap, rsa_alt_free_wrap, NULL, + NULL, }; #endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index e84783667..b8b222b2f 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -270,6 +270,8 @@ void pk_sign_verify( int type, int sign_ret, int verify_ret ) TEST_ASSERT( mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, sizeof hash, sig, &sig_len, rnd_std_rand, NULL ) == sign_ret ); + if( sign_ret == 0 ) + TEST_ASSERT( sig_len <= mbedtls_pk_signature_size( &pk ) ); TEST_ASSERT( mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256, hash, sizeof hash, sig, sig_len ) == verify_ret );