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 ) );

