- Added support for NULL cipher (POLARSSL_CIPHER_NULL_CIPHER) and weak ciphersuites (POLARSSL_ENABLE_WEAK_CIPHERSUITES). They are disabled by default!


diff --git a/ChangeLog b/ChangeLog
index b331aa0..7be1df5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 PolarSSL ChangeLog
 
+= Version Trunk
+Features
+   * Added support for NULL cipher (POLARSSL_CIPHER_NULL_CIPHER) and weak
+     ciphersuites (POLARSSL_ENABLE_WEAK_CIPHERSUITES). They are disabled by
+     default!
+
 = Version 1.1.1 released on 2012-01-23
 Bugfix
    * Check for failed malloc() in ssl_set_hostname() and x509_get_entries()
diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h
index 8c94dd5..9605066 100644
--- a/include/polarssl/cipher.h
+++ b/include/polarssl/cipher.h
@@ -5,7 +5,7 @@
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  *
- *  Copyright (C) 2006-2011, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -48,6 +48,7 @@
 
 typedef enum {
     POLARSSL_CIPHER_ID_NONE = 0,
+    POLARSSL_CIPHER_ID_NULL,
     POLARSSL_CIPHER_ID_AES,
     POLARSSL_CIPHER_ID_DES,
     POLARSSL_CIPHER_ID_3DES,
@@ -56,6 +57,7 @@
 
 typedef enum {
     POLARSSL_CIPHER_NONE = 0,
+    POLARSSL_CIPHER_NULL,
     POLARSSL_CIPHER_AES_128_CBC,
     POLARSSL_CIPHER_AES_192_CBC,
     POLARSSL_CIPHER_AES_256_CBC,
@@ -81,6 +83,7 @@
 
 typedef enum {
     POLARSSL_MODE_NONE = 0,
+    POLARSSL_MODE_NULL,
     POLARSSL_MODE_CBC,
     POLARSSL_MODE_CFB128,
     POLARSSL_MODE_OFB,
diff --git a/include/polarssl/cipher_wrap.h b/include/polarssl/cipher_wrap.h
index 5df8174..e81c11d 100644
--- a/include/polarssl/cipher_wrap.h
+++ b/include/polarssl/cipher_wrap.h
@@ -5,7 +5,7 @@
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  *
- *  Copyright (C) 2006-2011, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -84,6 +84,10 @@
 
 #endif /* defined(POLARSSL_DES_C) */
 
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+extern const cipher_info_t null_cipher_info;
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index ea518d7..83319cc 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -130,6 +130,23 @@
 #define POLARSSL_CIPHER_MODE_CTR
 
 /**
+ * \def POLARSSL_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ *      SSL_RSA_NULL_MD5
+ *      SSL_RSA_NULL_SHA
+ *      SSL_RSA_NULL_SHA256
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+#define POLARSSL_CIPHER_NULL_CIPHER
+ */
+
+/**
  * \def POLARSSL_DEBUG_MSG
  *
  * Requires: POLARSSL_DEBUG_C
@@ -139,6 +156,21 @@
 #define POLARSSL_DEBUG_MSG
 
 /**
+ * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS (like RC4_40)
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels without virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ *      SSL_RSA_DES_SHA
+ *      SSL_EDH_RSA_DES_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+#define POLARSSL_ENABLE_WEAK_CIPHERSUITES
+ */
+
+/**
  * \def POLARSSL_GENPRIME
  *
  * Requires: POLARSSL_BIGNUM_C, POLARSSL_RSA_C
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 74c5d2d..4b7d272 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -3,7 +3,7 @@
  *
  * \brief SSL/TLS functions.
  *
- *  Copyright (C) 2006-2010, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -110,6 +110,12 @@
 /*
  * Supported ciphersuites
  */
+#define SSL_RSA_NULL_MD5             0x01   /**< Weak! */
+#define SSL_RSA_NULL_SHA             0x02   /**< Weak! */
+#define SSL_RSA_NULL_SHA256          0x3B   /**< Weak! */
+#define SSL_RSA_DES_SHA              0x09   /**< Weak! */
+#define SSL_EDH_RSA_DES_SHA          0x15   /**< Weak! */
+
 #define SSL_RSA_RC4_128_MD5          0x04
 #define SSL_RSA_RC4_128_SHA          0x05
 #define SSL_RSA_DES_168_SHA          0x0A
diff --git a/library/cipher.c b/library/cipher.c
index 485a09b..85c74ab 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -5,7 +5,7 @@
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  *
- *  Copyright (C) 2006-2010, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -86,6 +86,10 @@
         POLARSSL_CIPHER_DES_EDE3_CBC,
 #endif /* defined(POLARSSL_DES_C) */
 
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        POLARSSL_CIPHER_NULL,
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
         0
 };
 
@@ -164,6 +168,11 @@
             return &des_ede3_cbc_info;
 #endif
 
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        case POLARSSL_CIPHER_NULL:
+            return &null_cipher_info;
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
         default:
             return NULL;
     }
@@ -237,6 +246,12 @@
     if( !strcasecmp( "DES-EDE3-CBC", cipher_name ) )
         return cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
 #endif
+
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+    if( !strcasecmp( "NULL", cipher_name ) )
+        return cipher_info_from_type( POLARSSL_CIPHER_NULL );
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
     return NULL;
 }
 
