From 8aa4d75ec98d19446151d778d2113cc5e26cb758 Mon Sep 17 00:00:00 2001 From: Cedric Meuter Date: Tue, 21 Apr 2020 12:49:11 +0200 Subject: [PATCH] Introduced mbedtls_rsa_rsassa_pss_sign_ext(..., saltlen, ...) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit extension of mbedtls_rsa_rsassa_pss_sign() with an extra argument 'saltlen' which allows to inject the length of the salt to the function, as opposed to the original function which internally computes the maximum possible salt length. If MBEDTLS_RSA_SALT_LEN_ANY is passed the function falls back to the the original behaviour. The original function mbedtls_rsa_rsassa_pss_sign() can simply defer to it. This allows to make some CAVP PSS generation tests that require the use of a salt length which is smaller that the hash length. Signed-off-by: Cédric Meuter --- include/mbedtls/rsa.h | 66 +++++++++++++++++++++++++++++++++++++++++++ library/rsa.c | 53 +++++++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 14 deletions(-) diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index 6a315144d..41a00a9ed 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -968,6 +968,72 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, const unsigned char *hash, unsigned char *sig ); +/** + * \brief This function performs a PKCS#1 v2.1 PSS signature + * operation (RSASSA-PSS-SIGN). + * + * \note The \p hash_id in the RSA context is the one used for the + * encoding. \p md_alg in the function call is the type of hash + * that is encoded. According to RFC-3447: Public-Key + * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography + * Specifications it is advised to keep both hashes the + * same. + * + * \note This function always uses the maximum possible salt size, + * up to the length of the payload hash. This choice of salt + * size complies with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 + * v2.2) §9.1.1 step 3. Furthermore this function enforces a + * minimum salt size which is the hash size minus 2 bytes. If + * this minimum size is too large given the key size (the salt + * size, plus the hash size, plus 2 bytes must be no more than + * the key size in bytes), this function returns + * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA. + * + * \deprecated It is deprecated and discouraged to call this function + * in #MBEDTLS_RSA_PUBLIC mode. Future versions of the library + * are likely to remove the \p 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 might instead + * return #MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED. + * + * \param ctx The initialized RSA context to use. + * \param f_rng The RNG function. It must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL + * if \p f_rng doesn't need a context argument. + * \param mode The mode of operation. This must be either + * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated). + * \param md_alg The message-digest algorithm used to hash the original data. + * Use #MBEDTLS_MD_NONE for signing raw data. + * \param hashlen The length of the message digest. + * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE. + * \param hash The buffer holding the message digest or raw data. + * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable + * buffer of length \p hashlen Bytes. If \p md_alg is not + * #MBEDTLS_MD_NONE, it must be a readable buffer of length + * the size of the hash corresponding to \p md_alg. + * \param saltlen The length of the salt that should be used. + * If passed MBEDTLS_RSA_SALT_LEN_ANY, the function will use + * the largest possible salt length. + * \param sig The buffer to hold the signature. This must be a writable + * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes + * for an 2048-bit RSA modulus. A buffer length of + * #MBEDTLS_MPI_MAX_SIZE is always safe. + * + * \return \c 0 if the signing operation was successful. + * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure. + */ +int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + int saltlen, + unsigned char *sig ); + /** * \brief This function performs a PKCS#1 v2.1 PSS signature * operation (RSASSA-PSS-SIGN). diff --git a/library/rsa.c b/library/rsa.c index d6abd65d4..7652f3d6b 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -1788,15 +1788,17 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, #if defined(MBEDTLS_PKCS1_V21) /* - * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with + * the option to pass in the salt length. */ -int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, +int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, + int saltlen, unsigned char *sig ) { size_t olen; @@ -1839,19 +1841,26 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, hlen = mbedtls_md_get_size( md_info ); - /* Calculate the largest possible salt length. Normally this is the hash - * length, which is the maximum length the salt can have. If there is not - * enough room, use the maximum salt length that fits. The constraint is - * that the hash length plus the salt length plus 2 bytes must be at most - * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 - * (PKCS#1 v2.2) §9.1.1 step 3. */ - min_slen = hlen - 2; - if( olen < hlen + min_slen + 2 ) - return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - else if( olen >= hlen + hlen + 2 ) - slen = hlen; + if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY) + { + /* Calculate the largest possible salt length. Normally this is the hash + * length, which is the maximum length the salt can have. If there is not + * enough room, use the maximum salt length that fits. The constraint is + * that the hash length plus the salt length plus 2 bytes must be at most + * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017 + * (PKCS#1 v2.2) §9.1.1 step 3. */ + min_slen = hlen - 2; + if( olen < hlen + min_slen + 2 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + else if( olen >= hlen + hlen + 2 ) + slen = hlen; + else + slen = olen - hlen - 2; + } else - slen = olen - hlen - 2; + { + slen = (size_t)saltlen; + } memset( sig, 0, olen ); @@ -1909,6 +1918,22 @@ exit: ? mbedtls_rsa_public( ctx, sig, sig ) : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) ); } + +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function + */ +int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + return mbedtls_rsa_rsassa_pss_sign_ext( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig ); +} #endif /* MBEDTLS_PKCS1_V21 */ #if defined(MBEDTLS_PKCS1_V15)