diff --git a/ChangeLog b/ChangeLog
index a64de5dd1..6aa740c67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,11 @@ Bugfix
      (rsa_rsaes_pkcs1_v15_decrypt(), rsa_rsaes_oaep_decrypt).
      Found by Laurent Simon.
 
+Changes
+   * Clarify ECDSA documentation and improve the sample code to avoid
+     misunderstandings and potentially dangerous use of the API. Pointed out
+     by Jean-Philippe Aumasson.
+
 = mbed TLS 1.3.19 branch released 2017-03-08
 
 Security
diff --git a/include/polarssl/ecdsa.h b/include/polarssl/ecdsa.h
index 5eb83d9d2..47b644ef6 100644
--- a/include/polarssl/ecdsa.h
+++ b/include/polarssl/ecdsa.h
@@ -26,6 +26,23 @@
 
 #include "ecp.h"
 #include "md.h"
+/*
+ *  RFC 4492 page 20:
+ *
+ *      Ecdsa-Sig-Value ::= SEQUENCE {
+ *          r       INTEGER,
+ *          s       INTEGER
+ *      }
+ *
+ * Size is at most
+ *      1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
+ *      twice that + 1 (tag) + 2 (len) for the sequence
+ * (assuming ECP_MAX_BYTES is less than 126 for r and s,
+ * and less than 124 (total len <= 255) for the sequence)
+ *
+ */
+/** Maximum size of an ECDSA signature in bytes */
+#define POLARSSL_ECDSA_MAX_LEN  ( 3 + 2 * ( 3 + POLARSSL_ECP_MAX_BYTES ) )
 
 /**
  * \brief           ECDSA context structure
@@ -58,6 +75,10 @@ extern "C" {
  * \param f_rng     RNG function
  * \param p_rng     RNG parameter
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  prescribed by SEC1 4.1.3 step 5.
+ *
  * \return          0 if successful,
  *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
  */
@@ -78,6 +99,10 @@ int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s,
  * \param blen      Length of buf
  * \param md_alg    MD algorithm used to hash the message
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  prescribed by SEC1 4.1.3 step 5.
+ *
  * \return          0 if successful,
  *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
  */
@@ -96,6 +121,10 @@ int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s,
  * \param r         First integer of the signature
  * \param s         Second integer of the signature
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  prescribed by SEC1 4.1.4 step 3.
+ *
  * \return          0 if successful,
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid
  *                  or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
@@ -121,6 +150,10 @@ int ecdsa_verify( ecp_group *grp,
  *                  size of the curve used, plus 7 (eg. 71 bytes if a 256-bit
  *                  curve is used).
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  prescribed by SEC1 4.1.3 step 5.
+ *
  * \return          0 if successful,
  *                  or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or
  *                  POLARSSL_ERR_ASN1 error code
@@ -168,6 +201,10 @@ int ecdsa_write_signature_det( ecdsa_context *ctx,
  * \param sig       Signature to read and verify
  * \param slen      Size of sig
  *
+ * \note            If the bitlength of the message hash is larger than the
+ *                  bitlength of the group order, then the hash is truncated as
+ *                  prescribed by SEC1 4.1.4 step 3.
+ *
  * \return          0 if successful,
  *                  POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid,
  *                  POLARSSL_ERR_ECP_SIG_LEN_MISTMATCH if the signature is
diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c
index aa8eafb97..1411e42b0 100644
--- a/programs/pkey/ecdsa.c
+++ b/programs/pkey/ecdsa.c
@@ -38,6 +38,7 @@
 #include "polarssl/entropy.h"
 #include "polarssl/ctr_drbg.h"
 #include "polarssl/ecdsa.h"
+#include "polarssl/sha256.h"
 
 #include <string.h>
 #endif
@@ -102,16 +103,20 @@ int main( int argc, char *argv[] )
     ecdsa_context ctx_sign, ctx_verify;
     entropy_context entropy;
     ctr_drbg_context ctr_drbg;
-    unsigned char hash[] = "This should be the hash of a message.";
-    unsigned char sig[512];
+    sha256_context sha256_ctx;
+    unsigned char message[100];
+    unsigned char hash[32];
+    unsigned char sig[POLARSSL_ECDSA_MAX_LEN];
     size_t sig_len;
     const char *pers = "ecdsa";
     ((void) argv);
 
     ecdsa_init( &ctx_sign );
     ecdsa_init( &ctx_verify );
+    sha256_init( &sha256_ctx );
 
-    memset(sig, 0, sizeof( sig ) );
+    memset( sig, 0, sizeof( sig ) );
+    memset( message, 0x25, sizeof( message ) );
     ret = 1;
 
     if( argc != 1 )
@@ -155,9 +160,24 @@ int main( int argc, char *argv[] )
     dump_pubkey( "  + Public key: ", &ctx_sign );
 
     /*
-     * Sign some message hash
+     * Compute message hash
      */
     polarssl_printf( "  . Signing message..." );
+    polarssl_printf( "  . Computing message hash..." );
+    fflush( stdout );
+
+    sha256_starts( &sha256_ctx, 0 );
+    sha256_update( &sha256_ctx, message, sizeof( message ) );
+    sha256_finish( &sha256_ctx, hash );
+
+    polarssl_printf( " ok\n" );
+
+    dump_buf( "  + Hash: ", hash, sizeof( hash ) );
+
+    /*
+     * Sign message hash
+     */
+    polarssl_printf( "  . Signing message hash..." );
     fflush( stdout );
 
     if( ( ret = ecdsa_write_signature( &ctx_sign,
@@ -170,7 +190,6 @@ int main( int argc, char *argv[] )
     }
     polarssl_printf( " ok (signature length = %u)\n", (unsigned int) sig_len );
 
-    dump_buf( "  + Hash: ", hash, sizeof hash );
     dump_buf( "  + Signature: ", sig, sig_len );
 
     /*
@@ -233,6 +252,7 @@ exit:
     ecdsa_free( &ctx_sign );
     ctr_drbg_free( &ctr_drbg );
     entropy_free( &entropy );
+    sha256_free( &sha256_ctx );
 
     return( ret );
 }