Add ecdsa_write_signature_det()
diff --git a/include/polarssl/ecdsa.h b/include/polarssl/ecdsa.h
index a718c0e..0fab07e 100644
--- a/include/polarssl/ecdsa.h
+++ b/include/polarssl/ecdsa.h
@@ -137,6 +137,34 @@
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng );
 
+#if defined(POLARSSL_ECDSA_DETERMINISTIC)
+/**
+ * \brief           Compute ECDSA signature and write it to buffer,
+ *                  serialized as defined in RFC 4492 page 20.
+ *                  Deterministic version, RFC 6979.
+ *                  (Not thread-safe to use same context in multiple threads)
+ *
+ * \param ctx       ECDSA context
+ * \param hash      Message hash
+ * \param hlen      Length of hash
+ * \param sig       Buffer that will hold the signature
+ * \param slen      Length of the signature written
+ * \param md_alg    MD algorithm used to hash the message
+ *
+ * \note            The "sig" buffer must be at least as large as twice the
+ *                  size of the curve used, plus 7 (eg. 71 bytes if a 256-bit
+ *                  curve is used).
+ *
+ * \return          0 if successful,
+ *                  or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or
+ *                  POLARSSL_ERR_ASN1 error code
+ */
+int ecdsa_write_signature_det( ecdsa_context *ctx,
+                               const unsigned char *hash, size_t hlen,
+                               unsigned char *sig, size_t *slen,
+                               md_type_t md_alg );
+#endif
+
 /**
  * \brief           Read and verify an ECDSA signature
  *
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 0bd0e97..e2b6a77 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -372,25 +372,16 @@
 #define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) )
 
 /*
- * Compute and write signature
+ * Convert a signature (given by context) to ASN.1
  */
-int ecdsa_write_signature( ecdsa_context *ctx,
-                           const unsigned char *hash, size_t hlen,
-                           unsigned char *sig, size_t *slen,
-                           int (*f_rng)(void *, unsigned char *, size_t),
-                           void *p_rng )
+static int ecdsa_signature_to_asn1( ecdsa_context *ctx,
+                                    unsigned char *sig, size_t *slen )
 {
     int ret;
     unsigned char buf[MAX_SIG_LEN];
     unsigned char *p = buf + sizeof( buf );
     size_t len = 0;
 
-    if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
-                            hash, hlen, f_rng, p_rng ) ) != 0 )
-    {
-        return( ret );
-    }
-
     ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->s ) );
     ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->r ) );
 