@@ -274,6 +289,11 @@
     ctx->key_length = key_length;
     ctx->operation = operation;
 
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+    if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
+        return 0;
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
     /*
      * For CFB128 and CTR mode always use the encryption key schedule
      */
@@ -318,6 +338,15 @@
 
     *olen = 0;
 
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+    if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
+    {
+        memcpy( output, input, ilen );
+        *olen = ilen;
+        return 0;
+    }
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
     if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
     {
         /*
@@ -465,7 +494,8 @@
     *olen = 0;
 
     if( POLARSSL_MODE_CFB128 == ctx->cipher_info->mode ||
-        POLARSSL_MODE_CTR == ctx->cipher_info->mode )
+        POLARSSL_MODE_CTR == ctx->cipher_info->mode ||
+        POLARSSL_MODE_NULL == ctx->cipher_info->mode )
     {
         return 0;
     }
diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c
index 8edc06f..c5aa99b 100644
--- a/library/cipher_wrap.c
+++ b/library/cipher_wrap.c
@@ -5,7 +5,7 @@
  *
  * \author Adriaan de Jong <dejong@fox-it.com>
  *
- *  Copyright (C) 2006-2011, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -549,4 +549,38 @@
 };
 #endif
 
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+static void * null_ctx_alloc( void )
+{
+    return (void *) 1;
+}
+
+
+static void null_ctx_free( void *ctx )
+{
+    ((void) ctx);
+}
+
+const cipher_base_t null_base_info = {
+    POLARSSL_CIPHER_ID_NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    null_ctx_alloc,
+    null_ctx_free
+};
+
+const cipher_info_t null_cipher_info = {
+    POLARSSL_CIPHER_NULL,
+    POLARSSL_MODE_NULL,
+    0,
+    "NULL",
+    1,
+    1,
+    &null_base_info
+};
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
 #endif
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 95ceea6..7547d9f 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1,7 +1,7 @@
 /*
  *  SSLv3/TLSv1 client-side functions
  *
- *  Copyright (C) 2006-2010, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -342,7 +342,8 @@
 
     SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
 
-    if( ssl->session->ciphersuite != SSL_EDH_RSA_DES_168_SHA &&
+    if( ssl->session->ciphersuite != SSL_EDH_RSA_DES_SHA &&
+        ssl->session->ciphersuite != SSL_EDH_RSA_DES_168_SHA &&
         ssl->session->ciphersuite != SSL_EDH_RSA_AES_128_SHA &&
         ssl->session->ciphersuite != SSL_EDH_RSA_AES_256_SHA &&
         ssl->session->ciphersuite != SSL_EDH_RSA_CAMELLIA_128_SHA &&
@@ -536,7 +537,8 @@
 
     SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
 
-    if( ssl->session->ciphersuite == SSL_EDH_RSA_DES_168_SHA ||
+    if( ssl->session->ciphersuite == SSL_EDH_RSA_DES_SHA ||
+        ssl->session->ciphersuite == SSL_EDH_RSA_DES_168_SHA ||
         ssl->session->ciphersuite == SSL_EDH_RSA_AES_128_SHA ||
         ssl->session->ciphersuite == SSL_EDH_RSA_AES_256_SHA ||
         ssl->session->ciphersuite == SSL_EDH_RSA_CAMELLIA_128_SHA ||
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 5f2891d..70ca5bb 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1,7 +1,7 @@
 /*
  *  SSLv3/TLSv1 server-side functions
  *
- *  Copyright (C) 2006-2010, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -544,7 +544,8 @@
 
     SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
 
-    if( ssl->session->ciphersuite != SSL_EDH_RSA_DES_168_SHA &&
+    if( ssl->session->ciphersuite != SSL_EDH_RSA_DES_SHA &&
+        ssl->session->ciphersuite != SSL_EDH_RSA_DES_168_SHA &&
         ssl->session->ciphersuite != SSL_EDH_RSA_AES_128_SHA &&
         ssl->session->ciphersuite != SSL_EDH_RSA_AES_256_SHA &&
         ssl->session->ciphersuite != SSL_EDH_RSA_CAMELLIA_128_SHA &&
@@ -716,7 +717,8 @@
         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
     }
 
-    if( ssl->session->ciphersuite == SSL_EDH_RSA_DES_168_SHA ||
+    if( ssl->session->ciphersuite == SSL_EDH_RSA_DES_SHA ||
+        ssl->session->ciphersuite == SSL_EDH_RSA_DES_168_SHA ||
         ssl->session->ciphersuite == SSL_EDH_RSA_AES_128_SHA ||
         ssl->session->ciphersuite == SSL_EDH_RSA_AES_256_SHA ||
         ssl->session->ciphersuite == SSL_EDH_RSA_CAMELLIA_128_SHA ||
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 44e972c..bbe8388 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1,7 +1,7 @@
 /*
  *  SSLv3/TLSv1 shared functions
  *
- *  Copyright (C) 2006-2010, Brainspark B.V.
+ *  Copyright (C) 2006-2012, Brainspark B.V.
  *
  *  This file is part of PolarSSL (http://www.polarssl.org)
  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
@@ -41,6 +41,7 @@
 #include "polarssl/des.h"
 #include "polarssl/debug.h"
 #include "polarssl/ssl.h"
+#include "polarssl/sha2.h"
 
 #include <stdlib.h>
 #include <time.h>
@@ -277,6 +278,33 @@
             break;
 #endif
 
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        case SSL_RSA_NULL_MD5:
+            ssl->keylen = 0; ssl->minlen = 0;
+            ssl->ivlen = 0; ssl->maclen = 16;
+            break;
+
+        case SSL_RSA_NULL_SHA:
+            ssl->keylen = 0; ssl->minlen = 0;
+            ssl->ivlen = 0; ssl->maclen = 20;
+            break;
+
+        case SSL_RSA_NULL_SHA256:
+            ssl->keylen = 0; ssl->minlen = 0;
+            ssl->ivlen = 0; ssl->maclen = 32;
+            break;
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
+#if defined(POLARSSL_DES_C)
+        case SSL_RSA_DES_SHA:
+        case SSL_EDH_RSA_DES_SHA:
+            ssl->keylen =  8; ssl->minlen = 8;
+            ssl->ivlen  =  8; ssl->maclen = 20;
+            break;
+#endif
+#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
+
         default:
             SSL_DEBUG_MSG( 1, ( "ciphersuite %s is not available",
                            ssl_get_ciphersuite( ssl ) ) );
@@ -366,6 +394,23 @@
             break;
 #endif
 
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        case SSL_RSA_NULL_MD5:
+        case SSL_RSA_NULL_SHA:
+        case SSL_RSA_NULL_SHA256:
+            break;
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
+#if defined(POLARSSL_DES_C)
+        case SSL_RSA_DES_SHA:
+        case SSL_EDH_RSA_DES_SHA:
+            des_setkey_enc( (des_context *) ssl->ctx_enc, key1 );
+            des_setkey_dec( (des_context *) ssl->ctx_dec, key2 );
+            break;
+#endif
+#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
+
         default:
             return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
@@ -521,7 +566,12 @@
         if( ssl->maclen == 20 )
             sha1_hmac( ssl->mac_enc, 20,
                        ssl->out_ctr,  ssl->out_msglen + 13,
-                       ssl->out_msg + ssl->out_msglen );               
+                       ssl->out_msg + ssl->out_msglen );
+
+        if( ssl->maclen == 32 )
+            sha2_hmac( ssl->mac_enc, 32,
+                       ssl->out_ctr,  ssl->out_msglen + 13,
+                       ssl->out_msg + ssl->out_msglen, 0);
     }
 
     SSL_DEBUG_BUF( 4, "computed mac",
@@ -535,7 +585,6 @@
 
     if( ssl->ivlen == 0 )
     {
-#if defined(POLARSSL_ARC4_C)
         padlen = 0;
 
         SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
@@ -545,12 +594,23 @@
         SSL_DEBUG_BUF( 4, "before encrypt: output payload",
                        ssl->out_msg, ssl->out_msglen );
 
-        arc4_crypt( (arc4_context *) ssl->ctx_enc,
-                    ssl->out_msglen, ssl->out_msg,
-                    ssl->out_msg );
-#else
-        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+#if defined(POLARSSL_ARC4_C)
+        if( ssl->session->ciphersuite == SSL_RSA_RC4_128_MD5 ||
+            ssl->session->ciphersuite == SSL_RSA_RC4_128_SHA )
+        {
+            arc4_crypt( (arc4_context *) ssl->ctx_enc,
+                        ssl->out_msglen, ssl->out_msg,
+                        ssl->out_msg );
+        } else
 #endif
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        if( ssl->session->ciphersuite == SSL_RSA_NULL_MD5 ||
+            ssl->session->ciphersuite == SSL_RSA_NULL_SHA ||
+            ssl->session->ciphersuite == SSL_RSA_NULL_SHA256 )
+        {
+        } else
+#endif
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
     else
     {
@@ -605,11 +665,21 @@
 
         switch( ssl->ivlen )
         {
-            case  8:
 #if defined(POLARSSL_DES_C)
-                des3_crypt_cbc( (des3_context *) ssl->ctx_enc,
-                    DES_ENCRYPT, enc_msglen,
-                    ssl->iv_enc, enc_msg, enc_msg );
+            case  8:
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+                if( ssl->session->ciphersuite == SSL_RSA_DES_SHA ||
+                    ssl->session->ciphersuite == SSL_EDH_RSA_DES_SHA )
+                {
+                    des_crypt_cbc( (des_context *) ssl->ctx_enc,
+                                   DES_ENCRYPT, enc_msglen,
+                                   ssl->iv_enc, enc_msg, enc_msg );
+                }
+                else
+#endif
+                        des3_crypt_cbc( (des3_context *) ssl->ctx_enc,
+                        DES_ENCRYPT, enc_msglen,
+                        ssl->iv_enc, enc_msg, enc_msg );
                 break;
 #endif
 
@@ -650,10 +720,15 @@
     return( 0 );
 }
 
+/*
+ * TODO: Use digest version when integrated!
+ */
+#define POLARSSL_SSL_MAX_MAC_SIZE   32
+
 static int ssl_decrypt_buf( ssl_context *ssl )
 {
     size_t i, padlen;
-    unsigned char tmp[20];
+    unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE];
 
     SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
 
@@ -668,12 +743,22 @@
     {
 #if defined(POLARSSL_ARC4_C)
         padlen = 0;
-        arc4_crypt( (arc4_context *) ssl->ctx_dec,
+        if( ssl->session->ciphersuite == SSL_RSA_RC4_128_MD5 ||
+            ssl->session->ciphersuite == SSL_RSA_RC4_128_SHA )
+        {
+            arc4_crypt( (arc4_context *) ssl->ctx_dec,
                     ssl->in_msglen, ssl->in_msg,
                     ssl->in_msg );
-#else
-        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+        } else
 #endif
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        if( ssl->session->ciphersuite == SSL_RSA_NULL_MD5 ||
+            ssl->session->ciphersuite == SSL_RSA_NULL_SHA ||
+            ssl->session->ciphersuite == SSL_RSA_NULL_SHA256 )
+        {
+        } else
+#endif
+        return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
     else
     {
@@ -712,9 +797,19 @@
         {
 #if defined(POLARSSL_DES_C)
             case  8:
-                des3_crypt_cbc( (des3_context *) ssl->ctx_dec,
-                    DES_DECRYPT, dec_msglen,
-                    ssl->iv_dec, dec_msg, dec_msg_result );
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+                if( ssl->session->ciphersuite == SSL_RSA_DES_SHA ||
+                    ssl->session->ciphersuite == SSL_EDH_RSA_DES_SHA )
+                {
+                    des_crypt_cbc( (des_context *) ssl->ctx_dec,
+                                   DES_DECRYPT, dec_msglen,
+                                   ssl->iv_dec, dec_msg, dec_msg_result );
+                }
+                else
+#endif
+                    des3_crypt_cbc( (des3_context *) ssl->ctx_dec,
+                        DES_DECRYPT, dec_msglen,
+                        ssl->iv_dec, dec_msg, dec_msg_result );
                 break;
 #endif
 
@@ -790,7 +885,7 @@
     ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 );
     ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen      );
 
-    memcpy( tmp, ssl->in_msg + ssl->in_msglen, 20 );
+    memcpy( tmp, ssl->in_msg + ssl->in_msglen, POLARSSL_SSL_MAX_MAC_SIZE );
 
     if( ssl->minor_ver == SSL_MINOR_VERSION_0 )
     {
@@ -798,7 +893,7 @@
              ssl_mac_md5( ssl->mac_dec,
                           ssl->in_msg, ssl->in_msglen,
                           ssl->in_ctr, ssl->in_msgtype );
-        else
+        else if( ssl->maclen == 20 )
             ssl_mac_sha1( ssl->mac_dec,
                           ssl->in_msg, ssl->in_msglen,
                           ssl->in_ctr, ssl->in_msgtype );
@@ -809,10 +904,14 @@
              md5_hmac( ssl->mac_dec, 16,
                        ssl->in_ctr,  ssl->in_msglen + 13,
                        ssl->in_msg + ssl->in_msglen );
-        else
+        else if( ssl->maclen == 20 )
             sha1_hmac( ssl->mac_dec, 20,
                        ssl->in_ctr,  ssl->in_msglen + 13,
                        ssl->in_msg + ssl->in_msglen );
+        else if( ssl->maclen == 32 )
+            sha2_hmac( ssl->mac_dec, 32,
+                       ssl->in_ctr,  ssl->in_msglen + 13,
+                       ssl->in_msg + ssl->in_msglen, 0 );
     }
 
     SSL_DEBUG_BUF( 4, "message  mac", tmp, ssl->maclen );
@@ -1991,6 +2090,24 @@
             return( "SSL-EDH-RSA-CAMELLIA-256-SHA" );
 #endif
 
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+        case SSL_RSA_NULL_MD5:
+            return( "SSL-RSA-NULL-MD5" );
+        case SSL_RSA_NULL_SHA:
+            return( "SSL-RSA-NULL-SHA" );
+        case SSL_RSA_NULL_SHA256:
+            return( "SSL-RSA-NULL-SHA256" );
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
+#if defined(POLARSSL_DES_C)
+        case SSL_RSA_DES_SHA:
+            return( "SSL-RSA-DES-SHA" );
+        case SSL_EDH_RSA_DES_SHA:
+            return( "SSL-EDH-RSA-DES-SHA" );
+#endif
+#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
+
     default:
         break;
     }
@@ -2036,6 +2153,24 @@
         return( SSL_EDH_RSA_CAMELLIA_256_SHA );
 #endif
 
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+    if (0 == strcasecmp(ciphersuite_name, "SSL-RSA-NULL-MD5"))
+        return( SSL_RSA_NULL_MD5 );
+    if (0 == strcasecmp(ciphersuite_name, "SSL-RSA-NULL-SHA"))
+        return( SSL_RSA_NULL_SHA );
+    if (0 == strcasecmp(ciphersuite_name, "SSL-RSA-NULL-SHA256"))
+        return( SSL_RSA_NULL_SHA256 );
+#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */
+
+#if defined(POLARSSL_DES_C)
+    if (0 == strcasecmp(ciphersuite_name, "SSL-RSA-DES-SHA"))
+        return( SSL_RSA_DES_SHA );
+    if (0 == strcasecmp(ciphersuite_name, "SSL-EDH-RSA-DES-SHA"))
+        return( SSL_EDH_RSA_DES_SHA );
+#endif
+#endif /* defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) */
+
     return( 0 );
 }
 
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 10fe65f..4b84d51 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -144,6 +144,9 @@
     if( argc == 0 )
     {
     usage:
+        if( ret == 0 )
+            ret = 1;
+
         printf( USAGE );
 
         list = ssl_list_ciphersuites();
@@ -153,7 +156,6 @@
             list++;
         }
         printf("\n");
-        ret = 1;
         goto exit;
     }
 
