[gnutls-dev] Re: Bleichenbacher RSA signature forgery attack and GnuTLS

Simon Josefsson jas at extundo.com
Mon Sep 11 15:14:48 CEST 2006


Simon Josefsson <jas at extundo.com> writes:

> Simon Josefsson <jas at extundo.com> writes:
>
>> 	      _gnutls_handshake_log ("PKCS #1 padding error");
>> 	      ret = GNUTLS_E_PKCS1_WRONG_PAD;
>
> Werner Koch points out that this error message may result in a
> vulnerability similar to Bleichenbacher's Crypto 98 attack.  It is not
> exactly the same situation -- Bleichenbacher talks about PKCS#1
> encryption (block type 1, uses random padding) where this deals with
> PKCS#1 verification (block type 2, uses 0xFF padding) -- but at a
> glance, it appears to have similar consequences, but differ in the
> number of messages required to mount the attack.

Nikos points out that we have already protected against that attack,
for TLS sessions, in auth_rsa.c:

  ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2);	/* btype==2 */

  if (ret < 0 || plaintext.size != TLS_MASTER_SIZE)
    {
      /* In case decryption fails then don't inform
       * the peer. Just use a random key. (in order to avoid
       * attack against pkcs-1 formating).
       */
      gnutls_assert ();
      _gnutls_x509_log ("auth_rsa: Possible PKCS #1 format attack\n");
      randomize_key = 1;
    }
  else
    {
      /* If the secret was properly formatted, then
       * check the version number.
       */
      if (_gnutls_get_adv_version_major (session) != plaintext.data[0]
	  || _gnutls_get_adv_version_minor (session) != plaintext.data[1])
	{
	  /* No error is returned here, if the version number check
	   * fails. We proceed normally.
	   * That is to defend against the attack described in the paper
	   * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
	   * Ondej Pokorny and Tomas Rosa.
	   */
	  gnutls_assert ();
	  _gnutls_x509_log
	    ("auth_rsa: Possible PKCS #1 version check format attack\n");
	}
    }

The GNUTLS-SA-2006-3 security advisory thus was a false alarm, but I'm
keeping the information on:

http://www.gnu.org/software/gnutls/security.html

I'll add a link to this post, though.

There should be no harm in applying the patch, though.

Note 1: If someone is worried about the log file being used as the
oracle here, don't be: the above log statements are only executed if
in debug mode, and this isn't recommended nor typical behaviour.

Note 2: I'd be interested in if someone could establish whether it is
possible to extend this oracle attack from error codes to different
timings.  In other words, if it takes different amount of time to
verify a signature depending on the padding error.

/Simon

>
> /Simon
>
> Index: gnutls_pk.c
> ===================================================================
> RCS file: /cvs/gnutls/gnutls/lib/gnutls_pk.c,v
> retrieving revision 1.82
> retrieving revision 1.83
> diff -u -p -r1.82 -r1.83
> --- gnutls_pk.c	15 Dec 2005 13:24:29 -0000	1.82
> +++ gnutls_pk.c	8 Sep 2006 13:19:29 -0000	1.83
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
> + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
>   *
>   * Author: Nikos Mavroyanopoulos
>   *
> @@ -265,8 +265,13 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_
>  
>    _gnutls_mpi_release (&res);
>  
> -  /* EB = 00||BT||PS||00||D 
> +  /* EB = 00||BT||PS||00||D
>     * (use block type 'btype')
> +   *
> +   * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
> +   * avoid attacks similar to the one described by Bleichenbacher in:
> +   * "Chosen Ciphertext Attacks against Protocols Based on RSA
> +   * Encryption Standard PKCS #1".
>     */
>  
>  
> @@ -303,8 +308,8 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_
>  	    }
>  	  if (edata[i] != 0xff)
>  	    {
> -	      _gnutls_handshake_log ("PKCS #1 padding error");
> -	      ret = GNUTLS_E_PKCS1_WRONG_PAD;
> +	      /* PKCS #1 padding error.  Don't use
> +		 GNUTLS_E_PKCS1_WRONG_PAD here.  */
>  	      break;
>  	    }
>  	}
> @@ -312,7 +317,6 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_
>      default:
>        gnutls_assert ();
>        gnutls_afree (edata);
> -      return GNUTLS_E_INTERNAL_ERROR;
>      }
>    i++;



More information about the Gnutls-dev mailing list