- Added support for TLS v1.1
 - Renamed some SSL defines to prevent future naming confusion

diff --git a/ChangeLog b/ChangeLog
index 6fdbc0b..9e77f2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,12 +6,15 @@
      SSL_EDH_RSA_CAMELLIA_128_SHA ciphersuites

    * Added compile-time and run-time version information

    * Expanded ssl_client2 arguments for more flexibility

+   * Added support for TLS v1.1

 

 Changes

    * Made Makefile cleaner

    * Removed dependency on rand() in rsa_pkcs1_encrypt().

      Now using random fuction provided to context.

 	 Requires initialization with rsa_init() before use!

+   * Some SSL defines were renamed in order to avoid

+     future confusion

 

 Bug fixes

    * Fixed CMake out of source build for tests (found by

diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 0eb46cc..254c8ef 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -92,14 +92,14 @@
 /*
  * Supported ciphersuites
  */
-#define SSL_RSA_RC4_128_MD5             4
-#define SSL_RSA_RC4_128_SHA             5
-#define SSL_RSA_DES_168_SHA            10
-#define SSL_EDH_RSA_DES_168_SHA        22
-#define SSL_RSA_AES_128_SHA            47
-#define SSL_EDH_RSA_AES_128_SHA        51
-#define SSL_RSA_AES_256_SHA            53
-#define SSL_EDH_RSA_AES_256_SHA        57
+#define SSL_RSA_RC4_128_MD5          0x04
+#define SSL_RSA_RC4_128_SHA          0x05
+#define SSL_RSA_DES_168_SHA          0x0A
+#define SSL_EDH_RSA_DES_168_SHA      0x16
+#define SSL_RSA_AES_128_SHA          0x2F
+#define SSL_EDH_RSA_AES_128_SHA      0x33
+#define SSL_RSA_AES_256_SHA          0x35
+#define SSL_EDH_RSA_AES_256_SHA      0x39
 
 #define SSL_RSA_CAMELLIA_128_SHA     0x41
 #define SSL_EDH_RSA_CAMELLIA_128_SHA 0x45
@@ -114,10 +114,33 @@
 #define SSL_MSG_HANDSHAKE              22
 #define SSL_MSG_APPLICATION_DATA       23
 
-#define SSL_ALERT_CLOSE_NOTIFY          0
-#define SSL_ALERT_WARNING               1
-#define SSL_ALERT_FATAL                 2
-#define SSL_ALERT_NO_CERTIFICATE       41
+#define SSL_ALERT_LEVEL_WARNING         1
+#define SSL_ALERT_LEVEL_FATAL           2
+
+#define SSL_ALERT_MSG_CLOSE_NOTIFY           0
+#define SSL_ALERT_MSG_UNEXPECTED_MESSAGE    10
+#define SSL_ALERT_MSG_BAD_RECORD_MAD        20
+#define SSL_ALERT_MSG_DECRYPTION_FAILED     21
+#define SSL_ALERT_MSG_RECORD_OVERFLOW       22
+#define SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30
+#define SSL_ALERT_MSG_HANDSHAKE_FAILURE     40
+#define SSL_ALERT_MSG_NO_CERT               41
+#define SSL_ALERT_MSG_BAD_CERT              42
+#define SSL_ALERT_MSG_UNSUPPORTED_CERT      43
+#define SSL_ALERT_MSG_CERT_REVOKED          44
+#define SSL_ALERT_MSG_CERT_EXPIRED          45
+#define SSL_ALERT_MSG_CERT_UNKNOWN          46
+#define SSL_ALERT_MSG_ILLEGAL_PARAMETER     47
+#define SSL_ALERT_MSG_UNKNOWN_CA            48
+#define SSL_ALERT_MSG_ACCESS_DENIED         49
+#define SSL_ALERT_MSG_DECODE_ERROR          50
+#define SSL_ALERT_MSG_DECRYPT_ERROR         51
+#define SSL_ALERT_MSG_EXPORT_RESTRICTION    60
+#define SSL_ALERT_MSG_PROTOCOL_VERSION      70
+#define SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71
+#define SSL_ALERT_MSG_INTERNAL_ERROR        80
+#define SSL_ALERT_MSG_USER_CANCELED         90
+#define SSL_ALERT_MSG_NO_RENEGOTIATION     100
 
 #define SSL_HS_HELLO_REQUEST            0
 #define SSL_HS_CLIENT_HELLO             1
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index b4828a1..ba1d287 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -48,7 +48,7 @@
     ssl->minor_ver = SSL_MINOR_VERSION_0;
 
     ssl->max_major_ver = SSL_MAJOR_VERSION_3;
-    ssl->max_minor_ver = SSL_MINOR_VERSION_1;
+    ssl->max_minor_ver = SSL_MINOR_VERSION_2;
 
     /*
      *     0  .   0   handshake type
@@ -208,8 +208,7 @@
         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
     }
 
-    if( buf[5] != SSL_MINOR_VERSION_0 &&
-        buf[5] != SSL_MINOR_VERSION_1 )
+    if( buf[5] > ssl->max_minor_ver )
     {
         SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
         return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index fa172c2..67eff47 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -294,6 +294,9 @@
         memcpy( ssl->mac_enc, keyblk,  ssl->maclen );
         memcpy( ssl->mac_dec, keyblk + ssl->maclen, ssl->maclen );
 
+        /*
+         * This is not used in TLS v1.1.
+         */
         memcpy( ssl->iv_enc, key2 + ssl->keylen,  ssl->ivlen );
         memcpy( ssl->iv_dec, key2 + ssl->keylen + ssl->ivlen,
                 ssl->ivlen );
@@ -306,6 +309,9 @@
         memcpy( ssl->mac_dec, keyblk,  ssl->maclen );
         memcpy( ssl->mac_enc, keyblk + ssl->maclen, ssl->maclen );
 
+        /*
+         * This is not used in TLS v1.1.
+         */
         memcpy( ssl->iv_dec, key1 + ssl->keylen,  ssl->ivlen );
         memcpy( ssl->iv_enc, key1 + ssl->keylen + ssl->ivlen,
                 ssl->ivlen );
@@ -545,6 +551,9 @@
     }
     else
     {
+        unsigned char *enc_msg;
+        int enc_msglen;
+
         padlen = ssl->ivlen - ( ssl->out_msglen + 1 ) % ssl->ivlen;
         if( padlen == ssl->ivlen )
             padlen = 0;
@@ -554,9 +563,38 @@
 
         ssl->out_msglen += padlen + 1;
 
+        enc_msglen = ssl->out_msglen;
+        enc_msg = ssl->out_msg;
+
+        /*
+         * Prepend per-record IV for block cipher in TLS v1.1 as per
+         * Method 1 (6.2.3.2. in RFC4346)
+         */
+        if( ssl->minor_ver == SSL_MINOR_VERSION_2 )
+        {
+            /*
+             * Generate IV
+             */
+            for( i = 0; i < ssl->ivlen; i++ )
+                ssl->iv_enc[i] = ssl->f_rng( ssl->p_rng );
+
+            /*
+             * Shift message for ivlen bytes and prepend IV
+             */
+            memmove( ssl->out_msg + ssl->ivlen, ssl->out_msg, ssl->out_msglen );
+            memcpy( ssl->out_msg, ssl->iv_enc, ssl->ivlen );
+
+            /*
+             * Fix pointer positions and message length with added IV
+             */
+            enc_msg = ssl->out_msg + ssl->ivlen;
+            enc_msglen = ssl->out_msglen;
+            ssl->out_msglen += ssl->ivlen;
+        }
+
         SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
-                            "including %d bytes of padding",
-                       ssl->out_msglen, padlen + 1 ) );
+                            "including %d bytes of IV and %d bytes of padding",
+                       ssl->out_msglen, ssl->ivlen, padlen + 1 ) );
 
         SSL_DEBUG_BUF( 4, "before encrypt: output payload",
                        ssl->out_msg, ssl->out_msglen );