@@ -210,8 +212,10 @@
             opt.force_ciphersuite[0] = ssl_get_ciphersuite_id( q );
 
             if( opt.force_ciphersuite[0] <= 0 )
+            {
+                ret = 2;
                 goto usage;
-
+            }
             opt.force_ciphersuite[1] = 0;
         }
         else
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 5ee2f63..f3ad42f 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -84,6 +84,15 @@
     SSL_RSA_DES_168_SHA,
     SSL_RSA_RC4_128_SHA,
     SSL_RSA_RC4_128_MD5,
+#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
+    SSL_EDH_RSA_DES_SHA,
+    SSL_RSA_DES_SHA,
+#if defined(POLARSSL_CIPHER_NULL_CIPHER)
+    SSL_RSA_NULL_MD5,
+    SSL_RSA_NULL_SHA,
+    SSL_RSA_NULL_SHA256,
+#endif
+#endif
     0
 };
 
@@ -206,6 +215,8 @@
     ((void) argc);
     ((void) argv);
 
+    memset( &ssl, 0, sizeof( ssl_context ) );
+
     /*
      * 1. Load the certificates and private RSA key
      */
@@ -448,7 +459,6 @@
     len = ret;
     printf( " %d bytes written\n\n%s\n", len, (char *) buf );
     
