Add minified HMAC_DRBG for deterministic ECDSA
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index ca0c176..f4f5f77 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -279,6 +279,18 @@
 #define POLARSSL_ECP_NIST_OPTIM
 
 /**
+ * \def POLARSSL_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define POLARSSL_ECDSA_DETERMINISTIC
+
+/**
  * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED
  *
  * Enable the PSK based ciphersuite modes in SSL / TLS.
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 6f09994..3ab6921 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -36,6 +36,125 @@
 #include "polarssl/ecdsa.h"
 #include "polarssl/asn1write.h"
 
+#if defined(POLARSSL_ECDSA_DETERMINISTIC)
+#include "polarssl/md.h"
+#endif
+
+/*
+ * If using deterministic ECDSA (RFC 6979), we need HMAC_DRBG.
+ * Actually a simplified version is enough, so we implement it below.
+ */
+#if defined(POLARSSL_ECDSA_DETERMINISTIC)
+/*
+ * Simplified HMAC_DRBG context.
+ * No reseed counter, no prediction resistance flag.
+ */
+typedef struct
+{
+    md_context_t md_ctx;
+    unsigned char V[POLARSSL_MD_MAX_SIZE];
+    unsigned char K[POLARSSL_MD_MAX_SIZE];
+} hmac_drbg_context;
+
+/*
+ * Simplified HMAC_DRBG initialisation.
+ *
+ * Uses an entropy buffer rather than callback,
+ * assumes personalisation is not null,
+ * assumes md_info is not NULL and valid.
+ */
+static int hmac_drbg_init( hmac_drbg_context *ctx,
+                           const md_info_t * md_info,
+                           const unsigned char *entropy, size_t entropy_len,
+                           const unsigned char *pers, size_t pers_len )
+{
+    unsigned char sep[1];
+    size_t md_len = md_info->size;
+
+    memset( ctx, 0, sizeof( hmac_drbg_context ) );
+    md_init_ctx( &ctx->md_ctx, md_info );
+
+    memset( ctx->V, 0x01, md_len );
+    /* ctx->K is already 0 */
+
+    sep[0] = 0x00;
+    md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+    md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+    md_hmac_update( &ctx->md_ctx, sep, 1 );
+    md_hmac_update( &ctx->md_ctx, entropy, entropy_len );
+    md_hmac_update( &ctx->md_ctx, pers, pers_len );
+    md_hmac_finish( &ctx->md_ctx, ctx->K );
+
+    /* Step e */
+    md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+    md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+    md_hmac_finish( &ctx->md_ctx, ctx->V );
+
+    /* Step f */
+    sep[0] = 0x01;
+    md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+    md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+    md_hmac_update( &ctx->md_ctx, sep, 1 );
+    md_hmac_update( &ctx->md_ctx, entropy, entropy_len );
+    md_hmac_update( &ctx->md_ctx, pers, pers_len );
+    md_hmac_finish( &ctx->md_ctx, ctx->K );
+
+    /* Step g */
+    md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+    md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+    md_hmac_finish( &ctx->md_ctx, ctx->V );
+
+    return( 0 );
+}
+
+/*
+ * Simplified HMAC_DRBG random function
+ */
+static int hmac_drbg_random( void *state,
+                             unsigned char *output, size_t out_len )
+{
+    hmac_drbg_context *ctx = (hmac_drbg_context *) state;
+    unsigned char sep[1] = { 0 };
+    size_t md_len = ctx->md_ctx.md_info->size;
+    size_t left = out_len;
+    unsigned char *out = output;
+
+    while( left != 0 )
+    {
+        size_t use_len = left > md_len ? md_len : left;
+
+        md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+        md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+        md_hmac_finish( &ctx->md_ctx, ctx->V );
+
+        memcpy( out, ctx->V, use_len );
+        out += use_len;
+        left -= use_len;
+    }
+
+    md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+    md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+    md_hmac_update( &ctx->md_ctx, sep, 1 );
+    md_hmac_finish( &ctx->md_ctx, ctx->K );
+
+    md_hmac_starts( &ctx->md_ctx, ctx->K, md_len );
+    md_hmac_update( &ctx->md_ctx, ctx->V, md_len );
+    md_hmac_finish( &ctx->md_ctx, ctx->V );
+
+    return( 0 );
+}
+
+static void hmac_drbg_free( hmac_drbg_context *ctx )
+{
+    if( ctx == NULL )
+        return;
+
+    md_free_ctx( &ctx->md_ctx );
+
+    memset( ctx, 0, sizeof( hmac_drbg_context ) );
+}
+#endif
+
 /*
  * Derive a suitable integer for group grp from a buffer of length len
  * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3
@@ -51,6 +170,10 @@
     if( use_size * 8 > grp->nbits )
         MPI_CHK( mpi_shift_r( x, use_size * 8 - grp->nbits ) );
 
+    /* While at it, reduce modulo N */
+    if( mpi_cmp_mpi( x, &grp->N ) >= 0 )
+        MPI_CHK( mpi_sub_mpi( x, x, &grp->N ) );
+
 cleanup:
     return( ret );
 }