Upstream has published a patch against 0.14 that is claimed
to resolve the present issue. It is straightforward to adapt
this to our release 0.12.1.

However, this patch _must_ not be applied as it stands,
since the selftest 'test_suite_dhm' fails for one out
of three tests, once the patch is applied. My knowledge
of the code is too week to debug this, but I hope to lower
the threshold of the present maintainer by contributing
this refactored patch, which upstream has cared to publish
for polarssl_0.14.

Best regards,
  Mats Erik Andersson, DM
Description: Sanity checks on Diffie-Hellman parameters.
 CVE-2009-3555
 .
 TEMP-0616114-D52278
Author: PolarSSL
X-Comment: PolarSSL Security Advisory 2011-01
X-Original: http://polarssl.org/trac/wiki/SecurityAdvisory201101?format=txt
X-Adaptor: Mats Erik Andersson
--- polarssl-0.12.1.orig/library/dhm.c	2009-10-04 17:39:55.000000000 +0200
+++ polarssl-0.12.1/library/dhm.c	2011-04-02 01:41:16.000000000 +0200
@@ -61,6 +61,35 @@
 }
 
 /*
+ * Verify sanity of public parameter with regards to P
+ *
+ * Public parameter should be: 2 <= public_param <= P - 2
+ *
+ * For more information on the attack, see:
+ *  http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
+ *  http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
+ */
+static int dhm_check_range( const mpi *public_param, const mpi *P )
+{
+    mpi L, U;
+    int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA;
+
+    mpi_init( &L, &U, NULL );
+    mpi_lset( &L, 2 );
+    mpi_sub_int( &U, P, 2 );
+
+    if( mpi_cmp_mpi( public_param, &L ) >= 0 &&
+        mpi_cmp_mpi( public_param, &U ) <= 0 )
+    {
+        ret = 0;
+    }
+
+    mpi_free( &L, &U, NULL );
+
+    return( ret );
+}
+
+/*
  * Parse the ServerKeyExchange parameters
  */
 int dhm_read_params( dhm_context *ctx,
@@ -76,6 +105,9 @@
         ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
         return( ret );
 
+    if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
+        return( ret );
+
     ctx->len = mpi_size( &ctx->P );
 
     if( end - *p < 2 )
@@ -118,6 +150,9 @@
     MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
                           &ctx->P , &ctx->RP ) );
 
+    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
+        return( ret );
+
     /*
      * export P, G, GX
      */
@@ -195,6 +230,9 @@
     MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
                           &ctx->P , &ctx->RP ) );
 
+    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
+        return( ret );
+
     MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) );
 
 cleanup:
@@ -219,6 +257,9 @@
     MPI_CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X,
                           &ctx->P, &ctx->RP ) );
 
+    if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
+        return( ret );
+
     *olen = mpi_size( &ctx->K );
 
     MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) );

Reply via email to