Merge pull request #8802 from mpg/adjust-vs-check
Misc. clean-ups in `check_config.h`
diff --git a/3rdparty/everest/Makefile.inc b/3rdparty/everest/Makefile.inc
index 77a6b49..8055ce9 100644
--- a/3rdparty/everest/Makefile.inc
+++ b/3rdparty/everest/Makefile.inc
@@ -1,6 +1,6 @@
-THIRDPARTY_INCLUDES+=-I../3rdparty/everest/include -I../3rdparty/everest/include/everest -I../3rdparty/everest/include/everest/kremlib
+THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/everest/include -I$(THIRDPARTY_DIR)/everest/include/everest -I$(THIRDPARTY_DIR)/everest/include/everest/kremlib
THIRDPARTY_CRYPTO_OBJECTS+= \
- ../3rdparty/everest/library/everest.o \
- ../3rdparty/everest/library/x25519.o \
- ../3rdparty/everest/library/Hacl_Curve25519_joined.o
+ $(THIRDPARTY_DIR)/everest/library/everest.o \
+ $(THIRDPARTY_DIR)/everest/library/x25519.o \
+ $(THIRDPARTY_DIR)/everest/library/Hacl_Curve25519_joined.o
diff --git a/3rdparty/p256-m/Makefile.inc b/3rdparty/p256-m/Makefile.inc
index fc8f73b..53bb55b 100644
--- a/3rdparty/p256-m/Makefile.inc
+++ b/3rdparty/p256-m/Makefile.inc
@@ -1,5 +1,5 @@
-THIRDPARTY_INCLUDES+=-I../3rdparty/p256-m/p256-m/include -I../3rdparty/p256-m/p256-m/include/p256-m -I../3rdparty/p256-m/p256-m_driver_interface
+THIRDPARTY_INCLUDES+=-I$(THIRDPARTY_DIR)/p256-m/p256-m/include -I$(THIRDPARTY_DIR)/p256-m/p256-m/include/p256-m -I$(THIRDPARTY_DIR)/p256-m/p256-m_driver_interface
THIRDPARTY_CRYPTO_OBJECTS+= \
- ../3rdparty/p256-m//p256-m_driver_entrypoints.o \
- ../3rdparty/p256-m//p256-m/p256-m.o
+ $(THIRDPARTY_DIR)/p256-m//p256-m_driver_entrypoints.o \
+ $(THIRDPARTY_DIR)/p256-m//p256-m/p256-m.o
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 78599d9..38806d9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,6 +114,11 @@
endif()
+# We now potentially need to link all executables against PThreads, if available
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+find_package(Threads)
+
# If this is the root project add longer list of available CMAKE_BUILD_TYPE values
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
diff --git a/ChangeLog.d/7765.txt b/ChangeLog.d/7765.txt
new file mode 100644
index 0000000..3dd6b5d
--- /dev/null
+++ b/ChangeLog.d/7765.txt
@@ -0,0 +1,3 @@
+Features
+ * Add functions mbedtls_ecdsa_raw_to_der() and mbedtls_ecdsa_der_to_raw() to
+ convert ECDSA signatures between raw and DER (ASN.1) formats.
diff --git a/ChangeLog.d/8647.txt b/ChangeLog.d/8647.txt
new file mode 100644
index 0000000..98326dc
--- /dev/null
+++ b/ChangeLog.d/8647.txt
@@ -0,0 +1,10 @@
+Default behavior changes
+ * psa_import_key() now only accepts RSA keys in the PSA standard formats.
+ The undocumented ability to import other formats (PKCS#8, SubjectPublicKey,
+ PEM) accepted by the pkparse module has been removed. Applications that
+ need these formats can call mbedtls_pk_parse_{public,}key() followed by
+ mbedtls_pk_import_into_psa().
+
+Changes
+ * RSA support in PSA no longer auto-enables the pkparse and pkwrite modules,
+ saving code size when those are not otherwise enabled.
diff --git a/ChangeLog.d/add-aes-cbc-to-pkcs5-pbes2.txt b/ChangeLog.d/add-aes-cbc-to-pkcs5-pbes2.txt
new file mode 100644
index 0000000..7f0fbc7
--- /dev/null
+++ b/ChangeLog.d/add-aes-cbc-to-pkcs5-pbes2.txt
@@ -0,0 +1,3 @@
+Features
+ * Add support for using AES-CBC 128, 192, and 256 bit schemes
+ with PKCS#5 PBES2. Keys encrypted this way can now be parsed by PK parse.
diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h
index 3c3bfad..ff019f4 100644
--- a/include/mbedtls/asn1.h
+++ b/include/mbedtls/asn1.h
@@ -197,7 +197,8 @@
}
mbedtls_asn1_named_data;
-#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
+#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
+ defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
@@ -244,7 +245,7 @@
int mbedtls_asn1_get_tag(unsigned char **p,
const unsigned char *end,
size_t *len, int tag);
-#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
+#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C)
/**
diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h
index 7af4aba..0c5a85a 100644
--- a/include/mbedtls/asn1write.h
+++ b/include/mbedtls/asn1write.h
@@ -36,7 +36,8 @@
extern "C" {
#endif
-#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
+#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
+ defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
/**
* \brief Write a length field in ASN.1 format.
*
@@ -65,7 +66,7 @@
*/
int mbedtls_asn1_write_tag(unsigned char **p, const unsigned char *start,
unsigned char tag);
-#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
+#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA*/
#if defined(MBEDTLS_ASN1_WRITE_C)
/**
diff --git a/include/mbedtls/config_adjust_legacy_crypto.h b/include/mbedtls/config_adjust_legacy_crypto.h
index 6126a1e..9b06041 100644
--- a/include/mbedtls/config_adjust_legacy_crypto.h
+++ b/include/mbedtls/config_adjust_legacy_crypto.h
@@ -340,15 +340,6 @@
#define MBEDTLS_PSA_CRYPTO_CLIENT
#endif /* MBEDTLS_PSA_CRYPTO_C */
-/* The PK wrappers need pk_write/pk_parse functions to format RSA key objects
- * when they are dispatching to the PSA API. This happens under MBEDTLS_USE_PSA_CRYPTO,
- * and even under just MBEDTLS_PSA_CRYPTO_C in psa_crypto_rsa.c. */
-#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_RSA_C)
-#define MBEDTLS_PK_C
-#define MBEDTLS_PK_WRITE_C
-#define MBEDTLS_PK_PARSE_C
-#endif
-
/* Helpers to state that each key is supported either on the builtin or PSA side. */
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || defined(PSA_WANT_ECC_SECP_R1_521)
#define MBEDTLS_ECP_HAVE_SECP521R1
@@ -416,6 +407,13 @@
#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY
#endif
+/* psa_util file features some ECDSA conversion functions, to convert between
+ * legacy's ASN.1 DER format and PSA's raw one. */
+#if defined(MBEDTLS_ECDSA_C) || (defined(MBEDTLS_PSA_CRYPTO_C) && \
+ (defined(PSA_WANT_ALG_ECDSA) || defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA)))
+#define MBEDTLS_PSA_UTIL_HAVE_ECDSA
+#endif
+
/* Some internal helpers to determine which keys are availble. */
#if (!defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_AES_C)) || \
(defined(MBEDTLS_USE_PSA_CRYPTO) && defined(PSA_WANT_KEY_TYPE_AES))
diff --git a/include/mbedtls/config_adjust_legacy_from_psa.h b/include/mbedtls/config_adjust_legacy_from_psa.h
index 56ec276..0091e24 100644
--- a/include/mbedtls/config_adjust_legacy_from_psa.h
+++ b/include/mbedtls/config_adjust_legacy_from_psa.h
@@ -685,9 +685,6 @@
#define MBEDTLS_RSA_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_OID_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_PK_WRITE_C
-#define MBEDTLS_PK_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY */
diff --git a/include/mbedtls/oid.h b/include/mbedtls/oid.h
index 8a67486..fdc25eb 100644
--- a/include/mbedtls/oid.h
+++ b/include/mbedtls/oid.h
@@ -288,12 +288,17 @@
#define MBEDTLS_OID_HMAC_RIPEMD160 MBEDTLS_OID_INTERNET "\x05\x05\x08\x01\x04" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) iso-identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) ipsec(8) isakmpOakley(1) hmacRIPEMD160(4)} */
/*
- * Encryption algorithms
+ * Encryption algorithms,
+ * the following standardized object identifiers are specified at
+ * https://datatracker.ietf.org/doc/html/rfc8018#appendix-C.
*/
#define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */
#define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */
#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */
+#define MBEDTLS_OID_AES_128_CBC MBEDTLS_OID_AES "\x02" /** aes128-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes128-CBC-PAD(2) } */
+#define MBEDTLS_OID_AES_192_CBC MBEDTLS_OID_AES "\x16" /** aes192-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes192-CBC-PAD(22) } */
+#define MBEDTLS_OID_AES_256_CBC MBEDTLS_OID_AES "\x2a" /** aes256-cbc-pad OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithms(4) aes(1) aes256-CBC-PAD(42) } */
/*
* Key Wrapping algorithms
diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h
index 47724c6..984f031 100644
--- a/include/mbedtls/psa_util.h
+++ b/include/mbedtls/psa_util.h
@@ -16,6 +16,11 @@
#include "psa/crypto.h"
+/* ASN1 defines used in the ECDSA conversion functions.
+ * Note: intentionally not adding MBEDTLS_ASN1_[PARSE|WRITE]_C guards here
+ * otherwise error codes would be unknown in test_suite_psa_crypto_util.data.*/
+#include <mbedtls/asn1write.h>
+
#if defined(MBEDTLS_PSA_CRYPTO_C)
/* Expose whatever RNG the PSA subsystem uses to applications using the
@@ -175,8 +180,50 @@
{
return (mbedtls_md_type_t) (psa_alg & PSA_ALG_HASH_MASK);
}
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
+
+/** Convert an ECDSA signature from raw format to DER ASN.1 format.
+ *
+ * \param bits Size of each coordinate in bits.
+ * \param raw Buffer that contains the signature in raw format.
+ * \param raw_len Length of \p raw in bytes. This must be
+ * PSA_BITS_TO_BYTES(bits) bytes.
+ * \param[out] der Buffer that will be filled with the converted DER
+ * output. It can overlap with raw buffer.
+ * \param der_size Size of \p der in bytes. It is enough if \p der_size
+ * is at least the size of the actual output. (The size
+ * of the output can vary depending on the presence of
+ * leading zeros in the data.) You can use
+ * #MBEDTLS_ECDSA_MAX_SIG_LEN(\p bits) to determine a
+ * size that is large enough for all signatures for a
+ * given value of \p bits.
+ * \param[out] der_len On success it contains the amount of valid data
+ * (in bytes) written to \p der. It's undefined
+ * in case of failure.
+ */
+int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
+ unsigned char *der, size_t der_size, size_t *der_len);
+
+/** Convert an ECDSA signature from DER ASN.1 format to raw format.
+ *
+ * \param bits Size of each coordinate in bits.
+ * \param der Buffer that contains the signature in DER format.
+ * \param der_len Size of \p der in bytes.
+ * \param[out] raw Buffer that will be filled with the converted raw
+ * signature. It can overlap with der buffer.
+ * \param raw_size Size of \p raw in bytes. Must be at least
+ * 2 * PSA_BITS_TO_BYTES(bits) bytes.
+ * \param[out] raw_len On success it is updated with the amount of valid
+ * data (in bytes) written to \p raw. It's undefined
+ * in case of failure.
+ */
+int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
+ unsigned char *raw, size_t raw_size, size_t *raw_len);
+
+#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
/**@}*/
-#endif /* MBEDTLS_PSA_CRYPTO_C */
#endif /* MBEDTLS_PSA_UTIL_H */
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index c67345b..10a23f6 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -198,6 +198,8 @@
*
* This function clears all data associated with the PSA layer,
* including the whole key store.
+ * This function is not thread safe, it wipes every key slot regardless of
+ * state and reader count. It should only be called when no slot is in use.
*
* This is an Mbed TLS extension.
*/
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index b6ea73e..47ecf17 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -231,7 +231,7 @@
endif(HAIKU)
if(LINK_WITH_PTHREAD)
- set(libs ${libs} pthread)
+ set(libs ${libs} ${CMAKE_THREAD_LIBS_INIT})
endif()
if(LINK_WITH_TRUSTED_STORAGE)
diff --git a/library/asn1parse.c b/library/asn1parse.c
index c02b233..e33fdf7 100644
--- a/library/asn1parse.c
+++ b/library/asn1parse.c
@@ -7,7 +7,8 @@
#include "common.h"
-#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C)
+#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
+ defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
@@ -73,7 +74,7 @@
return mbedtls_asn1_get_len(p, end, len);
}
-#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C */
+#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_PARSE_C)
int mbedtls_asn1_get_bool(unsigned char **p,
diff --git a/library/asn1write.c b/library/asn1write.c
index 114091d..775a9ef 100644
--- a/library/asn1write.c
+++ b/library/asn1write.c
@@ -7,7 +7,8 @@
#include "common.h"
-#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C)
+#if defined(MBEDTLS_ASN1_WRITE_C) || defined(MBEDTLS_X509_USE_C) || \
+ defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
#include "mbedtls/asn1write.h"
#include "mbedtls/error.h"
@@ -62,7 +63,7 @@
return 1;
}
-#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C */
+#endif /* MBEDTLS_ASN1_WRITE_C || MBEDTLS_X509_USE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
#if defined(MBEDTLS_ASN1_WRITE_C)
static int mbedtls_asn1_write_len_and_tag(unsigned char **p,
diff --git a/library/oid.c b/library/oid.c
index d30a464..1d6b1eb 100644
--- a/library/oid.c
+++ b/library/oid.c
@@ -684,6 +684,18 @@
MBEDTLS_CIPHER_DES_EDE3_CBC,
},
{
+ OID_DESCRIPTOR(MBEDTLS_OID_AES_128_CBC, "aes128-cbc", "AES128-CBC"),
+ MBEDTLS_CIPHER_AES_128_CBC,
+ },
+ {
+ OID_DESCRIPTOR(MBEDTLS_OID_AES_192_CBC, "aes192-cbc", "AES192-CBC"),
+ MBEDTLS_CIPHER_AES_192_CBC,
+ },
+ {
+ OID_DESCRIPTOR(MBEDTLS_OID_AES_256_CBC, "aes256-cbc", "AES256-CBC"),
+ MBEDTLS_CIPHER_AES_256_CBC,
+ },
+ {
NULL_OID_DESCRIPTOR,
MBEDTLS_CIPHER_NONE,
},
diff --git a/library/pk_wrap.c b/library/pk_wrap.c
index c232650..2e00d4a 100644
--- a/library/pk_wrap.c
+++ b/library/pk_wrap.c
@@ -29,9 +29,11 @@
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa_util_internal.h"
#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
#if defined(MBEDTLS_RSA_C)
#include "pkwrite.h"
+#include "rsa_internal.h"
#endif
#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
@@ -69,9 +71,9 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
- mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
+ unsigned char *p = buf + sizeof(buf);
psa_algorithm_t psa_alg_md =
PSA_ALG_RSA_PKCS1V15_SIGN(mbedtls_md_psa_alg_from_type(md_alg));
size_t rsa_len = mbedtls_rsa_get_len(rsa);
@@ -86,11 +88,7 @@
return MBEDTLS_ERR_RSA_VERIFY_FAILED;
}
- /* mbedtls_pk_write_pubkey_der() expects a full PK context;
- * re-construct one to make it happy */
- key.pk_info = &mbedtls_rsa_info;
- key.pk_ctx = rsa;
- key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
+ key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@@ -172,14 +170,15 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
- mbedtls_pk_context key;
int key_len;
unsigned char *buf = NULL;
+ unsigned char *p;
+
buf = mbedtls_calloc(1, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
if (buf == NULL) {
return MBEDTLS_ERR_PK_ALLOC_FAILED;
}
- mbedtls_pk_info_t pk_info = mbedtls_rsa_info;
+ p = buf + MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES;
*sig_len = mbedtls_rsa_get_len(rsa_ctx);
if (sig_size < *sig_len) {
@@ -187,11 +186,7 @@
return MBEDTLS_ERR_PK_BUFFER_TOO_SMALL;
}
- /* mbedtls_pk_write_key_der() expects a full PK context;
- * re-construct one to make it happy */
- key.pk_info = &pk_info;
- key.pk_ctx = rsa_ctx;
- key_len = mbedtls_pk_write_key_der(&key, buf, MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES);
+ key_len = mbedtls_rsa_write_key(rsa_ctx, buf, &p);
if (key_len <= 0) {
mbedtls_free(buf);
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@@ -282,9 +277,9 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
- mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PRV_DER_MAX_BYTES];
+ unsigned char *p = buf + sizeof(buf);
((void) f_rng);
((void) p_rng);
@@ -299,11 +294,7 @@
return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
- /* mbedtls_pk_write_key_der() expects a full PK context;
- * re-construct one to make it happy */
- key.pk_info = &mbedtls_rsa_info;
- key.pk_ctx = rsa;
- key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf));
+ key_len = mbedtls_rsa_write_key(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@@ -368,9 +359,9 @@
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_status_t status;
- mbedtls_pk_context key;
int key_len;
unsigned char buf[MBEDTLS_PK_RSA_PUB_DER_MAX_BYTES];
+ unsigned char *p = buf + sizeof(buf);
((void) f_rng);
((void) p_rng);
@@ -385,11 +376,7 @@
return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
}
- /* mbedtls_pk_write_pubkey_der() expects a full PK context;
- * re-construct one to make it happy */
- key.pk_info = &mbedtls_rsa_info;
- key.pk_ctx = rsa;
- key_len = mbedtls_pk_write_pubkey_der(&key, buf, sizeof(buf));
+ key_len = mbedtls_rsa_write_pubkey(rsa, buf, &p);
if (key_len <= 0) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
}
@@ -536,66 +523,6 @@
#if defined(MBEDTLS_PK_CAN_ECDSA_VERIFY)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/*
- * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
- * those integers and convert it to the fixed-length encoding expected by PSA.
- */
-static int extract_ecdsa_sig_int(unsigned char **from, const unsigned char *end,
- unsigned char *to, size_t to_len)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t unpadded_len, padding_len;
-
- if ((ret = mbedtls_asn1_get_tag(from, end, &unpadded_len,
- MBEDTLS_ASN1_INTEGER)) != 0) {
- return ret;
- }
-
- while (unpadded_len > 0 && **from == 0x00) {
- (*from)++;
- unpadded_len--;
- }
-
- if (unpadded_len > to_len || unpadded_len == 0) {
- return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
- }
-
- padding_len = to_len - unpadded_len;
- memset(to, 0x00, padding_len);
- memcpy(to + padding_len, *from, unpadded_len);
- (*from) += unpadded_len;
-
- return 0;
-}
-
-/*
- * Convert a signature from an ASN.1 sequence of two integers
- * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
- * twice as big as int_size.
- */
-static int extract_ecdsa_sig(unsigned char **p, const unsigned char *end,
- unsigned char *sig, size_t int_size)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t tmp_size;
-
- if ((ret = mbedtls_asn1_get_tag(p, end, &tmp_size,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
- return ret;
- }
-
- /* Extract r */
- if ((ret = extract_ecdsa_sig_int(p, end, sig, int_size)) != 0) {
- return ret;
- }
- /* Extract s */
- if ((ret = extract_ecdsa_sig_int(p, end, sig + int_size, int_size)) != 0) {
- return ret;
- }
-
- return 0;
-}
-
/* Common helper for ECDSA verify using PSA functions. */
static int ecdsa_verify_psa(unsigned char *key, size_t key_len,
psa_ecc_family_t curve, size_t curve_bits,
@@ -607,6 +534,7 @@
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
size_t signature_len = PSA_ECDSA_SIGNATURE_SIZE(curve_bits);
+ size_t converted_sig_len;
unsigned char extracted_sig[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
unsigned char *p;
psa_status_t status;
@@ -631,11 +559,14 @@
}
p = (unsigned char *) sig;
- /* extract_ecdsa_sig's last parameter is the size
- * of each integer to be parsed, so it's actually half
- * the size of the signature. */
- if ((ret = extract_ecdsa_sig(&p, sig + sig_len, extracted_sig,
- signature_len/2)) != 0) {
+ ret = mbedtls_ecdsa_der_to_raw(curve_bits, p, sig_len, extracted_sig,
+ sizeof(extracted_sig), &converted_sig_len);
+ if (ret != 0) {
+ goto cleanup;
+ }
+
+ if (converted_sig_len != signature_len) {
+ ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
goto cleanup;
}
@@ -646,10 +577,6 @@
goto cleanup;
}
- if (p != sig + sig_len) {
- ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
- goto cleanup;
- }
ret = 0;
cleanup:
@@ -751,90 +678,6 @@
#if defined(MBEDTLS_PK_CAN_ECDSA_SIGN)
#if defined(MBEDTLS_USE_PSA_CRYPTO)
-/*
- * Simultaneously convert and move raw MPI from the beginning of a buffer
- * to an ASN.1 MPI at the end of the buffer.
- * See also mbedtls_asn1_write_mpi().
- *
- * p: pointer to the end of the output buffer
- * start: start of the output buffer, and also of the mpi to write at the end
- * n_len: length of the mpi to read from start
- */
-static int asn1_write_mpibuf(unsigned char **p, unsigned char *start,
- size_t n_len)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0;
-
- if ((size_t) (*p - start) < n_len) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
-
- len = n_len;
- *p -= len;
- memmove(*p, start, len);
-
- /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
- * Neither r nor s should be 0, but as a failsafe measure, still detect
- * that rather than overflowing the buffer in case of a PSA error. */
- while (len > 0 && **p == 0x00) {
- ++(*p);
- --len;
- }
-
- /* this is only reached if the signature was invalid */
- if (len == 0) {
- return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
- }
-
- /* if the msb is 1, ASN.1 requires that we prepend a 0.
- * Neither r nor s can be 0, so we can assume len > 0 at all times. */
- if (**p & 0x80) {
- if (*p - start < 1) {
- return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
- }
-
- *--(*p) = 0x00;
- len += 1;
- }
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
- MBEDTLS_ASN1_INTEGER));
-
- return (int) len;
-}
-
-/* Transcode signature from PSA format to ASN.1 sequence.
- * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
- * MPIs, and in-place.
- *
- * [in/out] sig: the signature pre- and post-transcoding
- * [in/out] sig_len: signature length pre- and post-transcoding
- * [int] buf_len: the available size the in/out buffer
- */
-static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len,
- size_t buf_len)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0;
- const size_t rs_len = *sig_len / 2;
- unsigned char *p = sig + buf_len;
-
- MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig + rs_len, rs_len));
- MBEDTLS_ASN1_CHK_ADD(len, asn1_write_mpibuf(&p, sig, rs_len));
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, sig, len));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, sig,
- MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE));
-
- memmove(sig, p, len);
- *sig_len = len;
-
- return 0;
-}
-
/* Common helper for ECDSA sign using PSA functions.
* Instead of extracting key's properties in order to check which kind of ECDSA
* signature it supports, we try both deterministic and non-deterministic.
@@ -845,6 +688,15 @@
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
psa_status_t status;
+ psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
+ size_t key_bits = 0;
+
+ status = psa_get_key_attributes(key_id, &key_attr);
+ if (status != PSA_SUCCESS) {
+ return PSA_PK_ECDSA_TO_MBEDTLS_ERR(status);
+ }
+ key_bits = psa_get_key_bits(&key_attr);
+ psa_reset_key_attributes(&key_attr);
status = psa_sign_hash(key_id,
PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_md_psa_alg_from_type(md_alg)),
@@ -863,7 +715,7 @@
}
done:
- ret = pk_ecdsa_sig_asn1_from_psa(sig, sig_len, sig_size);
+ ret = mbedtls_ecdsa_raw_to_der(key_bits, sig, *sig_len, sig, sig_size, sig_len);
return ret;
}
diff --git a/library/pkparse.c b/library/pkparse.c
index 5f95545..5a3d3b2 100644
--- a/library/pkparse.c
+++ b/library/pkparse.c
@@ -28,6 +28,7 @@
/* Key types */
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
+#include "rsa_internal.h"
#endif
/* Extended formats */
@@ -757,68 +758,6 @@
#endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
-#if defined(MBEDTLS_RSA_C)
-/*
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e
- * }
- */
-static int pk_get_rsapubkey(unsigned char **p,
- const unsigned char *end,
- mbedtls_rsa_context *rsa)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len;
-
- if ((ret = mbedtls_asn1_get_tag(p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
- }
-
- if (*p + len != end) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
- }
-
- /* Import N */
- if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
- }
-
- if ((ret = mbedtls_rsa_import_raw(rsa, *p, len, NULL, 0, NULL, 0,
- NULL, 0, NULL, 0)) != 0) {
- return MBEDTLS_ERR_PK_INVALID_PUBKEY;
- }
-
- *p += len;
-
- /* Import E */
- if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
- }
-
- if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0,
- NULL, 0, *p, len)) != 0) {
- return MBEDTLS_ERR_PK_INVALID_PUBKEY;
- }
-
- *p += len;
-
- if (mbedtls_rsa_complete(rsa) != 0 ||
- mbedtls_rsa_check_pubkey(rsa) != 0) {
- return MBEDTLS_ERR_PK_INVALID_PUBKEY;
- }
-
- if (*p != end) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
- }
-
- return 0;
-}
-#endif /* MBEDTLS_RSA_C */
-
/* Get a PK algorithm identifier
*
* AlgorithmIdentifier ::= SEQUENCE {
@@ -911,7 +850,17 @@
#if defined(MBEDTLS_RSA_C)
if (pk_alg == MBEDTLS_PK_RSA) {
- ret = pk_get_rsapubkey(p, end, mbedtls_pk_rsa(*pk));
+ ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), *p, (size_t) (end - *p));
+ if (ret == 0) {
+ /* On success all the input has been consumed by the parsing function. */
+ *p += end - *p;
+ } else if ((ret <= MBEDTLS_ERR_ASN1_OUT_OF_DATA) &&
+ (ret >= MBEDTLS_ERR_ASN1_BUF_TOO_SMALL)) {
+ /* In case of ASN1 error codes add MBEDTLS_ERR_PK_INVALID_PUBKEY. */
+ ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
+ } else {
+ ret = MBEDTLS_ERR_PK_INVALID_PUBKEY;
+ }
} else
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
@@ -944,195 +893,6 @@
return ret;
}
-#if defined(MBEDTLS_RSA_C)
-/*
- * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
- *
- * The value zero is:
- * - never a valid value for an RSA parameter
- * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
- *
- * Since values can't be omitted in PKCS#1, passing a zero value to
- * rsa_complete() would be incorrect, so reject zero values early.
- */
-static int asn1_get_nonzero_mpi(unsigned char **p,
- const unsigned char *end,
- mbedtls_mpi *X)
-{
- int ret;
-
- ret = mbedtls_asn1_get_mpi(p, end, X);
- if (ret != 0) {
- return ret;
- }
-
- if (mbedtls_mpi_cmp_int(X, 0) == 0) {
- return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
- }
-
- return 0;
-}
-
-/*
- * Parse a PKCS#1 encoded private RSA key
- */
-static int pk_parse_key_pkcs1_der(mbedtls_rsa_context *rsa,
- const unsigned char *key,
- size_t keylen)
-{
- int ret, version;
- size_t len;
- unsigned char *p, *end;
-
- mbedtls_mpi T;
- mbedtls_mpi_init(&T);
-
- p = (unsigned char *) key;
- end = p + keylen;
-
- /*
- * This function parses the RSAPrivateKey (PKCS#1)
- *
- * RSAPrivateKey ::= SEQUENCE {
- * version Version,
- * modulus INTEGER, -- n
- * publicExponent INTEGER, -- e
- * privateExponent INTEGER, -- d
- * prime1 INTEGER, -- p
- * prime2 INTEGER, -- q
- * exponent1 INTEGER, -- d mod (p-1)
- * exponent2 INTEGER, -- d mod (q-1)
- * coefficient INTEGER, -- (inverse of q) mod p
- * otherPrimeInfos OtherPrimeInfos OPTIONAL
- * }
- */
- if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
- MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
- }
-
- end = p + len;
-
- if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
- return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
- }
-
- if (version != 0) {
- return MBEDTLS_ERR_PK_KEY_INVALID_VERSION;
- }
-
- /* Import N */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
- NULL, NULL)) != 0) {
- goto cleanup;
- }
-
- /* Import E */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
- NULL, &T)) != 0) {
- goto cleanup;
- }
-
- /* Import D */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
- &T, NULL)) != 0) {
- goto cleanup;
- }
-
- /* Import P */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
- NULL, NULL)) != 0) {
- goto cleanup;
- }
-
- /* Import Q */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
- NULL, NULL)) != 0) {
- goto cleanup;
- }
-
-#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
- /*
- * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
- * that they can be easily recomputed from D, P and Q. However by
- * parsing them from the PKCS1 structure it is possible to avoid
- * recalculating them which both reduces the overhead of loading
- * RSA private keys into memory and also avoids side channels which
- * can arise when computing those values, since all of D, P, and Q
- * are secret. See https://eprint.iacr.org/2020/055 for a
- * description of one such attack.
- */
-
- /* Import DP */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) {
- goto cleanup;
- }
-
- /* Import DQ */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) {
- goto cleanup;
- }
-
- /* Import QP */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) {
- goto cleanup;
- }
-
-#else
- /* Verify existence of the CRT params */
- if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
- (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) {
- goto cleanup;
- }
-#endif
-
- /* rsa_complete() doesn't complete anything with the default
- * implementation but is still called:
- * - for the benefit of alternative implementation that may want to
- * pre-compute stuff beyond what's provided (eg Montgomery factors)
- * - as is also sanity-checks the key
- *
- * Furthermore, we also check the public part for consistency with
- * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
- */
- if ((ret = mbedtls_rsa_complete(rsa)) != 0 ||
- (ret = mbedtls_rsa_check_pubkey(rsa)) != 0) {
- goto cleanup;
- }
-
- if (p != end) {
- ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
- }
-
-cleanup:
-
- mbedtls_mpi_free(&T);
-
- if (ret != 0) {
- /* Wrap error code if it's coming from a lower level */
- if ((ret & 0xff80) == 0) {
- ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
- } else {
- ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
- }
-
- mbedtls_rsa_free(rsa);
- }
-
- return ret;
-}
-#endif /* MBEDTLS_RSA_C */
-
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
/*
* Parse a SEC1 encoded private EC key
@@ -1348,7 +1108,7 @@
#if defined(MBEDTLS_RSA_C)
if (pk_alg == MBEDTLS_PK_RSA) {
- if ((ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), p, len)) != 0) {
+ if ((ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), p, len)) != 0) {
mbedtls_pk_free(pk);
return ret;
}
@@ -1538,8 +1298,8 @@
if (ret == 0) {
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
- (ret = pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk),
- pem.buf, pem.buflen)) != 0) {
+ (ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk),
+ pem.buf, pem.buflen)) != 0) {
mbedtls_pk_free(pk);
}
@@ -1679,7 +1439,7 @@
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
if (mbedtls_pk_setup(pk, pk_info) == 0 &&
- pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
+ mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
return 0;
}
@@ -1754,7 +1514,7 @@
return ret;
}
- if ((ret = pk_get_rsapubkey(&p, p + pem.buflen, mbedtls_pk_rsa(*ctx))) != 0) {
+ if ((ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, pem.buflen)) != 0) {
mbedtls_pk_free(ctx);
}
@@ -1801,13 +1561,12 @@
}
p = (unsigned char *) key;
- ret = pk_get_rsapubkey(&p, p + keylen, mbedtls_pk_rsa(*ctx));
+ ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, keylen);
if (ret == 0) {
return ret;
}
mbedtls_pk_free(ctx);
- if (ret != (MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG))) {
+ if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
return ret;
}
#endif /* MBEDTLS_RSA_C */
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 1f0d399..b9ddcf1 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -32,6 +32,9 @@
#if defined(MBEDTLS_PEM_WRITE_C)
#include "mbedtls/pem.h"
#endif
+#if defined(MBEDTLS_RSA_C)
+#include "rsa_internal.h"
+#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
@@ -56,60 +59,13 @@
* Internal functions for RSA keys.
******************************************************************************/
#if defined(MBEDTLS_RSA_C)
-/*
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e
- * }
- */
-static int pk_write_rsa_pubkey(unsigned char **p, unsigned char *start,
- const mbedtls_pk_context *pk)
-{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- size_t len = 0;
- mbedtls_mpi T;
- mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
-
- mbedtls_mpi_init(&T);
-
- /* Export E */
- if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export N */
- if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
-end_of_export:
-
- mbedtls_mpi_free(&T);
- if (ret < 0) {
- return ret;
- }
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE));
-
- return (int) len;
-}
-
static int pk_write_rsa_der(unsigned char **p, unsigned char *buf,
const mbedtls_pk_context *pk)
{
- size_t len = 0;
- int ret;
-
#if defined(MBEDTLS_USE_PSA_CRYPTO)
if (mbedtls_pk_get_type(pk) == MBEDTLS_PK_OPAQUE) {
uint8_t tmp[PSA_EXPORT_KEY_PAIR_MAX_SIZE];
- size_t tmp_len = 0;
+ size_t len = 0, tmp_len = 0;
if (psa_export_key(pk->priv_id, tmp, sizeof(tmp), &tmp_len) != PSA_SUCCESS) {
return MBEDTLS_ERR_PK_BAD_INPUT_DATA;
@@ -118,94 +74,11 @@
memcpy(*p, tmp, tmp_len);
len += tmp_len;
mbedtls_platform_zeroize(tmp, sizeof(tmp));
- } else
-#endif /* MBEDTLS_USE_PSA_CRYPTO */
- {
- mbedtls_mpi T; /* Temporary holding the exported parameters */
- mbedtls_rsa_context *rsa = mbedtls_pk_rsa(*pk);
- /*
- * Export the parameters one after another to avoid simultaneous copies.
- */
-
- mbedtls_mpi_init(&T);
-
- /* Export QP */
- if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export DQ */
- if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export DP */
- if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export Q */
- if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
- &T, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export P */
- if ((ret = mbedtls_rsa_export(rsa, NULL, &T,
- NULL, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export D */
- if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
- NULL, &T, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export E */
- if ((ret = mbedtls_rsa_export(rsa, NULL, NULL,
- NULL, NULL, &T)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
- /* Export N */
- if ((ret = mbedtls_rsa_export(rsa, &T, NULL,
- NULL, NULL, NULL)) != 0 ||
- (ret = mbedtls_asn1_write_mpi(p, buf, &T)) < 0) {
- goto end_of_export;
- }
- len += ret;
-
-end_of_export:
-
- mbedtls_mpi_free(&T);
- if (ret < 0) {
- return ret;
- }
-
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, buf, 0));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, buf, len));
- MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p,
- buf, MBEDTLS_ASN1_CONSTRUCTED |
- MBEDTLS_ASN1_SEQUENCE));
+ return (int) len;
}
-
- return (int) len;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ return mbedtls_rsa_write_key(mbedtls_pk_rsa(*pk), buf, p);
}
#endif /* MBEDTLS_RSA_C */
@@ -543,7 +416,7 @@
#if defined(MBEDTLS_RSA_C)
if (mbedtls_pk_get_type(key) == MBEDTLS_PK_RSA) {
- MBEDTLS_ASN1_CHK_ADD(len, pk_write_rsa_pubkey(p, start, key));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_rsa_write_pubkey(mbedtls_pk_rsa(*key), start, p));
} else
#endif
#if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index beafc48..4a0666b 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1089,6 +1089,14 @@
return status;
}
+#if defined(MBEDTLS_THREADING_C)
+ /* We cannot unlock between setting the state to PENDING_DELETION
+ * and destroying the key in storage, as otherwise another thread
+ * could load the key into a new slot and the key will not be
+ * fully destroyed. */
+ PSA_THREADING_CHK_GOTO_EXIT(mbedtls_mutex_lock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
/* Set the key slot containing the key description's state to
* PENDING_DELETION. This stops new operations from registering
* to read the slot. Current readers can safely continue to access
@@ -1097,7 +1105,12 @@
* If the key is persistent, we can now delete the copy of the key
* from memory. If the key is opaque, we require the driver to
* deal with the deletion. */
- slot->state = PSA_SLOT_PENDING_DELETION;
+ status = psa_key_slot_state_transition(slot, PSA_SLOT_FULL,
+ PSA_SLOT_PENDING_DELETION);
+
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
if (PSA_KEY_LIFETIME_IS_READ_ONLY(slot->attr.lifetime)) {
/* Refuse the destruction of a read-only key (which may or may not work
@@ -1152,11 +1165,6 @@
if (overall_status == PSA_SUCCESS) {
overall_status = status;
}
-
- /* TODO: other slots may have a copy of the same key. We should
- * invalidate them.
- * https://github.com/ARMmbed/mbed-crypto/issues/214
- */
}
#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */
@@ -1182,6 +1190,14 @@
if (status != PSA_SUCCESS) {
overall_status = status;
}
+
+#if defined(MBEDTLS_THREADING_C)
+ /* Don't overwrite existing errors if the unlock fails. */
+ status = overall_status;
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
+
return overall_status;
}
diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c
index 7b58ea2..4a574d1 100644
--- a/library/psa_crypto_rsa.c
+++ b/library/psa_crypto_rsa.c
@@ -24,8 +24,7 @@
#include <mbedtls/rsa.h>
#include <mbedtls/error.h>
-#include <mbedtls/pk.h>
-#include "pk_wrap.h"
+#include "rsa_internal.h"
#if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || \
defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) || \
@@ -62,50 +61,38 @@
mbedtls_rsa_context **p_rsa)
{
psa_status_t status;
- mbedtls_pk_context ctx;
size_t bits;
- mbedtls_pk_init(&ctx);
+
+ *p_rsa = mbedtls_calloc(1, sizeof(mbedtls_rsa_context));
+ if (*p_rsa == NULL) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+ mbedtls_rsa_init(*p_rsa);
/* Parse the data. */
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
- status = mbedtls_to_psa_error(
- mbedtls_pk_parse_key(&ctx, data, data_length, NULL, 0,
- mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE));
+ status = mbedtls_to_psa_error(mbedtls_rsa_parse_key(*p_rsa, data, data_length));
} else {
- status = mbedtls_to_psa_error(
- mbedtls_pk_parse_public_key(&ctx, data, data_length));
+ status = mbedtls_to_psa_error(mbedtls_rsa_parse_pubkey(*p_rsa, data, data_length));
}
if (status != PSA_SUCCESS) {
goto exit;
}
- /* We have something that the pkparse module recognizes. If it is a
- * valid RSA key, store it. */
- if (mbedtls_pk_get_type(&ctx) != MBEDTLS_PK_RSA) {
- status = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
-
/* The size of an RSA key doesn't have to be a multiple of 8. Mbed TLS
* supports non-byte-aligned key sizes, but not well. For example,
* mbedtls_rsa_get_len() returns the key size in bytes, not in bits. */
- bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(mbedtls_pk_rsa(ctx)));
+ bits = PSA_BYTES_TO_BITS(mbedtls_rsa_get_len(*p_rsa));
if (bits > PSA_VENDOR_RSA_MAX_KEY_BITS) {
status = PSA_ERROR_NOT_SUPPORTED;
goto exit;
}
- status = psa_check_rsa_key_byte_aligned(mbedtls_pk_rsa(ctx));
+ status = psa_check_rsa_key_byte_aligned(*p_rsa);
if (status != PSA_SUCCESS) {
goto exit;
}
- /* Copy out the pointer to the RSA context, and reset the PK context
- * such that pk_free doesn't free the RSA context we just grabbed. */
- *p_rsa = mbedtls_pk_rsa(ctx);
- ctx.pk_info = NULL;
-
exit:
- mbedtls_pk_free(&ctx);
return status;
}
#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) ||
@@ -168,20 +155,15 @@
size_t *data_length)
{
int ret;
- mbedtls_pk_context pk;
- uint8_t *pos = data + data_size;
-
- mbedtls_pk_init(&pk);
- pk.pk_info = &mbedtls_rsa_info;
- pk.pk_ctx = rsa;
+ uint8_t *end = data + data_size;
/* PSA Crypto API defines the format of an RSA key as a DER-encoded
* representation of the non-encrypted PKCS#1 RSAPrivateKey for a
* private key and of the RFC3279 RSAPublicKey for a public key. */
if (PSA_KEY_TYPE_IS_KEY_PAIR(type)) {
- ret = mbedtls_pk_write_key_der(&pk, data, data_size);
+ ret = mbedtls_rsa_write_key(rsa, data, &end);
} else {
- ret = mbedtls_pk_write_pubkey(&pos, data, &pk);
+ ret = mbedtls_rsa_write_pubkey(rsa, data, &end);
}
if (ret < 0) {
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 47ace35..dc38662 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -521,44 +521,78 @@
psa_status_t psa_close_key(psa_key_handle_t handle)
{
- psa_status_t status;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
if (psa_key_handle_is_null(handle)) {
return PSA_SUCCESS;
}
+#if defined(MBEDTLS_THREADING_C)
+ /* We need to set status as success, otherwise CORRUPTION_DETECTED
+ * would be returned if the lock fails. */
+ status = PSA_SUCCESS;
+ PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
status = psa_get_and_lock_key_slot_in_memory(handle, &slot);
if (status != PSA_SUCCESS) {
if (status == PSA_ERROR_DOES_NOT_EXIST) {
status = PSA_ERROR_INVALID_HANDLE;
}
-
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
return status;
}
+
if (slot->registered_readers == 1) {
- return psa_wipe_key_slot(slot);
+ status = psa_wipe_key_slot(slot);
} else {
- return psa_unregister_read(slot);
+ status = psa_unregister_read(slot);
}
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
+
+ return status;
}
psa_status_t psa_purge_key(mbedtls_svc_key_id_t key)
{
- psa_status_t status;
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
psa_key_slot_t *slot;
+#if defined(MBEDTLS_THREADING_C)
+ /* We need to set status as success, otherwise CORRUPTION_DETECTED
+ * would be returned if the lock fails. */
+ status = PSA_SUCCESS;
+ PSA_THREADING_CHK_RET(mbedtls_mutex_lock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
status = psa_get_and_lock_key_slot_in_memory(key, &slot);
if (status != PSA_SUCCESS) {
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
return status;
}
if ((!PSA_KEY_LIFETIME_IS_VOLATILE(slot->attr.lifetime)) &&
(slot->registered_readers == 1)) {
- return psa_wipe_key_slot(slot);
+ status = psa_wipe_key_slot(slot);
} else {
- return psa_unregister_read(slot);
+ status = psa_unregister_read(slot);
}
+#if defined(MBEDTLS_THREADING_C)
+ PSA_THREADING_CHK_RET(mbedtls_mutex_unlock(
+ &mbedtls_threading_key_slot_mutex));
+#endif
+
+ return status;
}
void mbedtls_psa_get_stats(mbedtls_psa_stats_t *stats)
diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h
index 002429b..18a9144 100644
--- a/library/psa_crypto_slot_management.h
+++ b/library/psa_crypto_slot_management.h
@@ -92,6 +92,8 @@
psa_status_t psa_initialize_key_slots(void);
/** Delete all data from key slots in memory.
+ * This function is not thread safe, it wipes every key slot regardless of
+ * state and reader count. It should only be called when no slot is in use.
*
* This does not affect persistent storage. */
void psa_wipe_all_key_slots(void);
diff --git a/library/psa_util.c b/library/psa_util.c
index 41586e2..fd119bf 100644
--- a/library/psa_util.c
+++ b/library/psa_util.c
@@ -8,14 +8,20 @@
#include "common.h"
+/* This is needed for MBEDTLS_ERR_XXX macros */
+#include <mbedtls/error.h>
+
+#if defined(MBEDTLS_ASN1_WRITE_C)
+#include <mbedtls/asn1write.h>
+#include <psa/crypto_sizes.h>
+#endif
+
+#include "psa_util_internal.h"
+
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include <psa/crypto.h>
-#include "psa_util_internal.h"
-
-/* The following includes are needed for MBEDTLS_ERR_XXX macros */
-#include <mbedtls/error.h>
#if defined(MBEDTLS_MD_LIGHT)
#include <mbedtls/md.h>
#endif
@@ -331,3 +337,239 @@
#endif /* PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY */
#endif /* MBEDTLS_PSA_CRYPTO_C */
+
+#if defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
+
+/**
+ * \brief Convert a single raw coordinate to DER ASN.1 format. The output der
+ * buffer is filled backward (i.e. starting from its end).
+ *
+ * \param raw_buf Buffer containing the raw coordinate to be
+ * converted.
+ * \param raw_len Length of raw_buf in bytes. This must be > 0.
+ * \param der_buf_start Pointer to the beginning of the buffer which
+ * will be filled with the DER converted data.
+ * \param der_buf_end End of the buffer used to store the DER output.
+ *
+ * \return On success, the amount of data (in bytes) written to
+ * the DER buffer.
+ * \return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if the provided der
+ * buffer is too small to contain all the converted data.
+ * \return MBEDTLS_ERR_ASN1_INVALID_DATA if the input raw
+ * coordinate is null (i.e. all zeros).
+ *
+ * \warning Raw and der buffer must not be overlapping.
+ */
+static int convert_raw_to_der_single_int(const unsigned char *raw_buf, size_t raw_len,
+ unsigned char *der_buf_start,
+ unsigned char *der_buf_end)
+{
+ unsigned char *p = der_buf_end;
+ int len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
+ * Provided input MPIs should not be 0, but as a failsafe measure, still
+ * detect that and return error in case. */
+ while (*raw_buf == 0x00) {
+ ++raw_buf;
+ --raw_len;
+ if (raw_len == 0) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ }
+ len = (int) raw_len;
+
+ /* Copy the raw coordinate to the end of der_buf. */
+ if ((p - der_buf_start) < len) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+ p -= len;
+ memcpy(p, raw_buf, len);
+
+ /* If MSb is 1, ASN.1 requires that we prepend a 0. */
+ if (*p & 0x80) {
+ if ((p - der_buf_start) < 1) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+ --p;
+ *p = 0x00;
+ ++len;
+ }
+
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der_buf_start, len));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der_buf_start, MBEDTLS_ASN1_INTEGER));
+
+ return len;
+}
+
+int mbedtls_ecdsa_raw_to_der(size_t bits, const unsigned char *raw, size_t raw_len,
+ unsigned char *der, size_t der_size, size_t *der_len)
+{
+ unsigned char r[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
+ unsigned char s[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
+ const size_t coordinate_len = PSA_BITS_TO_BYTES(bits);
+ size_t len = 0;
+ unsigned char *p = der + der_size;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if (raw_len != (2 * coordinate_len)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+
+ /* Since raw and der buffers might overlap, dump r and s before starting
+ * the conversion. */
+ memcpy(r, raw, coordinate_len);
+ memcpy(s, raw + coordinate_len, coordinate_len);
+
+ /* der buffer will initially be written starting from its end so we pick s
+ * first and then r. */
+ ret = convert_raw_to_der_single_int(s, coordinate_len, der, p);
+ if (ret < 0) {
+ return ret;
+ }
+ p -= ret;
+ len += ret;
+
+ ret = convert_raw_to_der_single_int(r, coordinate_len, der, p);
+ if (ret < 0) {
+ return ret;
+ }
+ p -= ret;
+ len += ret;
+
+ /* Add ASN.1 header (len + tag). */
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, der, len));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, der,
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE));
+
+ /* memmove the content of der buffer to its beginnig. */
+ memmove(der, p, len);
+ *der_len = len;
+
+ return 0;
+}
+
+/**
+ * \brief Convert a single integer from ASN.1 DER format to raw.
+ *
+ * \param der Buffer containing the DER integer value to be
+ * converted.
+ * \param der_len Length of the der buffer in bytes.
+ * \param raw Output buffer that will be filled with the
+ * converted data. This should be at least
+ * coordinate_size bytes and it must be zeroed before
+ * calling this function.
+ * \param coordinate_size Size (in bytes) of a single coordinate in raw
+ * format.
+ *
+ * \return On success, the amount of DER data parsed from the
+ * provided der buffer.
+ * \return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the integer tag
+ * is missing in the der buffer.
+ * \return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the integer
+ * is null (i.e. all zeros) or if the output raw buffer
+ * is too small to contain the converted raw value.
+ *
+ * \warning Der and raw buffers must not be overlapping.
+ */
+static int convert_der_to_raw_single_int(unsigned char *der, size_t der_len,
+ unsigned char *raw, size_t coordinate_size)
+{
+ unsigned char *p = der;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t unpadded_len, padding_len = 0;
+
+ /* Get the length of ASN.1 element (i.e. the integer we need to parse). */
+ ret = mbedtls_asn1_get_tag(&p, p + der_len, &unpadded_len,
+ MBEDTLS_ASN1_INTEGER);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* It's invalid to have:
+ * - unpadded_len == 0.
+ * - MSb set without a leading 0x00 (leading 0x00 is checked below). */
+ if (((unpadded_len == 0) || (*p & 0x80) != 0)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+
+ /* Skip possible leading zero */
+ if (*p == 0x00) {
+ p++;
+ unpadded_len--;
+ /* It is not allowed to have more than 1 leading zero.
+ * Ignore the case in which unpadded_len = 0 because that's a 0 encoded
+ * in ASN.1 format (i.e. 020100). */
+ if ((unpadded_len > 0) && (*p == 0x00)) {
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ }
+
+ if (unpadded_len > coordinate_size) {
+ /* Parsed number is longer than the maximum expected value. */
+ return MBEDTLS_ERR_ASN1_INVALID_DATA;
+ }
+ padding_len = coordinate_size - unpadded_len;
+ /* raw buffer was already zeroed by the calling function so zero-padding
+ * operation is skipped here. */
+ memcpy(raw + padding_len, p, unpadded_len);
+ p += unpadded_len;
+
+ return (int) (p - der);
+}
+
+int mbedtls_ecdsa_der_to_raw(size_t bits, const unsigned char *der, size_t der_len,
+ unsigned char *raw, size_t raw_size, size_t *raw_len)
+{
+ unsigned char raw_tmp[PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE];
+ unsigned char *p = (unsigned char *) der;
+ size_t data_len;
+ size_t coordinate_size = PSA_BITS_TO_BYTES(bits);
+ int ret;
+
+ /* The output raw buffer should be at least twice the size of a raw
+ * coordinate in order to store r and s. */
+ if (raw_size < coordinate_size * 2) {
+ return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL;
+ }
+
+ /* Check that the provided input DER buffer has the right header. */
+ ret = mbedtls_asn1_get_tag(&p, der + der_len, &data_len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+ if (ret != 0) {
+ return ret;
+ }
+
+ memset(raw_tmp, 0, 2 * coordinate_size);
+
+ /* Extract r */
+ ret = convert_der_to_raw_single_int(p, data_len, raw_tmp, coordinate_size);
+ if (ret < 0) {
+ return ret;
+ }
+ p += ret;
+ data_len -= ret;
+
+ /* Extract s */
+ ret = convert_der_to_raw_single_int(p, data_len, raw_tmp + coordinate_size,
+ coordinate_size);
+ if (ret < 0) {
+ return ret;
+ }
+ p += ret;
+ data_len -= ret;
+
+ /* Check that we consumed all the input der data. */
+ if ((size_t) (p - der) != der_len) {
+ return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ }
+
+ memcpy(raw, raw_tmp, 2 * coordinate_size);
+ *raw_len = 2 * coordinate_size;
+
+ return 0;
+}
+
+#endif /* MBEDTLS_PSA_UTIL_HAVE_ECDSA */
diff --git a/library/rsa.c b/library/rsa.c
index a90b83a..f4c0862 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -32,6 +32,7 @@
#include "rsa_alt_helpers.h"
#include "rsa_internal.h"
#include "mbedtls/oid.h"
+#include "mbedtls/asn1write.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include "constant_time_internal.h"
@@ -46,6 +47,367 @@
#include "mbedtls/platform.h"
+/*
+ * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
+ *
+ * The value zero is:
+ * - never a valid value for an RSA parameter
+ * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
+ *
+ * Since values can't be omitted in PKCS#1, passing a zero value to
+ * rsa_complete() would be incorrect, so reject zero values early.
+ */
+static int asn1_get_nonzero_mpi(unsigned char **p,
+ const unsigned char *end,
+ mbedtls_mpi *X)
+{
+ int ret;
+
+ ret = mbedtls_asn1_get_mpi(p, end, X);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (mbedtls_mpi_cmp_int(X, 0) == 0) {
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
+
+ return 0;
+}
+
+int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen)
+{
+ int ret, version;
+ size_t len;
+ unsigned char *p, *end;
+
+ mbedtls_mpi T;
+ mbedtls_mpi_init(&T);
+
+ p = (unsigned char *) key;
+ end = p + keylen;
+
+ /*
+ * This function parses the RSAPrivateKey (PKCS#1)
+ *
+ * RSAPrivateKey ::= SEQUENCE {
+ * version Version,
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER, -- e
+ * privateExponent INTEGER, -- d
+ * prime1 INTEGER, -- p
+ * prime2 INTEGER, -- q
+ * exponent1 INTEGER, -- d mod (p-1)
+ * exponent2 INTEGER, -- d mod (q-1)
+ * coefficient INTEGER, -- (inverse of q) mod p
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL
+ * }
+ */
+ if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+ return ret;
+ }
+
+ /* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
+ end = p + len;
+
+ if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
+ return ret;
+ }
+
+ if (version != 0) {
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
+
+ /* Import N */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
+ NULL, NULL)) != 0) {
+ goto cleanup;
+ }
+
+ /* Import E */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
+ NULL, &T)) != 0) {
+ goto cleanup;
+ }
+
+ /* Import D */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
+ &T, NULL)) != 0) {
+ goto cleanup;
+ }
+
+ /* Import P */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
+ NULL, NULL)) != 0) {
+ goto cleanup;
+ }
+
+ /* Import Q */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
+ NULL, NULL)) != 0) {
+ goto cleanup;
+ }
+
+#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
+ /*
+ * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
+ * that they can be easily recomputed from D, P and Q. However by
+ * parsing them from the PKCS1 structure it is possible to avoid
+ * recalculating them which both reduces the overhead of loading
+ * RSA private keys into memory and also avoids side channels which
+ * can arise when computing those values, since all of D, P, and Q
+ * are secret. See https://eprint.iacr.org/2020/055 for a
+ * description of one such attack.
+ */
+
+ /* Import DP */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0) {
+ goto cleanup;
+ }
+
+ /* Import DQ */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0) {
+ goto cleanup;
+ }
+
+ /* Import QP */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0) {
+ goto cleanup;
+ }
+
+#else
+ /* Verify existence of the CRT params */
+ if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
+ (ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0) {
+ goto cleanup;
+ }
+#endif
+
+ /* rsa_complete() doesn't complete anything with the default
+ * implementation but is still called:
+ * - for the benefit of alternative implementation that may want to
+ * pre-compute stuff beyond what's provided (eg Montgomery factors)
+ * - as is also sanity-checks the key
+ *
+ * Furthermore, we also check the public part for consistency with
+ * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
+ */
+ if ((ret = mbedtls_rsa_complete(rsa)) != 0 ||
+ (ret = mbedtls_rsa_check_pubkey(rsa)) != 0) {
+ goto cleanup;
+ }
+
+ if (p != end) {
+ ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ }
+
+cleanup:
+
+ mbedtls_mpi_free(&T);
+
+ if (ret != 0) {
+ mbedtls_rsa_free(rsa);
+ }
+
+ return ret;
+}
+
+int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen)
+{
+ unsigned char *p = (unsigned char *) key;
+ unsigned char *end = (unsigned char *) (key + keylen);
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len;
+
+ /*
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER -- e
+ * }
+ */
+
+ if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
+ return ret;
+ }
+
+ /* mbedtls_asn1_get_tag() already ensures that len is valid (i.e. p+len <= end)*/
+ end = p + len;
+
+ /* Import N */
+ if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
+ return ret;
+ }
+
+ if ((ret = mbedtls_rsa_import_raw(rsa, p, len, NULL, 0, NULL, 0,
+ NULL, 0, NULL, 0)) != 0) {
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
+
+ p += len;
+
+ /* Import E */
+ if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
+ return ret;
+ }
+
+ if ((ret = mbedtls_rsa_import_raw(rsa, NULL, 0, NULL, 0, NULL, 0,
+ NULL, 0, p, len)) != 0) {
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
+
+ p += len;
+
+ if (mbedtls_rsa_complete(rsa) != 0 ||
+ mbedtls_rsa_check_pubkey(rsa) != 0) {
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
+
+ if (p != end) {
+ return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ }
+
+ return 0;
+}
+
+int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start,
+ unsigned char **p)
+{
+ size_t len = 0;
+ int ret;
+
+ mbedtls_mpi T; /* Temporary holding the exported parameters */
+
+ /*
+ * Export the parameters one after another to avoid simultaneous copies.
+ */
+
+ mbedtls_mpi_init(&T);
+
+ /* Export QP */
+ if ((ret = mbedtls_rsa_export_crt(rsa, NULL, NULL, &T)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export DQ */
+ if ((ret = mbedtls_rsa_export_crt(rsa, NULL, &T, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export DP */
+ if ((ret = mbedtls_rsa_export_crt(rsa, &T, NULL, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export Q */
+ if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, &T, NULL, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export P */
+ if ((ret = mbedtls_rsa_export(rsa, NULL, &T, NULL, NULL, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export D */
+ if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, &T, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export E */
+ if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export N */
+ if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+end_of_export:
+
+ mbedtls_mpi_free(&T);
+ if (ret < 0) {
+ return ret;
+ }
+
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(p, start, 0));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start,
+ MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE));
+
+ return (int) len;
+}
+
+/*
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER -- e
+ * }
+ */
+int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start,
+ unsigned char **p)
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+ mbedtls_mpi T;
+
+ mbedtls_mpi_init(&T);
+
+ /* Export E */
+ if ((ret = mbedtls_rsa_export(rsa, NULL, NULL, NULL, NULL, &T)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+ /* Export N */
+ if ((ret = mbedtls_rsa_export(rsa, &T, NULL, NULL, NULL, NULL)) != 0 ||
+ (ret = mbedtls_asn1_write_mpi(p, start, &T)) < 0) {
+ goto end_of_export;
+ }
+ len += ret;
+
+end_of_export:
+
+ mbedtls_mpi_free(&T);
+ if (ret < 0) {
+ return ret;
+ }
+
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len));
+ MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE));
+
+ return (int) len;
+}
#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
@@ -660,7 +1022,6 @@
return ctx->len;
}
-
#if defined(MBEDTLS_GENPRIME)
/*
diff --git a/library/rsa_internal.h b/library/rsa_internal.h
index 4081ac6..f79c3b7 100644
--- a/library/rsa_internal.h
+++ b/library/rsa_internal.h
@@ -15,6 +15,85 @@
#define MBEDTLS_RSA_INTERNAL_H
#include "mbedtls/rsa.h"
+#include "mbedtls/asn1.h"
+
+/**
+ * \brief Parse a PKCS#1 (ASN.1) encoded private RSA key.
+ *
+ * \param rsa The RSA context where parsed data will be stored.
+ * \param key The buffer that contains the key.
+ * \param keylen The length of the key buffer in bytes.
+ *
+ * \return 0 on success.
+ * \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors.
+ * \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while
+ * parsing data.
+ * \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the
+ * provided key fail.
+ */
+int mbedtls_rsa_parse_key(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen);
+
+/**
+ * \brief Parse a PKCS#1 (ASN.1) encoded public RSA key.
+ *
+ * \param rsa The RSA context where parsed data will be stored.
+ * \param key The buffer that contains the key.
+ * \param keylen The length of the key buffer in bytes.
+ *
+ * \return 0 on success.
+ * \return MBEDTLS_ERR_ASN1_xxx in case of ASN.1 parsing errors.
+ * \return MBEDTLS_ERR_RSA_xxx in case of RSA internal failures while
+ * parsing data.
+ * \return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED if validity checks on the
+ * provided key fail.
+ */
+int mbedtls_rsa_parse_pubkey(mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen);
+
+/**
+ * \brief Write a PKCS#1 (ASN.1) encoded private RSA key.
+ *
+ * \param rsa The RSA context which contains the data to be written.
+ * \param start Beginning of the buffer that will be filled with the
+ * private key.
+ * \param p End of the buffer that will be filled with the private key.
+ * On successful return, the referenced pointer will be
+ * updated in order to point to the beginning of written data.
+ *
+ * \return On success, the number of bytes written to the output buffer
+ * (i.e. a value > 0).
+ * \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not
+ * contain a valid key pair.
+ * \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the
+ * output buffer.
+ *
+ * \note The output buffer is filled backward, i.e. starting from its
+ * end and moving toward its start.
+ */
+int mbedtls_rsa_write_key(const mbedtls_rsa_context *rsa, unsigned char *start,
+ unsigned char **p);
+
+/**
+ * \brief Parse a PKCS#1 (ASN.1) encoded public RSA key.
+ *
+ * \param rsa The RSA context which contains the data to be written.
+ * \param start Beginning of the buffer that will be filled with the
+ * private key.
+ * \param p End of the buffer that will be filled with the private key.
+ * On successful return, the referenced pointer will be
+ * updated in order to point to the beginning of written data.
+ *
+ * \return On success, the number of bytes written to the output buffer
+ * (i.e. a value > 0).
+ * \return MBEDTLS_ERR_RSA_BAD_INPUT_DATA if the RSA context does not
+ * contain a valid public key.
+ * \return MBEDTLS_ERR_ASN1_xxx in case of failure while writing to the
+ * output buffer.
+ *
+ * \note The output buffer is filled backward, i.e. starting from its
+ * end and moving toward its start.
+ */
+int mbedtls_rsa_write_pubkey(const mbedtls_rsa_context *rsa, unsigned char *start,
+ unsigned char **p);
#if defined(MBEDTLS_PKCS1_V21)
/**
diff --git a/programs/Makefile b/programs/Makefile
index 82c8569..6baf465 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -114,7 +114,7 @@
endif
fuzz: ${MBEDTLS_TEST_OBJS}
- $(MAKE) -C fuzz THIRDPARTY_INCLUDES=$(THIRDPARTY_INCLUDES)
+ $(MAKE) -C fuzz
${MBEDTLS_TEST_OBJS}:
$(MAKE) -C ../tests mbedtls_test
diff --git a/programs/aes/CMakeLists.txt b/programs/aes/CMakeLists.txt
index 85bcd5f..ccb8db5 100644
--- a/programs/aes/CMakeLists.txt
+++ b/programs/aes/CMakeLists.txt
@@ -4,7 +4,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/cipher/CMakeLists.txt b/programs/cipher/CMakeLists.txt
index 93e5f31..e925524 100644
--- a/programs/cipher/CMakeLists.txt
+++ b/programs/cipher/CMakeLists.txt
@@ -4,7 +4,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/fuzz/CMakeLists.txt b/programs/fuzz/CMakeLists.txt
index 7747744..c389029 100644
--- a/programs/fuzz/CMakeLists.txt
+++ b/programs/fuzz/CMakeLists.txt
@@ -1,5 +1,6 @@
set(libs
${mbedtls_target}
+ ${CMAKE_THREAD_LIBS_INIT}
)
find_library(FUZZINGENGINE_LIB FuzzingEngine)
diff --git a/programs/fuzz/Makefile b/programs/fuzz/Makefile
index b4fc76a..828e518 100644
--- a/programs/fuzz/Makefile
+++ b/programs/fuzz/Makefile
@@ -1,36 +1,14 @@
-MBEDTLS_TEST_PATH:=../../tests/src
-MBEDTLS_TEST_OBJS:=$(patsubst %.c,%.o,$(wildcard ${MBEDTLS_TEST_PATH}/*.c ${MBEDTLS_TEST_PATH}/drivers/*.c))
+MBEDTLS_TEST_PATH:=../../tests
-CFLAGS ?= -O2
-WARNING_CFLAGS ?= -Wall -Wextra
-LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../../tests/include -I../../include -D_FILE_OFFSET_BITS=64
-LOCAL_LDFLAGS = ${MBEDTLS_TEST_OBJS} \
- -L../../library \
- -lmbedtls$(SHARED_SUFFIX) \
- -lmbedx509$(SHARED_SUFFIX) \
- -lmbedcrypto$(SHARED_SUFFIX)
+MBEDTLS_PATH := ../..
+include ../../scripts/common.make
-LOCAL_CFLAGS += $(patsubst -I../%,-I../../%,$(THIRDPARTY_INCLUDES))
-
-ifndef SHARED
-DEP=../../library/libmbedcrypto.a ../../library/libmbedx509.a ../../library/libmbedtls.a
-else
-DEP=../../library/libmbedcrypto.$(DLEXT) ../../library/libmbedx509.$(DLEXT) ../../library/libmbedtls.$(DLEXT)
-endif
-
-
-DLEXT ?= so
-EXEXT=
-SHARED_SUFFIX=
+DEP=${MBEDLIBS}
ifdef FUZZINGENGINE
LOCAL_LDFLAGS += -lFuzzingEngine
endif
-ifdef WINDOWS_BUILD
-LOCAL_LDFLAGS += -lbcrypt
-endif
-
# A test application is built for each suites/test_suite_*.data file.
# Application name is same as .data file's base name and can be
# constructed by stripping path 'suites/' and extension .data.
@@ -45,9 +23,6 @@
all: $(BINARIES)
-$(DEP):
- $(MAKE) -C ../../library
-
C_FILES := $(addsuffix .c,$(APPS))
%.o: %.c
diff --git a/programs/hash/CMakeLists.txt b/programs/hash/CMakeLists.txt
index da98188..fcacf3b 100644
--- a/programs/hash/CMakeLists.txt
+++ b/programs/hash/CMakeLists.txt
@@ -6,7 +6,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/pkey/CMakeLists.txt b/programs/pkey/CMakeLists.txt
index 3ad5643..cd0387a 100644
--- a/programs/pkey/CMakeLists.txt
+++ b/programs/pkey/CMakeLists.txt
@@ -5,7 +5,7 @@
foreach(exe IN LISTS executables_mbedtls)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedtls_target})
+ target_link_libraries(${exe} ${mbedtls_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
@@ -32,7 +32,7 @@
foreach(exe IN LISTS executables_mbedcrypto)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c
index 91bac0e..1ae5651 100644
--- a/programs/pkey/dh_server.c
+++ b/programs/pkey/dh_server.c
@@ -66,7 +66,7 @@
mbedtls_dhm_context dhm;
mbedtls_aes_context aes;
- mbedtls_mpi N, P, Q, D, E;
+ mbedtls_mpi N, P, Q, D, E, dhm_P, dhm_G;
mbedtls_net_init(&listen_fd);
mbedtls_net_init(&client_fd);
@@ -75,8 +75,8 @@
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_mpi_init(&N); mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
- mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
-
+ mbedtls_mpi_init(&D); mbedtls_mpi_init(&E); mbedtls_mpi_init(&dhm_P);
+ mbedtls_mpi_init(&dhm_G);
/*
* 1. Setup the RNG
*/
@@ -141,8 +141,9 @@
goto exit;
}
- if (mbedtls_mpi_read_file(&dhm.MBEDTLS_PRIVATE(P), 16, f) != 0 ||
- mbedtls_mpi_read_file(&dhm.MBEDTLS_PRIVATE(G), 16, f) != 0) {
+ if ((ret = mbedtls_mpi_read_file(&dhm_P, 16, f)) != 0 ||
+ (ret = mbedtls_mpi_read_file(&dhm_G, 16, f)) != 0 ||
+ (ret = mbedtls_dhm_set_group(&dhm, &dhm_P, &dhm_G) != 0)) {
mbedtls_printf(" failed\n ! Invalid DH parameter file\n\n");
fclose(f);
goto exit;
@@ -176,7 +177,7 @@
memset(buf, 0, sizeof(buf));
if ((ret =
- mbedtls_dhm_make_params(&dhm, (int) mbedtls_mpi_size(&dhm.MBEDTLS_PRIVATE(P)), buf, &n,
+ mbedtls_dhm_make_params(&dhm, (int) mbedtls_dhm_get_len(&dhm), buf, &n,
mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) {
mbedtls_printf(" failed\n ! mbedtls_dhm_make_params returned %d\n\n", ret);
goto exit;
@@ -286,7 +287,8 @@
exit:
mbedtls_mpi_free(&N); mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
- mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
+ mbedtls_mpi_free(&D); mbedtls_mpi_free(&E); mbedtls_mpi_free(&dhm_P);
+ mbedtls_mpi_free(&dhm_G);
mbedtls_net_free(&client_fd);
mbedtls_net_free(&listen_fd);
diff --git a/programs/psa/CMakeLists.txt b/programs/psa/CMakeLists.txt
index c8ee626..a8e4b0e 100644
--- a/programs/psa/CMakeLists.txt
+++ b/programs/psa/CMakeLists.txt
@@ -28,7 +28,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/random/CMakeLists.txt b/programs/random/CMakeLists.txt
index e5edf7b..5940395 100644
--- a/programs/random/CMakeLists.txt
+++ b/programs/random/CMakeLists.txt
@@ -5,7 +5,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/ssl/CMakeLists.txt b/programs/ssl/CMakeLists.txt
index 280bbcf..ec2c86f 100644
--- a/programs/ssl/CMakeLists.txt
+++ b/programs/ssl/CMakeLists.txt
@@ -1,4 +1,3 @@
-set(THREADS_USE_PTHREADS_WIN32 true)
find_package(Threads)
set(libs
@@ -39,7 +38,7 @@
endif()
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>
${extra_sources})
- target_link_libraries(${exe} ${libs})
+ target_link_libraries(${exe} ${libs} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
if(exe STREQUAL "ssl_client2" OR exe STREQUAL "ssl_server2")
if(GEN_FILES)
diff --git a/programs/ssl/ssl_test_lib.c b/programs/ssl/ssl_test_lib.c
index 650fbfb..a65332a 100644
--- a/programs/ssl/ssl_test_lib.c
+++ b/programs/ssl/ssl_test_lib.c
@@ -13,7 +13,7 @@
#include "ssl_test_lib.h"
#if defined(MBEDTLS_TEST_HOOKS)
-#include "test/helpers.h"
+#include "test/threading_helpers.h"
#endif
#if !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
@@ -427,7 +427,7 @@
mbedtls_test_mutex_usage_check();
#endif
- if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_SUCCESS) {
+ if (mbedtls_test_get_result() != MBEDTLS_TEST_RESULT_SUCCESS) {
return 1;
}
return 0;
diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt
index 0778731..f91f786 100644
--- a/programs/test/CMakeLists.txt
+++ b/programs/test/CMakeLists.txt
@@ -26,7 +26,7 @@
)
add_executable(cpp_dummy_build "${cpp_dummy_build_cpp}")
target_include_directories(cpp_dummy_build PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
- target_link_libraries(cpp_dummy_build ${mbedcrypto_target})
+ target_link_libraries(cpp_dummy_build ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
endif()
if(USE_SHARED_MBEDTLS_LIBRARY AND
@@ -81,9 +81,9 @@
# This emulates "if ( ... IN_LIST ... )" which becomes available in CMake 3.3
list(FIND executables_libs ${exe} exe_index)
if (${exe_index} GREATER -1)
- target_link_libraries(${exe} ${libs})
+ target_link_libraries(${exe} ${libs} ${CMAKE_THREAD_LIBS_INIT})
else()
- target_link_libraries(${exe} ${mbedcrypto_target})
+ target_link_libraries(${exe} ${mbedcrypto_target} ${CMAKE_THREAD_LIBS_INIT})
endif()
endforeach()
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 6f7f69b..8fa5d62 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -1089,20 +1089,24 @@
mbedtls_dhm_context dhm;
size_t olen;
size_t n;
+ mbedtls_mpi P, G;
+ mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
for (i = 0; (size_t) i < sizeof(dhm_sizes) / sizeof(dhm_sizes[0]); i++) {
mbedtls_dhm_init(&dhm);
- if (mbedtls_mpi_read_binary(&dhm.MBEDTLS_PRIVATE(P), dhm_P[i],
+ if (mbedtls_mpi_read_binary(&P, dhm_P[i],
dhm_P_size[i]) != 0 ||
- mbedtls_mpi_read_binary(&dhm.MBEDTLS_PRIVATE(G), dhm_G[i],
- dhm_G_size[i]) != 0) {
+ mbedtls_mpi_read_binary(&G, dhm_G[i],
+ dhm_G_size[i]) != 0 ||
+ mbedtls_dhm_set_group(&dhm, &P, &G) != 0) {
mbedtls_exit(1);
}
- n = mbedtls_mpi_size(&dhm.MBEDTLS_PRIVATE(P));
+ n = mbedtls_dhm_get_len(&dhm);
mbedtls_dhm_make_public(&dhm, (int) n, buf, n, myrand, NULL);
- if (mbedtls_mpi_copy(&dhm.MBEDTLS_PRIVATE(GY), &dhm.MBEDTLS_PRIVATE(GX)) != 0) {
+
+ if (mbedtls_dhm_read_public(&dhm, buf, n) != 0) {
mbedtls_exit(1);
}
@@ -1119,6 +1123,7 @@
mbedtls_dhm_calc_secret(&dhm, buf, sizeof(buf), &olen, myrand, NULL));
mbedtls_dhm_free(&dhm);
+ mbedtls_mpi_free(&P), mbedtls_mpi_free(&G);
}
}
#endif
diff --git a/programs/test/cmake_subproject/CMakeLists.txt b/programs/test/cmake_subproject/CMakeLists.txt
index 3c3cba3..78bd5e7 100644
--- a/programs/test/cmake_subproject/CMakeLists.txt
+++ b/programs/test/cmake_subproject/CMakeLists.txt
@@ -20,4 +20,4 @@
)
add_executable(cmake_subproject cmake_subproject.c)
-target_link_libraries(cmake_subproject ${libs})
+target_link_libraries(cmake_subproject ${libs} ${CMAKE_THREAD_LIBS_INIT})
diff --git a/programs/test/metatest.c b/programs/test/metatest.c
index b8dffa9..8e798cd 100644
--- a/programs/test/metatest.c
+++ b/programs/test/metatest.c
@@ -31,6 +31,7 @@
#include <mbedtls/platform.h>
#include <mbedtls/platform_util.h>
#include "test/helpers.h"
+#include "test/threading_helpers.h"
#include "test/macros.h"
#include <stdio.h>
@@ -343,9 +344,11 @@
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
mbedtls_test_mutex_usage_check();
#endif
+ int result = (int) mbedtls_test_get_result();
+
mbedtls_printf("Running metatest %s... done, result=%d\n",
- argv[1], (int) mbedtls_test_info.result);
- mbedtls_exit(mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SUCCESS ?
+ argv[1], result);
+ mbedtls_exit(result == MBEDTLS_TEST_RESULT_SUCCESS ?
MBEDTLS_EXIT_SUCCESS :
MBEDTLS_EXIT_FAILURE);
}
diff --git a/programs/util/CMakeLists.txt b/programs/util/CMakeLists.txt
index 7fc58cb..cb6bc3d 100644
--- a/programs/util/CMakeLists.txt
+++ b/programs/util/CMakeLists.txt
@@ -9,7 +9,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${libs})
+ target_link_libraries(${exe} ${libs} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/programs/x509/CMakeLists.txt b/programs/x509/CMakeLists.txt
index 5876b8d..43437f0 100644
--- a/programs/x509/CMakeLists.txt
+++ b/programs/x509/CMakeLists.txt
@@ -13,7 +13,7 @@
foreach(exe IN LISTS executables)
add_executable(${exe} ${exe}.c $<TARGET_OBJECTS:mbedtls_test>)
- target_link_libraries(${exe} ${libs})
+ target_link_libraries(${exe} ${libs} ${CMAKE_THREAD_LIBS_INIT})
target_include_directories(${exe} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../tests/include)
endforeach()
diff --git a/scripts/common.make b/scripts/common.make
index 6c95b42..2714bcd 100644
--- a/scripts/common.make
+++ b/scripts/common.make
@@ -1,25 +1,29 @@
# To compile on SunOS: add "-lsocket -lnsl" to LDFLAGS
+ifndef MBEDTLS_PATH
+MBEDTLS_PATH := ..
+endif
+
CFLAGS ?= -O2
WARNING_CFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
WARNING_CXXFLAGS ?= -Wall -Wextra -Wformat=2 -Wno-format-nonliteral
LDFLAGS ?=
-LOCAL_CFLAGS = $(WARNING_CFLAGS) -I$(MBEDTLS_TEST_PATH)/include -I../include -D_FILE_OFFSET_BITS=64
-LOCAL_CXXFLAGS = $(WARNING_CXXFLAGS) -I../include -I../tests/include -D_FILE_OFFSET_BITS=64
+LOCAL_CFLAGS = $(WARNING_CFLAGS) -I$(MBEDTLS_TEST_PATH)/include -I$(MBEDTLS_PATH)/include -D_FILE_OFFSET_BITS=64
+LOCAL_CXXFLAGS = $(WARNING_CXXFLAGS) -I$(MBEDTLS_PATH)/include -I$(MBEDTLS_PATH)/tests/include -D_FILE_OFFSET_BITS=64
LOCAL_LDFLAGS = ${MBEDTLS_TEST_OBJS} \
- -L../library \
+ -L$(MBEDTLS_PATH)/library \
-lmbedtls$(SHARED_SUFFIX) \
-lmbedx509$(SHARED_SUFFIX) \
-lmbedcrypto$(SHARED_SUFFIX)
-include ../3rdparty/Makefile.inc
+include $(MBEDTLS_PATH)/3rdparty/Makefile.inc
LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES)
ifndef SHARED
-MBEDLIBS=../library/libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a
+MBEDLIBS=$(MBEDTLS_PATH)/library/libmbedcrypto.a $(MBEDTLS_PATH)/library/libmbedx509.a $(MBEDTLS_PATH)/library/libmbedtls.a
else
-MBEDLIBS=../library/libmbedcrypto.$(DLEXT) ../library/libmbedx509.$(DLEXT) ../library/libmbedtls.$(DLEXT)
+MBEDLIBS=$(MBEDTLS_PATH)/library/libmbedcrypto.$(DLEXT) $(MBEDTLS_PATH)/library/libmbedx509.$(DLEXT) $(MBEDTLS_PATH)/library/libmbedtls.$(DLEXT)
endif
ifdef DEBUG
@@ -97,7 +101,7 @@
default: all
$(MBEDLIBS):
- $(MAKE) -C ../library
+ $(MAKE) -C $(MBEDTLS_PATH)/library
neat: clean
ifndef WINDOWS
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 68bc57f..70f5bc9 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,5 +1,3 @@
-find_package(Threads)
-
set(libs
${mbedtls_target}
${CMAKE_THREAD_LIBS_INIT}
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index a7035cb..d6df19c 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -1052,6 +1052,30 @@
all_final += rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem
keys_rsa_enc_pkcs8_v2_2048_3des_sha384: rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.der rsa_pkcs8_pbes2_pbkdf2_2048_3des_sha384.pem
+rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der: rsa_pkcs1_2048_clear.pem
+ $(OPENSSL) pkcs8 -topk8 -v2 aes-128-cbc -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
+all_final += rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der
+rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem: rsa_pkcs1_2048_clear.pem
+ $(OPENSSL) pkcs8 -topk8 -v2 aes-128-cbc -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
+all_final += rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem
+keys_rsa_enc_pkcs8_v2_2048_aes128cbc_sha384: rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem
+
+rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der: rsa_pkcs1_2048_clear.pem
+ $(OPENSSL) pkcs8 -topk8 -v2 aes-192-cbc -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
+all_final += rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der
+rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem: rsa_pkcs1_2048_clear.pem
+ $(OPENSSL) pkcs8 -topk8 -v2 aes-192-cbc -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
+all_final += rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem
+keys_rsa_enc_pkcs8_v2_2048_aes192cbc_sha384: rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem
+
+rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der: rsa_pkcs1_2048_clear.pem
+ $(OPENSSL) pkcs8 -topk8 -v2 aes-256-cbc -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
+all_final += rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der
+rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem: rsa_pkcs1_2048_clear.pem
+ $(OPENSSL) pkcs8 -topk8 -v2 aes-256-cbc -v2prf hmacWithSHA384 -inform PEM -in $< -outform PEM -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
+all_final += rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem
+keys_rsa_enc_pkcs8_v2_2048_aes256cbc_sha384: rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem
+
rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der: rsa_pkcs1_2048_clear.pem
$(OPENSSL) pkcs8 -topk8 -v2 des -v2prf hmacWithSHA384 -inform PEM -in $< -outform DER -out $@ -passout "pass:$(keys_rsa_pkcs8_pwd)"
all_final += rsa_pkcs8_pbes2_pbkdf2_2048_des_sha384.der
diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der
new file mode 100644
index 0000000..0051940
--- /dev/null
+++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der
Binary files differ
diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem
new file mode 100644
index 0000000..b99af2c
--- /dev/null
+++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIID4AYf5oXcICAggA
+MAwGCCqGSIb3DQIKBQAwHQYJYIZIAWUDBAECBBCtsq1ZGRGQPDOZ5HWj2WM3BIIE
+0G6XYOdWx+gqDnXbV4/I8o/whdxUKNXi6lhrJHQBnl+qQPSJnDl4lH6/U7LimyeM
+SASN9h2BqOQhLi+FPxw19Vn7IzKkNe4c2S87t27/p9ss8jgbKfEDPJ77uxMb64eA
+WAmDjOr1eL+HM54pIxrWcHKUNrfliffyzcwcTqf99ORj9QeGJ37XuZ7RLMxfoOij
+4v1YVbSVlMX5SM0tI9/Atm3fUG1zVAm3p3SrSAOr9FkVE0wh/aC5f5KnMzurBq8J
+f8zGrCP4AmXiowbsJ+GCpKBqOB2mFpBjWt2cwYPuZzP5VUaXiJyOgOYXvxLF4TpB
++pDhJfs+P0iG1SWssfLOkp7smFWtowFrGn3y5nDHHd3P8/vyEDS02hdJxoLw0MBe
+zD3aVeaISOMqjc43cA27Kp7uvG7814XAXe1MPt7Bm5CGa9k6XtVhMTp6RBKxL2ow
+3U8SjA3PtuLLbNEB8FDGi2MCsoDGfmXdOZqJPJdxSbLWl5/385irsUKQDnDK9xr5
+tYVAjPLK4tkdtBgGB+Yv2bRYjPdqKiNrE2AuuFN8ESqoir0gOWbGgpmdDpVhG1az
+Y/Dyv1JcteXo/s3PsIZOXXDQEK7fdr9o/QWY62KJCIQXPZU7K4g2aWLbMN8pWabt
+3mpBeCeiLz0+miSwHFSfTg/weegogrfeBtSV6zFcBSG0nz73JT1U6U4ecDAsuk23
+nmLnm3t+n3MTZU18WxTiQrq0n5gOr1XoGduGQYBBS/bhFoQoWvVQ+gaCaR1hF4ap
+U5vTjYmdIv6Hq/Gl3sNpH324NVTQ2JIHzdItyaZiTugr89+7YxPxpL9pwJJyztdy
+31l4AvAot9vEJWH6wPC5v66MQrqcJRtdT8BuEJ2RFKkqP0wN66JC7qhtm4v5oVgp
+tblGcP4oWHMqAZuYUbgJYh5sEXMsO2tbp2ckKOR10ev+Yzq8vQ9AYFSOLNkFAIbA
+lxv0DJonU288A8Rei3WYU9PfYiYWK7cP/I40xtxOJe3cQEhQTBJwT6K1sv7Q0HAa
+hs5P2u45XqJh2waqJkeoeri0p20WnSfcWmov0OIMtxWQMT6Yb62v+aKk+nqlurIz
+BmvJvgZJtnhlJW7WfbSF3kDD8WZbmabJ+rfPclx5/Hyh0JfaHSJDa9Vd8518/wp4
+Tcptcq7GC93St7PG6RTg4nZzrguwdzBVeDGB0BjP4xI/tzEkk0MgFGAL6JDa/FLv
+5L8MOjeCLwWO9OtVjt02amc26SMmpEIyzh5f/eXWDBILnZAgbnieqyQm2+KsvQ87
+9aQdLlC4RvO73f+5Ckygf6vrIW/n8HVmHmLv+qeudVgIiYZVz3/GtiFJjuayMr/D
+SgvrzNyRw8SQWn5V0ORy/3u86ZfraIq3falIFJGZDG9rdgYoBNHzhMeOXL+fqqHa
+egvOQbfA4jpmtbWUxeqLqs1bY8T9hGW8lrRm7TofsuxDPOz+VajF/+lqWrvXp6+8
+Vp10Ig42X88TUroWRrOSXUkR45Xjq/XG5M5mbZQqBygWSqQJ9LrTzu9yqhYsqziB
+tnwXVpudK/9GK7OKEshJ0s/HsLFHAFRBPJnVP0cXTEg9EczgGBLLT6wAj5zy0dxz
+Pe8Y46K6wUUHP4Y9IQmJ+i/dBfiaquSNKKdqMU7sT5cd
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der
new file mode 100644
index 0000000..fc1ccb3
--- /dev/null
+++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der
Binary files differ
diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem
new file mode 100644
index 0000000..0a36a71
--- /dev/null
+++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI8i+OtR0wbD0CAggA
+MAwGCCqGSIb3DQIKBQAwHQYJYIZIAWUDBAEWBBBHvOq1294P18bekzyYVp4QBIIE
+0AJnZHjPZcPYKdSNaNfPfc2s+UmTgYeLCun5sd+9KIYyozJ2ljZTijsdp/hItWTu
+DmHrfLTLV8mtL/OFJ83u0rDoHVfSrDLwFMAy/nmbtlLYPFEfU9MQ8s2OtvKuobmI
+b3x7b+MrTlG5ConptsQQw5tl3dza9DZGfHUnO2EzXorytSMLFCGeQskzbN7Y/Sbf
+2+IL5yoifcfPddTbKDyTa77K2516tK2+WTU/VUfv2r5d5SiivZLuMjIYrbneHYoq
+hW30BZozCqJKJ5G2jwNjLUjPirA6qtS0Y1tIb5rRjZ0pSy1X5oIQL2laZLrDo9gP
+/Ud8m1k2nv9Uv9HPM+G4xCMSiJVaptYPyzFQACcSdA/BVUdBC0EwzIj2nbaoAlM0
++sZ2Asbohnds/AsDz+/b6MaMKg9Onoort0zF/HtpSII6+WSmvGOaV2469JEIvZlU
+JIn1YugpDPIe6/B35J9sYfvVNKVsvJntCKxmcz6Nw2VvPKXC3o/bseBqAhLKDMZZ
+Hr3id3O7bN2ng3lKuGofmQeMYnW4zb4coXytdc/XCvf63xE0NsUEBFuRMpc9iocC
+2RMBEzNyE4tnigI61T/zkpwgBic1p/isGoXMdPWl+Z+IAIYgyxOVwO9g78yVW9tp
+1xF9WzJrGHKNT9RLmINyo3jt/wRj8Q+T0EG45cDQcHwpyXdNS614hUCIaeTvQcR9
+8F+f4D8IvL+GJt2EtbqL+D687X/hptNehpFf+uxGiHQfrtOvYS/ArNrewa1ts9nq
+SMAE7Hb7MzFdnhDqRFBa+//H1jvNkDx3qXfb1/MNE8pR6vjcueKKQ0BzlrNX1O2C
+oz0OCMeDfXZhWdYmNjLNcdbonrvq5Z9nOUEdw2lNWELT4lOAmqgA/xBFdQa4glCx
+WS1r6DyjgTdGlPbcGugRuTcYXNx6iikWzoS1369maz+WV9qW7r8kA1Fs7WUiYnOb
+I1E06yQKVANe+t2SQYN2jPK3EsFFOBxG9tlcXbZVxvx9m6XJR7f7YnLPN+b0f1qF
+cT2c5IhK5pKRiZds82lWBnk+eli+qUXILIBbDvBmY4PyPk+kyewAHI1HWBfoSH/3
+aLIV6JPgwjAJKnr0++jUqETID/yGyLHNNy1u4ALyAfbFVU//RGmwAxhrBNPdVVGb
+rBfKL+VL8Hu/m5XWXez0nHKyD8J1i/XO1OutBsXYxEn6Xnu9rJn8F6nJ+XB3zt6K
+QdkUp85t3GM0wyizuPRWJrSVfYyjV41yEBXqe2lgqTT9dpvpgIRtvUeq83e8PD/3
+6qKoeTv+3cppCFZ3vLArGvsvRTcbfc3YEzXxz6gc/1HTzd8UpCnA/9+jepG3IzRL
+1bLs8QVzIBAT/UpuC6QWUdAR/JZMEFLU5FnRh6oXuh2Zys66Ot7LyNhnGlSEPlXI
+polURx0bew+QigBGiH7NpyMgRi9Wh+1HOA/wsAp4X7O+DhaX6vdiDbQoilN1LclU
+TRFShpuaxwRA1ek2Jz3JLn7wCsGaVXrd2v/CgrxofCWzGjR2RWj9hAkV4eoJ3G6A
+x3DhMRrqXc/O3ON9TyhKBZP1g35In5bZmBUv/o+7eYV7KDETxPwsD3A+dCqUJObU
+kyZehu2DsfyZFI98SnecRpb0M0vi6ZZueCykOVec6xkX
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der
new file mode 100644
index 0000000..136cfb9
--- /dev/null
+++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der
Binary files differ
diff --git a/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem
new file mode 100644
index 0000000..da2e90f
--- /dev/null
+++ b/tests/data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem
@@ -0,0 +1,30 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIhWg0Xe90dAcCAggA
+MAwGCCqGSIb3DQIKBQAwHQYJYIZIAWUDBAEqBBCRE60k0URZBki+hlzaxgZgBIIE
+0Hffn1sg3qNNUkFDHdbvU9E3+aaMJKWqDS4bUqGguT7Tz36TPM1drUZSFyWvPgNY
+dXonxu+2h6jzRny0clPyp3kCbJEqgvyj0laKNAfV1fmJRVkIFiCMs0iBLQnyjAJb
+IJ8hGxsnotdvmL3oTvHq0YawPXRXVDC4qeO+PzcDjSZ62E+Bz1bE2/tLif1BKd0k
+QbccsD9pCyF8pauCAxgN2AWWdus3IzH+hWUf4DTT7AhCdYNijY+ZmBgKGkJoJWwl
+aIZrPGJ7tNIDecQt86xLffKifI/b2dO5e3Q1NgNzHM77ncoeLr9nFSlsc2W3qA/A
+gEDcuGj1ujchKK70Phfz50HMfnP3pCqLk8jDI78/TSvHDiblF68hsUbAsvbtHNu6
++AXlDdSU2bcRyQRsjvaf2lMLt+qkUX+P640SKnXIYa1o9dv4+alE4XTZaimmOnao
+DjYm6bTHAYcE//DW/LXt7V+q1KCPqpoHMR140vyjIRN8uEcPXyTka6lU34ypIhUb
+N7ggLrXrCjh3nJo+nCtXOIMf9O9eD9I/0i8dktZFuTRj1sO/z9J/xFxHTdBG/BB5
+1MEmwriRubrw5Ud+uXnRq+lg5rW3n4+5TBvwYq/GLfyj36ojegbE8OdMfJJqCdd4
+zywMXwYiMi76gYAwEL60DWRn+3vud02QwY8hBXfiOPq2kxazvZM5SWy/1bPgStkn
+fG9uzE8n/ABZA0XWuV8hNAcxYlS+0s3IguvvHogQtQMYTTg/D3OODpc0f/+y3O8N
+qI5Iym1SrWpnF8vVFZsMblMDr+tbeCvYQ+HuaTc0L5cpAozoY7iCzuqwDHFrYTzC
+rSZ70V+FQ956m4xkCBu6TrzqzhA8zfDFs3z9LfV62v9zLgUS8uCKSKWxznM0IdiE
+ZnNrwaE1xsO5QN8LfvlO4NVVxN/ATie5tmlLndS4c2ZkswcR3WM6cW1buVaIPsz7
+lU7sbd/I9pWpzd3eZNkVrWpyWxvFQxBUNNC5IXcgRBZsGgVGRw35LBlWXKluKrVi
+Z/FAf23dt3n2S4dtJ+Fd2+YL/YiK0lqtrm+GkSjmMvVQ57PJn8QvW359e4QsxDyN
+wv6iEQDUqZcQ89ggdGdoSFFgBtFACc9iCKsu5AjTJl+Tql/A3FV7SwYDfZwQuT4e
+gc4dZPuSSVd8cttUeFUmtrPCMx2nP7ZDVYFrZyK07eAIL89gv3bYWu8R/wMKNvzr
+g0Ao0+AnfLJg11C8pAhJea1dxwu7g6LSpA+oCZov4RpqUnLKMCpPbypyFhSizZtF
+evDMf+5aUAbe0+ZsCjUT+RftpzYCPV9uGhYhLMIFRP/7FCcHMrDn7CbAektm063U
+EwP2O1rUrMhPWqRztx71cGBloeVPE8Ddwnsorr4M7EXihZcvNsLfz3N9NUopkU3M
+sM2fEAnq2KMyrrwVGRSHvm70gUDpJeFanRBsI9z1Tr4r3utHIIQ+0u9pFPbQln0Q
+4X4U7KbKC4leTYGMPMFOPXihiMTazNcs232stAYUYe6/DmVX/p2dJHvHux5qBGIW
+Rbv7OuwazOsDqNfrqZTesENIGl/KPoNXiolp/YtG3DHQ1vDjEj/XTOVWWkBDXVgP
+ut4Pi20hvFBwvEBtypAgi1VLcad5+dlrEwryewlLLw5h
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/include/test/bignum_helpers.h b/tests/include/test/bignum_helpers.h
index 2f6bf89..a5e49cb 100644
--- a/tests/include/test/bignum_helpers.h
+++ b/tests/include/test/bignum_helpers.h
@@ -77,14 +77,14 @@
*
* - This function guarantees that if \p s begins with '-' then the sign
* bit of the result will be negative, even if the value is 0.
- * When this function encounters such a "negative 0", it
- * increments #mbedtls_test_case_uses_negative_0.
- * - The size of the result is exactly the minimum number of limbs needed
- * to fit the digits in the input. In particular, this function constructs
- * a bignum with 0 limbs for an empty string, and a bignum with leading 0
- * limbs if the string has sufficiently many leading 0 digits.
- * This is important so that the "0 (null)" and "0 (1 limb)" and
- * "leading zeros" test cases do what they claim.
+ * When this function encounters such a "negative 0", it calls
+ * mbedtls_test_increment_case_uses_negative_0().
+ * - The size of the result is exactly the minimum number of limbs needed to fit
+ * the digits in the input. In particular, this function constructs a bignum
+ * with 0 limbs for an empty string, and a bignum with leading 0 limbs if the
+ * string has sufficiently many leading 0 digits. This is important so that
+ * the "0 (null)" and "0 (1 limb)" and "leading zeros" test cases do what they
+ * claim.
*
* \param[out] X The MPI object to populate. It must be initialized.
* \param[in] s The null-terminated hexadecimal string to read from.
@@ -93,14 +93,6 @@
*/
int mbedtls_test_read_mpi(mbedtls_mpi *X, const char *s);
-/** Nonzero if the current test case had an input parsed with
- * mbedtls_test_read_mpi() that is a negative 0 (`"-"`, `"-0"`, `"-00"`, etc.,
- * constructing a result with the sign bit set to -1 and the value being
- * all-limbs-0, which is not a valid representation in #mbedtls_mpi but is
- * tested for robustness).
- */
-extern unsigned mbedtls_test_case_uses_negative_0;
-
#endif /* MBEDTLS_BIGNUM_C */
#endif /* TEST_BIGNUM_HELPERS_H */
diff --git a/tests/include/test/helpers.h b/tests/include/test/helpers.h
index 47d4dcd..d08100f 100644
--- a/tests/include/test/helpers.h
+++ b/tests/include/test/helpers.h
@@ -39,9 +39,10 @@
# endif
#endif
-#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
- defined(MBEDTLS_TEST_HOOKS)
-#define MBEDTLS_TEST_MUTEX_USAGE
+#include "test/threading_helpers.h"
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+#include "mbedtls/threading.h"
#endif
#include "mbedtls/platform.h"
@@ -65,20 +66,128 @@
MBEDTLS_TEST_RESULT_SKIPPED
} mbedtls_test_result_t;
+#define MBEDTLS_TEST_LINE_LENGTH 76
+
typedef struct {
mbedtls_test_result_t result;
const char *test;
const char *filename;
int line_no;
unsigned long step;
- char line1[76];
- char line2[76];
+ char line1[MBEDTLS_TEST_LINE_LENGTH];
+ char line2[MBEDTLS_TEST_LINE_LENGTH];
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
const char *mutex_usage_error;
#endif
+#if defined(MBEDTLS_BIGNUM_C)
+ unsigned case_uses_negative_0;
+#endif
}
mbedtls_test_info_t;
-extern mbedtls_test_info_t mbedtls_test_info;
+
+/**
+ * \brief Get the current test result status
+ *
+ * \return The current test result status
+ */
+mbedtls_test_result_t mbedtls_test_get_result(void);
+
+/**
+ * \brief Get the current test name/description
+ *
+ * \return The current test name/description
+ */
+const char *mbedtls_test_get_test(void);
+
+/**
+ * \brief Get the current test filename
+ *
+ * \return The current test filename
+ */
+const char *mbedtls_get_test_filename(void);
+
+/**
+ * \brief Get the current test file line number (for failure / skip)
+ *
+ * \return The current test file line number (for failure / skip)
+ */
+int mbedtls_test_get_line_no(void);
+
+/**
+ * \brief Increment the current test step.
+ *
+ * \note It is not recommended for multiple threads to call this
+ * function concurrently - whilst it is entirely thread safe,
+ * the order of calls to this function can obviously not be
+ * ensured, so unexpected results may occur.
+ */
+void mbedtls_test_increment_step(void);
+
+/**
+ * \brief Get the current test step
+ *
+ * \return The current test step
+ */
+unsigned long mbedtls_test_get_step(void);
+
+/**
+ * \brief Get the current test line buffer 1
+ *
+ * \param line Buffer of minimum size \c MBEDTLS_TEST_LINE_LENGTH,
+ * which will have line buffer 1 copied to it.
+ */
+void mbedtls_test_get_line1(char *line);
+
+/**
+ * \brief Get the current test line buffer 2
+ *
+ * \param line Buffer of minimum size \c MBEDTLS_TEST_LINE_LENGTH,
+ * which will have line buffer 1 copied to it.
+ */
+void mbedtls_test_get_line2(char *line);
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+/**
+ * \brief Get the current mutex usage error message
+ *
+ * \return The current mutex error message (may be NULL if no error)
+ */
+const char *mbedtls_test_get_mutex_usage_error(void);
+
+/**
+ * \brief Set the current mutex usage error message
+ *
+ * \note This will only set the mutex error message if one has not
+ * already been set, or if we are clearing the message (msg is
+ * NULL)
+ *
+ * \param msg Error message to set (can be NULL to clear)
+ */
+void mbedtls_test_set_mutex_usage_error(const char *msg);
+#endif
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/**
+ * \brief Get whether the current test is a bignum test that uses
+ * negative zero.
+ *
+ * \return non zero if the current test uses bignum negative zero.
+ */
+unsigned mbedtls_test_get_case_uses_negative_0(void);
+
+/**
+ * \brief Indicate that the current test uses bignum negative zero.
+ *
+ * \note This function is called if the current test case had an
+ * input parsed with mbedtls_test_read_mpi() that is a negative
+ * 0 (`"-"`, `"-0"`, `"-00"`, etc., constructing a result with
+ * the sign bit set to -1 and the value being all-limbs-0,
+ * which is not a valid representation in #mbedtls_mpi but is
+ * tested for robustness). *
+ */
+void mbedtls_test_increment_case_uses_negative_0(void);
+#endif
int mbedtls_test_platform_setup(void);
void mbedtls_test_platform_teardown(void);
@@ -115,24 +224,42 @@
void mbedtls_test_skip(const char *test, int line_no, const char *filename);
/**
- * \brief Set the test step number for failure reports.
+ * \brief Set the test step number for failure reports.
*
- * Call this function to display "step NNN" in addition to the
- * line number and file name if a test fails. Typically the "step
- * number" is the index of a for loop but it can be whatever you
- * want.
+ * Call this function to display "step NNN" in addition to the
+ * line number and file name if a test fails. Typically the
+ * "step number" is the index of a for loop but it can be
+ * whatever you want.
+ *
+ * \note It is not recommended for multiple threads to call this
+ * function concurrently - whilst it is entirely thread safe,
+ * the order of calls to this function can obviously not be
+ * ensured, so unexpected results may occur.
*
* \param step The step number to report.
*/
void mbedtls_test_set_step(unsigned long step);
/**
- * \brief Reset mbedtls_test_info to a ready/starting state.
+ * \brief Reset mbedtls_test_info to a ready/starting state.
*/
void mbedtls_test_info_reset(void);
+#ifdef MBEDTLS_TEST_MUTEX_USAGE
/**
- * \brief Record the current test case as a failure if two integers
+ * \brief Get the test info data mutex.
+ *
+ * \note This is designed only to be used by threading_helpers to
+ * avoid a deadlock, not for general access to this mutex.
+ *
+ * \return The test info data mutex.
+ */
+mbedtls_threading_mutex_t *mbedtls_test_get_info_mutex(void);
+
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
+
+/**
+ * \brief Record the current test case as a failure if two integers
* have a different value.
*
* This function is usually called via the macro
@@ -258,24 +385,6 @@
#include "test/fake_external_rng_for_test.h"
#endif
-#if defined(MBEDTLS_TEST_MUTEX_USAGE)
-/**
- * Activate the mutex usage verification framework. See threading_helpers.c for
- * information.
- * */
-void mbedtls_test_mutex_usage_init(void);
-
-/**
- * Deactivate the mutex usage verification framework. See threading_helpers.c
- * for information.
- */
-void mbedtls_test_mutex_usage_end(void);
-
-/** Call this function after executing a test case to check for mutex usage
- * errors. */
-void mbedtls_test_mutex_usage_check(void);
-#endif /* MBEDTLS_TEST_MUTEX_USAGE */
-
#if defined(MBEDTLS_TEST_HOOKS)
/**
* \brief Check that only a pure high-level error code is being combined with
diff --git a/tests/include/test/threading_helpers.h b/tests/include/test/threading_helpers.h
new file mode 100644
index 0000000..79bc6c0
--- /dev/null
+++ b/tests/include/test/threading_helpers.h
@@ -0,0 +1,112 @@
+/**
+ * \file threading_helpers.h
+ *
+ * \brief This file contains the prototypes of helper functions for the purpose
+ * of testing threading.
+ */
+
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+ */
+
+#ifndef THREADING_HELPERS_H
+#define THREADING_HELPERS_H
+
+#if defined MBEDTLS_THREADING_C
+
+#include "mbedtls/private_access.h"
+#include "mbedtls/build_info.h"
+
+/* Most fields of publicly available structs are private and are wrapped with
+ * MBEDTLS_PRIVATE macro. This define allows tests to access the private fields
+ * directly (without using the MBEDTLS_PRIVATE wrapper). */
+#define MBEDTLS_ALLOW_PRIVATE_ACCESS
+
+#define MBEDTLS_ERR_THREADING_THREAD_ERROR -0x001F
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+#include <pthread.h>
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
+#if defined(MBEDTLS_THREADING_ALT)
+/* You should define the mbedtls_test_thread_t type in your header */
+#include "threading_alt.h"
+
+/**
+ * \brief Set your alternate threading implementation
+ * function pointers for test threads. If used, this
+ * function must be called once in the main thread
+ * before any other MbedTLS function is called.
+ *
+ * \note These functions are part of the testing API only and
+ * thus not considered part of the public API of
+ * MbedTLS and thus may change without notice.
+ *
+ * \param thread_create The thread create function implementation.
+ * \param thread_join The thread join function implementation.
+
+ */
+void mbedtls_test_thread_set_alt(int (*thread_create)(mbedtls_test_thread_t *thread,
+ void *(*thread_func)(
+ void *),
+ void *thread_data),
+ int (*thread_join)(mbedtls_test_thread_t *thread));
+
+#else /* MBEDTLS_THREADING_ALT*/
+
+typedef struct mbedtls_test_thread_t {
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+ pthread_t MBEDTLS_PRIVATE(thread);
+#else /* MBEDTLS_THREADING_PTHREAD */
+ /* Make sure this struct is always non-empty */
+ unsigned dummy;
+#endif
+
+} mbedtls_test_thread_t;
+
+#endif /* MBEDTLS_THREADING_ALT*/
+
+/**
+ * \brief The function pointers for thread create and thread
+ * join.
+ *
+ * \note These functions are part of the testing API only
+ * and thus not considered part of the public API of
+ * MbedTLS and thus may change without notice.
+ *
+ * \note All these functions are expected to work or
+ * the result will be undefined.
+ */
+extern int (*mbedtls_test_thread_create)(mbedtls_test_thread_t *thread,
+ void *(*thread_func)(void *), void *thread_data);
+extern int (*mbedtls_test_thread_join)(mbedtls_test_thread_t *thread);
+
+#if defined(MBEDTLS_THREADING_PTHREAD) && defined(MBEDTLS_TEST_HOOKS)
+#define MBEDTLS_TEST_MUTEX_USAGE
+#endif
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+/**
+ * Activate the mutex usage verification framework. See threading_helpers.c for
+ * information.
+ */
+void mbedtls_test_mutex_usage_init(void);
+
+/**
+ * Deactivate the mutex usage verification framework. See threading_helpers.c
+ * for information.
+ */
+void mbedtls_test_mutex_usage_end(void);
+
+/**
+ * Call this function after executing a test case to check for mutex usage
+ * errors.
+ */
+void mbedtls_test_mutex_usage_check(void);
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
+
+#endif /* MBEDTLS_THREADING_C */
+
+#endif /* THREADING_HELPERS_H */
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index d73a028..af32c06 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1079,8 +1079,8 @@
echo "!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH" >> $expected
# No PSA equivalent - used to skip decryption tests in PSA-ECB, CBC/XTS/NIST_KW/DES
echo "!MBEDTLS_BLOCK_CIPHER_NO_DECRYPT" >> $expected
- # This is used by import_rsa_made_up() in test_suite_psa_crypto in order
- # to build a fake RSA key of the wanted size based on
+ # MBEDTLS_ASN1_WRITE_C is used by import_rsa_made_up() in test_suite_psa_crypto
+ # in order to build a fake RSA key of the wanted size based on
# PSA_VENDOR_RSA_MAX_KEY_BITS. The legacy module is only used by
# the test code and that's probably the most convenient way of achieving
# the test's goal.
@@ -1089,9 +1089,6 @@
echo "MBEDTLS_ECP_RESTARTABLE" >> $expected
# No PSA equivalent - needed by some init tests
echo "MBEDTLS_ENTROPY_NV_SEED" >> $expected
- # Used by two tests that are about an extension to the PSA standard;
- # as such, no PSA equivalent.
- echo "MBEDTLS_PEM_PARSE_C" >> $expected
# Compare reality with expectation.
# We want an exact match, to ensure the above list remains up-to-date.
@@ -2795,12 +2792,6 @@
scripts/config.py unset MBEDTLS_PK_C
scripts/config.py unset MBEDTLS_PK_PARSE_C
scripts/config.py unset MBEDTLS_PK_WRITE_C
- # We need to disable RSA too or PK will be re-enabled.
- scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_KEY_TYPE_RSA_[0-9A-Z_a-z]*"
- scripts/config.py -f "$CRYPTO_CONFIG_H" unset-all "PSA_WANT_ALG_RSA_[0-9A-Z_a-z]*"
- scripts/config.py unset MBEDTLS_RSA_C
- scripts/config.py unset MBEDTLS_PKCS1_V15
- scripts/config.py unset MBEDTLS_PKCS1_V21
# Disable modules that are accelerated - some will be re-enabled
scripts/config.py unset MBEDTLS_ECDSA_C
diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py
index 6503f9a..8c7f21f 100755
--- a/tests/scripts/analyze_outcomes.py
+++ b/tests/scripts/analyze_outcomes.py
@@ -562,6 +562,11 @@
# but these are not available in the accelerated component.
re.compile('Set( non-existent)? padding with (AES|CAMELLIA).*'),
],
+ 'test_suite_pkcs5': [
+ # The AES part of PKCS#5 PBES2 is not yet supported.
+ # The rest of PKCS#5 (PBKDF2) works, though.
+ re.compile(r'PBES2 .* AES-.*')
+ ],
'test_suite_pkparse': [
# PEM (called by pkparse) requires AES_C in order to decrypt
# the key, but this is not available in the accelerated
diff --git a/tests/scripts/test_psa_compliance.py b/tests/scripts/test_psa_compliance.py
index 0d56ddf..8d70cbc 100755
--- a/tests/scripts/test_psa_compliance.py
+++ b/tests/scripts/test_psa_compliance.py
@@ -27,22 +27,10 @@
# The test numbers correspond to the numbers used by the console output of the test suite.
# Test number 2xx corresponds to the files in the folder
# psa-arch-tests/api-tests/dev_apis/crypto/test_c0xx
-EXPECTED_FAILURES = {
- # psa_hash_suspend() and psa_hash_resume() are not supported.
- # - Tracked in issue #3274
- 262, 263
-}
+EXPECTED_FAILURES = {} # type: dict
-# We currently use a fork of ARM-software/psa-arch-tests, with a couple of downstream patches
-# that allow it to build with Mbed TLS 3, and fixes a couple of issues in the compliance test suite.
-# These fixes allow the tests numbered 216, 248 and 249 to complete successfully.
-#
-# Once all the fixes are upstreamed, this fork should be replaced with an upstream commit/tag.
-# - Tracked in issue #5145
-#
-# Web URL: https://github.com/bensze01/psa-arch-tests/tree/fixes-for-mbedtls-3
-PSA_ARCH_TESTS_REPO = 'https://github.com/bensze01/psa-arch-tests.git'
-PSA_ARCH_TESTS_REF = 'fix-pr-5736'
+PSA_ARCH_TESTS_REPO = 'https://github.com/ARM-software/psa-arch-tests.git'
+PSA_ARCH_TESTS_REF = 'v23.06_API1.5_ADAC_EAC'
#pylint: disable=too-many-branches,too-many-statements,too-many-locals
def main(library_build_dir: str):
diff --git a/tests/src/bignum_helpers.c b/tests/src/bignum_helpers.c
index c85e2ca..913f5e3 100644
--- a/tests/src/bignum_helpers.c
+++ b/tests/src/bignum_helpers.c
@@ -135,7 +135,7 @@
}
if (negative) {
if (mbedtls_mpi_cmp_int(X, 0) == 0) {
- ++mbedtls_test_case_uses_negative_0;
+ mbedtls_test_increment_case_uses_negative_0();
}
X->s = -1;
}
diff --git a/tests/src/helpers.c b/tests/src/helpers.c
index eb28919..da0b54a 100644
--- a/tests/src/helpers.c
+++ b/tests/src/helpers.c
@@ -13,6 +13,10 @@
#include <test/psa_crypto_helpers.h>
#endif
+#if defined(MBEDTLS_THREADING_C)
+#include "mbedtls/threading.h"
+#endif
+
/*----------------------------------------------------------------------------*/
/* Static global variables */
@@ -20,7 +24,267 @@
static mbedtls_platform_context platform_ctx;
#endif
-mbedtls_test_info_t mbedtls_test_info;
+static mbedtls_test_info_t mbedtls_test_info;
+
+#ifdef MBEDTLS_THREADING_C
+mbedtls_threading_mutex_t mbedtls_test_info_mutex;
+#endif /* MBEDTLS_THREADING_C */
+
+/*----------------------------------------------------------------------------*/
+/* Mbedtls Test Info accessors */
+
+mbedtls_test_result_t mbedtls_test_get_result(void)
+{
+ mbedtls_test_result_t result;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ result = mbedtls_test_info.result;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ return result;
+}
+
+void mbedtls_test_set_result(mbedtls_test_result_t result, const char *test,
+ int line_no, const char *filename)
+{
+ /* Internal function only - mbedtls_test_info_mutex should be held prior
+ * to calling this function. */
+
+ mbedtls_test_info.result = result;
+ mbedtls_test_info.test = test;
+ mbedtls_test_info.line_no = line_no;
+ mbedtls_test_info.filename = filename;
+}
+
+const char *mbedtls_test_get_test(void)
+{
+ const char *test;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ test = mbedtls_test_info.test;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ return test;
+}
+const char *mbedtls_get_test_filename(void)
+{
+ const char *filename;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ /* It should be ok just to pass back the pointer here, as it is going to
+ * be a pointer into non changing data. */
+ filename = mbedtls_test_info.filename;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ return filename;
+}
+
+int mbedtls_test_get_line_no(void)
+{
+ int line_no;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ line_no = mbedtls_test_info.line_no;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ return line_no;
+}
+
+void mbedtls_test_increment_step(void)
+{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ ++mbedtls_test_info.step;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
+
+unsigned long mbedtls_test_get_step(void)
+{
+ unsigned long step;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ step = mbedtls_test_info.step;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ return step;
+}
+
+void mbedtls_test_reset_step(void)
+{
+ /* Internal function only - mbedtls_test_info_mutex should be held prior
+ * to calling this function. */
+
+ mbedtls_test_info.step = (unsigned long) (-1);
+}
+
+void mbedtls_test_set_step(unsigned long step)
+{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ mbedtls_test_info.step = step;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
+
+void mbedtls_test_get_line1(char *line)
+{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ memcpy(line, mbedtls_test_info.line1, MBEDTLS_TEST_LINE_LENGTH);
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
+
+void mbedtls_test_set_line1(const char *line)
+{
+ /* Internal function only - mbedtls_test_info_mutex should be held prior
+ * to calling this function. */
+
+ if (line == NULL) {
+ memset(mbedtls_test_info.line1, 0, MBEDTLS_TEST_LINE_LENGTH);
+ } else {
+ memcpy(mbedtls_test_info.line1, line, MBEDTLS_TEST_LINE_LENGTH);
+ }
+}
+
+void mbedtls_test_get_line2(char *line)
+{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ memcpy(line, mbedtls_test_info.line2, MBEDTLS_TEST_LINE_LENGTH);
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
+
+void mbedtls_test_set_line2(const char *line)
+{
+ /* Internal function only - mbedtls_test_info_mutex should be held prior
+ * to calling this function. */
+
+ if (line == NULL) {
+ memset(mbedtls_test_info.line2, 0, MBEDTLS_TEST_LINE_LENGTH);
+ } else {
+ memcpy(mbedtls_test_info.line2, line, MBEDTLS_TEST_LINE_LENGTH);
+ }
+}
+
+
+#if defined(MBEDTLS_TEST_MUTEX_USAGE)
+const char *mbedtls_test_get_mutex_usage_error(void)
+{
+ return mbedtls_test_info.mutex_usage_error;
+}
+
+void mbedtls_test_set_mutex_usage_error(const char *msg)
+{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ if (mbedtls_test_info.mutex_usage_error == NULL || msg == NULL) {
+ mbedtls_test_info.mutex_usage_error = msg;
+ }
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
+#endif // #if defined(MBEDTLS_TEST_MUTEX_USAGE)
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+unsigned mbedtls_test_get_case_uses_negative_0(void)
+{
+ unsigned test_case_uses_negative_0 = 0;
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+ test_case_uses_negative_0 = mbedtls_test_info.case_uses_negative_0;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ return test_case_uses_negative_0;
+}
+
+void mbedtls_test_set_case_uses_negative_0(unsigned uses)
+{
+ /* Internal function only - mbedtls_test_info_mutex should be held prior
+ * to calling this function. */
+
+ mbedtls_test_info.case_uses_negative_0 = uses;
+}
+
+void mbedtls_test_increment_case_uses_negative_0(void)
+{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ ++mbedtls_test_info.case_uses_negative_0;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#ifdef MBEDTLS_TEST_MUTEX_USAGE
+mbedtls_threading_mutex_t *mbedtls_test_get_info_mutex(void)
+{
+ return &mbedtls_test_info_mutex;
+}
+
+#endif /* MBEDTLS_TEST_MUTEX_USAGE */
/*----------------------------------------------------------------------------*/
/* Helper Functions */
@@ -44,11 +308,19 @@
ret = mbedtls_platform_setup(&platform_ctx);
#endif /* MBEDTLS_PLATFORM_C */
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_init(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
return ret;
}
void mbedtls_test_platform_teardown(void)
{
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_free(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
#if defined(MBEDTLS_PLATFORM_C)
mbedtls_platform_teardown(&platform_ctx);
#endif /* MBEDTLS_PLATFORM_C */
@@ -71,46 +343,53 @@
void mbedtls_test_fail(const char *test, int line_no, const char *filename)
{
- if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED) {
- /* We've already recorded the test as having failed. Don't
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ /* Don't use accessor, we already hold mutex. */
+ if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
+ /* If we have already recorded the test as having failed then don't
* overwrite any previous information about the failure. */
- return;
+ mbedtls_test_set_result(MBEDTLS_TEST_RESULT_FAILED, test, line_no, filename);
}
- mbedtls_test_info.result = MBEDTLS_TEST_RESULT_FAILED;
- mbedtls_test_info.test = test;
- mbedtls_test_info.line_no = line_no;
- mbedtls_test_info.filename = filename;
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
}
void mbedtls_test_skip(const char *test, int line_no, const char *filename)
{
- mbedtls_test_info.result = MBEDTLS_TEST_RESULT_SKIPPED;
- mbedtls_test_info.test = test;
- mbedtls_test_info.line_no = line_no;
- mbedtls_test_info.filename = filename;
-}
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
-void mbedtls_test_set_step(unsigned long step)
-{
- mbedtls_test_info.step = step;
-}
+ mbedtls_test_set_result(MBEDTLS_TEST_RESULT_SKIPPED, test, line_no, filename);
-#if defined(MBEDTLS_BIGNUM_C)
-unsigned mbedtls_test_case_uses_negative_0 = 0;
-#endif
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+}
void mbedtls_test_info_reset(void)
{
- mbedtls_test_info.result = MBEDTLS_TEST_RESULT_SUCCESS;
- mbedtls_test_info.step = (unsigned long) (-1);
- mbedtls_test_info.test = 0;
- mbedtls_test_info.line_no = 0;
- mbedtls_test_info.filename = 0;
- memset(mbedtls_test_info.line1, 0, sizeof(mbedtls_test_info.line1));
- memset(mbedtls_test_info.line2, 0, sizeof(mbedtls_test_info.line2));
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ mbedtls_test_set_result(MBEDTLS_TEST_RESULT_SUCCESS, 0, 0, 0);
+ mbedtls_test_reset_step();
+ mbedtls_test_set_line1(NULL);
+ mbedtls_test_set_line2(NULL);
+
#if defined(MBEDTLS_BIGNUM_C)
- mbedtls_test_case_uses_negative_0 = 0;
+ mbedtls_test_set_case_uses_negative_0(0);
#endif
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
}
int mbedtls_test_equal(const char *test, int line_no, const char *filename,
@@ -123,20 +402,31 @@
return 1;
}
- if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED) {
- /* We've already recorded the test as having failed. Don't
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ /* Don't use accessor, as we already hold mutex. */
+ if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
+ /* If we've already recorded the test as having failed then don't
* overwrite any previous information about the failure. */
- return 0;
+
+ char buf[MBEDTLS_TEST_LINE_LENGTH];
+ mbedtls_test_fail(test, line_no, filename);
+ (void) mbedtls_snprintf(buf, sizeof(buf),
+ "lhs = 0x%016llx = %lld",
+ value1, (long long) value1);
+ mbedtls_test_set_line1(buf);
+ (void) mbedtls_snprintf(buf, sizeof(buf),
+ "rhs = 0x%016llx = %lld",
+ value2, (long long) value2);
+ mbedtls_test_set_line2(buf);
}
- mbedtls_test_fail(test, line_no, filename);
- (void) mbedtls_snprintf(mbedtls_test_info.line1,
- sizeof(mbedtls_test_info.line1),
- "lhs = 0x%016llx = %lld",
- value1, (long long) value1);
- (void) mbedtls_snprintf(mbedtls_test_info.line2,
- sizeof(mbedtls_test_info.line2),
- "rhs = 0x%016llx = %lld",
- value2, (long long) value2);
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
return 0;
}
@@ -150,20 +440,31 @@
return 1;
}
- if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED) {
- /* We've already recorded the test as having failed. Don't
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ /* Don't use accessor, we already hold mutex. */
+ if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
+ /* If we've already recorded the test as having failed then don't
* overwrite any previous information about the failure. */
- return 0;
+
+ char buf[MBEDTLS_TEST_LINE_LENGTH];
+ mbedtls_test_fail(test, line_no, filename);
+ (void) mbedtls_snprintf(buf, sizeof(buf),
+ "lhs = 0x%016llx = %llu",
+ value1, value1);
+ mbedtls_test_set_line1(buf);
+ (void) mbedtls_snprintf(buf, sizeof(buf),
+ "rhs = 0x%016llx = %llu",
+ value2, value2);
+ mbedtls_test_set_line2(buf);
}
- mbedtls_test_fail(test, line_no, filename);
- (void) mbedtls_snprintf(mbedtls_test_info.line1,
- sizeof(mbedtls_test_info.line1),
- "lhs = 0x%016llx = %llu",
- value1, value1);
- (void) mbedtls_snprintf(mbedtls_test_info.line2,
- sizeof(mbedtls_test_info.line2),
- "rhs = 0x%016llx = %llu",
- value2, value2);
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
return 0;
}
@@ -177,20 +478,31 @@
return 1;
}
- if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED) {
- /* We've already recorded the test as having failed. Don't
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_lock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
+ /* Don't use accessor, we already hold mutex. */
+ if (mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
+ /* If we've already recorded the test as having failed then don't
* overwrite any previous information about the failure. */
- return 0;
+
+ char buf[MBEDTLS_TEST_LINE_LENGTH];
+ mbedtls_test_fail(test, line_no, filename);
+ (void) mbedtls_snprintf(buf, sizeof(buf),
+ "lhs = 0x%016llx = %lld",
+ (unsigned long long) value1, value1);
+ mbedtls_test_set_line1(buf);
+ (void) mbedtls_snprintf(buf, sizeof(buf),
+ "rhs = 0x%016llx = %lld",
+ (unsigned long long) value2, value2);
+ mbedtls_test_set_line2(buf);
}
- mbedtls_test_fail(test, line_no, filename);
- (void) mbedtls_snprintf(mbedtls_test_info.line1,
- sizeof(mbedtls_test_info.line1),
- "lhs = 0x%016llx = %lld",
- (unsigned long long) value1, value1);
- (void) mbedtls_snprintf(mbedtls_test_info.line2,
- sizeof(mbedtls_test_info.line2),
- "rhs = 0x%016llx = %lld",
- (unsigned long long) value2, value2);
+
+#ifdef MBEDTLS_THREADING_C
+ mbedtls_mutex_unlock(&mbedtls_test_info_mutex);
+#endif /* MBEDTLS_THREADING_C */
+
return 0;
}
diff --git a/tests/src/threading_helpers.c b/tests/src/threading_helpers.c
index 5fbf65b..ff0c712 100644
--- a/tests/src/threading_helpers.c
+++ b/tests/src/threading_helpers.c
@@ -6,8 +6,74 @@
*/
#include <test/helpers.h>
+#include <test/threading_helpers.h>
#include <test/macros.h>
+#include "mbedtls/threading.h"
+
+#if defined(MBEDTLS_THREADING_C)
+
+#if defined(MBEDTLS_THREADING_PTHREAD)
+
+static int threading_thread_create_pthread(mbedtls_test_thread_t *thread, void *(*thread_func)(
+ void *), void *thread_data)
+{
+ if (thread == NULL || thread_func == NULL) {
+ return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
+ }
+
+ if (pthread_create(&thread->thread, NULL, thread_func, thread_data)) {
+ return MBEDTLS_ERR_THREADING_THREAD_ERROR;
+ }
+
+ return 0;
+}
+
+static int threading_thread_join_pthread(mbedtls_test_thread_t *thread)
+{
+ if (thread == NULL) {
+ return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
+ }
+
+ if (pthread_join(thread->thread, NULL) != 0) {
+ return MBEDTLS_ERR_THREADING_THREAD_ERROR;
+ }
+
+ return 0;
+}
+
+int (*mbedtls_test_thread_create)(mbedtls_test_thread_t *thread, void *(*thread_func)(void *),
+ void *thread_data) = threading_thread_create_pthread;
+int (*mbedtls_test_thread_join)(mbedtls_test_thread_t *thread) = threading_thread_join_pthread;
+
+#endif /* MBEDTLS_THREADING_PTHREAD */
+
+#if defined(MBEDTLS_THREADING_ALT)
+
+static int threading_thread_create_fail(mbedtls_test_thread_t *thread,
+ void *(*thread_func)(void *),
+ void *thread_data)
+{
+ (void) thread;
+ (void) thread_func;
+ (void) thread_data;
+
+ return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
+}
+
+static int threading_thread_join_fail(mbedtls_test_thread_t *thread)
+{
+ (void) thread;
+
+ return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
+}
+
+int (*mbedtls_test_thread_create)(mbedtls_test_thread_t *thread, void *(*thread_func)(void *),
+ void *thread_data) = threading_thread_create_fail;
+int (*mbedtls_test_thread_join)(mbedtls_test_thread_t *thread) = threading_thread_join_fail;
+
+#endif /* MBEDTLS_THREADING_ALT */
+
#if defined(MBEDTLS_TEST_MUTEX_USAGE)
#include "mbedtls/threading.h"
@@ -109,9 +175,7 @@
{
(void) mutex;
- if (mbedtls_test_info.mutex_usage_error == NULL) {
- mbedtls_test_info.mutex_usage_error = msg;
- }
+ mbedtls_test_set_mutex_usage_error(msg);
mbedtls_fprintf(stdout, "[mutex: %s] ", msg);
/* Don't mark the test as failed yet. This way, if the test fails later
* for a functional reason, the test framework will report the message
@@ -119,40 +183,60 @@
* mbedtls_test_mutex_usage_check() will mark it as failed. */
}
+static int mbedtls_test_mutex_can_test(mbedtls_threading_mutex_t *mutex)
+{
+ /* If we attempt to run tests on this mutex then we are going to run into a
+ * couple of problems:
+ * 1. If any test on this mutex fails, we are going to deadlock when
+ * reporting that failure, as we already hold the mutex at that point.
+ * 2. Given the 'global' position of the initialization and free of this
+ * mutex, it will be shown as leaked on the first test run. */
+ if (mutex == mbedtls_test_get_info_mutex()) {
+ return 0;
+ }
+
+ return 1;
+}
+
static void mbedtls_test_wrap_mutex_init(mbedtls_threading_mutex_t *mutex)
{
mutex_functions.init(mutex);
- if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
- mutex->state = MUTEX_IDLE;
- ++live_mutexes;
+ if (mbedtls_test_mutex_can_test(mutex)) {
+ if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+ mutex->state = MUTEX_IDLE;
+ ++live_mutexes;
- mutex_functions.unlock(&mbedtls_test_mutex_mutex);
+ mutex_functions.unlock(&mbedtls_test_mutex_mutex);
+ }
}
}
static void mbedtls_test_wrap_mutex_free(mbedtls_threading_mutex_t *mutex)
{
- if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+ if (mbedtls_test_mutex_can_test(mutex)) {
+ if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
- switch (mutex->state) {
- case MUTEX_FREED:
- mbedtls_test_mutex_usage_error(mutex, "free without init or double free");
- break;
- case MUTEX_IDLE:
- mutex->state = MUTEX_FREED;
- --live_mutexes;
- break;
- case MUTEX_LOCKED:
- mbedtls_test_mutex_usage_error(mutex, "free without unlock");
- break;
- default:
- mbedtls_test_mutex_usage_error(mutex, "corrupted state");
- break;
+ switch (mutex->state) {
+ case MUTEX_FREED:
+ mbedtls_test_mutex_usage_error(mutex, "free without init or double free");
+ break;
+ case MUTEX_IDLE:
+ mutex->state = MUTEX_FREED;
+ --live_mutexes;
+ break;
+ case MUTEX_LOCKED:
+ mbedtls_test_mutex_usage_error(mutex, "free without unlock");
+ break;
+ default:
+ mbedtls_test_mutex_usage_error(mutex, "corrupted state");
+ break;
+ }
+
+ mutex_functions.unlock(&mbedtls_test_mutex_mutex);
}
-
- mutex_functions.unlock(&mbedtls_test_mutex_mutex);
}
+
mutex_functions.free(mutex);
}
@@ -162,26 +246,30 @@
* is to hold the passed in and internal mutex - otherwise we create a race
* condition. */
int ret = mutex_functions.lock(mutex);
- if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
- switch (mutex->state) {
- case MUTEX_FREED:
- mbedtls_test_mutex_usage_error(mutex, "lock without init");
- break;
- case MUTEX_IDLE:
- if (ret == 0) {
- mutex->state = MUTEX_LOCKED;
- }
- break;
- case MUTEX_LOCKED:
- mbedtls_test_mutex_usage_error(mutex, "double lock");
- break;
- default:
- mbedtls_test_mutex_usage_error(mutex, "corrupted state");
- break;
- }
- mutex_functions.unlock(&mbedtls_test_mutex_mutex);
+ if (mbedtls_test_mutex_can_test(mutex)) {
+ if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+ switch (mutex->state) {
+ case MUTEX_FREED:
+ mbedtls_test_mutex_usage_error(mutex, "lock without init");
+ break;
+ case MUTEX_IDLE:
+ if (ret == 0) {
+ mutex->state = MUTEX_LOCKED;
+ }
+ break;
+ case MUTEX_LOCKED:
+ mbedtls_test_mutex_usage_error(mutex, "double lock");
+ break;
+ default:
+ mbedtls_test_mutex_usage_error(mutex, "corrupted state");
+ break;
+ }
+
+ mutex_functions.unlock(&mbedtls_test_mutex_mutex);
+ }
}
+
return ret;
}
@@ -190,23 +278,26 @@
/* Lock the internal mutex first and change state, so that the only way to
* change the state is to hold the passed in and internal mutex - otherwise
* we create a race condition. */
- if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
- switch (mutex->state) {
- case MUTEX_FREED:
- mbedtls_test_mutex_usage_error(mutex, "unlock without init");
- break;
- case MUTEX_IDLE:
- mbedtls_test_mutex_usage_error(mutex, "unlock without lock");
- break;
- case MUTEX_LOCKED:
- mutex->state = MUTEX_IDLE;
- break;
- default:
- mbedtls_test_mutex_usage_error(mutex, "corrupted state");
- break;
+ if (mbedtls_test_mutex_can_test(mutex)) {
+ if (mutex_functions.lock(&mbedtls_test_mutex_mutex) == 0) {
+ switch (mutex->state) {
+ case MUTEX_FREED:
+ mbedtls_test_mutex_usage_error(mutex, "unlock without init");
+ break;
+ case MUTEX_IDLE:
+ mbedtls_test_mutex_usage_error(mutex, "unlock without lock");
+ break;
+ case MUTEX_LOCKED:
+ mutex->state = MUTEX_IDLE;
+ break;
+ default:
+ mbedtls_test_mutex_usage_error(mutex, "corrupted state");
+ break;
+ }
+ mutex_functions.unlock(&mbedtls_test_mutex_mutex);
}
- mutex_functions.unlock(&mbedtls_test_mutex_mutex);
}
+
return mutex_functions.unlock(mutex);
}
@@ -233,17 +324,15 @@
* negative number means a missing init somewhere. */
mbedtls_fprintf(stdout, "[mutex: %d leaked] ", live_mutexes);
live_mutexes = 0;
- if (mbedtls_test_info.mutex_usage_error == NULL) {
- mbedtls_test_info.mutex_usage_error = "missing free";
- }
+ mbedtls_test_set_mutex_usage_error("missing free");
}
- if (mbedtls_test_info.mutex_usage_error != NULL &&
- mbedtls_test_info.result != MBEDTLS_TEST_RESULT_FAILED) {
+ if (mbedtls_test_get_mutex_usage_error() != NULL &&
+ mbedtls_test_get_result() != MBEDTLS_TEST_RESULT_FAILED) {
/* Functionally, the test passed. But there was a mutex usage error,
* so mark the test as failed after all. */
mbedtls_test_fail("Mutex usage error", __LINE__, __FILE__);
}
- mbedtls_test_info.mutex_usage_error = NULL;
+ mbedtls_test_set_mutex_usage_error(NULL);
}
void mbedtls_test_mutex_usage_end(void)
@@ -257,3 +346,5 @@
}
#endif /* MBEDTLS_TEST_MUTEX_USAGE */
+
+#endif /* MBEDTLS_THREADING_C */
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 86ff5b4..b5f5796 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -8,6 +8,7 @@
#include <test/random.h>
#include <test/bignum_helpers.h>
#include <test/psa_crypto_helpers.h>
+#include <test/threading_helpers.h>
#include <errno.h>
#include <limits.h>
diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function
index cc28697..eb42a07 100644
--- a/tests/suites/host_test.function
+++ b/tests/suites/host_test.function
@@ -371,14 +371,12 @@
* \param missing_unmet_dependencies Non-zero if there was a problem tracking
* all unmet dependencies, 0 otherwise.
* \param ret The test dispatch status (DISPATCH_xxx).
- * \param info A pointer to the test info structure.
*/
static void write_outcome_result(FILE *outcome_file,
size_t unmet_dep_count,
int unmet_dependencies[],
int missing_unmet_dependencies,
- int ret,
- const mbedtls_test_info_t *info)
+ int ret)
{
if (outcome_file == NULL) {
return;
@@ -401,7 +399,7 @@
}
break;
}
- switch (info->result) {
+ switch (mbedtls_test_get_result()) {
case MBEDTLS_TEST_RESULT_SUCCESS:
mbedtls_fprintf(outcome_file, "PASS;");
break;
@@ -410,8 +408,9 @@
break;
default:
mbedtls_fprintf(outcome_file, "FAIL;%s:%d:%s",
- info->filename, info->line_no,
- info->test);
+ mbedtls_get_test_filename(),
+ mbedtls_test_get_line_no(),
+ mbedtls_test_get_test());
break;
}
break;
@@ -614,7 +613,7 @@
break;
}
mbedtls_fprintf(stdout, "%s%.66s",
- mbedtls_test_info.result == MBEDTLS_TEST_RESULT_FAILED ?
+ mbedtls_test_get_result() == MBEDTLS_TEST_RESULT_FAILED ?
"\n" : "", buf);
mbedtls_fprintf(stdout, " ");
for (i = strlen(buf) + 1; i < 67; i++) {
@@ -690,7 +689,7 @@
write_outcome_result(outcome_file,
unmet_dep_count, unmet_dependencies,
missing_unmet_dependencies,
- ret, &mbedtls_test_info);
+ ret);
if (unmet_dep_count > 0 || ret == DISPATCH_UNSUPPORTED_SUITE) {
total_skipped++;
mbedtls_fprintf(stdout, "----");
@@ -715,30 +714,33 @@
unmet_dep_count = 0;
missing_unmet_dependencies = 0;
} else if (ret == DISPATCH_TEST_SUCCESS) {
- if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SUCCESS) {
+ if (mbedtls_test_get_result() == MBEDTLS_TEST_RESULT_SUCCESS) {
mbedtls_fprintf(stdout, "PASS\n");
- } else if (mbedtls_test_info.result == MBEDTLS_TEST_RESULT_SKIPPED) {
+ } else if (mbedtls_test_get_result() == MBEDTLS_TEST_RESULT_SKIPPED) {
mbedtls_fprintf(stdout, "----\n");
total_skipped++;
} else {
+ char line_buffer[MBEDTLS_TEST_LINE_LENGTH];
+
total_errors++;
mbedtls_fprintf(stdout, "FAILED\n");
mbedtls_fprintf(stdout, " %s\n at ",
- mbedtls_test_info.test);
- if (mbedtls_test_info.step != (unsigned long) (-1)) {
+ mbedtls_test_get_test());
+ if (mbedtls_test_get_step() != (unsigned long) (-1)) {
mbedtls_fprintf(stdout, "step %lu, ",
- mbedtls_test_info.step);
+ mbedtls_test_get_step());
}
mbedtls_fprintf(stdout, "line %d, %s",
- mbedtls_test_info.line_no,
- mbedtls_test_info.filename);
- if (mbedtls_test_info.line1[0] != 0) {
- mbedtls_fprintf(stdout, "\n %s",
- mbedtls_test_info.line1);
+ mbedtls_test_get_line_no(),
+ mbedtls_get_test_filename());
+
+ mbedtls_test_get_line1(line_buffer);
+ if (line_buffer[0] != 0) {
+ mbedtls_fprintf(stdout, "\n %s", line_buffer);
}
- if (mbedtls_test_info.line2[0] != 0) {
- mbedtls_fprintf(stdout, "\n %s",
- mbedtls_test_info.line2);
+ mbedtls_test_get_line2(line_buffer);
+ if (line_buffer[0] != 0) {
+ mbedtls_fprintf(stdout, "\n %s", line_buffer);
}
}
fflush(stdout);
diff --git a/tests/suites/test_suite_bignum.function b/tests/suites/test_suite_bignum.function
index 2305f48..50be2d2 100644
--- a/tests/suites/test_suite_bignum.function
+++ b/tests/suites/test_suite_bignum.function
@@ -24,7 +24,7 @@
* we sometimes test the robustness of library functions when given
* a negative zero input. If a test case has a negative zero as input,
* we don't mind if the function has a negative zero output. */
- if (!mbedtls_test_case_uses_negative_0 &&
+ if (!mbedtls_test_get_case_uses_negative_0() &&
mbedtls_mpi_bitlen(X) == 0 && X->s != 1) {
return 0;
}
diff --git a/tests/suites/test_suite_ctr_drbg.function b/tests/suites/test_suite_ctr_drbg.function
index 425c43e..720eb3e 100644
--- a/tests/suites/test_suite_ctr_drbg.function
+++ b/tests/suites/test_suite_ctr_drbg.function
@@ -347,19 +347,24 @@
void ctr_drbg_threads(data_t *expected_result, int reseed, int arg_thread_count)
{
size_t thread_count = (size_t) arg_thread_count;
- pthread_t *threads = NULL;
+ mbedtls_test_thread_t *threads = NULL;
unsigned char out[16];
unsigned char *entropy = NULL;
const size_t n_random_calls = thread_count * thread_random_reps + 1;
- /* Based on the size of MBEDTLS_CTR_DRBG_ENTROPY_LEN for SHA512. */
+ /* This is a known-answer test, and although tests use a mock entropy
+ * function the input entropy length will still affect the output.
+ * We therefore need to pick a fixed entropy length, rather than using the
+ * default entropy length (MBEDTLS_CTR_DRBG_ENTROPY_LEN). We've chosen to
+ * use the default value of MBEDTLS_CTR_DRBG_ENTROPY_LEN for SHA-512,
+ * as this was the value used when the expected answers were calculated. */
const size_t entropy_len = 48;
AES_PSA_INIT();
- TEST_CALLOC(threads, sizeof(pthread_t) * thread_count);
+ TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
memset(out, 0, sizeof(out));
mbedtls_ctr_drbg_context ctx;
@@ -367,8 +372,8 @@
test_offset_idx = 0;
- /* Need to do this, otherwise if we are forced into using SHA256 for
- * whaever reason, output will differ. */
+ /* Need to set a non-default fixed entropy len, to ensure same output across
+ * all configs - see above for details. */
mbedtls_ctr_drbg_set_entropy_len(&ctx, entropy_len);
if (reseed == 0) {
@@ -393,13 +398,13 @@
for (size_t i = 0; i < thread_count; i++) {
TEST_EQUAL(
- pthread_create(&threads[i], NULL,
- thread_random_function, (void *) &ctx),
+ mbedtls_test_thread_create(&threads[i],
+ thread_random_function, (void *) &ctx),
0);
}
for (size_t i = 0; i < thread_count; i++) {
- TEST_EQUAL(pthread_join(threads[i], NULL), 0);
+ TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
}
/* Take a last output for comparing and thus verifying the DRBG state */
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index e6f75de..2090594 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -31,7 +31,7 @@
int ok = 0;
mbedtls_mpi_init(&actual);
- ++mbedtls_test_info.step;
+ mbedtls_test_increment_step();
TEST_ASSERT(size >= *offset + 2);
n = (buffer[*offset] << 8) | buffer[*offset + 1];
diff --git a/tests/suites/test_suite_pkcs5.data b/tests/suites/test_suite_pkcs5.data
index f3ea553..52e6823 100644
--- a/tests/suites/test_suite_pkcs5.data
+++ b/tests/suites/test_suite_pkcs5.data
@@ -126,6 +126,18 @@
depends_on:MBEDTLS_MD_CAN_SHA1:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_CIPHER_PADDING_PKCS7
pbes2_encrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D5510101010101010101010101010101010":138:MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:""
+PBES2 Encrypt, AES-128-CBC (OK, generated with OpenSSL)
+depends_on:MBEDTLS_MD_CAN_SHA1:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
+pbes2_encrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E0408010203040506070802022710301D060960864801650304010204102F904F75B47B48A618068D79BD9A826C":"50617373776F726450617373776F726450617373776F7264":"5468697320697320612066696c6520746f20626520656e6372797074656420776974682050424553322c20776974682061206b65792067656e657261746564207573696e67206120707266202853484132353629":96:0:"0c953c3a9be1502f4d1df1b82df9d99a61ebd2f60ed570d16b241f70b9e61f329174747d052efe5c39bec9d0f7404f84af242914e2ecb74e6e36e8b4147bd0a092a82df789aa3351e0de9f75b285ccb742806526771c8353ffb66176188b556e"
+
+PBES2 Encrypt, AES-192-CBC (OK, generated with OpenSSL)
+depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
+pbes2_encrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302a06092A864886F70D01050C301d0408010203040506070802022710020118300a06082A864886F70D0209301D060960864801650304011604102F904F75B47B48A618068D79BD9A826C":"50617373776F726450617373776F726450617373776F7264":"5468697320697320612066696c6520746f20626520656e6372797074656420776974682050424553322c20776974682061206b65792067656e657261746564207573696e67206120707266202853484132353629":96:0:"7c648a9df9759ba49283c261269a71bc06d45f6c24ab6431d77b2ecec1fd6d1aa751bd05b1c026fc8ff91baeb1b1838aa0f825b23be79bc09331d0607181e234dfea4ab3cbf7997747516486b6865e85de95dc9b64d45462197c891b31af6c94"
+
+PBES2 Encrypt, AES-256-CBC (OK, generated with OpenSSL)
+depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH:MBEDTLS_CIPHER_PADDING_PKCS7
+pbes2_encrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301a0408010203040506070802022710300a06082A864886F70D0209301D060960864801650304012A04102F904F75B47B48A618068D79BD9A826C":"50617373776F726450617373776F726450617373776F7264":"5468697320697320612066696c6520746f20626520656e6372797074656420776974682050424553322c20776974682061206b65792067656e657261746564207573696e67206120707266202853484132353629":96:0:"7077e6e8e679962c6feda69c704d58507d143cf77be284f773dfcaa4a5f5e7c1cd5527204916302d435071c01126f4aa76205ce61998d7b8fdf065a77d4a77634376b9968e4722c27f2ac85d79565ff4fca9204d3e4bc8c5bd53c1785bb6e566"
+
PBES2 Decrypt (OK)
depends_on:MBEDTLS_MD_CAN_SHA1:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC
pbes2_decrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FD980E1C5741FC0DB7":144:0:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF"
@@ -142,6 +154,18 @@
depends_on:MBEDTLS_MD_CAN_SHA1:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_CIPHER_PADDING_PKCS7
pbes2_decrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E04082ED7F24A1D516DD702020800301406082A864886F70D030704088A4FCC9DCC394910":"70617373776f7264":"1B60098D4834CA752D37B430E70B7A085CFF86E21F4849F969DD1DF623342662443F8BD1252BF83CEF6917551B08EF55A69C8F2BFFC93BCB2DFE2E354DA28F896D1BD1BFB972A1251219A6EC7183B0A4CF2C4998449ED786CAE2138437289EB2203974000C38619DA57A4E685D29649284602BD1806131772DA11A682674DC22B2CF109128DDB7FDA3488A7144097565":144:MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH:"308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420F12A1320760270A83CBFFD53F6031EF76A5D86C8A204F2C30CA9EBF51F0F0EA7A1440342000437CC56D976091E5A723EC7592DFF206EEE7CF9069174D0AD14B5F768225962924EE500D82311FFEA2FD2345D5D16BD8A88C26B770D55CD8A2A0EFA01C8B4EDFF060606060607"
+PBES2 Decrypt AES-128-CBC (OK, generated with OpenSSL)
+depends_on:MBEDTLS_MD_CAN_SHA1:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC
+pbes2_decrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"301B06092A864886F70D01050C300E0408010203040506070802022710301D060960864801650304010204102F904F75B47B48A618068D79BD9A826C":"50617373776F726450617373776F726450617373776F7264":"0c953c3a9be1502f4d1df1b82df9d99a61ebd2f60ed570d16b241f70b9e61f329174747d052efe5c39bec9d0f7404f84af242914e2ecb74e6e36e8b4147bd0a092a82df789aa3351e0de9f75b285ccb742806526771c8353ffb66176188b556e":96:0:"5468697320697320612066696c6520746f20626520656e6372797074656420776974682050424553322c20776974682061206b65792067656e657261746564207573696e67206120707266202853484132353629"
+
+PBES2 Decrypt AES-192-CBC (OK, generated with OpenSSL)
+depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+pbes2_decrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302a06092A864886F70D01050C301d0408010203040506070802022710020118300a06082A864886F70D0209301D060960864801650304011604102F904F75B47B48A618068D79BD9A826C":"50617373776F726450617373776F726450617373776F7264":"7c648a9df9759ba49283c261269a71bc06d45f6c24ab6431d77b2ecec1fd6d1aa751bd05b1c026fc8ff91baeb1b1838aa0f825b23be79bc09331d0607181e234dfea4ab3cbf7997747516486b6865e85de95dc9b64d45462197c891b31af6c94":96:0:"5468697320697320612066696c6520746f20626520656e6372797074656420776974682050424553322c20776974682061206b65792067656e657261746564207573696e67206120707266202853484132353629"
+
+PBES2 Decrypt AES-256-CBC (OK, generated with OpenSSL)
+depends_on:MBEDTLS_MD_CAN_SHA256:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+pbes2_decrypt:MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE:"302706092A864886F70D01050C301a0408010203040506070802022710300a06082A864886F70D0209301D060960864801650304012A04102F904F75B47B48A618068D79BD9A826C":"50617373776F726450617373776F726450617373776F7264":"7077e6e8e679962c6feda69c704d58507d143cf77be284f773dfcaa4a5f5e7c1cd5527204916302d435071c01126f4aa76205ce61998d7b8fdf065a77d4a77634376b9968e4722c27f2ac85d79565ff4fca9204d3e4bc8c5bd53c1785bb6e566":96:0:"5468697320697320612066696c6520746f20626520656e6372797074656420776974682050424553322c20776974682061206b65792067656e657261746564207573696e67206120707266202853484132353629"
+
PBES2 Decrypt (bad params tag)
depends_on:MBEDTLS_MD_CAN_SHA1:MBEDTLS_DES_C
pbes2_decrypt:MBEDTLS_ASN1_SEQUENCE:"":"":"":0:MBEDTLS_ERR_PKCS5_INVALID_FORMAT + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG:""
diff --git a/tests/suites/test_suite_pkparse.data b/tests/suites/test_suite_pkparse.data
index 6387735..707da7f 100644
--- a/tests/suites/test_suite_pkparse.data
+++ b/tests/suites/test_suite_pkparse.data
@@ -890,6 +890,30 @@
depends_on:MBEDTLS_DES_C:MBEDTLS_MD_CAN_SHA512:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C
pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_4096_des_sha512.der":"":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+Parse RSA Key #99.3 (PKCS#8 encrypted v2 PBKDF2 AES-128-CBC hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_AES_C:MBEDTLS_MD_CAN_SHA384:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #99.4 (PKCS#8 encrypted v2 PBKDF2 AES-192-CBC hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_AES_C:MBEDTLS_MD_CAN_SHA384:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #99.5 (PKCS#8 encrypted v2 PBKDF2 AES-256-CBC hmacWithSHA384, 2048-bit)
+depends_on:MBEDTLS_AES_C:MBEDTLS_MD_CAN_SHA384:MBEDTLS_PEM_PARSE_C:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.pem":"PolarSSLTest":0
+
+Parse RSA Key #99.6 (PKCS#8 encrypted v2 PBKDF2 AES-128-CBC hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_AES_C:MBEDTLS_MD_CAN_SHA384:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes128cbc_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #99.7 (PKCS#8 encrypted v2 PBKDF2 AES-192-CBC hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_AES_C:MBEDTLS_MD_CAN_SHA384:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes192cbc_sha384.der":"PolarSSLTest":0
+
+Parse RSA Key #99.8 (PKCS#8 encrypted v2 PBKDF2 AES-256-CBC hmacWithSHA384 DER, 2048-bit)
+depends_on:MBEDTLS_AES_C:MBEDTLS_MD_CAN_SHA384:MBEDTLS_PKCS5_C:MBEDTLS_CIPHER_C:MBEDTLS_CIPHER_MODE_CBC:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+pk_parse_keyfile_rsa:"data_files/rsa_pkcs8_pbes2_pbkdf2_2048_aes256cbc_sha384.der":"PolarSSLTest":0
+
Parse Public RSA Key #1 (PKCS#8 wrapped)
depends_on:MBEDTLS_PEM_PARSE_C
pk_parse_public_keyfile_rsa:"data_files/rsa_pkcs8_2048_public.pem":0
@@ -1120,78 +1144,6 @@
Key ASN1 (First tag not Sequence)
pk_parse_key:"020100":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-Key ASN1 (RSAPrivateKey, incorrect version tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"300100":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, version tag missing)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3000":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, invalid version)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3003020101":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct version, incorrect tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"300402010000":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct format+values, minimal modulus size (128 bit))
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":0
-
-Key ASN1 (RSAPrivateKey, correct format, modulus too small (127 bit))
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"30630201000211007c8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct format, modulus even)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857002030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct format, d == 0)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"30630201000211007c8ab070369ede72920e5a51523c8571020301000102110000000000000000000000000000000000020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct format, d == p == q == 0)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c8571020301000102110000000000000000000000000000000000020900000000000000000002090000000000000000000209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, trailing garbage)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3064020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c00":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, n wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100FF1100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, e wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c8571FF030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, d wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c85710203010001FF11009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, p wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201FF0900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, q wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61FF0900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, dp wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a211FF09009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, dq wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401FF0813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
-Key ASN1 (RSAPrivateKey, correct values, qp wrong tag)
-depends_on:MBEDTLS_RSA_C
-pk_parse_key:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b7221FF08052b93d01747a87c":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
-
Key ASN1 (ECPrivateKey, empty parameters)
depends_on:MBEDTLS_PK_HAVE_ECC_KEYS
pk_parse_key:"30070201010400a000":MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data
index 122552d..34af94a 100644
--- a/tests/suites/test_suite_psa_crypto.data
+++ b/tests/suites/test_suite_psa_crypto.data
@@ -496,16 +496,6 @@
depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT:PSA_CRYPTO_DRIVER_TEST
import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( PSA_KEY_PERSISTENCE_VOLATILE, TEST_DRIVER_LOCATION ):1024:0:PSA_ERROR_NOT_PERMITTED:1
-# Test PEM import. Note that this is not a PSA feature, it's an Mbed TLS
-# extension which we may drop in the future.
-PSA import/export RSA public key: import PEM
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PEM_PARSE_C
-import_export:"2d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d4947664d413047435371475349623344514542415155414134474e4144434269514b4267514376425830356275685074312f6274634b7850482f6c706c53710a69714a4843315165346636777353306c7835635255784a4a34524b574b41517475376242494e46454e5354765441357548596c57377249486576456a536433750a355553447641624378686c497a514b7941756557727232553036664c2b466e43775947634d6b79344b357a545474346d4f69712f2f6b637a384865476e6f5a670a3939614454615539615137336d46397277774944415141420a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d0a00":PSA_KEY_TYPE_RSA_PUBLIC_KEY:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:0:1024:0:PSA_SUCCESS:0
-
-PSA import/export RSA keypair: import PEM
-depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT:MBEDTLS_PEM_PARSE_C
-import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b2400":PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_KEY_USAGE_EXPORT:PSA_ALG_RSA_PKCS1V15_SIGN_RAW:0:1024:0:PSA_SUCCESS:0
-
PSA import/export FFDH RFC7919 2048 key pair: good
depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_BASIC:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_IMPORT:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_EXPORT:PSA_WANT_DH_RFC7919_2048
import_export:"2A45292441157B3C25572F76A5CDF960A7BDBF06731D783C5BF8920FB94CCC3D5DCCF86A3CB66B4E3AEDD23106222458ACF3F72C753CB67C2E19AD399566866FEBC16C3B4DC72773B4709047AE1AEC2D9107C2041B06B86A8F604465B26E0E753D6B10772798B3797232D950A36F2D4B33B04B36DE73AC6B8A7365015DF5745A1F892728B0CA947702C36E3BC646E72E23E80C345DBB014B7F93B36C80B4051F9A716D19B980861E86D62977466565462FBD3C1BB4EFD630DCCBEB351A7FA95602B7FE23903C7C7DC999950493BEC028AC42346858FAD969452DCF1DE9AD445F7F928D63B75FA86E8C1D722AB242D91995D3545A1791D72B0F384E74B45C7C01":PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:0:2048:0:PSA_SUCCESS:1
diff --git a/tests/suites/test_suite_psa_crypto_util.data b/tests/suites/test_suite_psa_crypto_util.data
new file mode 100644
index 0000000..807007b
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto_util.data
@@ -0,0 +1,167 @@
+ECDSA Raw -> DER, 256bit, Success
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA Raw -> DER, 256bit, DER buffer too small
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"304402201111111111111111111111111111111111111111111111111111111111111111022022222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+
+ECDSA Raw -> DER, 256bit, Null r
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA Raw -> DER, 256bit, Null s
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA Raw -> DER, 256bit, r with MSb set
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"91111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"3045022100911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA Raw -> DER, 256bit, s with MSb set
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"1111111111111111111111111111111111111111111111111111111111111111A222222222222222222222222222222222222222222222222222222222222222":"304502201111111111111111111111111111111111111111111111111111111111111111022100A222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA Raw -> DER, 256bit, both r and s with MSb set
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"A111111111111111111111111111111111111111111111111111111111111111A222222222222222222222222222222222222222222222222222222222222222":"3046022100A111111111111111111111111111111111111111111111111111111111111111022100A222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA Raw -> DER, 256bit, r and s only 1 byte of data
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"00000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000022":"3006020111020122":0
+
+ECDSA Raw -> DER, 256bit, r and s only 1 byte of data with MSb set
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"000000000000000000000000000000000000000000000000000000000000009100000000000000000000000000000000000000000000000000000000000000A2":"300802020091020200A2":0
+
+ECDSA Raw -> DER, 256bit, Invalid raw signature (r 1 byte shorter)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA Raw -> DER, 256bit, Invalid raw signature (r and s 1 byte shorter)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"1111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA Raw -> DER, 256bit, Invalid raw signature (r 1 byte longer)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"1111111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA Raw -> DER, 256bit, Invalid raw signature (r and s 1 byte longer)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der:256:"111111111111111111111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222222222222222222222222":"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Success
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA DER -> Raw, 256bit, Raw buffer too small
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
+
+ECDSA DER -> Raw, 256bit, Wrong sequence tag
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"40440220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+ECDSA DER -> Raw, 256bit, Invalid sequence length
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30ff0220111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_LENGTH
+
+ECDSA DER -> Raw, 256bit, Wrong integer tag
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440120111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+ECDSA DER -> Raw, 256bit, Wrong r integer length (1 byte smaller than the actual size)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440219111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+ECDSA DER -> Raw, 256bit, Wrong r integer length (1 byte larger than the actual size)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440221111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Wrong s integer length (1 byte smaller than the actual size)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102192222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+ECDSA DER -> Raw, 256bit, Wrong s integer length (1 byte larger than the actual size)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102212222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+ECDSA DER -> Raw, 256bit, r size 1 byte larger than allowed for output raw coordinate
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"3045022111111111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, r with MSb set
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"3045022100911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"91111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA DER -> Raw, 256bit, Invalid r all zeros
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220000000000000000000000000000000000000000000000000000000000000000002202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Invalid s all zeros
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220111111111111111111111111111111111111111111111111111111111111111102200000000000000000000000000000000000000000000000000000000000000000":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Valid r only 1 zero byte
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"302502010002202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA DER -> Raw, 256bit, Valid s only 1 zero byte
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"302502201111111111111111111111111111111111111111111111111111111111111111020100":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":0
+
+ECDSA DER -> Raw, 256bit, Invalid 0-length r
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"3024020002202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Invalid 0-length s
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"3024022011111111111111111111111111111111111111111111111111111111111111110200":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Invalid r 2 leading zeros
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"3027020300000102202222222222222222222222222222222222222222222222222222222222222222":"00000000000000000000000000000000000000000000000000000000000000002222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Invalid s 2 leading zeros
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"3027022011111111111111111111111111111111111111111111111111111111111111110203000001":"11111111111111111111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+ECDSA DER -> Raw, 256bit, Invalid r: MSb set without leading zero
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_der_to_raw:256:"30440220911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222":"11111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":MBEDTLS_ERR_ASN1_INVALID_DATA
+
+# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
+ECDSA Raw -> DER, 512bit, Success
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 512
+ecdsa_raw_to_der:512:"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"308184024011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111024022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
+
+# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
+ECDSA DER -> Raw, 512bit, Success
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 512
+ecdsa_der_to_raw:512:"308184024011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111024022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
+
+# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
+ECDSA Raw -> DER, 521bit, Success
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 521
+ecdsa_raw_to_der:521:"011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"30818802420111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110242012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
+
+# 512/521 bit sizes are useful to test sequence's length encoded with 2 bytes.
+ECDSA DER -> Raw, 521bit, Success
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 521
+ecdsa_der_to_raw:521:"30818802420111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110242012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":0
+
+ECDSA Raw -> DER, 256bit, Incremental DER buffer sizes
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der_incremental:256:"91111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222222":"3045022100911111111111111111111111111111111111111111111111111111111111111102202222222222222222222222222222222222222222222222222222222222222222"
+
+ECDSA Raw -> DER, 512bit, Incremental DER buffer sizes
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 512
+ecdsa_raw_to_der_incremental:512:"9111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"30818502410091111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111024022222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
+
+ECDSA Raw -> DER, 521bit, Incremental DER buffer sizes
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 521
+ecdsa_raw_to_der_incremental:521:"011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222":"30818802420111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110242012222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222"
+
+ECDSA Raw -> DER, 256bit, DER buffer of minimal length (1 byte per integer)
+depends_on:PSA_VENDOR_ECC_MAX_CURVE_BITS >= 256
+ecdsa_raw_to_der_incremental:256:"00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002":"3006020101020102"
diff --git a/tests/suites/test_suite_psa_crypto_util.function b/tests/suites/test_suite_psa_crypto_util.function
new file mode 100644
index 0000000..2d8915e
--- /dev/null
+++ b/tests/suites/test_suite_psa_crypto_util.function
@@ -0,0 +1,91 @@
+/* BEGIN_HEADER */
+#include <test/helpers.h>
+#include <mbedtls/psa_util.h>
+/* END_HEADER */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_UTIL_HAVE_ECDSA */
+void ecdsa_raw_to_der(int key_bits, data_t *input, data_t *exp_result, int exp_ret)
+{
+ unsigned char *tmp_buf = NULL;
+ size_t tmp_buf_len = exp_result->len;
+ size_t ret_len;
+
+ TEST_CALLOC(tmp_buf, tmp_buf_len);
+
+ TEST_EQUAL(mbedtls_ecdsa_raw_to_der(key_bits, input->x, input->len,
+ tmp_buf, tmp_buf_len, &ret_len), exp_ret);
+
+ if (exp_ret == 0) {
+ ASSERT_COMPARE(exp_result->x, exp_result->len, tmp_buf, ret_len);
+ }
+
+exit:
+ mbedtls_free(tmp_buf);
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_UTIL_HAVE_ECDSA */
+void ecdsa_raw_to_der_incremental(int key_bits, data_t *input, data_t *exp_result)
+{
+ unsigned char *tmp_buf = NULL;
+ size_t ret_len;
+ size_t i;
+
+ /* Test with an output buffer smaller than required (expexted to fail). */
+ for (i = 1; i < exp_result->len; i++) {
+ TEST_CALLOC(tmp_buf, i);
+ TEST_ASSERT(mbedtls_ecdsa_raw_to_der(key_bits, input->x, input->len,
+ tmp_buf, i, &ret_len) != 0);
+ mbedtls_free(tmp_buf);
+ tmp_buf = NULL;
+ }
+ /* Test with an output buffer larger/equal than required (expexted to
+ * succeed). */
+ for (i = exp_result->len; i < (2 * exp_result->len); i++) {
+ TEST_CALLOC(tmp_buf, i);
+ TEST_ASSERT(mbedtls_ecdsa_raw_to_der(key_bits, input->x, input->len,
+ tmp_buf, i, &ret_len) == 0);
+ mbedtls_free(tmp_buf);
+ tmp_buf = NULL;
+ }
+
+exit:
+ mbedtls_free(tmp_buf);
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_PSA_UTIL_HAVE_ECDSA */
+void ecdsa_der_to_raw(int key_bits, data_t *input, data_t *exp_result, int exp_ret)
+{
+ unsigned char *in_buf = NULL;
+ size_t in_buf_len;
+ unsigned char *out_buf = NULL;
+ size_t out_buf_len = exp_result->len;
+ size_t ret_len;
+
+ TEST_CALLOC(out_buf, out_buf_len);
+
+ /* Verify that parsing of truncated input always fails. */
+ for (in_buf_len = 1; in_buf_len < input->len; in_buf_len++) {
+ /* We alloc a copy of input buffer with limited length so that sanitizers
+ * can detect overreads. */
+ TEST_CALLOC(in_buf, in_buf_len);
+ memcpy(in_buf, input->x, in_buf_len);
+ TEST_ASSERT(mbedtls_ecdsa_der_to_raw(key_bits, in_buf, in_buf_len,
+ out_buf, out_buf_len, &ret_len) != 0);
+ mbedtls_free(in_buf);
+ in_buf = NULL;
+ }
+
+ TEST_EQUAL(mbedtls_ecdsa_der_to_raw(key_bits, input->x, input->len,
+ out_buf, out_buf_len, &ret_len), exp_ret);
+
+ if (exp_ret == 0) {
+ ASSERT_COMPARE(exp_result->x, exp_result->len, out_buf, ret_len);
+ }
+
+exit:
+ mbedtls_free(in_buf);
+ mbedtls_free(out_buf);
+}
+/* END_CASE */
diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data
index 0a60f31..b89d158 100644
--- a/tests/suites/test_suite_rsa.data
+++ b/tests/suites/test_suite_rsa.data
@@ -615,3 +615,120 @@
RSA Selftest
depends_on:MBEDTLS_SELF_TEST
rsa_selftest:
+
+RSA parse/write PKCS#1 private key - 1024 bits
+rsa_parse_write_pkcs1_key:0:"3082025d020100028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb702030100010281801e97247066217ff6303881341a259c4bcd3e147f87f1a714045e80a06b541847e2ce54a78801d21b302fd33f616d6ed7cfa8a262ef5e23257a1642b5fc5a61577f7dba2324e687a10b25751c78996e72d5a8c3bc4e33e4a2a96b2b44b6685e85c37200a34381269250b59f65468ea4288713c4ae3e0e064e524a53a5d7e1ec91024100cbd11d9aad72bfb8db4e6bc7c6910661b3f38fbfa368d6dba0cd6c9aa3a716c03fa374bf8b2e7ba73a216d6ded9468fbaa3d130ee376190cc41ef30419a7da1d024100c7c0e189209483f36ee00a67474960c6ddf0d3a63ca0c76955fe9f358435a5e5318c35397c4245042e0dfabf8decedfd36e4d211349b8ecc4c1baac83f30d4e3024008e692f2644cb48eb01516a3dcca0c8b4bbe81328f424ecfbc8ffc042ccd6932f014854eb017519315f8cbbc973979f4339503360d3ce50f27a96a576d7f65090241009c9b4ef74870c7a6b215ba7250446a385fc6b0d8d30da669a23f172948f71a923f2f528738316894a75ad46d1be3568ec05bd38a23b995d1fc1570e6c00c13cb0241008716c9fa7d2295f34f5849b7c593d1adcec72556ed1044cd79c868c890620b143874a8208a65b7c5e235ccaae4c2492107af513fb2cbb682a3e8119af028f7a8"
+
+RSA parse/write PKCS#1 public key - 1024 bits
+rsa_parse_write_pkcs1_key:1:"308189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001"
+
+RSA parse/write PKCS#1 private key - 2048 bits
+rsa_parse_write_pkcs1_key:0:"308204a40201000282010100dcabfd25f3b7d67155e5c2520518570e95754ef883a973f94b2b0fb2d7ad733a3b0976c6314770eaf728304ee61e0dfe91811fc4a8219fbc3687cb3cfca54b58804d1ed4de985dc827374cb31b7b23225e130858d6b812dee6a356a8f8d211ba0930d0ec38193cee0a186f4a760cc3aa40e1d04fe4a14506ed279a9080aedd2676a4026bcb1ee24b2c00853bffcc04b5fb3e542626c2b2c54a62f3d6e01df95544fdf85c22cc0846275cb9cdfe73876e94e532ced0bca9876de74ff1edc9c8ac89aa8586aa34ca6f44c972d1e73aaddae168a5e67ec69cd14f206155e6e1161e7aa6754e947d5d26ee5f8789598a79ea4ff0263e2b8bf90641320771955007d102030100010282010100d25c964f769d3aad0210ac04da5c90a9136b27e41a47108a86d0beff6341330640bf4dddb39e82134b97a12da58ae3165988f94ad4687148cfc6f5c4e6a7804316d3eddf496f807f4c7b17ffe9e3a1e3a2408c857bf32ff2137584284242a7a96c1780229f7bd7aca82d10f2afc48d4620e1e35e35fa52be3e97b16dad6e84dbdfab4e7e21c7c2e5e5cd1c936f6c221e806bd14afa77b3eefc62e984aa2d391da408aaec0dbd2eade3023ebac77e3416cd67491d60053d317c6c8665be5c33961c379309d37d0a653d1859a6abfe195644d474739dbc44f62e623505f9460d9d8defafb12f4149d5baaf798f1345f565430cd7c096c24ca8d02d13fe90c20c5102818100f116cfdbfc0d5b3528cbfada1b21d4292ff188d41a4b22e658a9e29f610adf5fcb3329b0f567ba5029195fd648d06cc2174638f2f18ff0e0251e283e0a0b1f792751925efb617af3405083245c673dae77edc811fd668769d28ac1bee36261658a32f56a5e1b9b9e4f4fa7da55adeeb08c92f1de89f6186bd9c6d1e721638d2d02818100ea51e8798225e4ee77aa08e2f5ee0f8b847edd4c34d9bf7b8cf339b61d5bd22d504c5ab5f17572850f39018736474a449186e783dfda35da95902c8eaaec4bebb8ab6c057c678f37cd53fc1a12e5ace83d2a44d72195d565b3e8c12f89f2523fe37e52adbafde783be361fcd1f021aaaabf860febd8c5726c7089622ccca73b50281807d8248b7d76204a78a13970650b5adc3bb67dcb9beee7abebc4dc4e3001c2ee9a9d97accdb1523137431f78890e3a09af28ee63ae3b2f1cd5ec57261c9ccbc97cff651630d2f5458aa94bf910061e6e49b1eb8d754ba39a8c7a8e0f04564041c5e73e4fb78fe9a673216dfe57451563fa70f20c79fbef43bc166160463877609028180693b0fa44206b2a145ac5f014e60f32a3cfe9c73b4e8754e0f26cc2c35531f38aa6f1fedc5da70ebc0c261255003041f771b96ad6ac29c9ce5be31c4808e4e2a366d05be10f89121065d49428c6a0914e32330774ce5f5480f5be02671551a0b07279c09d9885d8894cbc9cc5cb89d3138b9fb156c1ab2a8ff89a3a34d453e6102818100aff57dd813fd064d8d1a5e8c7ea7e534dff6963a9b5b1c4da12219268c0500288901bbd36edb8071679bcd9d0d8deacfaa52e4b3659f4a69a5c5322f104524f83eb4b94bf6f02b5ad7c2ccd9bc5688f4e18ff2a70ae7638a83f2f87d8ecc9e0eebf2283f809670c8a0b79e1a576a6c9c04d4d71b75647c818a23873cdc0d77bf"
+
+RSA parse/write PKCS#1 public key - 2048 bits
+rsa_parse_write_pkcs1_key:1:"3082010a0282010100dcabfd25f3b7d67155e5c2520518570e95754ef883a973f94b2b0fb2d7ad733a3b0976c6314770eaf728304ee61e0dfe91811fc4a8219fbc3687cb3cfca54b58804d1ed4de985dc827374cb31b7b23225e130858d6b812dee6a356a8f8d211ba0930d0ec38193cee0a186f4a760cc3aa40e1d04fe4a14506ed279a9080aedd2676a4026bcb1ee24b2c00853bffcc04b5fb3e542626c2b2c54a62f3d6e01df95544fdf85c22cc0846275cb9cdfe73876e94e532ced0bca9876de74ff1edc9c8ac89aa8586aa34ca6f44c972d1e73aaddae168a5e67ec69cd14f206155e6e1161e7aa6754e947d5d26ee5f8789598a79ea4ff0263e2b8bf90641320771955007d10203010001"
+
+RSA parse private key - incorrect version tag
+rsa_parse_pkcs1_key:0:"300100":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - version tag missing
+rsa_parse_pkcs1_key:0:"3000":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+RSA parse private key - invalid version
+rsa_parse_pkcs1_key:0:"3003020101":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse private key - correct version, incorrect tag
+rsa_parse_pkcs1_key:0:"300402010000":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct format+values, minimal modulus size (128 bit)
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":0
+
+RSA parse private key - missing SEQUENCE
+rsa_parse_pkcs1_key:0:"020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct format, modulus too small (127 bit)
+rsa_parse_pkcs1_key:0:"30630201000211007c8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_RSA_KEY_CHECK_FAILED
+
+RSA parse private key - correct format, modulus even
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857002030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse private key - correct format, d == 0
+rsa_parse_pkcs1_key:0:"30630201000211007c8ab070369ede72920e5a51523c8571020301000102110000000000000000000000000000000000020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse private key - correct format, d == p == q == 0
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c8571020301000102110000000000000000000000000000000000020900000000000000000002090000000000000000000209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse private key - correct values, extra integer inside the SEQUENCE
+rsa_parse_pkcs1_key:0:"3066020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c020100":MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+RSA parse private key - correct values, extra integer outside the SEQUENCE
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c020100":0
+
+RSA parse private key - correct values, n wrong tag
+rsa_parse_pkcs1_key:0:"3063020100FF1100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, e wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c8571FF030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, d wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c85710203010001FF11009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, p wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201FF0900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, q wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61FF0900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, dp wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a211FF09009471f14c26428401020813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, dq wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401FF0813425f060c4b72210208052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse private key - correct values, qp wrong tag
+rsa_parse_pkcs1_key:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b7221FF08052b93d01747a87c":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse public key - missing SEQUENCE
+rsa_parse_pkcs1_key:1:"028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse public key - wrong initial tag
+rsa_parse_pkcs1_key:1:"318189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse public key - wrong modulus tag
+rsa_parse_pkcs1_key:1:"308189038181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse public key - wrong public exponent tag
+rsa_parse_pkcs1_key:1:"308189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70303010001":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse public key - modulus 0
+rsa_parse_pkcs1_key:1:"3081890281810000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000203010001":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse public key - public exponent 0
+rsa_parse_pkcs1_key:1:"308189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203000000":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse public key - wrong sequence length
+rsa_parse_pkcs1_key:1:"308188028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+RSA parse public key - wrong modulus length
+rsa_parse_pkcs1_key:1:"308189028180009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001":MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
+
+RSA parse public key - wrong public exponent length
+rsa_parse_pkcs1_key:1:"308189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70202010001":MBEDTLS_ERR_RSA_BAD_INPUT_DATA
+
+RSA parse public key - missing modulus
+rsa_parse_pkcs1_key:1:"30050203010001":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+RSA parse public key - missing public exponent
+rsa_parse_pkcs1_key:1:"308184028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb7":MBEDTLS_ERR_ASN1_OUT_OF_DATA
+
+RSA parse public key - correct values, extra integer inside the SEQUENCE
+rsa_parse_pkcs1_key:1:"30818c028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001020100":MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+
+RSA parse public key - correct values, extra integer outside the SEQUENCE
+rsa_parse_pkcs1_key:1:"308189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001020100":0
+
+RSA priv key write - incremental output buffer size
+rsa_key_write_incremental:0:"3063020100021100cc8ab070369ede72920e5a51523c857102030100010211009a6318982a7231de1894c54aa4909201020900f3058fd8dc484d61020900d7770dbd8b78a2110209009471f14c26428401020813425f060c4b72210208052b93d01747a87c"
+
+RSA priv public key write - incremental output buffer size
+rsa_key_write_incremental:1:"308189028181009f091e6968b474f76f0e9c237c1d895996ae704b4f6d706acec8d2daac6209bf524aa3f658d0283adba1077f6cbe92e425dcde52290b239cade91be86c88425434986806e85734e159768f3dfea932baaa9409d25bace8ee9dce0cdde0903207299de575ae60feccf0daf82334ab83638539b0da74072f253acea8afc8e66bb70203010001"
diff --git a/tests/suites/test_suite_rsa.function b/tests/suites/test_suite_rsa.function
index 37bed6d..2f70028 100644
--- a/tests/suites/test_suite_rsa.function
+++ b/tests/suites/test_suite_rsa.function
@@ -1,6 +1,7 @@
/* BEGIN_HEADER */
#include "mbedtls/rsa.h"
#include "rsa_alt_helpers.h"
+#include "rsa_internal.h"
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -1371,6 +1372,112 @@
}
/* END_CASE */
+/* BEGIN_CASE */
+void rsa_parse_pkcs1_key(int is_public, data_t *input, int exp_ret_val)
+{
+ mbedtls_rsa_context rsa_ctx;
+
+ mbedtls_rsa_init(&rsa_ctx);
+
+ if (is_public) {
+ TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), exp_ret_val);
+ } else {
+ TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), exp_ret_val);
+ }
+
+exit:
+ mbedtls_rsa_free(&rsa_ctx);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void rsa_parse_write_pkcs1_key(int is_public, data_t *input)
+{
+ mbedtls_rsa_context rsa_ctx;
+ unsigned char *output_buf = NULL;
+ unsigned char *output_end, *output_p;
+ size_t output_len;
+
+ mbedtls_rsa_init(&rsa_ctx);
+
+ TEST_CALLOC(output_buf, input->len);
+ output_end = output_buf + input->len;
+ output_p = output_end;
+
+ /* Parse the key and write it back to output_buf. */
+ if (is_public) {
+ TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
+ TEST_EQUAL(mbedtls_rsa_write_pubkey(&rsa_ctx, output_buf, &output_p), input->len);
+ } else {
+ TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
+ TEST_EQUAL(mbedtls_rsa_write_key(&rsa_ctx, output_buf, &output_p), input->len);
+ }
+ output_len = output_end - output_p;
+
+ /* Check that the written key matches with the one provided in input. */
+ TEST_MEMORY_COMPARE(output_p, output_len, input->x, input->len);
+
+exit:
+ mbedtls_free(output_buf);
+ mbedtls_rsa_free(&rsa_ctx);
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void rsa_key_write_incremental(int is_public, data_t *input)
+{
+ mbedtls_rsa_context rsa_ctx;
+ unsigned char *buf = NULL, *end, *p;
+ size_t i, written_data;
+
+ mbedtls_rsa_init(&rsa_ctx);
+
+ /* This is supposed to succeed as the real target of this test are the
+ * write attempt below. */
+ if (is_public) {
+ TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
+ } else {
+ TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
+ }
+
+ /* Test with an output buffer smaller than required. */
+ for (i = 1; i < input->len; i++) {
+ TEST_CALLOC(buf, i);
+ end = buf + i;
+ p = end;
+ /* We don't care much about the return value as long as it fails. */
+ if (is_public) {
+ TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) != 0);
+ } else {
+ TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) != 0);
+ }
+ mbedtls_free(buf);
+ buf = NULL;
+ }
+
+ /* Test with an output buffer equal or larger than what it is strictly required. */
+ for (i = input->len; i < (2 * input->len); i++) {
+ TEST_CALLOC(buf, i);
+ end = buf + i;
+ p = end;
+ /* This time all write functions must succeed. */
+ if (is_public) {
+ TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) > 0);
+ } else {
+ TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) > 0);
+ }
+ written_data = (end - p);
+ TEST_MEMORY_COMPARE(p, written_data, input->x, input->len);
+ mbedtls_free(buf);
+ buf = NULL;
+ }
+
+exit:
+ mbedtls_free(buf);
+ mbedtls_rsa_free(&rsa_ctx);
+}
+/* END_CASE */
+
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void rsa_selftest()
{
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 261c220..b9ae20c 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -1774,7 +1774,7 @@
X509 CRT ASN1 (TBS, inv SubPubKeyInfo, inv internal bitstring length)
depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256
-x509parse_crt:"308180306ba0030201008204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743015300d06092A864886F70D0101010500030400300000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
+x509parse_crt:"308180306ba0030201008204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a300806001304546573743015300d06092A864886F70D0101010500030400300000300d06092a864886f70d01010b0500030200ff":"":MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_OUT_OF_DATA
X509 CRT ASN1 (TBS, inv SubPubKeyInfo, inv internal bitstring tag)
depends_on:MBEDTLS_RSA_C:MBEDTLS_MD_CAN_SHA256