Merge remote-tracking branch 'restricted/pr/397' into development

* restricted/pr/397:
  Don't split error code description across multiple lines
  Register new error code in error.h
  Move deprecation to separate section in ChangeLog
  Extend scope of ERR_RSA_UNSUPPORTED_OPERATION error code
  Adapt RSA test suite
  Adapt ChangeLog
  Deprecate usage of RSA primitives with wrong key type
diff --git a/ChangeLog b/ChangeLog
index f954c95..4b627a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -60,6 +60,10 @@
      and the message digest. Further, allow enabling/disabling of authority
      identifier, subject identifier and basic constraints extensions.
 
+New deprecations
+   * Deprecate usage of RSA primitives with non-matching key-type
+     (e.g., signing with a public key).
+
 = mbed TLS 2.6.0 branch released 2017-08-10
 
 Security
diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
index 31591e2..d51bcde 100644
--- a/include/mbedtls/error.h
+++ b/include/mbedtls/error.h
@@ -75,7 +75,7 @@
  * PKCS5     2   4 (Started from top)
  * DHM       3   9
  * PK        3   14 (Started from top)
- * RSA       4   9
+ * RSA       4   10
  * ECP       4   8 (Started from top)
  * MD        5   4
  * CIPHER    6   6
diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h
index 7d7469d..d04e71d 100644
--- a/include/mbedtls/rsa.h
+++ b/include/mbedtls/rsa.h
@@ -48,6 +48,7 @@
 #define MBEDTLS_ERR_RSA_VERIFY_FAILED                     -0x4380  /**< The PKCS#1 verification failed. */
 #define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE                  -0x4400  /**< The output buffer for decryption is not large enough. */
 #define MBEDTLS_ERR_RSA_RNG_FAILED                        -0x4480  /**< The random generator failed to generate non-zeros. */
+#define MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION             -0x4500  /**< The implementation doesn't offer the requested operation, e.g. because of security violations or lack of functionality */
 
 /*
  * RSA constants
@@ -250,6 +251,15 @@
  * \param input    buffer holding the data to be encrypted
  * \param output   buffer that will hold the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PRIVATE. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PRIVATE and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  *
  * \note           The output buffer must be as large as the size
@@ -273,6 +283,15 @@
  * \param input    buffer holding the data to be encrypted
  * \param output   buffer that will hold the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PRIVATE. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PRIVATE and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  *
  * \note           The output buffer must be as large as the size
@@ -299,6 +318,15 @@
  * \param input    buffer holding the data to be encrypted
  * \param output   buffer that will hold the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PRIVATE. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PRIVATE and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  *
  * \note           The output buffer must be as large as the size
@@ -327,13 +355,22 @@
  * \param output   buffer that will hold the plaintext
  * \param output_max_len    maximum length of the output buffer
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PUBLIC. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PUBLIC and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  *
  * \note           The output buffer length \c output_max_len should be
  *                 as large as the size ctx->len of ctx->N (eg. 128 bytes
  *                 if RSA-1024 is used) to be able to hold an arbitrary
  *                 decrypted message. If it is not large enough to hold
- *                 the decryption of the particular ciphertext provided, 
+ *                 the decryption of the particular ciphertext provided,
  *                 the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
  *
  * \note           The input buffer must be as large as the size
@@ -359,13 +396,22 @@
  * \param output   buffer that will hold the plaintext
  * \param output_max_len    maximum length of the output buffer
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PUBLIC. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PUBLIC and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  *
  * \note           The output buffer length \c output_max_len should be
  *                 as large as the size ctx->len of ctx->N (eg. 128 bytes
  *                 if RSA-1024 is used) to be able to hold an arbitrary
  *                 decrypted message. If it is not large enough to hold
- *                 the decryption of the particular ciphertext provided, 
+ *                 the decryption of the particular ciphertext provided,
  *                 the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
  *
  * \note           The input buffer must be as large as the size
@@ -393,16 +439,25 @@
  * \param output   buffer that will hold the plaintext
  * \param output_max_len    maximum length of the output buffer
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PUBLIC. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PUBLIC and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if successful, or an MBEDTLS_ERR_RSA_XXX error code
  *
  * \note           The output buffer length \c output_max_len should be
  *                 as large as the size ctx->len of ctx->N (eg. 128 bytes
  *                 if RSA-1024 is used) to be able to hold an arbitrary
  *                 decrypted message. If it is not large enough to hold
- *                 the decryption of the particular ciphertext provided, 
+ *                 the decryption of the particular ciphertext provided,
  *                 the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE.
  *
- * \note           The input buffer must be as large as the size 
+ * \note           The input buffer must be as large as the size
  *                 of ctx->N (eg. 128 bytes if RSA-1024 is used).
  */
 int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