@@ -566,8 +604,8 @@
             case  8:
 #if defined(POLARSSL_DES_C)
                 des3_crypt_cbc( (des3_context *) ssl->ctx_enc,
-                    DES_ENCRYPT, ssl->out_msglen,
-                    ssl->iv_enc, ssl->out_msg, ssl->out_msg );
+                    DES_ENCRYPT, enc_msglen,
+                    ssl->iv_enc, enc_msg, enc_msg );
                 break;
 #endif
 
@@ -579,8 +617,8 @@
 		     ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA)
 		{
                     aes_crypt_cbc( (aes_context *) ssl->ctx_enc,
-                        AES_ENCRYPT, ssl->out_msglen,
-                        ssl->iv_enc, ssl->out_msg, ssl->out_msg );
+                        AES_ENCRYPT, enc_msglen,
+                        ssl->iv_enc, enc_msg, enc_msg);
                     break;
 		}
 #endif
@@ -592,8 +630,8 @@
 		     ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
 		{
                     camellia_crypt_cbc( (camellia_context *) ssl->ctx_enc,
-                        CAMELLIA_ENCRYPT, ssl->out_msglen,
-                        ssl->iv_enc, ssl->out_msg, ssl->out_msg );
+                        CAMELLIA_ENCRYPT, enc_msglen,
+                        ssl->iv_enc, enc_msg, enc_msg );
                     break;
 		}
 #endif
@@ -635,6 +673,10 @@
     }
     else
     {
+        unsigned char *dec_msg;
+        unsigned char *dec_msg_result;
+        int dec_msglen;
+
         /*
          * Decrypt and check the padding
          */
@@ -645,13 +687,30 @@
             return( POLARSSL_ERR_SSL_INVALID_MAC );
         }
 
