From 55bf3d117124f21a28d2b57e0549ab266d1deb78 Mon Sep 17 00:00:00 2001
From: Gilles Peskine <Gilles.Peskine@arm.com>
Date: Tue, 26 Jun 2018 15:53:48 +0200
Subject: [PATCH] Sort out RSA mechanisms

* PSS needs to be parametrized by a hash.
* Don't use `_MGF1` in the names of macros for OAEP and PSS. No one
  ever uses anything else.
* Add brief documentation for the RSA signature mechanisms.
---
 include/psa/crypto.h                    | 60 ++++++++++++++++++++-----
 library/psa_crypto.c                    |  8 ++--
 tests/suites/test_suite_psa_crypto.data |  2 +-
 3 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/include/psa/crypto.h b/include/psa/crypto.h
index e6911238ca..32e0f3d836 100644
--- a/include/psa/crypto.h
+++ b/include/psa/crypto.h
@@ -621,18 +621,52 @@ typedef uint32_t psa_algorithm_t;
 #define PSA_ALG_CCM                             ((psa_algorithm_t)0x06000001)
 #define PSA_ALG_GCM                             ((psa_algorithm_t)0x06000002)
 
-#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW           ((psa_algorithm_t)0x10010000)
-#define PSA_ALG_RSA_PSS_MGF1                    ((psa_algorithm_t)0x10020000)
-#define PSA_ALG_RSA_PKCS1V15_CRYPT              ((psa_algorithm_t)0x12010000)
-#define PSA_ALG_RSA_OAEP_MGF1_BASE              ((psa_algorithm_t)0x12020000)
+#define PSA_ALG_RSA_PKCS1V15_SIGN_BASE          ((psa_algorithm_t)0x10020000)
+/** RSA PKCS#1 v1.5 signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PKCS1-v1_5.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(alg) is true).
+ *
+ * \return              The corresponding RSA PKCS#1 v1.5 signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
 #define PSA_ALG_RSA_PKCS1V15_SIGN(hash_alg)                             \
-    (PSA_ALG_RSA_PKCS1V15_SIGN_RAW | ((hash_alg) & PSA_ALG_HASH_MASK))
+    (PSA_ALG_RSA_PKCS1V15_SIGN_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+/** Raw PKCS#1 v1.5 signature.
+ *
+ * The input to this algorithm is the DigestInfo structure used by
+ * RFC 8017 (PKCS#1: RSA Cryptography Specifications), &sect;9.2
+ * steps 3&ndash;6.
+ */
+#define PSA_ALG_RSA_PKCS1V15_SIGN_RAW PSA_ALG_RSA_PKCS1V15_SIGN_BASE
 #define PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)                               \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_RAW)
-#define PSA_ALG_RSA_OAEP_MGF1(hash_alg)                             \
-    (PSA_ALG_RSA_OAEP_MGF1_RAW | ((hash_alg) & PSA_ALG_HASH_MASK))
-#define PSA_ALG_IS_RSA_OAEP_MGF1(alg)                               \
-    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_MGF1_BASE)
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PKCS1V15_SIGN_BASE)
+#define PSA_ALG_RSA_PSS_BASE               ((psa_algorithm_t)0x10030000)
+/** RSA PSS signature with hashing.
+ *
+ * This is the signature scheme defined by RFC 8017
+ * (PKCS#1: RSA Cryptography Specifications) under the name
+ * RSASSA-PSS, with the message generation function MGF1. The specified
+ * hash algorithm is used to hash the input message, to create the
+ * salted hash, and for the mask generation.
+ *
+ * \param hash_alg      A hash algorithm (\c PSA_ALG_XXX value such that
+ *                      #PSA_ALG_IS_HASH(alg) is true).
+ *
+ * \return              The corresponding RSA PSS signature algorithm.
+ * \return              Unspecified if \p alg is not a supported
+ *                      hash algorithm.
+ */
+#define PSA_ALG_RSA_PSS(hash_alg)                               \
+    (PSA_ALG_RSA_PSS_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_PSS(alg)                                 \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_PSS_BASE)
+
 /** Get the hash used by a hash-and-sign signature algorithm.
  *
  * A hash-and-sign algorithm is a signature algorithm which is
@@ -657,6 +691,12 @@ typedef uint32_t psa_algorithm_t;
      0)
 
 #define PSA_ALG_ECDSA_RAW                       ((psa_algorithm_t)0x10030000)
+#define PSA_ALG_RSA_PKCS1V15_CRYPT              ((psa_algorithm_t)0x12020000)
+#define PSA_ALG_RSA_OAEP_BASE                   ((psa_algorithm_t)0x12030000)
+#define PSA_ALG_RSA_OAEP(hash_alg)                              \
+    (PSA_ALG_RSA_OAEP_BASE | ((hash_alg) & PSA_ALG_HASH_MASK))
+#define PSA_ALG_IS_RSA_OAEP(alg)                                \
+    (((alg) & ~PSA_ALG_HASH_MASK) == PSA_ALG_RSA_OAEP_BASE)
 
 /**@}*/
 
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index 44867dc48f..a4fac648e6 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1690,7 +1690,7 @@ psa_status_t psa_asymmetric_sign( psa_key_slot_t key,
         else
 #endif /* MBEDTLS_PKCS1_V15 */
 #if defined(MBEDTLS_PKCS1_V21)
-        if( alg == PSA_ALG_RSA_PSS_MGF1 )
+        if( PSA_ALG_IS_RSA_PSS( alg ) )
         {
             mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
             ret = mbedtls_rsa_rsassa_pss_sign( rsa,
@@ -1789,7 +1789,7 @@ psa_status_t psa_asymmetric_verify( psa_key_slot_t key,
         else
 #endif /* MBEDTLS_PKCS1_V15 */
 #if defined(MBEDTLS_PKCS1_V21)
-        if( alg == PSA_ALG_RSA_PSS_MGF1 )
+        if( PSA_ALG_IS_RSA_PSS( alg ) )
         {
             mbedtls_rsa_set_padding( rsa, MBEDTLS_RSA_PKCS_V21, md_alg );
             ret = mbedtls_rsa_rsassa_pss_verify( rsa,
@@ -1872,7 +1872,7 @@ psa_status_t psa_asymmetric_encrypt( psa_key_slot_t key,
         else
 #endif /* MBEDTLS_PKCS1_V15 */
 #if defined(MBEDTLS_PKCS1_V21)
-        if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
+        if( PSA_ALG_IS_RSA_OAEP( alg ) )
         {
             return( PSA_ERROR_NOT_SUPPORTED );
         }
@@ -1941,7 +1941,7 @@ psa_status_t psa_asymmetric_decrypt( psa_key_slot_t key,
         else
 #endif /* MBEDTLS_PKCS1_V15 */
 #if defined(MBEDTLS_PKCS1_V21)
-        if( PSA_ALG_IS_RSA_OAEP_MGF1( alg ) )
+        if( PSA_ALG_IS_RSA_OAEP( alg ) )
         {
             return( PSA_ERROR_NOT_SUPPORTED );
         }
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 5bdc718c68..d3186783d9 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -503,7 +503,7 @@ PSA signature size: RSA keypair, 1024 bits, PKCS#1 v1.5 SHA-256
 signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):128
 
 PSA signature size: RSA keypair, 1024 bits, PSS
-signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PSS_MGF1:128
+signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1024:PSA_ALG_RSA_PSS( PSA_ALG_SHA_256 ):128
 
 PSA signature size: RSA keypair, 1023 bits, PKCS#1 v1.5 raw
 signature_size:PSA_KEY_TYPE_RSA_KEYPAIR:1023:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:128