Merged RSA-PSK key-exchange and ciphersuites
diff --git a/ChangeLog b/ChangeLog
index 57761ed..939d4f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
 Features
    * Support for Brainpool curves and TLS ciphersuites (RFC 7027)
    * Support for ECDHE-PSK key-exchange and ciphersuites
+   * Support for RSA-PSK key-exchange and ciphersuites
 
 Changes
    * RSA blinding locks for a smaller amount of time
diff --git a/include/polarssl/config.h b/include/polarssl/config.h
index ebb02d1..4973ea4 100644
--- a/include/polarssl/config.h
+++ b/include/polarssl/config.h
@@ -321,7 +321,7 @@
  * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
  *
  * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
- * (NOT YET IMPLEMENTED)
+ *
  * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15,
  *           POLARSSL_X509_CRT_PARSE_C
  *
@@ -336,7 +336,7 @@
  *      TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
  *      TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
  */
-//#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
 
 /**
  * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 2de45c1..c682c0a 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -75,6 +75,14 @@
 #include <time.h>
 #endif
 
+/* For convenience below and in programs */
+#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
+    defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) ||                       \
+    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED
+#endif
+
 #if defined(_MSC_VER) && !defined(inline)
 #define inline _inline
 #else
@@ -614,9 +622,7 @@
     void *p_vrfy;               /*!< context for verification         */
 #endif
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     int (*f_psk)(void *, ssl_context *, const unsigned char *, size_t);
     void *p_psk;               /*!< context for PSK retrieval         */
 #endif
@@ -717,9 +723,7 @@
     mpi dhm_G;                          /*!<  generator for DHM       */
 #endif
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     /*
      * PSK values
      */
@@ -1061,9 +1065,7 @@
                           rsa_key_len_func rsa_key_len );
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 /**
  * \brief          Set the Pre Shared Key (PSK) and the identity name connected
  *                 to it.
@@ -1103,9 +1105,7 @@
                      int (*f_psk)(void *, ssl_context *, const unsigned char *,
                                   size_t),
                      void *p_psk );
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(POLARSSL_DHM_C)
 /**
@@ -1531,9 +1531,7 @@
 
 void ssl_optimize_checksum( ssl_context *ssl, const ssl_ciphersuite_t *ciphersuite_info );
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex );
 #endif
 
diff --git a/library/debug.c b/library/debug.c
index d640bff..2497a3b 100644
--- a/library/debug.c
+++ b/library/debug.c
@@ -251,9 +251,12 @@
 
         if( items[i].type == POLARSSL_PK_DEBUG_MPI )
             debug_print_mpi( ssl, level, file, line, name, items[i].value );
-        else if( items[i].type == POLARSSL_PK_DEBUG_ECP )
+        else
+#if defined(POLARSSL_ECP_C)
+        if( items[i].type == POLARSSL_PK_DEBUG_ECP )
             debug_print_ecp( ssl, level, file, line, name, items[i].value );
         else
+#endif
             debug_print_msg( ssl, level, file, line, "should not happen" );
     }
 }
diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
index b4560a3..781edb2 100644
--- a/library/ssl_ciphersuites.c
+++ b/library/ssl_ciphersuites.c
@@ -1046,6 +1046,22 @@
       SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
       POLARSSL_CIPHERSUITE_WEAK },
 #endif /* POLARSSL_SHA1_C */
+
+#if defined(POLARSSL_SHA256_C)
+    { TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256",
+      POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_SHA256_C */
+
+#if defined(POLARSSL_SHA512_C)
+    { TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
+      POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
+      POLARSSL_CIPHERSUITE_WEAK },
+#endif /* POLARSSL_SHA512_C */
 #endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
 #endif /* POLARSSL_CIPHER_NULL_CIPHER */
 
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index a01b38d..b3521d3 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1147,9 +1147,7 @@
           POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
           POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 static int ssl_parse_server_psk_hint( ssl_context *ssl,
                                       unsigned char **p,
                                       unsigned char *end )
@@ -1163,7 +1161,7 @@
      *
      * opaque psk_identity_hint<0..2^16-1>;
      */
-    len = (*p)[1] << 8 | (*p)[0];
+    len = (*p)[0] << 8 | (*p)[1];
     *p += 2;
 
     if( (*p) + len > end )
@@ -1179,9 +1177,73 @@
 
     return( ret );
 }
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) ||                           \
+    defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
+/*
+ * Generate a pre-master secret and encrypt it with the server's RSA key
+ */
+static int ssl_write_encrypted_pms( ssl_context *ssl,
+                                    size_t offset, size_t *olen,
+                                    size_t pms_offset )
+{
+    int ret;
+    size_t len_bytes = ssl->minor_ver == SSL_MINOR_VERSION_0 ? 0 : 2;
+    unsigned char *p = ssl->handshake->premaster + pms_offset;
+
+    /*
+     * Generate (part of) the pre-master as
+     *  struct {
+     *      ProtocolVersion client_version;
+     *      opaque random[46];
+     *  } PreMasterSecret;
+     */
+    p[0] = (unsigned char) ssl->max_major_ver;
+    p[1] = (unsigned char) ssl->max_minor_ver;
+
+    if( ( ret = ssl->f_rng( ssl->p_rng, p + 2, 46 ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "f_rng", ret );
+        return( ret );
+    }
+
+    ssl->handshake->pmslen = 48;
+
+    /*
+     * Now write it out, encrypted
+     */
+    if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
+                POLARSSL_PK_RSA ) )
+    {
+        SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
+        return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
+    }
+
+    if( ( ret = pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
+                            p, ssl->handshake->pmslen,
+                            ssl->out_msg + offset + len_bytes, olen,
+                            SSL_MAX_CONTENT_LEN - offset - len_bytes,
+                            ssl->f_rng, ssl->p_rng ) ) != 0 )
+    {
+        SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
+        return( ret );
+    }
+
+#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
+    defined(POLARSSL_SSL_PROTO_TLS1_2)
+    if( len_bytes == 2 )
+    {
+        ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
+        ssl->out_msg[offset+1] = (unsigned char)( *olen      );
+        *olen += 2;
+    }
+#endif
+
+    return( 0 );
+}
+#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
 
 #if defined(POLARSSL_SSL_PROTO_TLS1_2)
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
@@ -1241,10 +1303,10 @@
 {
     int ret;
     const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+    unsigned char *p, *end;
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-    unsigned char *p, *end;
     size_t sig_len, params_len;
     unsigned char hash[64];
     md_type_t md_alg = POLARSSL_MD_NONE;
@@ -1254,17 +1316,16 @@
 
     SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
 
-    if( ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_DHE_RSA &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_RSA &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_PSK &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_DHE_PSK &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA )
     {
         SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
         ssl->state++;
         return( 0 );
     }
+    ((void) p);
+    ((void) end);
+#endif
 
     if( ( ret = ssl_read_record( ssl ) ) != 0 )
     {
@@ -1278,9 +1339,14 @@
         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
+    /*
+     * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
+     * doesn't use a psk_identity_hint
+     */
     if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
     {
-        if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
+        if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
+            ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
         {
             ssl->record_read = 1;
             goto exit;
@@ -1290,29 +1356,51 @@
         return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
     }
 
-    SSL_DEBUG_BUF( 3,   "server key exchange", ssl->in_msg + 4, ssl->in_hslen - 4 );
-
-#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
     p   = ssl->in_msg + 4;
     end = ssl->in_msg + ssl->in_hslen;
-#endif
+    SSL_DEBUG_BUF( 3,   "server key exchange", p, ssl->in_hslen - 4 );
 
-#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED)
-    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
+    {
+        if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
+        {
+            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+        }
+    } /* FALLTROUGH */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
+
+#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                       \
+    defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
+        ; /* nothing more to do */
+    else
+#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
+#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
+    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
     {
         if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
         {
-            SSL_DEBUG_MSG( 1, ( "failed to parsebad server key exchange message" ) );
+            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
         }
     }
     else
-#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
+    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
     defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ||
         ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA )
     {
         if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
@@ -1323,60 +1411,10 @@
     }
     else
 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
           POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
-    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
     {
-        unsigned char *p = ssl->in_msg + 4;
-        unsigned char *end = ssl->in_msg + ssl->in_hslen;
-
-        if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
-        {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-        }
-    }
-    else
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
-#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
-    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
-    {
-        unsigned char *p = ssl->in_msg + 4;
-        unsigned char *end = ssl->in_msg + ssl->in_hslen;
-
-        if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
-        {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-        }
-        if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
-        {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-        }
-    }
-    else
-#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
-#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
-    {
-        unsigned char *p = ssl->in_msg + 4;
-        unsigned char *end = ssl->in_msg + ssl->in_hslen;
-
-        if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
-        {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-        }
-        if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
-        {
-            SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-            return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-        }
-    }
-    else
-#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-    {
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
 
@@ -1802,10 +1840,9 @@
     else
 #endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
           POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ||
         ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ||
         ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
     {
@@ -1830,6 +1867,14 @@
         }
         else
 #endif
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
+        if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
+        {
+            if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
+                return( ret );
+        }
+        else
+#endif
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
         if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
         {
@@ -1884,57 +1929,19 @@
         }
     }
     else
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA )
     {
-        /*
-         * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
-         */
-        ssl->handshake->premaster[0] = (unsigned char) ssl->max_major_ver;
-        ssl->handshake->premaster[1] = (unsigned char) ssl->max_minor_ver;
-        ssl->handshake->pmslen = 48;
-
-        ret = ssl->f_rng( ssl->p_rng, ssl->handshake->premaster + 2,
-                          ssl->handshake->pmslen - 2 );
-        if( ret != 0 )
+        i = 4;
+        if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
             return( ret );
-
-        if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
-                         POLARSSL_PK_RSA ) )
-        {
-            SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
-            return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
-        }
-
-        i = ssl->minor_ver == SSL_MINOR_VERSION_0 ? 4 : 6;
-
-        ret = pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
-                ssl->handshake->premaster, ssl->handshake->pmslen,
-                ssl->out_msg + i, &n, SSL_BUFFER_LEN,
-                ssl->f_rng, ssl->p_rng );
-        if( ret != 0 )
-        {
-            SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret );
-            return( ret );
-        }
-
-#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
-    defined(POLARSSL_SSL_PROTO_TLS1_2)
-        if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
-        {
-            ssl->out_msg[4] = (unsigned char)( n >> 8 );
-            ssl->out_msg[5] = (unsigned char)( n      );
-        }
-#endif
-
     }
     else
 #endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */
     {
         ((void) ciphersuite_info);
+        SSL_DEBUG_MSG( 1, ( "should never happen" ) );
         return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
     }
 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index a43d226..5b35b94 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1911,7 +1911,8 @@
 {
     int ret;
     size_t n = 0;
-    const ssl_ciphersuite_t *ciphersuite_info;
+    const ssl_ciphersuite_t *ciphersuite_info =
+                            ssl->transform_negotiate->ciphersuite_info;
 
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
     defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
@@ -1925,15 +1926,11 @@
     ((void) dig_signed_len);
 #endif
 
-    ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
-
     SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
 
-    if( ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_DHE_RSA &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_RSA &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_DHE_PSK &&
-        ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_PSK )
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
+        ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
     {
         SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
         ssl->state++;
@@ -2288,11 +2285,16 @@
 #endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED ||
           POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */
 
-#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
-static int ssl_parse_encrypted_pms_secret( ssl_context *ssl )
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) ||                           \
+    defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
+static int ssl_parse_encrypted_pms( ssl_context *ssl,
+                                    const unsigned char *p,
+                                    const unsigned char *end,
+                                    size_t pms_offset )
 {
-    int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
-    size_t i, n = 0;
+    int ret;
+    size_t len = pk_get_len( ssl_own_key( ssl ) );
+    unsigned char *pms = ssl->handshake->premaster + pms_offset;
 
     if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_RSA ) )
     {
@@ -2303,17 +2305,12 @@
     /*
      * Decrypt the premaster using own private RSA key
      */
-    i = 4;
-    n = pk_get_len( ssl_own_key( ssl ) );
-    ssl->handshake->pmslen = 48;
-
 #if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \
     defined(POLARSSL_SSL_PROTO_TLS1_2)
     if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
     {
-        i += 2;
-        if( ssl->in_msg[4] != ( ( n >> 8 ) & 0xFF ) ||
-            ssl->in_msg[5] != ( ( n      ) & 0xFF ) )
+        if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
+            *p++ != ( ( len      ) & 0xFF ) )
         {
             SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -2321,21 +2318,20 @@
     }
 #endif
 
-    if( ssl->in_hslen != i + n )
+    if( p + len != end )
     {
         SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
         return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
     }
 
-    ret = pk_decrypt( ssl_own_key( ssl ),
-                      ssl->in_msg + i, n,
-                      ssl->handshake->premaster, &ssl->handshake->pmslen,
+    ret = pk_decrypt( ssl_own_key( ssl ), p, len,
+                      pms, &ssl->handshake->pmslen,
                       sizeof(ssl->handshake->premaster),
                       ssl->f_rng, ssl->p_rng );
 
     if( ret != 0 || ssl->handshake->pmslen != 48 ||
-        ssl->handshake->premaster[0] != ssl->handshake->max_major_ver ||
-        ssl->handshake->premaster[1] != ssl->handshake->max_minor_ver )
+        pms[0] != ssl->handshake->max_major_ver ||
+        pms[1] != ssl->handshake->max_minor_ver )
     {
         SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
 
@@ -2347,19 +2343,17 @@
          */
         ssl->handshake->pmslen = 48;
 
-        ret = ssl->f_rng( ssl->p_rng, ssl->handshake->premaster,
-                          ssl->handshake->pmslen );
+        ret = ssl->f_rng( ssl->p_rng, pms, ssl->handshake->pmslen );
         if( ret != 0 )
             return( ret );
     }
 
     return( ret );
 }
-#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED ||
+          POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 static int ssl_parse_client_psk_identity( ssl_context *ssl, unsigned char **p,
                                           const unsigned char *end )
 {
@@ -2425,9 +2419,7 @@
 
     return( ret );
 }
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 static int ssl_parse_client_key_exchange( ssl_context *ssl )
 {
@@ -2542,6 +2534,33 @@
     }
     else
 #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK )
+    {
+        unsigned char *p = ssl->in_msg + 4;
+        unsigned char *end = ssl->in_msg + ssl->in_msglen;
+
+        if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
+            return( ret );
+        }
+
+        if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
+            return( ret );
+        }
+
+        if( ( ret = ssl_psk_derive_premaster( ssl,
+                        ciphersuite_info->key_exchange ) ) != 0 )
+        {
+            SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret );
+            return( ret );
+        }
+    }
+    else
+#endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK )
     {
@@ -2601,7 +2620,10 @@
 #if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED)
     if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA )
     {
-        if( ( ret = ssl_parse_encrypted_pms_secret( ssl ) ) != 0 )
+        if( ( ret = ssl_parse_encrypted_pms( ssl,
+                                             ssl->in_msg + 4,
+                                             ssl->in_msg + ssl->in_msglen,
+                                             0 ) ) != 0 )
         {
             SSL_DEBUG_RET( 1, ( "ssl_parse_parse_ecrypted_pms_secret" ), ret );
             return( ret );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 0c905ad..70c0836 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -839,9 +839,7 @@
 #endif /* POLARSSL_SHA512_C */
 #endif /* POLARSSL_SSL_PROTO_TLS1_2 */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex )
 {
     unsigned char *p = ssl->handshake->premaster;
@@ -866,6 +864,19 @@
     }
     else
 #endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
+#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED)
+    if( key_ex == POLARSSL_KEY_EXCHANGE_RSA_PSK )
+    {
+        /*
+         * other_secret already set by the ClientKeyExchange message,
+         * and is 48 bytes long
+         */
+        *p++ = 0;
+        *p++ = 48;
+        p += 48;
+    }
+    else
+#endif /* POLARSSL_KEY_EXCHANGE_RSA_PKS_ENABLED */
 #if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED)
     if( key_ex == POLARSSL_KEY_EXCHANGE_DHE_PSK )
     {
@@ -926,9 +937,7 @@
 
     return( 0 );
 }
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(POLARSSL_SSL_PROTO_SSL3)
 /*
@@ -3669,9 +3678,7 @@
 }
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
                  const unsigned char *psk_identity, size_t psk_identity_len )
 {
@@ -3707,9 +3714,7 @@
     ssl->f_psk = f_psk;
     ssl->p_psk = p_psk;
 }
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(POLARSSL_DHM_C)
 int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G )
@@ -4386,9 +4391,7 @@
     }
 #endif
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     if( ssl->psk != NULL )
     {
         memset( ssl->psk, 0, ssl->psk_len );
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 7b97841..247abbe 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -166,17 +166,13 @@
 #define USAGE_IO ""
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 #define USAGE_PSK                                                   \
     "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
     "    psk_identity=%%s     default: \"Client_identity\"\n"
 #else
 #define USAGE_PSK ""
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(POLARSSL_SSL_SESSION_TICKETS)
 #define USAGE_TICKETS                                       \
@@ -244,9 +240,7 @@
 {
     int ret = 0, len, server_fd, i, written, frags;
     unsigned char buf[1024];
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     unsigned char psk[256];
     size_t psk_len = 0;
 #endif
@@ -500,9 +494,7 @@
             opt.min_version = ciphersuite_info->min_minor_ver;
     }
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     /*
      * Unhexify the pre-shared key if any is given
      */
@@ -550,9 +542,7 @@
             psk[ j / 2 ] |= c;
         }
     }
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
     /*
      * 0. Initialize the RNG and the session data
@@ -720,9 +710,7 @@
     ssl_set_own_cert( &ssl, &clicert, &pkey );
 #endif
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity,
                  strlen( opt.psk_identity ) );
 #endif
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 0148103..8e7ee0e 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -144,17 +144,13 @@
 #define USAGE_IO ""
 #endif /* POLARSSL_X509_CRT_PARSE_C */
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
 #define USAGE_PSK                                                   \
     "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
     "    psk_identity=%%s     default: \"Client_identity\"\n"
 #else
 #define USAGE_PSK ""
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
 #if defined(POLARSSL_SSL_SESSION_TICKETS)
 #define USAGE_TICKETS                                       \
@@ -213,9 +209,7 @@
     int listen_fd;
     int client_fd = -1;
     unsigned char buf[1024];
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     unsigned char psk[256];
     size_t psk_len = 0;
 #endif
@@ -473,9 +467,7 @@
             opt.min_version = ciphersuite_info->min_minor_ver;
     }
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     /*
      * Unhexify the pre-shared key if any is given
      */
@@ -523,9 +515,7 @@
             psk[ j / 2 ] |= c;
         }
     }
-#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED ||
-          POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
+#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */
 
     /*
      * 0. Initialize the RNG and the session data
@@ -739,9 +729,7 @@
         ssl_set_own_cert( &ssl, &srvcert2, &pkey2 );
 #endif
 
-#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) ||                           \
-    defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) ||                       \
-    defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
+#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED)
     ssl_set_psk( &ssl, psk, psk_len, (const unsigned char *) opt.psk_identity,
                  strlen( opt.psk_identity ) );
 #endif
diff --git a/tests/compat.sh b/tests/compat.sh
index a001ddb..584575c 100755
--- a/tests/compat.sh
+++ b/tests/compat.sh
@@ -401,10 +401,28 @@
             TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA        \
             TLS-DHE-PSK-WITH-AES-128-CBC-SHA         \
             TLS-DHE-PSK-WITH-AES-256-CBC-SHA         \
-            TLS-PSK-WITH-NULL-SHA                    \
             TLS-DHE-PSK-WITH-NULL-SHA                \
+            TLS-PSK-WITH-NULL-SHA                    \
+            TLS-RSA-PSK-WITH-RC4-128-SHA             \
+            TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA        \
+            TLS-RSA-PSK-WITH-AES-256-CBC-SHA         \
+            TLS-RSA-PSK-WITH-AES-128-CBC-SHA         \
+            TLS-RSA-WITH-NULL-SHA                    \
+            TLS-RSA-WITH-NULL-MD5                    \
             "
 
+
+        if [ "$MODE" != "ssl3" ];
+        then
+            P_CIPHERS="$P_CIPHERS                       \
+                TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA      \
+                TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA      \
+                TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA     \
+                TLS-ECDHE-PSK-WITH-RC4-128-SHA          \
+                TLS-ECDHE-PSK-WITH-NULL-SHA             \
+                "
+        fi
+
         if [ "$MODE" = "tls1_2" ];
         then
             P_CIPHERS="$P_CIPHERS                        \
@@ -424,6 +442,19 @@
                 TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384     \
                 TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256 \
                 TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384 \
+                TLS-RSA-PSK-WITH-AES-256-CBC-SHA384         \
+                TLS-RSA-PSK-WITH-AES-256-GCM-SHA384         \
+                TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384    \
+                TLS-RSA-PSK-WITH-AES-128-CBC-SHA256         \
+                TLS-RSA-PSK-WITH-AES-128-GCM-SHA256         \
+                TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256    \
+                TLS-RSA-WITH-NULL-SHA256                    \
+                TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384       \
+                TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384  \
+                TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256       \
+                TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256  \
+                TLS-ECDHE-PSK-WITH-NULL-SHA384              \
+                TLS-ECDHE-PSK-WITH-NULL-SHA256              \
                 "
         fi