+        dec_msglen = ssl->in_msglen;
+        dec_msg = ssl->in_msg;
+        dec_msg_result = ssl->in_msg;
+
+        /*
+         * Initialize for prepended IV for block cipher in TLS v1.1
+         */
+        if( ssl->minor_ver == SSL_MINOR_VERSION_2 )
+        {
+            dec_msg += ssl->ivlen;
+            dec_msglen -= ssl->ivlen;
+            ssl->in_msglen -= ssl->ivlen;
+
+            for( i = 0; i < ssl->ivlen; i++ )
+                ssl->iv_dec[i] = ssl->in_msg[i];
+        }
+
         switch( ssl->ivlen )
         {
 #if defined(POLARSSL_DES_C)
             case  8:
                 des3_crypt_cbc( (des3_context *) ssl->ctx_dec,
-                    DES_DECRYPT, ssl->in_msglen,
-                    ssl->iv_dec, ssl->in_msg, ssl->in_msg );
+                    DES_DECRYPT, dec_msglen,
+                    ssl->iv_dec, dec_msg, dec_msg_result );
                 break;
 #endif
 
@@ -663,8 +722,8 @@
 		     ssl->session->cipher == SSL_EDH_RSA_AES_256_SHA)
 		{
                     aes_crypt_cbc( (aes_context *) ssl->ctx_dec,
-                       AES_DECRYPT, ssl->in_msglen,
-                       ssl->iv_dec, ssl->in_msg, ssl->in_msg );
+                       AES_DECRYPT, dec_msglen,
+                       ssl->iv_dec, dec_msg, dec_msg_result );
                     break;
 		}
 #endif
@@ -676,8 +735,8 @@
 		     ssl->session->cipher == SSL_EDH_RSA_CAMELLIA_256_SHA)
 		{
                     camellia_crypt_cbc( (camellia_context *) ssl->ctx_dec,
-                       CAMELLIA_DECRYPT, ssl->in_msglen,
-                       ssl->iv_dec, ssl->in_msg, ssl->in_msg );
+                       CAMELLIA_DECRYPT, dec_msglen,
+                       ssl->iv_dec, dec_msg, dec_msg_result );
                     break;
 		}
 #endif
@@ -982,8 +1041,7 @@
         return( POLARSSL_ERR_SSL_INVALID_RECORD );
     }
 
-    if( ssl->in_hdr[2] != SSL_MINOR_VERSION_0 &&
-        ssl->in_hdr[2] != SSL_MINOR_VERSION_1 )
+    if( ssl->in_hdr[2] > ssl->max_minor_ver )
     {
         SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
         return( POLARSSL_ERR_SSL_INVALID_RECORD );
@@ -1093,14 +1151,14 @@
         /*
          * Ignore non-fatal alerts, except close_notify
          */
-        if( ssl->in_msg[0] == SSL_ALERT_FATAL )
+        if( ssl->in_msg[0] == SSL_ALERT_LEVEL_FATAL )
         {
             SSL_DEBUG_MSG( 1, ( "is a fatal alert message" ) );
             return( POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE | ssl->in_msg[1] );
         }
 
-        if( ssl->in_msg[0] == SSL_ALERT_WARNING &&
-            ssl->in_msg[1] == SSL_ALERT_CLOSE_NOTIFY )
+        if( ssl->in_msg[0] == SSL_ALERT_LEVEL_WARNING &&
+            ssl->in_msg[1] == SSL_ALERT_MSG_CLOSE_NOTIFY )
         {
             SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
             return( POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY );
@@ -1142,8 +1200,8 @@
         {
             ssl->out_msglen  = 2;
             ssl->out_msgtype = SSL_MSG_ALERT;
-            ssl->out_msg[0]  = SSL_ALERT_WARNING;
-            ssl->out_msg[1]  = SSL_ALERT_NO_CERTIFICATE;
+            ssl->out_msg[0]  = SSL_ALERT_LEVEL_WARNING;
+            ssl->out_msg[1]  = SSL_ALERT_MSG_NO_CERT;
 
             SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) );
             goto write_msg;
@@ -1241,10 +1299,10 @@
     if( ssl->endpoint  == SSL_IS_SERVER &&
         ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
-        if( ssl->in_msglen  == 2                    &&
-            ssl->in_msgtype == SSL_MSG_ALERT        &&
-            ssl->in_msg[0]  == SSL_ALERT_WARNING    &&
-            ssl->in_msg[1]  == SSL_ALERT_NO_CERTIFICATE )
+        if( ssl->in_msglen  == 2                        &&
+            ssl->in_msgtype == SSL_MSG_ALERT            &&
+            ssl->in_msg[0]  == SSL_ALERT_LEVEL_WARNING  &&
+            ssl->in_msg[1]  == SSL_ALERT_MSG_NO_CERT )
         {
             SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
 
@@ -2026,8 +2084,8 @@
     {
         ssl->out_msgtype = SSL_MSG_ALERT;
         ssl->out_msglen  = 2;
-        ssl->out_msg[0]  = SSL_ALERT_WARNING;
-        ssl->out_msg[1]  = SSL_ALERT_CLOSE_NOTIFY;
+        ssl->out_msg[0]  = SSL_ALERT_LEVEL_WARNING;
+        ssl->out_msg[1]  = SSL_ALERT_MSG_CLOSE_NOTIFY;
 
         if( ( ret = ssl_write_record( ssl ) ) != 0 )
         {