@@ -430,6 +485,15 @@
  * \param hash     buffer holding the message digest
  * \param sig      buffer that will hold the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PUBLIC. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PUBLIC and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if the signing operation was successful,
  *                 or an MBEDTLS_ERR_RSA_XXX error code
  *
@@ -460,6 +524,15 @@
  * \param hash     buffer holding the message digest
  * \param sig      buffer that will hold the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PUBLIC. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PUBLIC and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if the signing operation was successful,
  *                 or an MBEDTLS_ERR_RSA_XXX error code
  *
@@ -488,6 +561,15 @@
  * \param hash     buffer holding the message digest
  * \param sig      buffer that will hold the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PUBLIC. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PRIVATE.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PUBLIC and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if the signing operation was successful,
  *                 or an MBEDTLS_ERR_RSA_XXX error code
  *
@@ -522,6 +604,15 @@
  * \param hash     buffer holding the message digest
  * \param sig      buffer holding the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PRIVATE. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PRIVATE and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if the verify operation was successful,
  *                 or an MBEDTLS_ERR_RSA_XXX error code
  *
@@ -552,6 +643,15 @@
  * \param hash     buffer holding the message digest
  * \param sig      buffer holding the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PRIVATE. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PRIVATE and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if the verify operation was successful,
  *                 or an MBEDTLS_ERR_RSA_XXX error code
  *
@@ -580,6 +680,15 @@
  * \param hash     buffer holding the message digest
  * \param sig      buffer holding the ciphertext
  *
+ * \deprecated     It is deprecated and discouraged to call this function
+ *                 in mode MBEDTLS_RSA_PRIVATE. Future versions of the libary
+ *                 are likely to remove the mode argument and have it implicitly
+ *                 set to MBEDTLS_RSA_PUBLIC.
+ *
+ * \note           Alternative implementations of RSA need not support
+ *                 mode being set to MBEDTLS_RSA_PRIVATE and may instead
+ *                 return MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION.
+ *
  * \return         0 if the verify operation was successful,
  *                 or an MBEDTLS_ERR_RSA_XXX error code
  *
diff --git a/library/error.c b/library/error.c
index db42381..23e4953 100644
--- a/library/error.c
+++ b/library/error.c
@@ -331,6 +331,8 @@
             mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
         if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
             mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
+        if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
+            mbedtls_snprintf( buf, buflen, "RSA - The implementation doesn't offer the requested operation, e.g. because of security violations or lack of functionality" );
 #endif /* MBEDTLS_RSA_C */
 
 #if defined(MBEDTLS_SSL_TLS_C)
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 270e2d9..09309d6 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -60,9 +60,12 @@
     msg_len = unhexify( message_str, message_hex_string );
 
     if( mbedtls_md_info_from_type( digest ) != NULL )
-        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ), message_str, msg_len, hash_result ) == 0 );
+        TEST_ASSERT( mbedtls_md( mbedtls_md_info_from_type( digest ),
+                                 message_str, msg_len, hash_result ) == 0 );
 
-    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, digest, 0, hash_result, output ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_pseudo_rand, &rnd_info,
+                                         MBEDTLS_RSA_PRIVATE, digest, 0,
+                                         hash_result, output ) == result );
     if( result == 0 )
     {
         hexify( output_str, output, ctx.len );
@@ -71,7 +74,8 @@
     }
 
 exit:
-    mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G );
+    mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 );
+    mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G );
     mbedtls_rsa_free( &ctx );
 }
 /* END_CASE */
