pk: function to calculate the signature size

Expose a function mbedtls_pk_signature_size to calculate the maximum
size of a signature made with a given key. Document that this is the
buffer size that mbedtls_pk_sign requires.

Add a corresponding field signature_size_func to the mbedtls_pk_info
structure.
diff --git a/include/mbedtls/pk.h b/include/mbedtls/pk.h
index e208da2..92f43ac 100644
--- a/include/mbedtls/pk.h
+++ b/include/mbedtls/pk.h
@@ -359,12 +359,18 @@
  * \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.
@@ -381,6 +387,15 @@
              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).
  *
  * \param ctx       PK context to use - must hold a private key
diff --git a/include/mbedtls/pk_internal.h b/include/mbedtls/pk_internal.h
index 592eb4b..4823294 100644
--- a/include/mbedtls/pk_internal.h
+++ b/include/mbedtls/pk_internal.h
@@ -82,7 +82,10 @@
     /** 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 9037646..b48f4d9 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -343,6 +343,20 @@
 }
 
 /*
+ * 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
  */
 int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items )
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index 55be595..0d8aee1 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -195,6 +195,7 @@
     rsa_alloc_wrap,
     rsa_free_wrap,
     rsa_debug,
+    NULL,
 };
 #endif /* MBEDTLS_RSA_C */
 
@@ -262,6 +263,12 @@
     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 @@
     eckey_alloc_wrap,
     eckey_free_wrap,
     eckey_debug,
+#if defined(MBEDTLS_ECDSA_C)
+    ecdsa_signature_size,
+#else
+    NULL,
+#endif
 };
 
 /*
@@ -336,6 +348,7 @@
     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 @@
     ecdsa_alloc_wrap,
     ecdsa_free_wrap,
     eckey_debug,        /* Compatible key structures */
+    ecdsa_signature_size,
 };
 #endif /* MBEDTLS_ECDSA_C */
 
@@ -519,6 +533,7 @@
     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 e847836..b8b222b 100644
--- a/tests/suites/test_suite_pk.function
+++ b/tests/suites/test_suite_pk.function
@@ -270,6 +270,8 @@
 
     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 );