-    ssl_close_notify( &ssl );
     ret = 0;
     goto reset;
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index a37fd56..48c766f 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -34,6 +34,7 @@
 add_test_suite(cipher cipher.aes)
 add_test_suite(cipher cipher.camellia)
 add_test_suite(cipher cipher.des)
+add_test_suite(cipher cipher.null)
 add_test_suite(ctr_drbg)
 add_test_suite(debug)
 add_test_suite(des)
diff --git a/tests/Makefile b/tests/Makefile
index 8ecf346..990637d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -12,8 +12,8 @@
 APPS =	test_suite_aes			test_suite_arc4			\
 		test_suite_base64		test_suite_camellia		\
 		test_suite_cipher.aes	test_suite_cipher.camellia	\
-		test_suite_cipher.des	test_suite_ctr_drbg		\
-		test_suite_debug		\
+		test_suite_cipher.des	test_suite_cipher.null	\
+		test_suite_ctr_drbg		test_suite_debug		\
 		test_suite_des			test_suite_dhm			\
 		test_suite_error		test_suite_hmac_shax	\
 		test_suite_md			test_suite_mdx			\
@@ -38,6 +38,10 @@
 	echo   "  Generate	$@"
 	scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.des
 
+test_suite_cipher.null.c : suites/test_suite_cipher.function suites/test_suite_cipher.null.data scripts/generate_code.pl suites/helpers.function
+	echo   "  Generate	$@"
+	scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.null
+
 %.c : suites/%.function suites/%.data scripts/generate_code.pl suites/helpers.function
 	echo   "  Generate	$@"
 	scripts/generate_code.pl suites $* $*