@@ -119,6 +123,7 @@
                          char *input_N, int radix_E, char *input_E,
                          char *result_hex_str )
 {
+    int res;
     unsigned char message_str[1000];
     unsigned char hash_result[1000];
     unsigned char output[1000];
@@ -157,7 +162,9 @@
     unhexify( message_str, message_hex_string );
     hash_len = unhexify( hash_result, hash_result_string );
 
-    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_NONE, hash_len, hash_result, output ) == 0 );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_sign( &ctx, &rnd_pseudo_rand, &rnd_info,
+                                         MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_NONE,
+                                         hash_len, hash_result, output ) == 0 );
 
     hexify( output_str, output, ctx.len );
 
@@ -169,13 +176,22 @@
         memset( output, 0x00, 1000 );
         memset( output_str, 0x00, 1000 );
 
-        TEST_ASSERT( mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx,
+        res = mbedtls_rsa_rsaes_pkcs1_v15_encrypt( &ctx,
                     &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PRIVATE,
-                    hash_len, hash_result, output ) == 0 );
+                    hash_len, hash_result, output );
 
-        hexify( output_str, output, ctx.len );
+#if !defined(MBEDTLS_RSA_ALT)
+        TEST_ASSERT( res == 0 );
+#else
+        TEST_ASSERT( ( res == 0 ) ||
+                     ( res == MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION ) );
+#endif
 
-        TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
+        if( res == 0 )
+        {
+            hexify( output_str, output, ctx.len );
+            TEST_ASSERT( strcasecmp( (char *) output_str, result_hex_str ) == 0 );
+        }
     }
 
 exit:
@@ -190,6 +206,7 @@
                            char *input_N, int radix_E, char *input_E,
                            char *result_hex_str, int correct )
 {
+    int res;
     unsigned char message_str[1000];
     unsigned char hash_result[1000];
     unsigned char result_str[1000];
@@ -220,15 +237,25 @@
     {
         int ok;
 
-        TEST_ASSERT( mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx,
+        res = mbedtls_rsa_rsaes_pkcs1_v15_decrypt( &ctx,
                     NULL, NULL, MBEDTLS_RSA_PUBLIC,
-                    &olen, result_str, output, sizeof( output ) ) == 0 );
+                    &olen, result_str, output, sizeof( output ) );
 
-        ok = olen == hash_len && memcmp( output, hash_result, olen ) == 0;
-        if( correct == 0 )
-            TEST_ASSERT( ok == 1 );
-        else
-            TEST_ASSERT( ok == 0 );
+#if !defined(MBEDTLS_RSA_ALT)
+        TEST_ASSERT( res == 0 );
+#else
+        TEST_ASSERT( ( res == 0 ) ||
+                     ( res == MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION ) );
+#endif
+
+        if( res == 0 )
+        {
+            ok = olen == hash_len && memcmp( output, hash_result, olen ) == 0;
+            if( correct == 0 )
+                TEST_ASSERT( ok == 1 );
+            else
+                TEST_ASSERT( ok == 0 );
+        }
     }
 
 exit:
@@ -263,7 +290,9 @@
 
     msg_len = unhexify( message_str, message_hex_string );
 
-    TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_pseudo_rand, &rnd_info, MBEDTLS_RSA_PUBLIC, msg_len, message_str, output ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_pseudo_rand, &rnd_info,
+                                            MBEDTLS_RSA_PUBLIC, msg_len,
+                                            message_str, output ) == result );
     if( result == 0 )
     {
         hexify( output_str, output, ctx.len );
@@ -301,7 +330,9 @@
 
     msg_len = unhexify( message_str, message_hex_string );
 
-    TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_zero_rand, NULL, MBEDTLS_RSA_PUBLIC, msg_len, message_str, output ) == result );
+    TEST_ASSERT( mbedtls_rsa_pkcs1_encrypt( &ctx, &rnd_zero_rand, NULL,
+                                            MBEDTLS_RSA_PUBLIC, msg_len,
+                                            message_str, output ) == result );
     if( result == 0 )
     {
         hexify( output_str, output, ctx.len );