@@ -405,6 +396,45 @@
 }
 
 /*
+ * Compute and write signature
+ */
+int ecdsa_write_signature( ecdsa_context *ctx,
+                           const unsigned char *hash, size_t hlen,
+                           unsigned char *sig, size_t *slen,
+                           int (*f_rng)(void *, unsigned char *, size_t),
+                           void *p_rng )
+{
+    int ret;
+
+    if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
+                            hash, hlen, f_rng, p_rng ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( ecdsa_signature_to_asn1( ctx, sig, slen ) );
+}
+
+/*
+ * Compute and write signature deterministically
+ */
+int ecdsa_write_signature_det( ecdsa_context *ctx,
+                               const unsigned char *hash, size_t hlen,
+                               unsigned char *sig, size_t *slen,
+                               md_type_t md_alg )
+{
+    int ret;
+
+    if( ( ret = ecdsa_sign_det( &ctx->grp, &ctx->r, &ctx->s, &ctx->d,
+                                hash, hlen, md_alg ) ) != 0 )
+    {
+        return( ret );
+    }
+
+    return( ecdsa_signature_to_asn1( ctx, sig, slen ) );
+}
+
+/*
  * Read and check signature
  */
 int ecdsa_read_signature( ecdsa_context *ctx,
diff --git a/tests/suites/test_suite_ecdsa.data b/tests/suites/test_suite_ecdsa.data
index 6441b81..501bdeb 100644
--- a/tests/suites/test_suite_ecdsa.data
+++ b/tests/suites/test_suite_ecdsa.data
@@ -249,3 +249,27 @@
 ECDSA deterministic test vector rfc 6979 p521 sha512
 depends_on:POLARSSL_ECP_DP_SECP521R1_ENABLED:POLARSSL_SHA512_C
 ecdsa_det_test_vectors:POLARSSL_ECP_DP_SECP521R1:"0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538":POLARSSL_MD_SHA512:"test":"13E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47EE6D":"1FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4DCE3"
+
+ECDSA deterministic read-write random p256 sha256
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA256_C
+ecdsa_write_read_det_random:POLARSSL_ECP_DP_SECP256R1:POLARSSL_MD_SHA256
+
+ECDSA deterministic read-write random p256 sha384
+depends_on:POLARSSL_ECP_DP_SECP256R1_ENABLED:POLARSSL_SHA512_C
+ecdsa_write_read_det_random:POLARSSL_ECP_DP_SECP256R1:POLARSSL_MD_SHA384
+
+ECDSA deterministic read-write random p384 sha256
+depends_on:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_SHA256_C
+ecdsa_write_read_det_random:POLARSSL_ECP_DP_SECP384R1:POLARSSL_MD_SHA256
+
+ECDSA deterministic read-write random p384 sha384
+depends_on:POLARSSL_ECP_DP_SECP384R1_ENABLED:POLARSSL_SHA512_C
+ecdsa_write_read_det_random:POLARSSL_ECP_DP_SECP384R1:POLARSSL_MD_SHA384
+
+ECDSA deterministic read-write random p521 sha256
+depends_on:POLARSSL_ECP_DP_SECP521R1_ENABLED:POLARSSL_SHA256_C
+ecdsa_write_read_det_random:POLARSSL_ECP_DP_SECP521R1:POLARSSL_MD_SHA256
+
+ECDSA deterministic read-write random p521 sha384
+depends_on:POLARSSL_ECP_DP_SECP521R1_ENABLED:POLARSSL_SHA512_C
+ecdsa_write_read_det_random:POLARSSL_ECP_DP_SECP521R1:POLARSSL_MD_SHA384
diff --git a/tests/suites/test_suite_ecdsa.function b/tests/suites/test_suite_ecdsa.function
index edf1f73..398b288 100644
--- a/tests/suites/test_suite_ecdsa.function
+++ b/tests/suites/test_suite_ecdsa.function
@@ -186,3 +186,35 @@
     ecdsa_free( &ctx );
 }
 /* END_CASE */
+
+/* BEGIN_CASE */
+void ecdsa_write_read_det_random( int id, int md_alg )
+{
+    ecdsa_context ctx;
+    rnd_pseudo_info rnd_info;
+    unsigned char msg[100];
+    unsigned char hash[POLARSSL_MD_MAX_SIZE];
+    unsigned char sig[200];
+    size_t sig_len;
+
+    ecdsa_init( &ctx );
+    memset( &rnd_info, 0x00, sizeof( rnd_pseudo_info ) );
+    memset( hash, 0, sizeof( hash ) );
+    memset( sig, 0x2a, sizeof( sig ) );
+
+    /* prepare material for signature */
+    TEST_ASSERT( rnd_pseudo_rand( &rnd_info, msg, sizeof( msg ) ) == 0 );
+    md( md_info_from_type( md_alg ), msg, sizeof( msg ), hash );
+
+    /* generate signing key */
+    TEST_ASSERT( ecdsa_genkey( &ctx, id, &rnd_pseudo_rand, &rnd_info ) == 0 );
+
+    /* generate and write signature, then read and verify it */
+    TEST_ASSERT( ecdsa_write_signature_det( &ctx, hash, sizeof( hash ),
+                 sig, &sig_len, md_alg ) == 0 );
+    TEST_ASSERT( ecdsa_read_signature( &ctx, hash, sizeof( hash ),
+                 sig, sig_len ) == 0 );
+
+    ecdsa_free( &ctx );
+}
+/* END_CASE */