@@ -66,11 +70,15 @@
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
 
-test_suite_ctr_drbg: test_suite_ctr_drbg.c ../library/libpolarssl.a
+test_suite_cipher.des: test_suite_cipher.des.c ../library/libpolarssl.a
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
 
-test_suite_cipher.des: test_suite_cipher.des.c ../library/libpolarssl.a
+test_suite_cipher.null: test_suite_cipher.null.c ../library/libpolarssl.a
+	echo   "  CC    	$@.c"
+	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
+
+test_suite_ctr_drbg: test_suite_ctr_drbg.c ../library/libpolarssl.a
 	echo   "  CC    	$@.c"
 	$(CC) $(CFLAGS) $(OFLAGS) $@.c	$(LDFLAGS) -o $@
 
diff --git a/tests/compat.sh b/tests/compat.sh
new file mode 100644
index 0000000..ab84899
--- /dev/null
+++ b/tests/compat.sh
@@ -0,0 +1,136 @@
+killall -q openssl ssl_server
+
+openssl s_server -cert data_files/server2.crt -key data_files/server2.key -www -quiet -cipher NULL,ALL &
+PROCESS_ID=$!
+
+sleep 1
+
+CIPHERS="                               \
+    SSL-EDH-RSA-AES-128-SHA             \
+    SSL-EDH-RSA-AES-256-SHA             \
+    SSL-EDH-RSA-CAMELLIA-128-SHA        \
+    SSL-EDH-RSA-CAMELLIA-256-SHA        \
+    SSL-EDH-RSA-DES-168-SHA             \
+    SSL-RSA-AES-256-SHA                 \
+    SSL-RSA-CAMELLIA-256-SHA            \
+    SSL-RSA-AES-128-SHA                 \
+    SSL-RSA-CAMELLIA-128-SHA            \
+    SSL-RSA-DES-168-SHA                 \
+    SSL-RSA-RC4-128-SHA                 \
+    SSL-RSA-RC4-128-MD5                 \
+    SSL-RSA-NULL-MD5                    \
+    SSL-RSA-NULL-SHA                    \
+    SSL-RSA-DES-SHA                     \
+    SSL-EDH-RSA-DES-SHA                 \
+    "
+
+#    Not supported by OpenSSL: SSL-RSA-NULL-SHA256
+for i in $CIPHERS;
+do
+    RESULT="$( ../programs/ssl/ssl_client2 force_ciphersuite=$i )"
+    EXIT=$?
+    echo -n "OpenSSL Server - PolarSSL Client - $i : $EXIT - "
+    if [ "$EXIT" = "2" ];
+    then
+        echo Ciphersuite not supported in client
+    elif [ "$EXIT" != "0" ];
+    then
+        echo Failed
+        echo $RESULT
+    else
+        echo Success
+    fi
+done
+kill $PROCESS_ID
+
+../programs/ssl/ssl_server > /dev/null &
+PROCESS_ID=$!
+
+sleep 1
+
+CIPHERS="                           \
+    DHE-RSA-AES128-SHA              \
+    DHE-RSA-AES256-SHA              \
+    DHE-RSA-CAMELLIA128-SHA         \
+    DHE-RSA-CAMELLIA256-SHA         \
+    EDH-RSA-DES-CBC3-SHA            \
+    AES256-SHA                      \
+    CAMELLIA256-SHA                 \
+    AES128-SHA                      \
+    CAMELLIA128-SHA                 \
+    DES-CBC3-SHA                    \
+    RC4-SHA                         \
+    RC4-MD5                         \
+    NULL-MD5                        \
+    NULL-SHA                        \
+    DES-CBC-SHA                     \
+    EDH-RSA-DES-CBC-SHA             \
+    "
+
+#    Not supported by OpenSSL: NULL-SHA256
+for i in $CIPHERS;
+do
+    RESULT="$( ( echo -e 'GET HTTP/1.0'; echo; sleep 1 ) | openssl s_client -cipher $i 2>&1)"
+    EXIT=$?
+    echo -n "PolarSSL Server - OpenSSL Client - $i : $EXIT - "
+
+    if [ "$EXIT" != "0" ];
+    then
+        SUPPORTED="$( echo $RESULT | grep 'Cipher is (NONE)' )"
+        if [ "X$SUPPORTED" != "X" ]
+        then
+            echo "Ciphersuite not supported in server"
+        else
+            echo Failed
+            echo $RESULT
+        fi
+    else
+        echo Success
+    fi
+done
+
+kill $PROCESS_ID
+
+../programs/ssl/ssl_server > /dev/null &
+PROCESS_ID=$!
+
+sleep 1
+
+CIPHERS="                               \
+    SSL-RSA-RC4-128-SHA                 \
+    SSL-RSA-NULL-MD5                    \
+    SSL-EDH-RSA-AES-128-SHA             \
+    SSL-EDH-RSA-AES-256-SHA             \
+    SSL-EDH-RSA-CAMELLIA-128-SHA        \
+    SSL-EDH-RSA-CAMELLIA-256-SHA        \
+    SSL-EDH-RSA-DES-168-SHA             \
+    SSL-RSA-NULL-SHA                    \
+    SSL-RSA-AES-256-SHA                 \
+    SSL-RSA-CAMELLIA-256-SHA            \
+    SSL-RSA-AES-128-SHA                 \
+    SSL-RSA-CAMELLIA-128-SHA            \
+    SSL-RSA-DES-168-SHA                 \
+    SSL-RSA-RC4-128-MD5                 \
+    SSL-RSA-DES-SHA                     \
+    SSL-EDH-RSA-DES-SHA                 \
+    SSL-RSA-NULL-SHA256                 \
+    "
+
+for i in $CIPHERS;
+do
+    RESULT="$( ../programs/ssl/ssl_client2 force_ciphersuite=$i )"
+    EXIT=$?
+    echo -n "PolarSSL Server - PolarSSL Client - $i : $EXIT - "
+    if [ "$EXIT" = "2" ];
+    then
+        echo Ciphersuite not supported in client
+    elif [ "$EXIT" != "0" ];
+    then
+        echo Failed
+        echo $RESULT
+    else
+        echo Success
+    fi
+done
+kill $PROCESS_ID
+
diff --git a/tests/suites/test_suite_cipher.null.data b/tests/suites/test_suite_cipher.null.data
new file mode 100644
index 0000000..96aa36a
--- /dev/null
+++ b/tests/suites/test_suite_cipher.null.data
@@ -0,0 +1,102 @@
+Cipher Selftest
+depends_on:POLARSSL_SELF_TEST
+cipher_selftest:
+
+Decrypt empty buffer
+dec_empty_buf:
+
+NULL Encrypt and decrypt 0 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:0
+
+NULL Encrypt and decrypt 1 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:1
+
+NULL Encrypt and decrypt 2 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:2
+
+NULL Encrypt and decrypt 7 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:7
+
+NULL Encrypt and decrypt 8 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:8
+
+NULL Encrypt and decrypt 9 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:9
+
+NULL Encrypt and decrypt 15 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:15
+
+NULL Encrypt and decrypt 16 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:16
+
+NULL Encrypt and decrypt 31 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:31
+
+NULL Encrypt and decrypt 32 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:32
+
+NULL Encrypt and decrypt 33 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:33
+
+NULL Encrypt and decrypt 47 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:47
+
+NULL Encrypt and decrypt 48 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:48
+
+NULL Encrypt and decrypt 49 bytes
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf:POLARSSL_CIPHER_NULL:NULL:0:49
+
+NULL Encrypt and decrypt 1 bytes in multiple parts 1
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:1:0:
+
+NULL Encrypt and decrypt 1 bytes in multiple parts 2
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:0:1:
+
+NULL Encrypt and decrypt 16 bytes in multiple parts 1
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:16:0:
+
+NULL Encrypt and decrypt 16 bytes in multiple parts 2
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:0:16:
+
+NULL Encrypt and decrypt 16 bytes in multiple parts 3
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:1:15:
+
+NULL Encrypt and decrypt 16 bytes in multiple parts 4
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:15:1:
+
+NULL Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:15:7:
+
+NULL Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:16:6:
+
+NULL Encrypt and decrypt 22 bytes in multiple parts 1
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:17:6:
+
+NULL Encrypt and decrypt 32 bytes in multiple parts 1
+depends_on:POLARSSL_CIPHER_NULL_CIPHER
+enc_dec_buf_multipart:POLARSSL_CIPHER_NULL:0:16:16: