Merge I/O contexts into one
diff --git a/ChangeLog b/ChangeLog
index 0f9ccf0..c7bda6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@
 API Changes
    * net_connect() and net_bind() have a new 'proto' argument to choose
      between TCP and UDP, using the macros NET_PROTO_TCP or NET_PROTO_UDP.
+   * ssl_set_bio() now requires that p_send == p_recv.
 
 = PolarSSL 1.3.9 released 2014-10-20
 Security
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h
index 1cfb606..29c8dc0 100644
--- a/include/polarssl/ssl.h
+++ b/include/polarssl/ssl.h
@@ -725,8 +725,7 @@
 
     void *p_rng;                /*!< context for the RNG function     */
     void *p_dbg;                /*!< context for the debug function   */
-    void *p_recv;               /*!< context for reading operations   */
-    void *p_send;               /*!< context for writing operations   */
+    void *p_bio;                /*!< context for I/O operations   */
     void *p_get_cache;          /*!< context for cache retrieval      */
     void *p_set_cache;          /*!< context for cache store          */
     void *p_hw_data;            /*!< context for HW acceleration      */
@@ -1069,9 +1068,13 @@
  *
  * \param ssl      SSL context
  * \param f_recv   read callback
- * \param p_recv   read parameter
+ * \param p_recv   read parameter (must be equal to write parameter)
  * \param f_send   write callback
- * \param p_send   write parameter
+ * \param p_send   write parameter (must be equal to read parameter)
+ *
+ * \warning        It is required that p_recv == p_send. Otherwise, the first
+ *                 attempt at sending or receiving will result in a
+ *                 POLARSSL_ERR_SSL_BAD_INPUT_DATA error.
  */
 void ssl_set_bio( ssl_context *ssl,
         int (*f_recv)(void *, unsigned char *, size_t), void *p_recv,
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 51a0ac7..126fbae 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1842,6 +1842,13 @@
 
     SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
 
+    if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
+    {
+        SSL_DEBUG_MSG( 1, ( "Bad usage of ssl_set_bio() "
+                            "or ssl_set_bio_timeout()" ) );
+        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+    }
+
     if( nb_want > SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
     {
         SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
@@ -1907,7 +1914,7 @@
         }
 
         len = SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
-        ret = ssl->f_recv( ssl->p_recv, ssl->in_hdr, len );
+        ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
 
         SSL_DEBUG_RET( 2, "ssl->f_recv", ret );
 
@@ -1928,7 +1935,7 @@
         while( ssl->in_left < nb_want )
         {
             len = nb_want - ssl->in_left;
-            ret = ssl->f_recv( ssl->p_recv, ssl->in_hdr + ssl->in_left, len );
+            ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr + ssl->in_left, len );
 
             SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
                            ssl->in_left, nb_want ) );
@@ -1959,6 +1966,13 @@
 
     SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
 
+    if( ssl->f_send == NULL )
+    {
+        SSL_DEBUG_MSG( 1, ( "Bad usage of ssl_set_bio() "
+                            "or ssl_set_bio_timeout()" ) );
+        return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
+    }
+
     /* Avoid incrementing counter if data is flushed */
     if( ssl->out_left == 0 )
     {
@@ -1973,7 +1987,7 @@
 
         buf = ssl->out_hdr + ssl_hdr_len( ssl ) +
               ssl->out_msglen - ssl->out_left;
-        ret = ssl->f_send( ssl->p_send, buf, ssl->out_left );
+        ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
 
         SSL_DEBUG_RET( 2, "ssl->f_send", ret );
 
@@ -4299,10 +4313,17 @@
             int (*f_recv)(void *, unsigned char *, size_t), void *p_recv,
             int (*f_send)(void *, const unsigned char *, size_t), void *p_send )
 {
+    if( p_recv != p_send )
+    {
+        ssl->f_recv = NULL;
+        ssl->f_send = NULL;
+        ssl->p_bio  = NULL;
+        return;
+    }
+
     ssl->f_recv     = f_recv;
     ssl->f_send     = f_send;
-    ssl->p_recv     = p_recv;
-    ssl->p_send     = p_send;
+    ssl->p_bio      = p_send;
 }
 
 void ssl_set_session_cache( ssl_context *ssl,