Merge pull request #3431 from naynajain/development-pkcs7
PKCS7 Parser - RFC 2315
diff --git a/ChangeLog.d/driver-only-hashes.txt b/ChangeLog.d/driver-only-hashes.txt
index 2062bcb..6ccd199 100644
--- a/ChangeLog.d/driver-only-hashes.txt
+++ b/ChangeLog.d/driver-only-hashes.txt
@@ -1,20 +1,19 @@
Features
- * Some crypto modules that previously depended on MD or a low-level hash
- module, either unconditionally (RSA, PK, PKCS5, PKCS12, EC J-PAKE), or
- for some features (PEM for encrypted files), are now able to use PSA
- Crypto instead when the legacy API is not available. This means it is
- now possible to use all features from those modules in configurations
- where the built-in implementations of hashes are excluded and the hashes
- are only provided by PSA drivers. In these configurations, you need to
- call `psa_crypto_init()` before you call any function from those
- modules; this is not required in configurations where the built-in
- implementation is still available. Note that some crypto modules and
- features still depend on the built-in implementation of hashes:
- MBEDTLS_HKDF_C (but the PSA HKDF function do not depend on it),
- MBEDTLS_ENTROPY_C, MBEDTLS_HMAC_DRBG_C and MBEDTLS_ECDSA_DETERMINISTIC.
- In particular, for now, compiling without built-in hashes requires use
- of MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
- * When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 no
- longer depend on MD. This means it is now possible to use them in
- configurations where the built-in implementations of hashes are excluded
- and the hashes are only provided by PSA drivers.
+ * Some modules can now use PSA drivers for hashes, including with no
+ built-in implementation present, but only in some configurations.
+ - RSA OAEP and PSS (PKCS#1 v2.1), PKCS5, PKCS12 and EC J-PAKE now use
+ hashes from PSA when (and only when) MBEDTLS_MD_C is disabled.
+ - PEM parsing of encrypted files now uses MD-5 from PSA when (and only
+ when) MBEDTLS_MD5_C is disabled.
+ See the documentation of the corresponding macros in mbedtls_config.h for
+ details.
+ Note that some modules are not able to use hashes from PSA yet, including
+ the entropy module. As a consequence, for now the only way to build with
+ all hashes only provided by drivers (no built-in hash) is to use
+ MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
+ * When MBEDTLS_USE_PSA_CRYPTO is enabled, X.509, TLS 1.2 and TLS 1.3 now
+ properly negotiate/accept hashes based on their availability in PSA.
+ As a consequence, they now work in configurations where the built-in
+ implementations of (some) hashes are excluded and those hashes are only
+ provided by PSA drivers. (See previous entry for limitation on RSA-PSS
+ though: that module only use hashes from PSA when MBEDTLS_MD_C is off).
diff --git a/ChangeLog.d/fix-possible-false-success-in-mbedtls_cipher_check_tag.txt b/ChangeLog.d/fix-possible-false-success-in-mbedtls_cipher_check_tag.txt
new file mode 100644
index 0000000..1f9e0aa
--- /dev/null
+++ b/ChangeLog.d/fix-possible-false-success-in-mbedtls_cipher_check_tag.txt
@@ -0,0 +1,5 @@
+Changes
+ * Calling AEAD tag-specific functions for non-AEAD algorithms (which
+ should not be done - they are documented for use only by AES-GCM and
+ ChaCha20+Poly1305) now returns MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE
+ instead of success (0).
diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h
index bd3872f..a4d0328 100644
--- a/include/mbedtls/mbedtls_config.h
+++ b/include/mbedtls/mbedtls_config.h
@@ -1146,6 +1146,11 @@
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS#1 v2.1 operation.
*
+ * \warning When building with MBEDTLS_MD_C, all hashes used with this
+ * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
+ * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
+ * this module in builds where MBEDTLS_MD_C is disabled.
+ *
* This enables support for RSAES-OAEP and RSASSA-PSS operations.
*/
#define MBEDTLS_PKCS1_V21
@@ -2433,6 +2438,11 @@
*
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any EC J-PAKE operations.
+ *
+ * \warning When building with MBEDTLS_MD_C, all hashes used with this
+ * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
+ * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
+ * this module in builds where MBEDTLS_MD_C is disabled.
*/
#define MBEDTLS_ECJPAKE_C
@@ -2777,6 +2787,11 @@
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS5 operation.
*
+ * \warning When building with MBEDTLS_MD_C, all hashes used with this
+ * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
+ * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
+ * this module in builds where MBEDTLS_MD_C is disabled.
+ *
* This module adds support for the PKCS#5 functions.
*/
#define MBEDTLS_PKCS5_C
@@ -2812,6 +2827,11 @@
* \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init()
* before doing any PKCS12 operation.
*
+ * \warning When building with MBEDTLS_MD_C, all hashes used with this
+ * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C,
+ * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by
+ * this module in builds where MBEDTLS_MD_C is disabled.
+ *
* This module enables PKCS#12 functions.
*/
#define MBEDTLS_PKCS12_C
diff --git a/library/bignum_mod_raw.c b/library/bignum_mod_raw.c
index b43add7..6c694b0 100644
--- a/library/bignum_mod_raw.c
+++ b/library/bignum_mod_raw.c
@@ -108,6 +108,16 @@
/* BEGIN MERGE SLOT 2 */
+void mbedtls_mpi_mod_raw_sub( mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *B,
+ const mbedtls_mpi_mod_modulus *N )
+{
+ mbedtls_mpi_uint c = mbedtls_mpi_core_sub( X, A, B, N->limbs );
+
+ (void) mbedtls_mpi_core_add_if( X, N->p, N->limbs, (unsigned) c );
+}
+
/* END MERGE SLOT 2 */
/* BEGIN MERGE SLOT 3 */
diff --git a/library/bignum_mod_raw.h b/library/bignum_mod_raw.h
index f738e91..05fa9d6 100644
--- a/library/bignum_mod_raw.h
+++ b/library/bignum_mod_raw.h
@@ -144,6 +144,28 @@
/* BEGIN MERGE SLOT 2 */
+/** \brief Subtract two MPIs, returning the residue modulo the specified
+ * modulus.
+ *
+ * The size of the operation is determined by \p N. \p A and \p B must have
+ * the same number of limbs as \p N.
+ *
+ * \p X may be aliased to \p A or \p B, or even both, but may not overlap
+ * either otherwise.
+ *
+ * \param[out] X The address of the result MPI.
+ * This must be initialized. Must have enough limbs to
+ * store the full value of the result.
+ * \param[in] A The address of the first MPI. This must be initialized.
+ * \param[in] B The address of the second MPI. This must be initialized.
+ * \param[in] N The address of the modulus. Used to perform a modulo
+ * operation on the result of the subtraction.
+ */
+void mbedtls_mpi_mod_raw_sub( mbedtls_mpi_uint *X,
+ const mbedtls_mpi_uint *A,
+ const mbedtls_mpi_uint *B,
+ const mbedtls_mpi_mod_modulus *N );
+
/* END MERGE SLOT 2 */
/* BEGIN MERGE SLOT 3 */
diff --git a/library/cipher.c b/library/cipher.c
index dfb7329..dffe3ad 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -500,7 +500,7 @@
}
#endif
- return( 0 );
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
@@ -1129,7 +1129,7 @@
}
#endif
- return( 0 );
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
@@ -1156,11 +1156,8 @@
}
#endif /* MBEDTLS_USE_PSA_CRYPTO */
- /* Status to return on a non-authenticated algorithm. It would make sense
- * to return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT or perhaps
- * MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, but at the time I write this our
- * unit tests assume 0. */
- ret = 0;
+ /* Status to return on a non-authenticated algorithm. */
+ ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
diff --git a/scripts/mbedtls_dev/bignum_mod_raw.py b/scripts/mbedtls_dev/bignum_mod_raw.py
index 60f2fed..c271048 100644
--- a/scripts/mbedtls_dev/bignum_mod_raw.py
+++ b/scripts/mbedtls_dev/bignum_mod_raw.py
@@ -30,6 +30,25 @@
# BEGIN MERGE SLOT 2
+class BignumModRawSub(bignum_common.ModOperationCommon,
+ BignumModRawTarget):
+ """Test cases for bignum mpi_mod_raw_sub()."""
+ symbol = "-"
+ test_function = "mpi_mod_raw_sub"
+ test_name = "mbedtls_mpi_mod_raw_sub"
+ input_style = "fixed"
+ arity = 2
+
+ def arguments(self) -> List[str]:
+ return [bignum_common.quote_str(n) for n in [self.arg_a,
+ self.arg_b,
+ self.arg_n]
+ ] + self.result()
+
+ def result(self) -> List[str]:
+ result = (self.int_a - self.int_b) % self.int_n
+ return [self.format_result(result)]
+
# END MERGE SLOT 2
# BEGIN MERGE SLOT 3
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c23cb6b..0ef6fdb 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -70,6 +70,7 @@
${CMAKE_CURRENT_SOURCE_DIR}/../tests/scripts/generate_bignum_tests.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_common.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_core.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/bignum_mod_raw.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_case.py
${CMAKE_CURRENT_SOURCE_DIR}/../scripts/mbedtls_dev/test_data_generation.py
)
diff --git a/tests/Makefile b/tests/Makefile
index 7c08f54..0b31cdd 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -94,6 +94,7 @@
generated_bignum_test_data: scripts/generate_bignum_tests.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_common.py
generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_core.py
+generated_bignum_test_data: ../scripts/mbedtls_dev/bignum_mod_raw.py
generated_bignum_test_data: ../scripts/mbedtls_dev/test_case.py
generated_bignum_test_data: ../scripts/mbedtls_dev/test_data_generation.py
generated_bignum_test_data:
diff --git a/tests/suites/test_suite_bignum_mod_raw.function b/tests/suites/test_suite_bignum_mod_raw.function
index 4adccce..2d9e412 100644
--- a/tests/suites/test_suite_bignum_mod_raw.function
+++ b/tests/suites/test_suite_bignum_mod_raw.function
@@ -275,6 +275,79 @@
/* BEGIN MERGE SLOT 2 */
+/* BEGIN_CASE */
+void mpi_mod_raw_sub( char * input_A,
+ char * input_B,
+ char * input_N,
+ char * result )
+{
+ mbedtls_mpi_uint *A = NULL;
+ mbedtls_mpi_uint *B = NULL;
+ mbedtls_mpi_uint *N = NULL;
+ mbedtls_mpi_uint *X = NULL;
+ mbedtls_mpi_uint *res = NULL;
+ size_t limbs_A;
+ size_t limbs_B;
+ size_t limbs_N;
+ size_t limbs_res;
+
+ mbedtls_mpi_mod_modulus m;
+ mbedtls_mpi_mod_modulus_init( &m );
+
+ TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &limbs_A, input_A ), 0 );
+ TEST_EQUAL( mbedtls_test_read_mpi_core( &B, &limbs_B, input_B ), 0 );
+ TEST_EQUAL( mbedtls_test_read_mpi_core( &N, &limbs_N, input_N ), 0 );
+ TEST_EQUAL( mbedtls_test_read_mpi_core( &res, &limbs_res, result ), 0 );
+
+ size_t limbs = limbs_N;
+ size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
+
+ TEST_EQUAL( limbs_A, limbs );
+ TEST_EQUAL( limbs_B, limbs );
+ TEST_EQUAL( limbs_res, limbs );
+
+ ASSERT_ALLOC( X, limbs );
+
+ TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
+ &m, N, limbs,
+ MBEDTLS_MPI_MOD_EXT_REP_BE,
+ MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
+
+ mbedtls_mpi_mod_raw_sub( X, A, B, &m );
+ ASSERT_COMPARE( X, bytes, res, bytes );
+
+ /* alias X to A */
+ memcpy( X, A, bytes );
+ mbedtls_mpi_mod_raw_sub( X, X, B, &m );
+ ASSERT_COMPARE( X, bytes, res, bytes );
+
+ /* alias X to B */
+ memcpy( X, B, bytes );
+ mbedtls_mpi_mod_raw_sub( X, A, X, &m );
+ ASSERT_COMPARE( X, bytes, res, bytes );
+
+ /* A == B: alias A and B */
+ if( memcmp( A, B, bytes ) == 0 )
+ {
+ mbedtls_mpi_mod_raw_sub( X, A, A, &m );
+ ASSERT_COMPARE( X, bytes, res, bytes );
+
+ /* X, A, B all aliased together */
+ memcpy( X, A, bytes );
+ mbedtls_mpi_mod_raw_sub( X, X, X, &m );
+ ASSERT_COMPARE( X, bytes, res, bytes );
+ }
+exit:
+ mbedtls_free( A );
+ mbedtls_free( B );
+ mbedtls_free( X );
+ mbedtls_free( res );
+
+ mbedtls_mpi_mod_modulus_free( &m );
+ mbedtls_free( N );
+}
+/* END_CASE */
+
/* END MERGE SLOT 2 */
/* BEGIN MERGE SLOT 3 */
diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function
index b7c3b51..ff936df 100644
--- a/tests/suites/test_suite_cipher.function
+++ b/tests/suites/test_suite_cipher.function
@@ -450,8 +450,12 @@
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, ad, sizeof( ad ) - i ) );
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, ad, sizeof( ad ) - i ) );
+ int expected = ( cipher_info->mode == MBEDTLS_MODE_GCM ||
+ cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) ?
+ 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx_dec, ad, sizeof(ad) - i ) );
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx_enc, ad, sizeof(ad) - i ) );
#endif
block_size = mbedtls_cipher_get_block_size( &ctx_enc );
@@ -470,7 +474,7 @@
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_write_tag( &ctx_enc, tag, sizeof( tag ) ) );
+ TEST_EQUAL( expected, mbedtls_cipher_write_tag( &ctx_enc, tag, sizeof(tag) ) );
#endif
TEST_ASSERT( total_len == length ||
@@ -491,7 +495,7 @@
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_check_tag( &ctx_dec, tag, sizeof( tag ) ) );
+ TEST_EQUAL( expected, mbedtls_cipher_check_tag( &ctx_dec, tag, sizeof(tag) ) );
#endif
/* check result */
@@ -547,7 +551,11 @@
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv, 16 ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, NULL, 0 ) );
+ int expected = ( cipher_info->mode == MBEDTLS_MODE_GCM ||
+ cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) ?
+ 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx, NULL, 0 ) );
#endif
/* encode length number of bytes from inbuf */
@@ -609,7 +617,11 @@
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) );
+ int expected = ( cipher_info->mode == MBEDTLS_MODE_GCM ||
+ cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) ?
+ 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) );
#endif
/* decode 0-byte string */
@@ -710,8 +722,12 @@
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) );
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, NULL, 0 ) );
+ int expected = ( cipher_info->mode == MBEDTLS_MODE_GCM ||
+ cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) ?
+ 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) );
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx_enc, NULL, 0 ) );
#endif
block_size = mbedtls_cipher_get_block_size( &ctx_enc );
@@ -795,7 +811,11 @@
TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv->x, iv->len ) );
TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) );
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, ad->x, ad->len ) );
+ int expected = ( ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
+ ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) ?
+ 0 : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+
+ TEST_EQUAL( expected, mbedtls_cipher_update_ad( &ctx, ad->x, ad->len ) );
#endif
/* decode buffer and check tag->x */
@@ -806,7 +826,11 @@
&outlen ) );
total_len += outlen;
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
- TEST_ASSERT( tag_result == mbedtls_cipher_check_tag( &ctx, tag->x, tag->len ) );
+ int tag_expected = ( ctx.cipher_info->mode == MBEDTLS_MODE_GCM ||
+ ctx.cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) ?
+ tag_result : MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE;
+
+ TEST_EQUAL( tag_expected, mbedtls_cipher_check_tag( &ctx, tag->x, tag->len ) );
#endif
/* check plaintext only if everything went fine */