diff --git a/.travis.yml b/.travis.yml index 54df776060..cdb79d1aa2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,8 +52,8 @@ jobs: - programs/test/selftest - tests/scripts/test_psa_constant_names.py - tests/ssl-opt.sh - # Modern OpenSSL does not support fixed ECDH or null ciphers. - - tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_' + # Modern OpenSSL does not support null ciphers. + - tests/compat.sh -p OpenSSL -e 'NULL' - tests/scripts/travis-log-failure.sh # GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it. - tests/compat.sh -p GnuTLS -e 'CAMELLIA' @@ -80,6 +80,58 @@ jobs: - sleep 5 - scripts/windows_msbuild.bat v141 # Visual Studio 2017 + - name: full configuration on arm64 + os: linux + dist: focal + arch: arm64 + addons: + apt: + packages: + - gcc + script: + # Do a manual build+test sequence rather than using all.sh, because + # there's no all.sh component that does what we want. We should set + # CFLAGS for arm64 host CC. + - scripts/config.py full + - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + - make generated_files + - make CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all' + - make test + - programs/test/selftest + - tests/scripts/test_psa_constant_names.py + # Modern OpenSSL does not support fixed ECDH or null ciphers. + - tests/compat.sh -p OpenSSL -e 'NULL\|ECDH_' + - tests/scripts/travis-log-failure.sh + - tests/context-info.sh + + - name: full configuration(GnuTLS compat tests) on arm64 + os: linux + dist: focal + arch: arm64 + addons: + apt: + packages: + - clang + - gnutls-bin + script: + # Do a manual build+test sequence rather than using all.sh, because + # there's no all.sh component that does what we want. We should set + # CFLAGS for arm64 host CC. + - scripts/config.py full + - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + - scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + - scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + - make generated_files + - make CC=clang CFLAGS='-march=armv8-a+crypto -O3 -Werror -fsanitize=address,undefined -fno-sanitize-recover=all' LDFLAGS='-Werror -fsanitize=address,undefined -fno-sanitize-recover=all' + # GnuTLS supports CAMELLIA but compat.sh doesn't properly enable it. + - tests/compat.sh -p GnuTLS -e 'CAMELLIA' + - tests/scripts/travis-log-failure.sh + - tests/context-info.sh + after_failure: - tests/scripts/travis-log-failure.sh diff --git a/ChangeLog.d/add-uri-san.txt b/ChangeLog.d/add-uri-san.txt new file mode 100644 index 0000000000..5184e8f5dc --- /dev/null +++ b/ChangeLog.d/add-uri-san.txt @@ -0,0 +1,3 @@ +Features + * Add parsing of uniformResourceIdentifier subtype for subjectAltName + extension in x509 certificates. diff --git a/ChangeLog.d/add_interruptible_sign_hash b/ChangeLog.d/add_interruptible_sign_hash new file mode 100644 index 0000000000..3d933038ea --- /dev/null +++ b/ChangeLog.d/add_interruptible_sign_hash @@ -0,0 +1,5 @@ +Features + * Add an interruptible version of sign and verify hash to the PSA interface, + backed by internal library support for ECDSA signing and verification. + + diff --git a/ChangeLog.d/empty-retval-description.txt b/ChangeLog.d/empty-retval-description.txt new file mode 100644 index 0000000000..491adf55d0 --- /dev/null +++ b/ChangeLog.d/empty-retval-description.txt @@ -0,0 +1,3 @@ +Bugfix + * Silence warnings from clang -Wdocumentation about empty \retval + descriptions, which started appearing with Clang 15. Fixes #6960. diff --git a/ChangeLog.d/fix-oid-to-string-bugs.txt b/ChangeLog.d/fix-oid-to-string-bugs.txt new file mode 100644 index 0000000000..799f444747 --- /dev/null +++ b/ChangeLog.d/fix-oid-to-string-bugs.txt @@ -0,0 +1,6 @@ +Bugfix + * Fix bug in conversion from OID to string in + mbedtls_oid_get_numeric_string(). OIDs such as 2.40.0.25 are now printed + correctly. + * Reject OIDs with overlong-encoded subidentifiers when converting + OID-to-string. diff --git a/ChangeLog.d/mpi-window-perf b/ChangeLog.d/mpi-window-perf new file mode 100644 index 0000000000..0f75d6af1e --- /dev/null +++ b/ChangeLog.d/mpi-window-perf @@ -0,0 +1,7 @@ +Changes + * Changed the default MBEDTLS_ECP_WINDOW_SIZE from 6 to 2. + As tested in issue 6790, the correlation between this define and + RSA decryption performance has changed lately due to security fixes. + To fix the performance degradation when using default values the + window was reduced from 6 to 2, a value that gives the best or close + to best results when tested on Cortex-M4 and Intel i7. diff --git a/ChangeLog.d/psa-alt-headers.txt b/ChangeLog.d/psa-alt-headers.txt new file mode 100644 index 0000000000..95556290a5 --- /dev/null +++ b/ChangeLog.d/psa-alt-headers.txt @@ -0,0 +1,4 @@ +Features + * The configuration macros MBEDTLS_PSA_CRYPTO_PLATFORM_FILE and + MBEDTLS_PSA_CRYPTO_STRUCT_FILE specify alternative locations for + the headers "psa/crypto_platform.h" and "psa/crypto_struct.h". diff --git a/ChangeLog.d/san_rfc822Name.txt b/ChangeLog.d/san_rfc822Name.txt new file mode 100644 index 0000000000..9720e5275c --- /dev/null +++ b/ChangeLog.d/san_rfc822Name.txt @@ -0,0 +1,3 @@ +Features + * Add parsing of rfc822Name subtype for subjectAltName + extension in x509 certificates. diff --git a/ChangeLog.d/tls13-only-renegotiation.txt b/ChangeLog.d/tls13-only-renegotiation.txt new file mode 100644 index 0000000000..f463de1af2 --- /dev/null +++ b/ChangeLog.d/tls13-only-renegotiation.txt @@ -0,0 +1,5 @@ +Bugfix + * Fix the handling of renegotiation attempts in TLS 1.3. They are now + systematically rejected. + * Fix an unused-variable warning in TLS 1.3-only builds if + MBEDTLS_SSL_RENEGOTIATION was enabled. Fixes #6200. diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index 0c744daaa2..c33c7e362e 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -27,3 +27,18 @@ HAVE_DOT = YES DOT_GRAPH_MAX_NODES = 200 MAX_DOT_GRAPH_DEPTH = 1000 DOT_TRANSPARENT = YES + +# We mostly use \retval declarations to document which error codes a function +# can return. The reader can follow the hyperlink to the definition of the +# constant to get the generic documentation of that error code. If we don't +# have anything to say about the specific error code for the specific +# function, we can leave the description part of the \retval command blank. +# This is perfectly valid as far as Doxygen is concerned. However, with +# Clang >=15, the -Wdocumentation option emits a warning for empty +# descriptions. +# https://github.com/Mbed-TLS/mbedtls/issues/6960 +# https://github.com/llvm/llvm-project/issues/60315 +# As a workaround, you can write something like +# \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription +# This avoids writing redundant text and keeps Clang happy. +ALIASES += emptydescription="" diff --git a/include/mbedtls/bignum.h b/include/mbedtls/bignum.h index e8fb2de4bd..b1d4b88ba5 100644 --- a/include/mbedtls/bignum.h +++ b/include/mbedtls/bignum.h @@ -63,7 +63,7 @@ #if !defined(MBEDTLS_MPI_WINDOW_SIZE) /* - * Maximum window size used for modular exponentiation. Default: 6 + * Maximum window size used for modular exponentiation. Default: 2 * Minimum value: 1. Maximum value: 6. * * Result is an array of ( 2 ** MBEDTLS_MPI_WINDOW_SIZE ) MPIs used @@ -71,7 +71,7 @@ * * Reduction in size, reduces speed. */ -#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ +#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ #endif /* !MBEDTLS_MPI_WINDOW_SIZE */ #if !defined(MBEDTLS_MPI_MAX_SIZE) diff --git a/include/mbedtls/build_info.h b/include/mbedtls/build_info.h index bc94acf104..4835beb00c 100644 --- a/include/mbedtls/build_info.h +++ b/include/mbedtls/build_info.h @@ -87,26 +87,22 @@ #define MBEDTLS_MD_LIGHT #endif +/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT + * is defined as well to include all PSA code. + */ +#if defined(MBEDTLS_PSA_CRYPTO_C) +#define MBEDTLS_PSA_CRYPTO_CLIENT +#endif /* MBEDTLS_PSA_CRYPTO_C */ + /* The PK wrappers need pk_write functions to format RSA key objects * when they are dispatching to the PSA API. This happens under USE_PSA_CRYPTO, - * and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). - * PSA crypto also needs pk_write to export RSA keys (otherwise the build - * goes through but psa_export_key() and psa_export_public_key() fail on - * RSA keys), and pk_parse to work with RSA keys in almost any way. - */ + * and also even without USE_PSA_CRYPTO for mbedtls_pk_sign_ext(). */ #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 -/* Under MBEDTLS_USE_PSA_CRYPTO, the pk module needs pk_write functions - * to pass ECC keys to PSA. */ -#if defined(MBEDTLS_PK_C) && \ - defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_ECP_C) -#define MBEDTLS_PK_WRITE_C -#endif - #if !defined(MBEDTLS_SSL_PROTO_TLS1_2) #undef MBEDTLS_KEY_EXCHANGE_RSA_ENABLED #undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 1efabdc1fd..3065df5d94 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -70,6 +70,10 @@ #error "MBEDTLS_AESNI_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_AESCE_C) && !defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_AESCE_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) #error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" #endif @@ -708,41 +712,6 @@ #if defined(MBEDTLS_SHA512_ALT) || defined(MBEDTLS_SHA512_PROCESS_ALT) #error "MBEDTLS_SHA512_*ALT can't be used with MBEDTLS_SHA512_USE_A64_CRYPTO_*" #endif -/* - * Best performance comes from most recent compilers, with intrinsics and -O3. - * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and - * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12). - * - * GCC < 8 won't work at all (lacks the sha512 instructions) - * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512 - * - * Clang < 7 won't work at all (lacks the sha512 instructions) - * Clang 7-12 don't have intrinsics (but we work around that with inline - * assembler) or __ARM_FEATURE_SHA512 - * Clang == 13.0.0 same as clang 12 (only seen on macOS) - * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics - */ -#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) - /* Test Clang first, as it defines __GNUC__ */ -# if defined(__clang__) -# if __clang_major__ < 7 -# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# elif __clang_major__ < 13 || \ - (__clang_major__ == 13 && __clang_minor__ == 0 && __clang_patchlevel__ == 0) - /* We implement the intrinsics with inline assembler, so don't error */ -# else -# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# endif -# elif defined(__GNUC__) -# if __GNUC__ < 8 -# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# else -# error "Must use minimum -march=armv8.2-a+sha3 for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# endif -# else -# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*" -# endif -#endif #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ @@ -763,9 +732,7 @@ #if defined(MBEDTLS_SHA256_ALT) || defined(MBEDTLS_SHA256_PROCESS_ALT) #error "MBEDTLS_SHA256_*ALT can't be used with MBEDTLS_SHA256_USE_A64_CRYPTO_*" #endif -#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) -#error "Must use minimum -march=armv8-a+crypto for MBEDTLS_SHA256_USE_A64_CRYPTO_*" -#endif + #endif #if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) && \ @@ -932,6 +899,11 @@ #error "MBEDTLS_SSL_EXTENDED_MASTER_SECRET defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) && \ + !defined(MBEDTLS_SSL_PROTO_TLS1_2) +#error "MBEDTLS_SSL_RENEGOTIATION defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_SSL_TICKET_C) && ( !defined(MBEDTLS_CIPHER_C) && \ !defined(MBEDTLS_USE_PSA_CRYPTO) ) #error "MBEDTLS_SSL_TICKET_C defined, but not all prerequisites" diff --git a/include/mbedtls/ecdsa.h b/include/mbedtls/ecdsa.h index 9847a68363..c5d9701f6e 100644 --- a/include/mbedtls/ecdsa.h +++ b/include/mbedtls/ecdsa.h @@ -222,6 +222,134 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, void *p_rng_blind); #endif /* MBEDTLS_ECDSA_DETERMINISTIC */ +#if !defined(MBEDTLS_ECDSA_SIGN_ALT) +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, in a restartable way. + * + * \note The deterministic version implemented in + * mbedtls_ecdsa_sign_det_restartable() is usually + * preferred. + * + * \note This function is like \c mbedtls_ecdsa_sign() but + * it can return early and restart according to the + * limit set with \c mbedtls_ecp_set_max_ops() to + * reduce blocking. + * + * \note If the bitlength of the message hash is larger + * than the bitlength of the group order, then the + * hash is truncated as defined in Standards for + * Efficient Cryptography Group (SECG): SEC1 Elliptic + * Curve Cryptography, section 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through + * mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param f_rng The RNG function. This must not be \c NULL. + * \param p_rng The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * \param rs_ctx The restart context to use. This may be \c NULL + * to disable restarting. If it is not \c NULL, it + * must point to an initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c + * mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c + * MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_restartable( + mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, + const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + +/** + * \brief This function computes the ECDSA signature of a + * previously-hashed message, in a restartable way. + * + * \note This function is like \c + * mbedtls_ecdsa_sign_det_ext() but it can return + * early and restart according to the limit set with + * \c mbedtls_ecp_set_max_ops() to reduce blocking. + * + * \note If the bitlength of the message hash is larger + * than the bitlength of the group order, then the + * hash is truncated as defined in Standards for + * Efficient Cryptography Group (SECG): SEC1 Elliptic + * Curve Cryptography, section 4.1.3, step 5. + * + * \see ecp.h + * + * \param grp The context for the elliptic curve to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param r The MPI context in which to store the first part + * the signature. This must be initialized. + * \param s The MPI context in which to store the second part + * the signature. This must be initialized. + * \param d The private signing key. This must be initialized + * and setup, for example through + * mbedtls_ecp_gen_privkey(). + * \param buf The hashed content to be signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param f_rng_blind The RNG function used for blinding. This must not be + * \c NULL. + * \param p_rng_blind The RNG context to be passed to \p f_rng. This may be + * \c NULL if \p f_rng doesn't need a context parameter. + * \param rs_ctx The restart context to use. This may be \c NULL + * to disable restarting. If it is not \c NULL, it + * must point to an initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c + * mbedtls_ecp_set_max_ops(). + * \return Another \c MBEDTLS_ERR_ECP_XXX, \c + * MBEDTLS_ERR_MPI_XXX or \c MBEDTLS_ERR_ASN1_XXX + * error code on failure. + */ +int mbedtls_ecdsa_sign_det_restartable( + mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +#endif /* !MBEDTLS_ECDSA_SIGN_ALT */ + /** * \brief This function verifies the ECDSA signature of a * previously-hashed message. @@ -257,6 +385,51 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s); +#if !defined(MBEDTLS_ECDSA_VERIFY_ALT) +/** + * \brief This function verifies the ECDSA signature of a + * previously-hashed message, in a restartable manner + * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * defined in Standards for Efficient Cryptography Group + * (SECG): SEC1 Elliptic Curve Cryptography, section + * 4.1.4, step 3. + * + * \see ecp.h + * + * \param grp The ECP group to use. + * This must be initialized and have group parameters + * set, for example through mbedtls_ecp_group_load(). + * \param buf The hashed content that was signed. This must be a readable + * buffer of length \p blen Bytes. It may be \c NULL if + * \p blen is zero. + * \param blen The length of \p buf in Bytes. + * \param Q The public key to use for verification. This must be + * initialized and setup. + * \param r The first integer of the signature. + * This must be initialized. + * \param s The second integer of the signature. + * This must be initialized. + * \param rs_ctx The restart context to use. This may be \c NULL to disable + * restarting. If it is not \c NULL, it must point to an + * initialized restart context. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of + * operations was reached: see \c mbedtls_ecp_set_max_ops(). + * \return An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX + * error code on failure. + */ +int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +#endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ + /** * \brief This function computes the ECDSA signature and writes it * to a buffer, serialized as defined in RFC-4492: diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h index 7a28a19573..b6144d9aeb 100644 --- a/include/mbedtls/ecp.h +++ b/include/mbedtls/ecp.h @@ -141,6 +141,15 @@ typedef enum { MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ } mbedtls_ecp_curve_type; +/* + * Curve modulus types + */ +typedef enum { + MBEDTLS_ECP_MOD_NONE = 0, + MBEDTLS_ECP_MOD_COORDINATE, + MBEDTLS_ECP_MOD_SCALAR +} mbedtls_ecp_modulus_type; + /** * Curve information, for use by other modules. * @@ -472,6 +481,12 @@ mbedtls_ecp_keypair; * only enabled for specific sides and key exchanges * (currently only for clients and ECDHE-ECDSA). * + * \warning Using the PSA interruptible interfaces with keys in local + * storage and no accelerator driver will also call this + * function to set the values specified via those interfaces, + * overwriting values previously set. Care should be taken if + * mixing these two interfaces. + * * \param max_ops Maximum number of basic operations done in a row. * Default: 0 (unlimited). * Lower (non-zero) values mean ECC functions will block for diff --git a/include/mbedtls/mbedtls_config.h b/include/mbedtls/mbedtls_config.h index 5d3cdb58f7..4814d50f89 100644 --- a/include/mbedtls/mbedtls_config.h +++ b/include/mbedtls/mbedtls_config.h @@ -2065,6 +2065,34 @@ */ #define MBEDTLS_AESNI_C +/** + * \def MBEDTLS_AESCE_C + * + * Enable AES crypto extension support on Arm64. + * + * Module: library/aesce.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C + * + * \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum + * of \c -march=armv8-a+crypto . + * + * \warning If the target architecture is set to something that includes the + * SHA3 feature (e.g. `-march=armv8.2-a+sha3`), for example because + * `MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT` is desired, compilers + * generate code for `MBEDTLS_AESCE_C` that includes instructions + * only present with the (optional) SHA3 feature. This will lead to an + * undefined instruction exception if the code is run on a CPU without + * that feature. + * + * \warning Runtime detection only works on linux. For non-linux operation + * system, crypto extension MUST be supported by CPU. + * + * This module adds support for the AES crypto instructions on Arm64 + */ +#define MBEDTLS_AESCE_C + /** * \def MBEDTLS_AES_C * @@ -3087,9 +3115,6 @@ * \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building * for a non-Aarch64 build it will be silently ignored. * - * \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum - * of \c -march=armv8-a+crypto. - * * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the * same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. * @@ -3112,9 +3137,6 @@ * \note This allows builds with a smaller code size than with * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT * - * \note The code uses Neon intrinsics, so \c CFLAGS must be set to a minimum - * of \c -march=armv8-a+crypto. - * * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same * time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. * @@ -3169,9 +3191,7 @@ * for a non-Aarch64 build it will be silently ignored. * * \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or - * Clang >= 7, and \c CFLAGS must be set to a minimum of - * \c -march=armv8.2-a+sha3. An optimisation level of \c -O3 generates the - * fastest code. + * Clang >= 7. * * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. @@ -3196,9 +3216,7 @@ * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT * * \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or - * Clang >= 7, and \c CFLAGS must be set to a minimum of - * \c -march=armv8.2-a+sha3. An optimisation level of \c -O3 generates the - * fastest code. + * Clang >= 7. * * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. @@ -3537,6 +3555,53 @@ */ //#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" +/** + * \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_platform.h"`. This file should declare the same identifiers + * as the one in Mbed TLS, but with definitions adapted to the platform on + * which the library code will run. + * + * \note The required content of this header can vary from one version of + * Mbed TLS to the next. Integrators who provide an alternative file + * should review the changes in the original file whenever they + * upgrade Mbed TLS. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_PLATFORM_FILE "psa/crypto_platform_alt.h" + +/** + * \def MBEDTLS_PSA_CRYPTO_STRUCT_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_struct.h"`. This file should declare the same identifiers + * as the one in Mbed TLS, but with definitions adapted to the environment + * in which the library code will run. The typical use for this feature + * is to provide alternative type definitions on the client side in + * client-server integrations of PSA crypto, where operation structures + * contain handles instead of cryptographic data. + * + * \note The required content of this header can vary from one version of + * Mbed TLS to the next. Integrators who provide an alternative file + * should review the changes in the original file whenever they + * upgrade Mbed TLS. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_STRUCT_FILE "psa/crypto_struct_alt.h" + /** \} name SECTION: General configuration options */ /** @@ -3559,7 +3624,7 @@ * comment in the specific module. */ /* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum window size used. */ +//#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ //#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ /* CTR_DRBG options */ diff --git a/include/mbedtls/pkcs7.h b/include/mbedtls/pkcs7.h index 5ddd5a3d71..126eac4228 100644 --- a/include/mbedtls/pkcs7.h +++ b/include/mbedtls/pkcs7.h @@ -135,22 +135,12 @@ typedef struct mbedtls_pkcs7_signer_info { } mbedtls_pkcs7_signer_info; -/** - * Structure holding attached data as part of PKCS7 signed data format - */ -typedef struct mbedtls_pkcs7_data { - mbedtls_pkcs7_buf MBEDTLS_PRIVATE(oid); - mbedtls_pkcs7_buf MBEDTLS_PRIVATE(data); -} -mbedtls_pkcs7_data; - /** * Structure holding the signed data section */ typedef struct mbedtls_pkcs7_signed_data { int MBEDTLS_PRIVATE(version); mbedtls_pkcs7_buf MBEDTLS_PRIVATE(digest_alg_identifiers); - struct mbedtls_pkcs7_data MBEDTLS_PRIVATE(content); int MBEDTLS_PRIVATE(no_of_certs); mbedtls_x509_crt MBEDTLS_PRIVATE(certs); int MBEDTLS_PRIVATE(no_of_crls); @@ -165,7 +155,6 @@ mbedtls_pkcs7_signed_data; */ typedef struct mbedtls_pkcs7 { mbedtls_pkcs7_buf MBEDTLS_PRIVATE(raw); - mbedtls_pkcs7_buf MBEDTLS_PRIVATE(content_type_oid); mbedtls_pkcs7_signed_data MBEDTLS_PRIVATE(signed_data); } mbedtls_pkcs7; @@ -178,7 +167,7 @@ mbedtls_pkcs7; void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7); /** - * \brief Parse a single DER formatted pkcs7 content. + * \brief Parse a single DER formatted pkcs7 detached signature. * * \param pkcs7 The pkcs7 structure to be filled by parser for the output. * \param buf The buffer holding only the DER encoded pkcs7. @@ -188,6 +177,7 @@ void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7); * \note This function makes an internal copy of the PKCS7 buffer * \p buf. In particular, \p buf may be destroyed or reused * after this call returns. + * \note Signatures with internal data are not supported. * * \return The \c mbedtls_pkcs7_type of \p buf, if successful. * \return A negative error code on failure. @@ -207,7 +197,8 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf, * matches. * * This function does not use the certificates held within the - * PKCS7 structure itself. + * PKCS7 structure itself, and does not check that the + * certificate is signed by a trusted certification authority. * * \param pkcs7 PKCS7 structure containing signature. * \param cert Certificate containing key to verify signature. @@ -228,15 +219,15 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7, * \brief Verification of PKCS7 signature against a caller-supplied * certificate. * - * For each signer in the PKCS structure, this function computes - * a signature over the supplied hash, using the supplied - * certificate and the same digest algorithm as specified by the - * signer. It then compares this signature against the - * signer's signature; verification succeeds if any comparison - * matches. + * For each signer in the PKCS structure, this function + * validates a signature over the supplied hash, using the + * supplied certificate and the same digest algorithm as + * specified by the signer. Verification succeeds if any + * signature is good. * * This function does not use the certificates held within the - * PKCS7 structure itself. + * PKCS7 structure itself, and does not check that the + * certificate is signed by a trusted certification authority. * * \param pkcs7 PKCS7 structure containing signature. * \param cert Certificate containing key to verify signature. @@ -244,7 +235,7 @@ int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7, * \param hashlen Length of the hash. * * \note This function is different from mbedtls_pkcs7_signed_data_verify() - * in a way that it directly receives the hash of the data. + * in that it is directly passed the hash of the data. * * \return 0 if the signature verifies, or a negative error code on failure. */ diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index dc74ac60cc..f6070dcba8 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -257,6 +257,9 @@ static inline int mbedtls_psa_get_ecc_oid_from_id( #define MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH \ PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) +#define MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH \ + PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS) + /* Expose whatever RNG the PSA subsystem uses to applications using the * mbedtls_xxx API. The declarations and definitions here need to be * consistent with the implementation in library/psa_crypto_random_impl.h. diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index aa1cd084ee..bd1947e465 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -294,7 +294,7 @@ typedef struct mbedtls_x509_subject_alternative_name { int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */ union { mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */ - mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */ + mbedtls_x509_buf unstructured_name; /**< The buffer for the unconstructed types. Only rfc822Name, dnsName and uniformResourceIdentifier are currently supported */ } san; /**< A union of the supported SAN types */ } @@ -385,8 +385,9 @@ int mbedtls_x509_time_is_future(const mbedtls_x509_time *from); * \param san The target structure to populate with the parsed presentation * of the subject alternative name encoded in \p san_raw. * - * \note Only "dnsName" and "otherName" of type hardware_module_name - * as defined in RFC 4180 is supported. + * \note Supported GeneralName types, as defined in RFC 5280: + * "rfc822Name", "dnsName", "uniformResourceIdentifier" and "hardware_module_name" + * of type "otherName", as defined in RFC 4108. * * \note This function should be called on a single raw data of * subject alternative name. For example, after successful diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 187e60aac8..036282f7c9 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -76,7 +76,7 @@ typedef struct mbedtls_x509_crt { mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ - mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */ + mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName, uniformResourceIdentifier and OtherName are listed). */ mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */ diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 2b9b2a27e8..8a05efd8b4 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -22,7 +22,11 @@ #ifndef PSA_CRYPTO_H #define PSA_CRYPTO_H +#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE) +#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE +#else #include "crypto_platform.h" +#endif #include @@ -88,16 +92,16 @@ extern "C" { * initialization may have security implications, for example due to improper * seeding of the random number generator. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription */ psa_status_t psa_crypto_init(void); @@ -368,14 +372,14 @@ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); * On failure, equivalent to a * freshly-initialized structure. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -486,7 +490,7 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); * identifier defined in \p attributes. * \c 0 on failure. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_HANDLE * \p source_key is invalid. * \retval #PSA_ERROR_ALREADY_EXISTS @@ -502,14 +506,14 @@ psa_status_t psa_purge_key(mbedtls_svc_key_id_t key); * The source key does not have the #PSA_KEY_USAGE_COPY usage flag, or * the source key is not exportable and its lifetime does not * allow copying it to the target's lifetime. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -631,14 +635,14 @@ psa_status_t psa_destroy_key(mbedtls_svc_key_id_t key); * the key data is not correctly formatted, or * the size in \p attributes is nonzero and does not match the size * of the key data. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -718,22 +722,22 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, * \param[out] data_length On success, the number of bytes * that make up the key data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription * \retval #PSA_ERROR_NOT_PERMITTED * The key does not have the #PSA_KEY_USAGE_EXPORT flag. - * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p data buffer is too small. You can determine a * sufficient buffer size by calling * #PSA_EXPORT_KEY_OUTPUT_SIZE(\c type, \c bits) * where \c type is the key type * and \c bits is the key size in bits. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -793,22 +797,22 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, * \param[out] data_length On success, the number of bytes * that make up the key data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * The key is neither a public key nor a key pair. - * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p data buffer is too small. You can determine a * sufficient buffer size by calling * #PSA_EXPORT_KEY_OUTPUT_SIZE(#PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(\c type), \c bits) * where \c type is the key type * and \c bits is the key size in bits. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -846,13 +850,13 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, * Success. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a hash algorithm. - * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * \p hash_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -884,10 +888,10 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg, * \p alg is not supported or is not a hash algorithm. * \retval #PSA_ERROR_INVALID_ARGUMENT * \p input_length or \p hash_length do not match the hash size for \p alg - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -977,10 +981,10 @@ static psa_hash_operation_t psa_hash_operation_init(void); * \p alg is not a supported hash algorithm. * \retval #PSA_ERROR_INVALID_ARGUMENT * \p alg is not a hash algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive), or * the library has not been previously initialized by psa_crypto_init(). @@ -1003,10 +1007,10 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active), or * the library has not been previously initialized by psa_crypto_init(). @@ -1049,10 +1053,10 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, * The size of the \p hash buffer is too small. You can determine a * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) * where \c alg is the hash algorithm that is calculated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active), or * the library has not been previously initialized by psa_crypto_init(). @@ -1090,10 +1094,10 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation, * \retval #PSA_ERROR_INVALID_SIGNATURE * The hash of the message was calculated successfully, but it * differs from the expected hash. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active), or * the library has not been previously initialized by psa_crypto_init(). @@ -1120,10 +1124,10 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, * * \param[in,out] operation Initialized hash operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1146,11 +1150,11 @@ psa_status_t psa_hash_abort(psa_hash_operation_t *operation); * \param[in,out] target_operation The operation object to set up. * It must be initialized but not active. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The \p source_operation state is not valid (it must be active), or * the \p target_operation state is not valid (it must be inactive), or @@ -1190,18 +1194,18 @@ psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a MAC algorithm. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * \p mac_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE * The key could not be retrieved from storage. * \retval #PSA_ERROR_BAD_STATE @@ -1233,16 +1237,16 @@ psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, * \retval #PSA_ERROR_INVALID_SIGNATURE * The MAC of the message was calculated successfully, but it * differs from the expected value. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE * The key could not be retrieved from storage. * \retval #PSA_ERROR_BAD_STATE @@ -1338,16 +1342,16 @@ static psa_mac_operation_t psa_mac_operation_init(void); * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE * The key could not be retrieved from storage. * \retval #PSA_ERROR_BAD_STATE @@ -1400,16 +1404,16 @@ psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \c key is not compatible with \c alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \c alg is not supported or is not a MAC algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE * The key could not be retrieved from storage. * \retval #PSA_ERROR_BAD_STATE @@ -1437,11 +1441,11 @@ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active), or * the library has not been previously initialized by psa_crypto_init(). @@ -1485,11 +1489,11 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p mac buffer is too small. You can determine a * sufficient buffer size by calling PSA_MAC_LENGTH(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active mac sign * operation), or the library has not been previously initialized @@ -1528,11 +1532,11 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, * \retval #PSA_ERROR_INVALID_SIGNATURE * The MAC of the message was calculated successfully, but it * differs from the expected MAC. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active mac verify * operation), or the library has not been previously initialized @@ -1560,10 +1564,10 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, * * \param[in,out] operation Initialized MAC operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1599,18 +1603,18 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation); * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1646,18 +1650,18 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -1753,17 +1757,17 @@ static psa_cipher_operation_t psa_cipher_operation_init(void); * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive), or * the library has not been previously initialized by psa_crypto_init(). @@ -1816,17 +1820,17 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not a cipher algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive), or * the library has not been previously initialized by psa_crypto_init(). @@ -1859,11 +1863,11 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, * Success. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p iv buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, with no IV set), * or the library has not been previously initialized @@ -1900,11 +1904,11 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, * \retval #PSA_ERROR_INVALID_ARGUMENT * The size of \p iv is not acceptable for the chosen algorithm, * or the chosen algorithm does not use an IV. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active cipher * encrypt operation, with no IV set), or the library has not been @@ -1941,11 +1945,11 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, * Success. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, with an IV set * if required for the algorithm), or the library has not been @@ -1993,11 +1997,11 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, * padding, and the ciphertext does not contain valid padding. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, with an IV set * if required for the algorithm), or the library has not been @@ -2026,10 +2030,10 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, * * \param[in,out] operation Initialized cipher operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2082,23 +2086,23 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * \p ciphertext_size is too small. * #PSA_AEAD_ENCRYPT_OUTPUT_SIZE(\c key_type, \p alg, * \p plaintext_length) or * #PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE(\p plaintext_length) can be used to * determine the required buffer size. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2153,25 +2157,25 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription * \retval #PSA_ERROR_INVALID_SIGNATURE * The ciphertext is not authentic. - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * \p plaintext_size is too small. * #PSA_AEAD_DECRYPT_OUTPUT_SIZE(\c key_type, \p alg, * \p ciphertext_length) or * #PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE(\p ciphertext_length) can be used * to determine the required buffer size. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2280,16 +2284,16 @@ static psa_aead_operation_t psa_aead_operation_init(void); * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive), or * the library has not been previously initialized by psa_crypto_init(). - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_STORAGE_FAILURE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2344,17 +2348,17 @@ psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p key is not compatible with \p alg. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported or is not an AEAD algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive), or the * library has not been previously initialized by psa_crypto_init(). @@ -2388,11 +2392,11 @@ psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, * Success. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p nonce buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active aead encrypt * operation, with no nonce set), or the library has not been @@ -2428,11 +2432,11 @@ psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation, * Success. * \retval #PSA_ERROR_INVALID_ARGUMENT * The size of \p nonce is not acceptable for the chosen algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, with no nonce * set), or the library has not been previously initialized @@ -2473,10 +2477,10 @@ psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation, * \retval #PSA_ERROR_INVALID_ARGUMENT * At least one of the lengths is not acceptable for the chosen * algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, and * psa_aead_update_ad() and psa_aead_update() must not have been @@ -2520,11 +2524,11 @@ psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation, * \retval #PSA_ERROR_INVALID_ARGUMENT * The total input length overflows the additional data length that * was previously specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, have a nonce * set, have lengths set if required by the algorithm, and @@ -2605,11 +2609,11 @@ psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, * specified with psa_aead_set_lengths(), or * the total input length overflows the plaintext length that * was previously specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, have a nonce * set, and have lengths set if required by the algorithm), or the @@ -2691,11 +2695,11 @@ psa_status_t psa_aead_update(psa_aead_operation_t *operation, * the total length of input to psa_aead_update() so far is * less than the plaintext length that was previously * specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active encryption * operation with a nonce set), or the library has not been previously @@ -2774,11 +2778,11 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation, * the total length of input to psa_aead_update() so far is * less than the plaintext length that was previously * specified with psa_aead_set_lengths(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active decryption * operation with a nonce set), or the library has not been previously @@ -2809,10 +2813,10 @@ psa_status_t psa_aead_verify(psa_aead_operation_t *operation, * * \param[in,out] operation Initialized AEAD operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2858,8 +2862,8 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation); * \param[out] signature_length On success, the number of bytes that make up * the returned signature value. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription * \retval #PSA_ERROR_NOT_PERMITTED * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, * or it does not permit the requested algorithm. @@ -2869,16 +2873,16 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation); * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2914,23 +2918,23 @@ psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, * \param[out] signature Buffer containing the signature to verify. * \param[in] signature_length Size of the \p signature buffer in bytes. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription * \retval #PSA_ERROR_NOT_PERMITTED * The key does not have the #PSA_KEY_USAGE_SIGN_MESSAGE flag, * or it does not permit the requested algorithm. * \retval #PSA_ERROR_INVALID_SIGNATURE * The calculation was performed successfully, but the passed signature * is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -2967,23 +2971,23 @@ psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, * \param[out] signature_length On success, the number of bytes * that make up the returned signature value. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p signature buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3023,18 +3027,18 @@ psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, * * \retval #PSA_SUCCESS * The signature is valid. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_SIGNATURE * The calculation was performed successfully, but the passed * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3076,23 +3080,23 @@ psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, * \param[out] output_length On success, the number of bytes * that make up the returned output. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3136,24 +3140,24 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, * \param[out] output_length On success, the number of bytes * that make up the returned output. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * \retval #PSA_ERROR_INVALID_PADDING + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INVALID_PADDING \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3263,11 +3267,11 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); * \c alg is not a key derivation algorithm. * \retval #PSA_ERROR_NOT_SUPPORTED * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive), or * the library has not been previously initialized by psa_crypto_init(). @@ -3287,10 +3291,10 @@ psa_status_t psa_key_derivation_setup( * \param[in] operation The operation to query. * \param[out] capacity On success, the capacity of the operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active), or * the library has not been previously initialized by psa_crypto_init(). @@ -3311,14 +3315,14 @@ psa_status_t psa_key_derivation_get_capacity( * It must be less or equal to the operation's * current capacity. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p capacity is larger than the operation's current capacity. * In this case, the operation object remains valid and its capacity * remains unchanged. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active), or the * library has not been previously initialized by psa_crypto_init(). @@ -3367,11 +3371,11 @@ psa_status_t psa_key_derivation_set_capacity( * \retval #PSA_ERROR_INVALID_ARGUMENT * \c step is not compatible with the operation's algorithm, or * \c step does not allow direct inputs. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid for this input \p step, or * the library has not been previously initialized by psa_crypto_init(). @@ -3410,11 +3414,11 @@ psa_status_t psa_key_derivation_input_bytes( * \retval #PSA_ERROR_INVALID_ARGUMENT * \c step is not compatible with the operation's algorithm, or * \c step does not allow numeric inputs. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid for this input \p step, or * the library has not been previously initialized by psa_crypto_init(). @@ -3468,7 +3472,7 @@ psa_status_t psa_key_derivation_input_integer( * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription * \retval #PSA_ERROR_NOT_PERMITTED * The key allows neither #PSA_KEY_USAGE_DERIVE nor * #PSA_KEY_USAGE_VERIFY_DERIVATION, or it doesn't allow this @@ -3477,11 +3481,11 @@ psa_status_t psa_key_derivation_input_integer( * \c step is not compatible with the operation's algorithm, or * \c step does not allow key inputs of the given type * or does not allow key inputs at all. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid for this input \p step, or * the library has not been previously initialized by psa_crypto_init(). @@ -3536,8 +3540,8 @@ psa_status_t psa_key_derivation_input_key( * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \c private_key is not compatible with \c alg, * or \p peer_key is not valid for \c alg or not compatible with @@ -3545,11 +3549,11 @@ psa_status_t psa_key_derivation_input_key( * from a key agreement. * \retval #PSA_ERROR_NOT_SUPPORTED * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid for this key agreement \p step, * or the library has not been previously initialized by psa_crypto_init(). @@ -3580,7 +3584,7 @@ psa_status_t psa_key_derivation_key_agreement( * \param[out] output Buffer where the output will be written. * \param output_length Number of bytes to output. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_NOT_PERMITTED * One of the inputs was a key whose policy didn't allow * #PSA_KEY_USAGE_DERIVE. @@ -3591,11 +3595,11 @@ psa_status_t psa_key_derivation_key_agreement( * The operation's capacity is set to 0, thus * subsequent calls to this function will not * succeed, even with a smaller output buffer. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active and completed * all required input steps), or the library has not been previously @@ -3738,14 +3742,14 @@ psa_status_t psa_key_derivation_output_bytes( * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a * key; or one of the inputs was a key whose policy didn't allow * #PSA_KEY_USAGE_DERIVE. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active and completed * all required input steps), or the library has not been previously @@ -3786,7 +3790,7 @@ psa_status_t psa_key_derivation_output_key( * \param output_length Length of the expected output; this is also the * number of bytes that will be read. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_SIGNATURE * The output was read successfully, but it differs from the expected * output. @@ -3799,11 +3803,11 @@ psa_status_t psa_key_derivation_output_key( * the operation's capacity is set to 0, thus * subsequent calls to this function will not * succeed, even with a smaller expected output. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active and completed * all required input steps), or the library has not been previously @@ -3845,7 +3849,7 @@ psa_status_t psa_key_derivation_verify_bytes( * computed by a previous call to * psa_key_derivation_output_key(). * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_SIGNATURE * The output was read successfully, but if differs from the expected * output. @@ -3863,11 +3867,11 @@ psa_status_t psa_key_derivation_verify_bytes( * the operation's capacity is set to 0, thus * subsequent calls to this function will not * succeed, even with a smaller expected output. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active and completed * all required input steps), or the library has not been previously @@ -3893,10 +3897,10 @@ psa_status_t psa_key_derivation_verify_key( * * \param[in,out] operation The operation to abort. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3934,8 +3938,8 @@ psa_status_t psa_key_derivation_abort( * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p alg is not a key agreement algorithm, or * \p private_key is not compatible with \p alg, @@ -3945,11 +3949,11 @@ psa_status_t psa_key_derivation_abort( * \p output_size is too small * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -3981,13 +3985,13 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, * \param[out] output Output buffer for the generated data. * \param output_size Number of bytes to generate and output. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -4024,17 +4028,17 @@ psa_status_t psa_generate_random(uint8_t *output, * \retval #PSA_ERROR_ALREADY_EXISTS * This is an attempt to create a persistent key, and there is * already a persistent key with the given identifier. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -4045,6 +4049,631 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, /**@}*/ +/** \defgroup interruptible_hash Interruptible sign/verify hash + * @{ + */ + +/** The type of the state data structure for interruptible hash + * signing operations. + * + * Before calling any function on a sign hash operation object, the + * application must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_sign_hash_interruptible_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_sign_hash_interruptible_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer + * #PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT, for example: + * \code + * psa_sign_hash_interruptible_operation_t operation = + * PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT; + * \endcode + * - Assign the result of the function + * psa_sign_hash_interruptible_operation_init() to the structure, for + * example: + * \code + * psa_sign_hash_interruptible_operation_t operation; + * operation = psa_sign_hash_interruptible_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ +typedef struct psa_sign_hash_interruptible_operation_s psa_sign_hash_interruptible_operation_t; + +/** The type of the state data structure for interruptible hash + * verification operations. + * + * Before calling any function on a sign hash operation object, the + * application must initialize it by any of the following means: + * - Set the structure to all-bits-zero, for example: + * \code + * psa_verify_hash_interruptible_operation_t operation; + * memset(&operation, 0, sizeof(operation)); + * \endcode + * - Initialize the structure to logical zero values, for example: + * \code + * psa_verify_hash_interruptible_operation_t operation = {0}; + * \endcode + * - Initialize the structure to the initializer + * #PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT, for example: + * \code + * psa_verify_hash_interruptible_operation_t operation = + * PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT; + * \endcode + * - Assign the result of the function + * psa_verify_hash_interruptible_operation_init() to the structure, for + * example: + * \code + * psa_verify_hash_interruptible_operation_t operation; + * operation = psa_verify_hash_interruptible_operation_init(); + * \endcode + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure. + * Implementation details can change in future versions without notice. */ +typedef struct psa_verify_hash_interruptible_operation_s psa_verify_hash_interruptible_operation_t; + +/** + * \brief Set the maximum number of ops allowed to be + * executed by an interruptible function in a + * single call. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note The time taken to execute a single op is + * implementation specific and depends on + * software, hardware, the algorithm, key type and + * curve chosen. Even within a single operation, + * successive ops can take differing amounts of + * time. The only guarantee is that lower values + * for \p max_ops means functions will block for a + * lesser maximum amount of time. The functions + * \c psa_sign_interruptible_get_num_ops() and + * \c psa_verify_interruptible_get_num_ops() are + * provided to help with tuning this value. + * + * \note This value defaults to + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, which + * means the whole operation will be done in one + * go, regardless of the number of ops required. + * + * \note If more ops are needed to complete a + * computation, #PSA_OPERATION_INCOMPLETE will be + * returned by the function performing the + * computation. It is then the caller's + * responsibility to either call again with the + * same operation context until it returns 0 or an + * error code; or to call the relevant abort + * function if the answer is no longer required. + * + * \note The interpretation of \p max_ops is also + * implementation defined. On a hard real time + * system, this can indicate a hard deadline, as a + * real-time system needs a guarantee of not + * spending more than X time, however care must be + * taken in such an implementation to avoid the + * situation whereby calls just return, not being + * able to do any actual work within the allotted + * time. On a non-real-time system, the + * implementation can be more relaxed, but again + * whether this number should be interpreted as as + * hard or soft limit or even whether a less than + * or equals as regards to ops executed in a + * single call is implementation defined. + * + * \note For keys in local storage when no accelerator + * driver applies, please see also the + * documentation for \c mbedtls_ecp_set_max_ops(), + * which is the internal implementation in these + * cases. + * + * \warning With implementations that interpret this number + * as a hard limit, setting this number too small + * may result in an infinite loop, whereby each + * call results in immediate return with no ops + * done (as there is not enough time to execute + * any), and thus no result will ever be achieved. + * + * \note This only applies to functions whose + * documentation mentions they may return + * #PSA_OPERATION_INCOMPLETE. + * + * \param max_ops The maximum number of ops to be executed in a + * single call. This can be a number from 0 to + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0 + * is the least amount of work done per call. + */ +void psa_interruptible_set_max_ops(uint32_t max_ops); + +/** + * \brief Get the maximum number of ops allowed to be + * executed by an interruptible function in a + * single call. This will return the last + * value set by + * \c psa_interruptible_set_max_ops() or + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED if + * that function has never been called. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \return Maximum number of ops allowed to be + * executed by an interruptible function in a + * single call. + */ +uint32_t psa_interruptible_get_max_ops(void); + +/** + * \brief Get the number of ops that a hash signing + * operation has taken so far. If the operation + * has completed, then this will represent the + * number of ops required for the entire + * operation. After initialization or calling + * \c psa_sign_hash_interruptible_abort() on + * the operation, a value of 0 will be returned. + * + * \note This interface is guaranteed re-entrant and + * thus may be called from driver code. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * This is a helper provided to help you tune the + * value passed to \c + * psa_interruptible_set_max_ops(). + * + * \param operation The \c psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \return Number of ops that the operation has taken so + * far. + */ +uint32_t psa_sign_hash_get_num_ops( + const psa_sign_hash_interruptible_operation_t *operation); + +/** + * \brief Get the number of ops that a hash verification + * operation has taken so far. If the operation + * has completed, then this will represent the + * number of ops required for the entire + * operation. After initialization or calling \c + * psa_verify_hash_interruptible_abort() on the + * operation, a value of 0 will be returned. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * This is a helper provided to help you tune the + * value passed to \c + * psa_interruptible_set_max_ops(). + * + * \param operation The \c + * psa_verify_hash_interruptible_operation_t to + * use. This must be initialized first. + * + * \return Number of ops that the operation has taken so + * far. + */ +uint32_t psa_verify_hash_get_num_ops( + const psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Start signing a hash or short message with a + * private key, in an interruptible manner. + * + * \see \c psa_sign_hash_complete() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_sign_hash_complete() is equivalent to + * \c psa_sign_hash() but + * \c psa_sign_hash_complete() can return early and + * resume according to the limit set with \c + * psa_interruptible_set_max_ops() to reduce the + * maximum time spent in a function call. + * + * \note Users should call \c psa_sign_hash_complete() + * repeatedly on the same context after a + * successful call to this function until \c + * psa_sign_hash_complete() either returns 0 or an + * error. \c psa_sign_hash_complete() will return + * #PSA_OPERATION_INCOMPLETE if there is more work + * to do. Alternatively users can call + * \c psa_sign_hash_abort() at any point if they no + * longer want the result. + * + * \note If this function returns an error status, the + * operation enters an error state and must be + * aborted by calling \c psa_sign_hash_abort(). + * + * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \param key Identifier of the key to use for the operation. + * It must be an asymmetric key pair. The key must + * allow the usage #PSA_KEY_USAGE_SIGN_HASH. + * \param alg A signature algorithm (\c PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with + * the type of \p key. + * \param[in] hash The hash or message to sign. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The operation started successfully - call \c psa_sign_hash_complete() + * with the same context to complete the operation + * + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_SIGN_HASH flag, or it does + * not permit the requested algorithm. + * \retval #PSA_ERROR_BAD_STATE + * An operation has previously been started on this context, and is + * still in progress. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_hash_start( + psa_sign_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length); + +/** + * \brief Continue and eventually complete the action of + * signing a hash or short message with a private + * key, in an interruptible manner. + * + * \see \c psa_sign_hash_start() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_sign_hash_start() is equivalent to + * \c psa_sign_hash() but this function can return + * early and resume according to the limit set with + * \c psa_interruptible_set_max_ops() to reduce the + * maximum time spent in a function call. + * + * \note Users should call this function on the same + * operation object repeatedly until it either + * returns 0 or an error. This function will return + * #PSA_OPERATION_INCOMPLETE if there is more work + * to do. Alternatively users can call + * \c psa_sign_hash_abort() at any point if they no + * longer want the result. + * + * \note When this function returns successfully, the + * operation becomes inactive. If this function + * returns an error status, the operation enters an + * error state and must be aborted by calling + * \c psa_sign_hash_abort(). + * + * \param[in, out] operation The \c psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first, and have + * had \c psa_sign_hash_start() called with it + * first. + * + * \param[out] signature Buffer where the signature is to be written. + * \param signature_size Size of the \p signature buffer in bytes. This + * must be appropriate for the selected + * algorithm and key: + * - The required signature size is + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c + * key_bits, \c alg) where \c key_type and \c + * key_bits are the type and bit-size + * respectively of key. + * - #PSA_SIGNATURE_MAX_SIZE evaluates to the + * maximum signature size of any supported + * signature algorithm. + * \param[out] signature_length On success, the number of bytes that make up + * the returned signature value. + * + * \retval #PSA_SUCCESS + * Operation completed successfully + * + * \retval #PSA_OPERATION_INCOMPLETE + * Operation was interrupted due to the setting of \c + * psa_interruptible_set_max_ops(). There is still work to be done. + * Call this function again with the same operation object. + * + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * + * \retval #PSA_ERROR_BAD_STATE + * An operation was not previously started on this context via + * \c psa_sign_hash_start(). + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has either not been previously initialized by + * psa_crypto_init() or you did not previously call + * psa_sign_hash_start() with this operation object. It is + * implementation-dependent whether a failure to initialize results in + * this error code. + */ +psa_status_t psa_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +/** + * \brief Abort a sign hash operation. + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function is the only function that clears + * the number of ops completed as part of the + * operation. Please ensure you copy this value via + * \c psa_sign_hash_get_num_ops() if required + * before calling. + * + * \note Aborting an operation frees all associated + * resources except for the \p operation structure + * itself. Once aborted, the operation object can + * be reused for another operation by calling \c + * psa_sign_hash_start() again. + * + * \note You may call this function any time after the + * operation object has been initialized. In + * particular, calling \c psa_sign_hash_abort() + * after the operation has already been terminated + * by a call to \c psa_sign_hash_abort() or + * psa_sign_hash_complete() is safe. + * + * \param[in,out] operation Initialized sign hash operation. + * + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *operation); + +/** + * \brief Start reading and verifying a hash or short + * message, in an interruptible manner. + * + * \see \c psa_verify_hash_complete() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_verify_hash_complete() is equivalent to + * \c psa_verify_hash() but \c + * psa_verify_hash_complete() can return early and + * resume according to the limit set with \c + * psa_interruptible_set_max_ops() to reduce the + * maximum time spent in a function. + * + * \note Users should call \c psa_verify_hash_complete() + * repeatedly on the same operation object after a + * successful call to this function until \c + * psa_verify_hash_complete() either returns 0 or + * an error. \c psa_verify_hash_complete() will + * return #PSA_OPERATION_INCOMPLETE if there is + * more work to do. Alternatively users can call + * \c psa_verify_hash_abort() at any point if they + * no longer want the result. + * + * \note If this function returns an error status, the + * operation enters an error state and must be + * aborted by calling \c psa_verify_hash_abort(). + * + * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \param key Identifier of the key to use for the operation. + * The key must allow the usage + * #PSA_KEY_USAGE_VERIFY_HASH. + * \param alg A signature algorithm (\c PSA_ALG_XXX + * value such that #PSA_ALG_IS_SIGN_HASH(\p alg) + * is true), that is compatible with + * the type of \p key. + * \param[in] hash The hash whose signature is to be verified. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[in] signature Buffer containing the signature to verify. + * \param signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * The operation started successfully - please call \c + * psa_verify_hash_complete() with the same context to complete the + * operation. + * + * \retval #PSA_ERROR_BAD_STATE + * Another operation has already been started on this context, and is + * still in progress. + * + * \retval #PSA_ERROR_NOT_PERMITTED + * The key does not have the #PSA_KEY_USAGE_VERIFY_HASH flag, or it does + * not permit the requested algorithm. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_hash_start( + psa_verify_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length); + +/** + * \brief Continue and eventually complete the action of + * reading and verifying a hash or short message + * signed with a private key, in an interruptible + * manner. + * + * \see \c psa_verify_hash_start() + * + * \warning This is a beta API, and thus subject to change + * at any point. It is not bound by the usual + * interface stability promises. + * + * \note This function combined with \c + * psa_verify_hash_start() is equivalent to + * \c psa_verify_hash() but this function can + * return early and resume according to the limit + * set with \c psa_interruptible_set_max_ops() to + * reduce the maximum time spent in a function + * call. + * + * \note Users should call this function on the same + * operation object repeatedly until it either + * returns 0 or an error. This function will return + * #PSA_OPERATION_INCOMPLETE if there is more work + * to do. Alternatively users can call + * \c psa_verify_hash_abort() at any point if they + * no longer want the result. + * + * \note When this function returns successfully, the + * operation becomes inactive. If this function + * returns an error status, the operation enters an + * error state and must be aborted by calling + * \c psa_verify_hash_abort(). + * + * \param[in, out] operation The \c psa_verify_hash_interruptible_operation_t + * to use. This must be initialized first, and have + * had \c psa_verify_hash_start() called with it + * first. + * + * \retval #PSA_SUCCESS + * Operation completed successfully, and the passed signature is valid. + * + * \retval #PSA_OPERATION_INCOMPLETE + * Operation was interrupted due to the setting of \c + * psa_interruptible_set_max_ops(). There is still work to be done. + * Call this function again with the same operation object. + * + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed + * signature is not a valid signature. + * \retval #PSA_ERROR_BAD_STATE + * An operation was not previously started on this context via + * \c psa_verify_hash_start(). + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has either not been previously initialized by + * psa_crypto_init() or you did not previously call + * psa_verify_hash_start() on this object. It is + * implementation-dependent whether a failure to initialize results in + * this error code. + */ +psa_status_t psa_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Abort a verify hash operation. + * + * \warning This is a beta API, and thus subject to change at + * any point. It is not bound by the usual interface + * stability promises. + * + * \note This function is the only function that clears the + * number of ops completed as part of the operation. + * Please ensure you copy this value via + * \c psa_verify_hash_get_num_ops() if required + * before calling. + * + * \note Aborting an operation frees all associated + * resources except for the operation structure + * itself. Once aborted, the operation object can be + * reused for another operation by calling \c + * psa_verify_hash_start() again. + * + * \note You may call this function any time after the + * operation object has been initialized. + * In particular, calling \c psa_verify_hash_abort() + * after the operation has already been terminated by + * a call to \c psa_verify_hash_abort() or + * psa_verify_hash_complete() is safe. + * + * \param[in,out] operation Initialized verify hash operation. + * + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *operation); + + +/**@}*/ + #ifdef __cplusplus } #endif @@ -4055,7 +4684,11 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, /* The file "crypto_struct.h" contains definitions for * implementation-specific structs that are declared above. */ +#if defined(MBEDTLS_PSA_CRYPTO_STRUCT_FILE) +#include MBEDTLS_PSA_CRYPTO_STRUCT_FILE +#else #include "crypto_struct.h" +#endif /* The file "crypto_extra.h" contains vendor-specific definitions. This * can include vendor-defined algorithms, extra functions, etc. */ diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index b7f0b11621..9f23551eb1 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -107,4 +107,78 @@ typedef struct { #define MBEDTLS_PSA_AEAD_OPERATION_INIT { 0, 0, 0, 0, { 0 } } +#include "mbedtls/ecdsa.h" + +/* Context structure for the Mbed TLS interruptible sign hash implementation. */ +typedef struct { +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx); + mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx); + + uint32_t MBEDTLS_PRIVATE(num_ops); + + size_t MBEDTLS_PRIVATE(coordinate_bytes); + psa_algorithm_t MBEDTLS_PRIVATE(alg); + mbedtls_md_type_t MBEDTLS_PRIVATE(md_alg); + uint8_t MBEDTLS_PRIVATE(hash)[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; + size_t MBEDTLS_PRIVATE(hash_length); + +#else + /* Make the struct non-empty if algs not supported. */ + unsigned MBEDTLS_PRIVATE(dummy); + +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} mbedtls_psa_sign_hash_interruptible_operation_t; + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 } +#else +#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 } +#endif + +/* Context structure for the Mbed TLS interruptible verify hash + * implementation.*/ +typedef struct { +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx); + mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx); + + uint32_t MBEDTLS_PRIVATE(num_ops); + + uint8_t MBEDTLS_PRIVATE(hash)[PSA_BITS_TO_BYTES(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; + size_t MBEDTLS_PRIVATE(hash_length); + + mbedtls_mpi MBEDTLS_PRIVATE(r); + mbedtls_mpi MBEDTLS_PRIVATE(s); + +#else + /* Make the struct non-empty if algs not supported. */ + unsigned MBEDTLS_PRIVATE(dummy); + +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ + +} mbedtls_psa_verify_hash_interruptible_operation_t; + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) +#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, { 0 }, \ + { 0 } } +#else +#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0 } +#endif + + + #endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/include/psa/crypto_compat.h b/include/psa/crypto_compat.h index 97e65848c3..3544f96327 100644 --- a/include/psa/crypto_compat.h +++ b/include/psa/crypto_compat.h @@ -105,11 +105,11 @@ static inline int psa_key_handle_is_null(psa_key_handle_t handle) * permission to access it. Note that this specification does not * define any way to create such a key, but it may be possible * through implementation-specific means. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -149,8 +149,8 @@ psa_status_t psa_open_key(mbedtls_svc_key_id_t key, * \p handle was a valid handle or \c 0. It is now closed. * \retval #PSA_ERROR_INVALID_HANDLE * \p handle is not a valid handle nor \c 0. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h index bcd000e703..1b95814f9e 100644 --- a/include/psa/crypto_driver_contexts_composites.h +++ b/include/psa/crypto_driver_contexts_composites.h @@ -114,5 +114,15 @@ typedef union { #endif } psa_driver_aead_context_t; +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_sign_hash_interruptible_operation_t mbedtls_ctx; +} psa_driver_sign_hash_interruptible_context_t; + +typedef union { + unsigned dummy; /* Make sure this union is always non-empty */ + mbedtls_psa_verify_hash_interruptible_operation_t mbedtls_ctx; +} psa_driver_verify_hash_interruptible_context_t; + #endif /* PSA_CRYPTO_DRIVER_CONTEXTS_COMPOSITES_H */ /* End of automatically generated file. */ diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index bd1b5af569..582d94249e 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -189,12 +189,12 @@ static inline void psa_clear_key_slot_number( * or the specified slot number is not valid. * \retval #PSA_ERROR_NOT_PERMITTED * The caller is not authorized to register the specified key slot. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -491,10 +491,10 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed, * according to \p type as described above. * \param data_length Size of the \p data buffer in bytes. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, psa_key_type_t type, @@ -521,8 +521,8 @@ psa_status_t psa_set_key_domain_parameters(psa_key_attributes_t *attributes, * \param[out] data_length On success, the number of bytes * that make up the key domain parameters data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_BUFFER_TOO_SMALL \emptydescription */ psa_status_t psa_get_key_domain_parameters( const psa_key_attributes_t *attributes, @@ -1352,8 +1352,8 @@ static psa_pake_operation_t psa_pake_operation_init(void); * compatible with the PAKE algorithm, or the hash algorithm in * \p cipher_suite is not supported or not compatible with the PAKE * algorithm and primitive. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid, or * the library has not been previously initialized by psa_crypto_init(). @@ -1397,11 +1397,11 @@ psa_status_t psa_pake_setup(psa_pake_operation_t *operation, * \retval #PSA_ERROR_NOT_SUPPORTED * The key type or key size of \p password is not supported with the * \p operation's cipher suite. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must have been set up.), or * the library has not been previously initialized by psa_crypto_init(). @@ -1439,9 +1439,9 @@ psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation, * suite. * \retval #PSA_ERROR_NOT_SUPPORTED * The value of \p user_id is not supported by the implementation. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid, or * the library has not been previously initialized by psa_crypto_init(). @@ -1480,9 +1480,9 @@ psa_status_t psa_pake_set_user(psa_pake_operation_t *operation, * suite. * \retval #PSA_ERROR_NOT_SUPPORTED * The algorithm doesn't associate a second identity with the session. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * Calling psa_pake_set_peer() is invalid with the \p operation's * algorithm, the operation state is not valid, or the library has not @@ -1524,8 +1524,8 @@ psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation, * The \p role is not a valid PAKE role in the \p operation’s algorithm. * \retval #PSA_ERROR_NOT_SUPPORTED * The \p role for this algorithm is not supported or is not valid. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid, or * the library has not been previously initialized by psa_crypto_init(). @@ -1575,13 +1575,13 @@ psa_status_t psa_pake_set_role(psa_pake_operation_t *operation, * \p step is not compatible with the operation's algorithm. * \retval #PSA_ERROR_NOT_SUPPORTED * \p step is not supported with the operation's algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, and fully set * up, and this call must conform to the algorithm's requirements @@ -1631,12 +1631,12 @@ psa_status_t psa_pake_output(psa_pake_operation_t *operation, * \p step p is not supported with the \p operation's algorithm, or the * \p input is not supported for the \p operation's algorithm, cipher * suite or \p step. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active, and fully set * up, and this call must conform to the algorithm's requirements @@ -1691,12 +1691,12 @@ psa_status_t psa_pake_input(psa_pake_operation_t *operation, * \retval #PSA_ERROR_NOT_SUPPORTED * Input from a PAKE is not supported by the algorithm in the \p output * key derivation operation. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription * \retval #PSA_ERROR_BAD_STATE * The PAKE operation state is not valid (it must be active, but beyond * that validity is specific to the algorithm), or @@ -1728,8 +1728,8 @@ psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, * * \retval #PSA_SUCCESS * Success. - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize diff --git a/include/psa/crypto_se_driver.h b/include/psa/crypto_se_driver.h index a0527897cf..9ae631ffec 100644 --- a/include/psa/crypto_se_driver.h +++ b/include/psa/crypto_se_driver.h @@ -385,8 +385,8 @@ typedef struct { * \param[in] direction Indicates whether the operation is an encrypt * or decrypt * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription */ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_context, void *op_context, @@ -407,7 +407,7 @@ typedef psa_status_t (*psa_drv_se_cipher_setup_t)(psa_drv_se_context_t *drv_cont * \param[in] p_iv A buffer containing the initialization vector * \param[in] iv_length The size (in bytes) of the `p_iv` buffer * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context, const uint8_t *p_iv, @@ -429,7 +429,7 @@ typedef psa_status_t (*psa_drv_se_cipher_set_iv_t)(void *op_context, * \param[out] p_output_length After completion, will contain the number * of bytes placed in the `p_output` buffer * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context, const uint8_t *p_input, @@ -450,7 +450,7 @@ typedef psa_status_t (*psa_drv_se_cipher_update_t)(void *op_context, * \param[out] p_output_length After completion, will contain the number of * bytes placed in the `p_output` buffer * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_cipher_finish_t)(void *op_context, uint8_t *p_output, @@ -485,8 +485,8 @@ typedef psa_status_t (*psa_drv_se_cipher_abort_t)(void *op_context); * \param[in] output_size The allocated size in bytes of the `p_output` * buffer * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription */ typedef psa_status_t (*psa_drv_se_cipher_ecb_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -554,7 +554,7 @@ typedef struct { * \param[out] p_signature_length On success, the number of bytes * that make up the returned signature value * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_asymmetric_sign_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -618,7 +618,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_verify_t)(psa_drv_se_context_t *drv * \param[out] p_output_length On success, the number of bytes that make up * the returned output * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -658,7 +658,7 @@ typedef psa_status_t (*psa_drv_se_asymmetric_encrypt_t)(psa_drv_se_context_t *dr * \param[out] p_output_length On success, the number of bytes * that make up the returned output * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_asymmetric_decrypt_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key_slot, @@ -904,8 +904,8 @@ typedef enum { * Success. * The core will record \c *key_slot as the key slot where the key * is stored and will update the persistent data in storage. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription */ typedef psa_status_t (*psa_drv_se_allocate_key_t)( psa_drv_se_context_t *drv_context, @@ -1043,13 +1043,13 @@ typedef psa_status_t (*psa_drv_se_destroy_key_t)( * \param[out] p_data_length On success, the number of bytes * that make up the key data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_DOES_NOT_EXIST - * \retval #PSA_ERROR_NOT_PERMITTED - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ typedef psa_status_t (*psa_drv_se_export_key_t)(psa_drv_se_context_t *drv_context, psa_key_slot_number_t key, @@ -1196,7 +1196,7 @@ typedef struct { * \param[in] source_key The key to be used as the source material for * the key derivation * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t *drv_context, void *op_context, @@ -1216,7 +1216,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_setup_t)(psa_drv_se_context_t * * \param[in] p_collateral A buffer containing the collateral data * \param[in] collateral_size The size in bytes of the collateral * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context, uint32_t collateral_id, @@ -1231,7 +1231,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_collateral_t)(void *op_context, * \param[in] dest_key The slot where the generated key material * should be placed * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context, psa_key_slot_number_t dest_key); @@ -1245,7 +1245,7 @@ typedef psa_status_t (*psa_drv_se_key_derivation_derive_t)(void *op_context, * \param[out] p_output_length Upon success, contains the number of bytes of * key material placed in `p_output` * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ typedef psa_status_t (*psa_drv_se_key_derivation_export_t)(void *op_context, uint8_t *p_output, diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 7a6caa2ed6..934bc176ef 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -491,6 +491,66 @@ static inline size_t psa_get_key_bits( return attributes->MBEDTLS_PRIVATE(core).MBEDTLS_PRIVATE(bits); } +/** + * \brief The context for PSA interruptible hash signing. + */ +struct psa_sign_hash_interruptible_operation_s { + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_crypto_driver_wrappers.h + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. none of the driver contexts are active). */ + unsigned int MBEDTLS_PRIVATE(id); + + psa_driver_sign_hash_interruptible_context_t MBEDTLS_PRIVATE(ctx); + + unsigned int MBEDTLS_PRIVATE(error_occurred) : 1; + + uint32_t MBEDTLS_PRIVATE(num_ops); +}; + +#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 } + +static inline struct psa_sign_hash_interruptible_operation_s +psa_sign_hash_interruptible_operation_init(void) +{ + const struct psa_sign_hash_interruptible_operation_s v = + PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT; + + return v; +} + +/** + * \brief The context for PSA interruptible hash verification. + */ +struct psa_verify_hash_interruptible_operation_s { + /** Unique ID indicating which driver got assigned to do the + * operation. Since driver contexts are driver-specific, swapping + * drivers halfway through the operation is not supported. + * ID values are auto-generated in psa_crypto_driver_wrappers.h + * ID value zero means the context is not valid or not assigned to + * any driver (i.e. none of the driver contexts are active). */ + unsigned int MBEDTLS_PRIVATE(id); + + psa_driver_verify_hash_interruptible_context_t MBEDTLS_PRIVATE(ctx); + + unsigned int MBEDTLS_PRIVATE(error_occurred) : 1; + + uint32_t MBEDTLS_PRIVATE(num_ops); +}; + +#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0, 0 } + +static inline struct psa_verify_hash_interruptible_operation_s +psa_verify_hash_interruptible_operation_init(void) +{ + const struct psa_verify_hash_interruptible_operation_s v = + PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT; + + return v; +} + #ifdef __cplusplus } #endif diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h index 95bf32fd98..a5154fcd6b 100644 --- a/include/psa/crypto_types.h +++ b/include/psa/crypto_types.h @@ -32,16 +32,17 @@ #ifndef PSA_CRYPTO_TYPES_H #define PSA_CRYPTO_TYPES_H + +/* Make sure the Mbed TLS configuration is visible. */ +#include "mbedtls/build_info.h" +/* Define the MBEDTLS_PRIVATE macro. */ #include "mbedtls/private_access.h" +#if defined(MBEDTLS_PSA_CRYPTO_PLATFORM_FILE) +#include MBEDTLS_PSA_CRYPTO_PLATFORM_FILE +#else #include "crypto_platform.h" - -/* If MBEDTLS_PSA_CRYPTO_C is defined, make sure MBEDTLS_PSA_CRYPTO_CLIENT - * is defined as well to include all PSA code. - */ -#if defined(MBEDTLS_PSA_CRYPTO_C) -#define MBEDTLS_PSA_CRYPTO_CLIENT -#endif /* MBEDTLS_PSA_CRYPTO_C */ +#endif #include diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index ee95745ade..39acd96c52 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -335,6 +335,13 @@ */ #define PSA_ERROR_DATA_INVALID ((psa_status_t)-153) +/** The function that returns this status is defined as interruptible and + * still has work to do, thus the user should call the function again with the + * same operation context until it either returns #PSA_SUCCESS or any other + * error. This is not an error per se, more a notification of status. + */ +#define PSA_OPERATION_INCOMPLETE ((psa_status_t)-248) + /* *INDENT-ON* */ /**@}*/ @@ -2739,4 +2746,18 @@ static inline int mbedtls_svc_key_id_is_null(mbedtls_svc_key_id_t key) /**@}*/ +/**@}*/ + +/** \defgroup interruptible Interruptible operations + * @{ + */ + +/** Maximum value for use with \c psa_interruptible_set_max_ops() to determine + * the maximum number of ops allowed to be executed by an interruptible + * function in a single call. + */ +#define PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED UINT32_MAX + +/**@}*/ + #endif /* PSA_CRYPTO_VALUES_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index c9714bbfbe..bef2e1c4bd 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -13,6 +13,7 @@ endif() set(src_crypto aes.c aesni.c + aesce.c aria.c asn1parse.c asn1write.c diff --git a/library/Makefile b/library/Makefile index dd16d06158..ed5e1e1729 100644 --- a/library/Makefile +++ b/library/Makefile @@ -78,6 +78,7 @@ endif OBJS_CRYPTO= \ aes.o \ aesni.o \ + aesce.o \ aria.o \ asn1parse.o \ asn1write.o \ diff --git a/library/aes.c b/library/aes.c index 566e74715f..64392fc56b 100644 --- a/library/aes.c +++ b/library/aes.c @@ -39,6 +39,9 @@ #if defined(MBEDTLS_AESNI_C) #include "aesni.h" #endif +#if defined(MBEDTLS_AESCE_C) +#include "aesce.h" +#endif #include "mbedtls/platform.h" @@ -544,6 +547,12 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key, } #endif +#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) + if (mbedtls_aesce_has_support()) { + return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits); + } +#endif + for (i = 0; i < (keybits >> 5); i++) { RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2); } @@ -652,6 +661,16 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, } #endif +#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) + if (mbedtls_aesce_has_support()) { + mbedtls_aesce_inverse_key( + (unsigned char *) RK, + (const unsigned char *) (cty.buf + cty.rk_offset), + ctx->nr); + goto exit; + } +#endif + SK = cty.buf + cty.rk_offset + cty.nr * 4; *RK++ = *SK++; @@ -944,6 +963,12 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx, } #endif +#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) + if (mbedtls_aesce_has_support()) { + return mbedtls_aesce_crypt_ecb(ctx, mode, input, output); + } +#endif + #if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) if (aes_padlock_ace > 0) { if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) { diff --git a/library/aesce.c b/library/aesce.c new file mode 100644 index 0000000000..ee0c8e12cf --- /dev/null +++ b/library/aesce.c @@ -0,0 +1,257 @@ +/* + * Arm64 crypto extension support functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "common.h" + +#if defined(MBEDTLS_AESCE_C) + +#include "aesce.h" + +#if defined(MBEDTLS_HAVE_ARM64) + +#if defined(__clang__) +# if __clang_major__ < 4 +# error "A more recent Clang is required for MBEDTLS_AESCE_C" +# endif +#elif defined(__GNUC__) +# if __GNUC__ < 6 +# error "A more recent GCC is required for MBEDTLS_AESCE_C" +# endif +#else +# error "Only GCC and Clang supported for MBEDTLS_AESCE_C" +#endif + +#if !defined(__ARM_FEATURE_CRYPTO) +# error "`crypto` feature moddifier MUST be enabled for MBEDTLS_AESCE_C." +# error "Typical option for GCC and Clang is `-march=armv8-a+crypto`." +#endif /* !__ARM_FEATURE_CRYPTO */ + +#include + +#if defined(__linux__) +#include +#include +#endif + +/* + * AES instruction support detection routine + */ +int mbedtls_aesce_has_support(void) +{ +#if defined(__linux__) + unsigned long auxval = getauxval(AT_HWCAP); + return (auxval & (HWCAP_ASIMD | HWCAP_AES)) == + (HWCAP_ASIMD | HWCAP_AES); +#else + /* Assume AES instructions are supported. */ + return 1; +#endif +} + +static uint8x16_t aesce_encrypt_block(uint8x16_t block, + unsigned char *keys, + int rounds) +{ + for (int i = 0; i < rounds - 1; i++) { + /* AES AddRoundKey, SubBytes, ShiftRows (in this order). + * AddRoundKey adds the round key for the previous round. */ + block = vaeseq_u8(block, vld1q_u8(keys + i * 16)); + /* AES mix columns */ + block = vaesmcq_u8(block); + } + + /* AES AddRoundKey for the previous round. + * SubBytes, ShiftRows for the final round. */ + block = vaeseq_u8(block, vld1q_u8(keys + (rounds -1) * 16)); + + /* Final round: no MixColumns */ + + /* Final AddRoundKey */ + block = veorq_u8(block, vld1q_u8(keys + rounds * 16)); + + return block; +} + +static uint8x16_t aesce_decrypt_block(uint8x16_t block, + unsigned char *keys, + int rounds) +{ + + for (int i = 0; i < rounds - 1; i++) { + /* AES AddRoundKey, SubBytes, ShiftRows */ + block = vaesdq_u8(block, vld1q_u8(keys + i * 16)); + /* AES inverse MixColumns for the next round. + * + * This means that we switch the order of the inverse AddRoundKey and + * inverse MixColumns operations. We have to do this as AddRoundKey is + * done in an atomic instruction together with the inverses of SubBytes + * and ShiftRows. + * + * It works because MixColumns is a linear operation over GF(2^8) and + * AddRoundKey is an exclusive or, which is equivalent to addition over + * GF(2^8). (The inverse of MixColumns needs to be applied to the + * affected round keys separately which has been done when the + * decryption round keys were calculated.) */ + block = vaesimcq_u8(block); + } + + /* The inverses of AES AddRoundKey, SubBytes, ShiftRows finishing up the + * last full round. */ + block = vaesdq_u8(block, vld1q_u8(keys + (rounds - 1) * 16)); + + /* Inverse AddRoundKey for inverting the initial round key addition. */ + block = veorq_u8(block, vld1q_u8(keys + rounds * 16)); + + return block; +} + +/* + * AES-ECB block en(de)cryption + */ +int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16]) +{ + uint8x16_t block = vld1q_u8(&input[0]); + unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset); + + if (mode == MBEDTLS_AES_ENCRYPT) { + block = aesce_encrypt_block(block, keys, ctx->nr); + } else { + block = aesce_decrypt_block(block, keys, ctx->nr); + } + vst1q_u8(&output[0], block); + + return 0; +} + +/* + * Compute decryption round keys from encryption round keys + */ +void mbedtls_aesce_inverse_key(unsigned char *invkey, + const unsigned char *fwdkey, + int nr) +{ + int i, j; + j = nr; + vst1q_u8(invkey, vld1q_u8(fwdkey + j * 16)); + for (i = 1, j--; j > 0; i++, j--) { + vst1q_u8(invkey + i * 16, + vaesimcq_u8(vld1q_u8(fwdkey + j * 16))); + } + vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16)); + +} + +static inline uint32_t aes_rot_word(uint32_t word) +{ + return (word << (32 - 8)) | (word >> 8); +} + +static inline uint32_t aes_sub_word(uint32_t in) +{ + uint8x16_t v = vreinterpretq_u8_u32(vdupq_n_u32(in)); + uint8x16_t zero = vdupq_n_u8(0); + + /* vaeseq_u8 does both SubBytes and ShiftRows. Taking the first row yields + * the correct result as ShiftRows doesn't change the first row. */ + v = vaeseq_u8(zero, v); + return vgetq_lane_u32(vreinterpretq_u32_u8(v), 0); +} + +/* + * Key expansion function + */ +static void aesce_setkey_enc(unsigned char *rk, + const unsigned char *key, + const size_t key_bit_length) +{ + static uint8_t const rcon[] = { 0x01, 0x02, 0x04, 0x08, 0x10, + 0x20, 0x40, 0x80, 0x1b, 0x36 }; + /* See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.197.pdf + * - Section 5, Nr = Nk + 6 + * - Section 5.2, the key expansion size is Nb*(Nr+1) + */ + const uint32_t key_len_in_words = key_bit_length / 32; /* Nk */ + const size_t round_key_len_in_words = 4; /* Nb */ + const size_t round_keys_needed = key_len_in_words + 6; /* Nr */ + const size_t key_expansion_size_in_words = + round_key_len_in_words * (round_keys_needed + 1); /* Nb*(Nr+1) */ + const uint32_t *rko_end = (uint32_t *) rk + key_expansion_size_in_words; + + memcpy(rk, key, key_len_in_words * 4); + + for (uint32_t *rki = (uint32_t *) rk; + rki + key_len_in_words < rko_end; + rki += key_len_in_words) { + + size_t iteration = (rki - (uint32_t *) rk) / key_len_in_words; + uint32_t *rko; + rko = rki + key_len_in_words; + rko[0] = aes_rot_word(aes_sub_word(rki[key_len_in_words - 1])); + rko[0] ^= rcon[iteration] ^ rki[0]; + rko[1] = rko[0] ^ rki[1]; + rko[2] = rko[1] ^ rki[2]; + rko[3] = rko[2] ^ rki[3]; + if (rko + key_len_in_words > rko_end) { + /* Do not write overflow words.*/ + continue; + } + switch (key_bit_length) { + case 128: + break; + case 192: + rko[4] = rko[3] ^ rki[4]; + rko[5] = rko[4] ^ rki[5]; + break; + case 256: + rko[4] = aes_sub_word(rko[3]) ^ rki[4]; + rko[5] = rko[4] ^ rki[5]; + rko[6] = rko[5] ^ rki[6]; + rko[7] = rko[6] ^ rki[7]; + break; + } + } +} + +/* + * Key expansion, wrapper + */ +int mbedtls_aesce_setkey_enc(unsigned char *rk, + const unsigned char *key, + size_t bits) +{ + switch (bits) { + case 128: + case 192: + case 256: + aesce_setkey_enc(rk, key, bits); + break; + default: + return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH; + } + + return 0; +} + +#endif /* MBEDTLS_HAVE_ARM64 */ + +#endif /* MBEDTLS_AESCE_C */ diff --git a/library/aesce.h b/library/aesce.h new file mode 100644 index 0000000000..da42446997 --- /dev/null +++ b/library/aesce.h @@ -0,0 +1,98 @@ +/** + * \file aesce.h + * + * \brief AES-CE for hardware AES acceleration on ARMv8 processors with crypto + * extension. + * + * \warning These functions are only for internal use by other library + * functions; you must not call them directly. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBEDTLS_AESCE_H +#define MBEDTLS_AESCE_H + +#include "mbedtls/build_info.h" + +#include "mbedtls/aes.h" + + +#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \ + defined(__aarch64__) && !defined(MBEDTLS_HAVE_ARM64) +#define MBEDTLS_HAVE_ARM64 +#endif + +#if defined(MBEDTLS_HAVE_ARM64) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Internal function to detect the crypto extension in CPUs. + * + * \return 1 if CPU has support for the feature, 0 otherwise + */ +int mbedtls_aesce_has_support(void); + +/** + * \brief Internal AES-ECB block encryption and decryption + * + * \param ctx AES context + * \param mode MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 on success (cannot fail) + */ +int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16]); + +/** + * \brief Internal round key inversion. This function computes + * decryption round keys from the encryption round keys. + * + * \param invkey Round keys for the equivalent inverse cipher + * \param fwdkey Original round keys (for encryption) + * \param nr Number of rounds (that is, number of round keys minus one) + */ +void mbedtls_aesce_inverse_key(unsigned char *invkey, + const unsigned char *fwdkey, + int nr); + +/** + * \brief Internal key expansion for encryption + * + * \param rk Destination buffer where the round keys are written + * \param key Encryption key + * \param bits Key size in bits (must be 128, 192 or 256) + * + * \return 0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH + */ +int mbedtls_aesce_setkey_enc(unsigned char *rk, + const unsigned char *key, + size_t bits); + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_HAVE_ARM64 */ + +#endif /* MBEDTLS_AESCE_H */ diff --git a/library/alignment.h b/library/alignment.h index aa09ff8569..f7330c9897 100644 --- a/library/alignment.h +++ b/library/alignment.h @@ -130,7 +130,7 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) * byte from x, where byte 0 is the least significant byte. */ #define MBEDTLS_BYTE_0(x) ((uint8_t) ((x) & 0xff)) -#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff)) +#define MBEDTLS_BYTE_1(x) ((uint8_t) (((x) >> 8) & 0xff)) #define MBEDTLS_BYTE_2(x) ((uint8_t) (((x) >> 16) & 0xff)) #define MBEDTLS_BYTE_3(x) ((uint8_t) (((x) >> 24) & 0xff)) #define MBEDTLS_BYTE_4(x) ((uint8_t) (((x) >> 32) & 0xff)) @@ -155,13 +155,13 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) * Detect Clang built-in byteswap routines */ #if defined(__clang__) && defined(__has_builtin) -#if __has_builtin(__builtin_bswap16) +#if __has_builtin(__builtin_bswap16) && !defined(MBEDTLS_BSWAP16) #define MBEDTLS_BSWAP16 __builtin_bswap16 #endif /* __has_builtin(__builtin_bswap16) */ -#if __has_builtin(__builtin_bswap32) +#if __has_builtin(__builtin_bswap32) && !defined(MBEDTLS_BSWAP32) #define MBEDTLS_BSWAP32 __builtin_bswap32 #endif /* __has_builtin(__builtin_bswap32) */ -#if __has_builtin(__builtin_bswap64) +#if __has_builtin(__builtin_bswap64) && !defined(MBEDTLS_BSWAP64) #define MBEDTLS_BSWAP64 __builtin_bswap64 #endif /* __has_builtin(__builtin_bswap64) */ #endif /* defined(__clang__) && defined(__has_builtin) */ @@ -170,13 +170,19 @@ inline void mbedtls_put_unaligned_uint64(void *p, uint64_t x) * Detect MSVC built-in byteswap routines */ #if defined(_MSC_VER) +#if !defined(MBEDTLS_BSWAP16) #define MBEDTLS_BSWAP16 _byteswap_ushort +#endif +#if !defined(MBEDTLS_BSWAP32) #define MBEDTLS_BSWAP32 _byteswap_ulong +#endif +#if !defined(MBEDTLS_BSWAP64) #define MBEDTLS_BSWAP64 _byteswap_uint64 +#endif #endif /* defined(_MSC_VER) */ /* Detect armcc built-in byteswap routine */ -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 410000) && !defined(MBEDTLS_BSWAP32) #define MBEDTLS_BSWAP32 __rev #endif @@ -239,8 +245,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the four bytes to build the 32 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT32_BE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ +#define MBEDTLS_GET_UINT32_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ ? mbedtls_get_unaligned_uint32((data) + (offset)) \ : MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ ) @@ -254,11 +260,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * \param offset Offset from \p data where to put the most significant * byte of the 32 bits unsigned integer \p n. */ -#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \ +#define MBEDTLS_PUT_UINT32_BE(n, data, offset) \ { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ + if (MBEDTLS_IS_BIG_ENDIAN) \ { \ - mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \ + mbedtls_put_unaligned_uint32((data) + (offset), (uint32_t) (n)); \ } \ else \ { \ @@ -275,8 +281,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the four bytes to build the 32 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT32_LE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ +#define MBEDTLS_GET_UINT32_LE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ ? MBEDTLS_BSWAP32(mbedtls_get_unaligned_uint32((data) + (offset))) \ : mbedtls_get_unaligned_uint32((data) + (offset)) \ ) @@ -291,15 +297,15 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * \param offset Offset from \p data where to put the least significant * byte of the 32 bits unsigned integer \p n. */ -#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \ +#define MBEDTLS_PUT_UINT32_LE(n, data, offset) \ { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ + if (MBEDTLS_IS_BIG_ENDIAN) \ { \ mbedtls_put_unaligned_uint32((data) + (offset), MBEDTLS_BSWAP32((uint32_t) (n))); \ } \ else \ { \ - mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \ + mbedtls_put_unaligned_uint32((data) + (offset), ((uint32_t) (n))); \ } \ } @@ -312,8 +318,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the two bytes to build the 16 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT16_LE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ +#define MBEDTLS_GET_UINT16_LE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ ? MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \ : mbedtls_get_unaligned_uint16((data) + (offset)) \ ) @@ -327,15 +333,15 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * \param offset Offset from \p data where to put the least significant * byte of the 16 bits unsigned integer \p n. */ -#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \ +#define MBEDTLS_PUT_UINT16_LE(n, data, offset) \ { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ + if (MBEDTLS_IS_BIG_ENDIAN) \ { \ mbedtls_put_unaligned_uint16((data) + (offset), MBEDTLS_BSWAP16((uint16_t) (n))); \ } \ else \ { \ - mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ + mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ } \ } @@ -348,8 +354,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the two bytes to build the 16 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT16_BE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ +#define MBEDTLS_GET_UINT16_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ ? mbedtls_get_unaligned_uint16((data) + (offset)) \ : MBEDTLS_BSWAP16(mbedtls_get_unaligned_uint16((data) + (offset))) \ ) @@ -363,11 +369,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * \param offset Offset from \p data where to put the most significant * byte of the 16 bits unsigned integer \p n. */ -#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \ +#define MBEDTLS_PUT_UINT16_BE(n, data, offset) \ { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ + if (MBEDTLS_IS_BIG_ENDIAN) \ { \ - mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ + mbedtls_put_unaligned_uint16((data) + (offset), (uint16_t) (n)); \ } \ else \ { \ @@ -384,11 +390,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the three bytes to build the 24 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT24_BE(data, offset) \ - ( \ - ((uint32_t) (data)[(offset)] << 16) \ - | ((uint32_t) (data)[(offset) + 1] << 8) \ - | ((uint32_t) (data)[(offset) + 2]) \ +#define MBEDTLS_GET_UINT24_BE(data, offset) \ + ( \ + ((uint32_t) (data)[(offset)] << 16) \ + | ((uint32_t) (data)[(offset) + 1] << 8) \ + | ((uint32_t) (data)[(offset) + 2]) \ ) /** @@ -401,8 +407,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the 24 bits unsigned integer \p n. */ #define MBEDTLS_PUT_UINT24_BE(n, data, offset) \ - { \ - (data)[(offset)] = MBEDTLS_BYTE_2(n); \ + { \ + (data)[(offset)] = MBEDTLS_BYTE_2(n); \ (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \ (data)[(offset) + 2] = MBEDTLS_BYTE_0(n); \ } @@ -416,9 +422,9 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the three bytes to build the 24 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT24_LE(data, offset) \ - ( \ - ((uint32_t) (data)[(offset)]) \ +#define MBEDTLS_GET_UINT24_LE(data, offset) \ + ( \ + ((uint32_t) (data)[(offset)]) \ | ((uint32_t) (data)[(offset) + 1] << 8) \ | ((uint32_t) (data)[(offset) + 2] << 16) \ ) @@ -433,8 +439,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the 24 bits unsigned integer \p n. */ #define MBEDTLS_PUT_UINT24_LE(n, data, offset) \ - { \ - (data)[(offset)] = MBEDTLS_BYTE_0(n); \ + { \ + (data)[(offset)] = MBEDTLS_BYTE_0(n); \ (data)[(offset) + 1] = MBEDTLS_BYTE_1(n); \ (data)[(offset) + 2] = MBEDTLS_BYTE_2(n); \ } @@ -448,8 +454,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the eight bytes to build the 64 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT64_BE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ +#define MBEDTLS_GET_UINT64_BE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ ? mbedtls_get_unaligned_uint64((data) + (offset)) \ : MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \ ) @@ -463,11 +469,11 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * \param offset Offset from \p data where to put the most significant * byte of the 64 bits unsigned integer \p n. */ -#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \ +#define MBEDTLS_PUT_UINT64_BE(n, data, offset) \ { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ + if (MBEDTLS_IS_BIG_ENDIAN) \ { \ - mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ + mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ } \ else \ { \ @@ -484,8 +490,8 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * byte of the eight bytes to build the 64 bits unsigned * integer from. */ -#define MBEDTLS_GET_UINT64_LE(data, offset) \ - ((MBEDTLS_IS_BIG_ENDIAN) \ +#define MBEDTLS_GET_UINT64_LE(data, offset) \ + ((MBEDTLS_IS_BIG_ENDIAN) \ ? MBEDTLS_BSWAP64(mbedtls_get_unaligned_uint64((data) + (offset))) \ : mbedtls_get_unaligned_uint64((data) + (offset)) \ ) @@ -499,15 +505,15 @@ static const uint16_t mbedtls_byte_order_detector = { 0x100 }; * \param offset Offset from \p data where to put the least significant * byte of the 64 bits unsigned integer \p n. */ -#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \ +#define MBEDTLS_PUT_UINT64_LE(n, data, offset) \ { \ - if (MBEDTLS_IS_BIG_ENDIAN) \ + if (MBEDTLS_IS_BIG_ENDIAN) \ { \ mbedtls_put_unaligned_uint64((data) + (offset), MBEDTLS_BSWAP64((uint64_t) (n))); \ } \ else \ { \ - mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ + mbedtls_put_unaligned_uint64((data) + (offset), (uint64_t) (n)); \ } \ } diff --git a/library/ecdsa.c b/library/ecdsa.c index 3ddb82b1e7..eb3c303197 100644 --- a/library/ecdsa.c +++ b/library/ecdsa.c @@ -239,13 +239,13 @@ cleanup: * Compute ECDSA signature of a hashed message (SEC1 4.1.3) * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) */ -static int ecdsa_sign_restartable(mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, - int (*f_rng_blind)(void *, unsigned char *, size_t), - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx) +int mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx) { int ret, key_tries, sign_tries; int *p_sign_tries = &sign_tries, *p_key_tries = &key_tries; @@ -394,8 +394,8 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng) { /* Use the same RNG for both blinding and ephemeral key generation */ - return ecdsa_sign_restartable(grp, r, s, d, buf, blen, - f_rng, p_rng, f_rng, p_rng, NULL); + return mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, + f_rng, p_rng, f_rng, p_rng, NULL); } #endif /* !MBEDTLS_ECDSA_SIGN_ALT */ @@ -406,13 +406,13 @@ int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, * note: The f_rng_blind parameter must not be NULL. * */ -static int ecdsa_sign_det_restartable(mbedtls_ecp_group *grp, - mbedtls_mpi *r, mbedtls_mpi *s, - const mbedtls_mpi *d, const unsigned char *buf, size_t blen, - mbedtls_md_type_t md_alg, - int (*f_rng_blind)(void *, unsigned char *, size_t), - void *p_rng_blind, - mbedtls_ecdsa_restart_ctx *rs_ctx) +int mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp, + mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg, + int (*f_rng_blind)(void *, unsigned char *, size_t), + void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_hmac_drbg_context rng_ctx; @@ -462,9 +462,9 @@ sign: ret = mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng); #else - ret = ecdsa_sign_restartable(grp, r, s, d, buf, blen, - mbedtls_hmac_drbg_random, p_rng, - f_rng_blind, p_rng_blind, rs_ctx); + ret = mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, + mbedtls_hmac_drbg_random, p_rng, + f_rng_blind, p_rng_blind, rs_ctx); #endif /* MBEDTLS_ECDSA_SIGN_ALT */ cleanup: @@ -487,8 +487,8 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, size_t), void *p_rng_blind) { - return ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg, - f_rng_blind, p_rng_blind, NULL); + return mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg, + f_rng_blind, p_rng_blind, NULL); } #endif /* MBEDTLS_ECDSA_DETERMINISTIC */ @@ -497,11 +497,12 @@ int mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, * Verify ECDSA signature of hashed message (SEC1 4.1.4) * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) */ -static int ecdsa_verify_restartable(mbedtls_ecp_group *grp, - const unsigned char *buf, size_t blen, - const mbedtls_ecp_point *Q, - const mbedtls_mpi *r, const mbedtls_mpi *s, - mbedtls_ecdsa_restart_ctx *rs_ctx) +int mbedtls_ecdsa_verify_restartable(mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, + const mbedtls_mpi *r, + const mbedtls_mpi *s, + mbedtls_ecdsa_restart_ctx *rs_ctx) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_mpi e, s_inv, u1, u2; @@ -610,7 +611,7 @@ int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp, const mbedtls_mpi *r, const mbedtls_mpi *s) { - return ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL); + return mbedtls_ecdsa_verify_restartable(grp, buf, blen, Q, r, s, NULL); } #endif /* !MBEDTLS_ECDSA_VERIFY_ALT */ @@ -665,9 +666,9 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, mbedtls_mpi_init(&s); #if defined(MBEDTLS_ECDSA_DETERMINISTIC) - MBEDTLS_MPI_CHK(ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d, - hash, hlen, md_alg, f_rng, - p_rng, rs_ctx)); + MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_restartable(&ctx->grp, &r, &s, &ctx->d, + hash, hlen, md_alg, f_rng, + p_rng, rs_ctx)); #else (void) md_alg; @@ -678,9 +679,9 @@ int mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, hash, hlen, f_rng, p_rng)); #else /* Use the same RNG for both blinding and ephemeral key generation */ - MBEDTLS_MPI_CHK(ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d, - hash, hlen, f_rng, p_rng, f_rng, - p_rng, rs_ctx)); + MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_restartable(&ctx->grp, &r, &s, &ctx->d, + hash, hlen, f_rng, p_rng, f_rng, + p_rng, rs_ctx)); #endif /* MBEDTLS_ECDSA_SIGN_ALT */ #endif /* MBEDTLS_ECDSA_DETERMINISTIC */ @@ -760,8 +761,8 @@ int mbedtls_ecdsa_read_signature_restartable(mbedtls_ecdsa_context *ctx, goto cleanup; } #else - if ((ret = ecdsa_verify_restartable(&ctx->grp, hash, hlen, - &ctx->Q, &r, &s, rs_ctx)) != 0) { + if ((ret = mbedtls_ecdsa_verify_restartable(&ctx->grp, hash, hlen, + &ctx->Q, &r, &s, rs_ctx)) != 0) { goto cleanup; } #endif /* MBEDTLS_ECDSA_VERIFY_ALT */ diff --git a/library/ecp_curves.c b/library/ecp_curves.c index 2a97b8c000..b352e7633d 100644 --- a/library/ecp_curves.c +++ b/library/ecp_curves.c @@ -4584,6 +4584,8 @@ static int ecp_mod_p384(mbedtls_mpi *); #endif #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) static int ecp_mod_p521(mbedtls_mpi *); +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *N_p, size_t N_n); #endif #define NIST_MODP(P) grp->modp = ecp_mod_ ## P; @@ -5189,11 +5191,6 @@ cleanup: MBEDTLS_ECP_DP_SECP384R1_ENABLED */ #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) -/* - * Here we have an actual Mersenne prime, so things are more straightforward. - * However, chunks are aligned on a 'weird' boundary (521 bits). - */ - /* Size of p521 in terms of mbedtls_mpi_uint */ #define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1) @@ -5201,48 +5198,81 @@ cleanup: #define P521_MASK 0x01FF /* - * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) - * Write N as A1 + 2^521 A0, return A0 + A1 + * Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) */ static int ecp_mod_p521(mbedtls_mpi *N) { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - size_t i; - mbedtls_mpi M; - mbedtls_mpi_uint Mp[P521_WIDTH + 1]; - /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: - * we need to hold bits 513 to 1056, which is 34 limbs, that is - * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ - - if (N->n < P521_WIDTH) { - return 0; - } - - /* M = A1 */ - M.s = 1; - M.n = N->n - (P521_WIDTH - 1); - if (M.n > P521_WIDTH + 1) { - M.n = P521_WIDTH + 1; - } - M.p = Mp; - memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint)))); - - /* N = A0 */ - N->p[P521_WIDTH - 1] &= P521_MASK; - for (i = P521_WIDTH; i < N->n; i++) { - N->p[i] = 0; - } - - /* N = A0 + A1 */ - MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M)); - + size_t expected_width = 2 * P521_WIDTH; + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, expected_width)); + ret = mbedtls_ecp_mod_p521_raw(N->p, expected_width); cleanup: return ret; } +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs) +{ + mbedtls_mpi_uint carry = 0; + + if (X_limbs != 2 * P521_WIDTH || X[2 * P521_WIDTH - 1] != 0) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + /* Step 1: Reduction to P521_WIDTH limbs */ + /* Helper references for bottom part of X */ + mbedtls_mpi_uint *X0 = X; + size_t X0_limbs = P521_WIDTH; + /* Helper references for top part of X */ + mbedtls_mpi_uint *X1 = X + X0_limbs; + size_t X1_limbs = X_limbs - X0_limbs; + /* Split X as X0 + 2^P521_WIDTH X1 and compute X0 + 2^(biL - 9) X1. + * (We are using that 2^P521_WIDTH = 2^(512 + biL) and that + * 2^(512 + biL) X1 = 2^(biL - 9) X1 mod P521.) + * The high order limb of the result will be held in carry and the rest + * in X0 (that is the result will be represented as + * 2^P521_WIDTH carry + X0). + * + * Also, note that the resulting carry is either 0 or 1: + * X0 < 2^P521_WIDTH = 2^(512 + biL) and X1 < 2^(P521_WIDTH-biL) = 2^512 + * therefore + * X0 + 2^(biL - 9) X1 < 2^(512 + biL) + 2^(512 + biL - 9) + * which in turn is less than 2 * 2^(512 + biL). + */ + mbedtls_mpi_uint shift = ((mbedtls_mpi_uint) 1u) << (biL - 9); + carry = mbedtls_mpi_core_mla(X0, X0_limbs, X1, X1_limbs, shift); + /* Set X to X0 (by clearing the top part). */ + memset(X1, 0, X1_limbs * sizeof(mbedtls_mpi_uint)); + + /* Step 2: Reduction modulo P521 + * + * At this point X is reduced to P521_WIDTH limbs. What remains is to add + * the carry (that is 2^P521_WIDTH carry) and to reduce mod P521. */ + + /* 2^P521_WIDTH carry = 2^(512 + biL) carry = 2^(biL - 9) carry mod P521. + * Also, recall that carry is either 0 or 1. */ + mbedtls_mpi_uint addend = carry << (biL - 9); + /* Keep the top 9 bits and reduce the rest, using 2^521 = 1 mod P521. */ + addend += (X[P521_WIDTH - 1] >> 9); + X[P521_WIDTH - 1] &= P521_MASK; + + /* Resuse the top part of X (already zeroed) as a helper array for + * carrying out the addition. */ + mbedtls_mpi_uint *addend_arr = X + P521_WIDTH; + addend_arr[0] = addend; + (void) mbedtls_mpi_core_add(X, X, addend_arr, P521_WIDTH); + /* Both addends were less than P521 therefore X < 2 * P521. (This also means + * that the result fit in P521_WIDTH limbs and there won't be any carry.) */ + + /* Clear the reused part of X. */ + addend_arr[0] = 0; + + return 0; +} + #undef P521_WIDTH #undef P521_MASK + #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ #endif /* MBEDTLS_ECP_NIST_OPTIM */ @@ -5504,6 +5534,188 @@ static int ecp_mod_p256k1(mbedtls_mpi *N) } #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ -#endif /* !MBEDTLS_ECP_ALT */ +#if defined(MBEDTLS_TEST_HOOKS) +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, + const mbedtls_ecp_group_id id, + const mbedtls_ecp_curve_type ctype) +{ + mbedtls_mpi_uint *p = NULL; + size_t p_limbs; + if (!(ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE || \ + ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_SCALAR)) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + switch (id) { +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + case MBEDTLS_ECP_DP_SECP192R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp192r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_p)); + } else { + p = (mbedtls_mpi_uint *) secp192r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp192r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + case MBEDTLS_ECP_DP_SECP224R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp224r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_p)); + } else { + p = (mbedtls_mpi_uint *) secp224r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp224r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + case MBEDTLS_ECP_DP_SECP256R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp256r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_p)); + } else { + p = (mbedtls_mpi_uint *) secp256r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp256r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + case MBEDTLS_ECP_DP_SECP384R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp384r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_p)); + } else { + p = (mbedtls_mpi_uint *) secp384r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp384r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + case MBEDTLS_ECP_DP_SECP521R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp521r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_p)); + } else { + p = (mbedtls_mpi_uint *) secp521r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp521r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + case MBEDTLS_ECP_DP_BP256R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) brainpoolP256r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_p)); + } else { + p = (mbedtls_mpi_uint *) brainpoolP256r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP256r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + case MBEDTLS_ECP_DP_BP384R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) brainpoolP384r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_p)); + } else { + p = (mbedtls_mpi_uint *) brainpoolP384r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP384r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + case MBEDTLS_ECP_DP_BP512R1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) brainpoolP512r1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_p)); + } else { + p = (mbedtls_mpi_uint *) brainpoolP512r1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(brainpoolP512r1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) curve25519_p; + p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_p)); + } else { + p = (mbedtls_mpi_uint *) curve25519_n; + p_limbs = CHARS_TO_LIMBS(sizeof(curve25519_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + case MBEDTLS_ECP_DP_SECP192K1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp192k1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_p)); + } else { + p = (mbedtls_mpi_uint *) secp192k1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp192k1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + case MBEDTLS_ECP_DP_SECP224K1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp224k1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_p)); + } else { + p = (mbedtls_mpi_uint *) secp224k1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp224k1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + case MBEDTLS_ECP_DP_SECP256K1: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) secp256k1_p; + p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_p)); + } else { + p = (mbedtls_mpi_uint *) secp256k1_n; + p_limbs = CHARS_TO_LIMBS(sizeof(secp256k1_n)); + } + break; +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) + case MBEDTLS_ECP_DP_CURVE448: + if (ctype == (mbedtls_ecp_curve_type) MBEDTLS_ECP_MOD_COORDINATE) { + p = (mbedtls_mpi_uint *) curve448_p; + p_limbs = CHARS_TO_LIMBS(sizeof(curve448_p)); + } else { + p = (mbedtls_mpi_uint *) curve448_n; + p_limbs = CHARS_TO_LIMBS(sizeof(curve448_n)); + } + break; +#endif + + default: + case MBEDTLS_ECP_DP_NONE: + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } + + if (mbedtls_mpi_mod_modulus_setup(N, p, p_limbs, + MBEDTLS_MPI_MOD_REP_MONTGOMERY)) { + return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + } + return 0; +} +#endif /* MBEDTLS_TEST_HOOKS */ +#endif /* !MBEDTLS_ECP_ALT */ #endif /* MBEDTLS_ECP_C */ diff --git a/library/ecp_invasive.h b/library/ecp_invasive.h index 3ee238ee53..aba7cca1ce 100644 --- a/library/ecp_invasive.h +++ b/library/ecp_invasive.h @@ -28,6 +28,7 @@ #include "common.h" #include "mbedtls/bignum.h" +#include "bignum_mod.h" #include "mbedtls/ecp.h" #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C) @@ -95,6 +96,50 @@ int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn); #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + +/** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5) + * + * \param[in,out] X The address of the MPI to be converted. + * Must have twice as many limbs as the modulus + * (the modulus is 521 bits long). Upon return this + * holds the reduced value. The reduced value is + * in range `0 <= X < 2 * N` (where N is the modulus). + * and its the bitlength is one plus the bitlength + * of the modulus. + * \param[in] X_limbs The length of \p X in limbs. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have + * twice as many limbs as the modulus. + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs); + +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +/** Initialise a modulus with hard-coded const curve data. + * + * \note The caller is responsible for the \p N modulus' memory. + * mbedtls_mpi_mod_modulus_free(&N) should be invoked at the + * end of its lifecycle. + * + * \param[in,out] N The address of the modulus structure to populate. + * Must be initialized. + * \param[in] id The mbedtls_ecp_group_id for which to initialise the modulus. + * \param[in] ctype The mbedtls_ecp_curve_type identifier for a coordinate modulus (P) + * or a scalar modulus (N). + * + * \return \c 0 if successful. + * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the given MPIs do not + * have the correct number of limbs. + * + */ +MBEDTLS_STATIC_TESTABLE +int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N, + const mbedtls_ecp_group_id id, + const mbedtls_ecp_curve_type ctype); + #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_INVASIVE_H */ diff --git a/library/oid.c b/library/oid.c index e7c12248a3..86214b23a0 100644 --- a/library/oid.c +++ b/library/oid.c @@ -834,21 +834,55 @@ int mbedtls_oid_get_numeric_string(char *buf, size_t size, p = buf; n = size; - /* First byte contains first two dots */ - if (oid->len > 0) { - ret = mbedtls_snprintf(p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40); - OID_SAFE_SNPRINTF; + /* First subidentifier contains first two OID components */ + i = 0; + value = 0; + if ((oid->p[0]) == 0x80) { + /* Overlong encoding is not allowed */ + return MBEDTLS_ERR_ASN1_INVALID_DATA; } - value = 0; - for (i = 1; i < oid->len; i++) { + while (i < oid->len && ((oid->p[i] & 0x80) != 0)) { /* Prevent overflow in value. */ - if (((value << 7) >> 7) != value) { - return MBEDTLS_ERR_OID_BUF_TOO_SMALL; + if (value > (UINT_MAX >> 7)) { + return MBEDTLS_ERR_ASN1_INVALID_DATA; + } + + value |= oid->p[i] & 0x7F; + value <<= 7; + i++; + } + if (i >= oid->len) { + return MBEDTLS_ERR_ASN1_OUT_OF_DATA; + } + /* Last byte of first subidentifier */ + value |= oid->p[i] & 0x7F; + i++; + + unsigned int component1 = value / 40; + if (component1 > 2) { + /* The first component can only be 0, 1 or 2. + * If oid->p[0] / 40 is greater than 2, the leftover belongs to + * the second component. */ + component1 = 2; + } + unsigned int component2 = value - (40 * component1); + ret = mbedtls_snprintf(p, n, "%u.%u", component1, component2); + OID_SAFE_SNPRINTF; + + value = 0; + for (; i < oid->len; i++) { + /* Prevent overflow in value. */ + if (value > (UINT_MAX >> 7)) { + return MBEDTLS_ERR_ASN1_INVALID_DATA; + } + if ((value == 0) && ((oid->p[i]) == 0x80)) { + /* Overlong encoding is not allowed */ + return MBEDTLS_ERR_ASN1_INVALID_DATA; } value <<= 7; - value += oid->p[i] & 0x7F; + value |= oid->p[i] & 0x7F; if (!(oid->p[i] & 0x80)) { /* Last byte */ diff --git a/library/pk_wrap.c b/library/pk_wrap.c index dc7a27f0ea..45cf807c66 100644 --- a/library/pk_wrap.c +++ b/library/pk_wrap.c @@ -19,6 +19,8 @@ #include "common.h" +#include "mbedtls/platform_util.h" + #if defined(MBEDTLS_PK_C) #include "pk_wrap.h" #include "mbedtls/error.h" @@ -26,39 +28,34 @@ /* Even if RSA not activated, for the sake of RSA-alt */ #include "mbedtls/rsa.h" -#include - #if defined(MBEDTLS_ECP_C) #include "mbedtls/ecp.h" #endif -#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECP_C) -#include "pkwrite.h" -#endif - #if defined(MBEDTLS_ECDSA_C) #include "mbedtls/ecdsa.h" #endif -#if defined(MBEDTLS_USE_PSA_CRYPTO) -#include "mbedtls/asn1write.h" -#endif - -#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) -#include "mbedtls/platform_util.h" +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PSA_CRYPTO_C) +#include "pkwrite.h" #endif #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "psa/crypto.h" #include "mbedtls/psa_util.h" -#include "mbedtls/asn1.h" #include "hash_info.h" + +#if defined(MBEDTLS_PK_CAN_ECDSA_SOME) +#include "mbedtls/asn1write.h" +#include "mbedtls/asn1.h" #endif +#endif /* MBEDTLS_USE_PSA_CRYPTO */ #include "mbedtls/platform.h" #include #include +#include #if defined(MBEDTLS_PSA_CRYPTO_C) int mbedtls_pk_error_from_psa(psa_status_t status) @@ -685,11 +682,14 @@ static int ecdsa_verify_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, 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_ECP_PUB_DER_MAX_BYTES]; + size_t key_len; + /* This buffer will initially contain the public key and then the signature + * but at different points in time. For all curves except secp224k1, which + * is not currently supported in PSA, the public key is one byte longer + * (header byte + 2 numbers, while the signature is only 2 numbers), + * so use that as the buffer size. */ + unsigned char buf[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH]; unsigned char *p; - mbedtls_pk_info_t pk_info = mbedtls_eckey_info; psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY; size_t curve_bits; psa_ecc_family_t curve = @@ -701,22 +701,19 @@ static int ecdsa_verify_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } - /* mbedtls_pk_write_pubkey() expects a full PK context; - * re-construct one to make it happy */ - key.pk_info = &pk_info; - key.pk_ctx = ctx; - p = buf + sizeof(buf); - key_len = mbedtls_pk_write_pubkey(&p, buf, &key); - if (key_len <= 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; - } - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve)); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); psa_set_key_algorithm(&attributes, psa_sig_md); + ret = mbedtls_ecp_point_write_binary(&ctx->grp, &ctx->Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &key_len, buf, sizeof(buf)); + if (ret != 0) { + goto cleanup; + } + status = psa_import_key(&attributes, - buf + sizeof(buf) - key_len, key_len, + buf, key_len, &key_id); if (status != PSA_SUCCESS) { ret = mbedtls_pk_error_from_psa(status); @@ -864,54 +861,6 @@ static int pk_ecdsa_sig_asn1_from_psa(unsigned char *sig, size_t *sig_len, return 0; } -/* Locate an ECDSA privateKey in a RFC 5915, or SEC1 Appendix C.4 ASN.1 buffer - * - * [in/out] buf: ASN.1 buffer start as input - ECDSA privateKey start as output - * [in] end: ASN.1 buffer end - * [out] key_len: the ECDSA privateKey length in bytes - */ -static int find_ecdsa_private_key(unsigned char **buf, unsigned char *end, - size_t *key_len) -{ - size_t len; - int ret; - - /* - * RFC 5915, or SEC1 Appendix C.4 - * - * ECPrivateKey ::= SEQUENCE { - * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), - * privateKey OCTET STRING, - * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, - * publicKey [1] BIT STRING OPTIONAL - * } - */ - - if ((ret = mbedtls_asn1_get_tag(buf, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | - MBEDTLS_ASN1_SEQUENCE)) != 0) { - return ret; - } - - /* version */ - if ((ret = mbedtls_asn1_get_tag(buf, end, &len, - MBEDTLS_ASN1_INTEGER)) != 0) { - return ret; - } - - *buf += len; - - /* privateKey */ - if ((ret = mbedtls_asn1_get_tag(buf, end, &len, - MBEDTLS_ASN1_OCTET_STRING)) != 0) { - return ret; - } - - *key_len = len; - - return 0; -} - static int ecdsa_sign_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len, @@ -922,19 +871,18 @@ static int ecdsa_sign_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, 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; - size_t key_len; - unsigned char buf[MBEDTLS_PK_ECP_PRV_DER_MAX_BYTES]; - unsigned char *p; - psa_algorithm_t psa_hash = mbedtls_hash_info_psa_from_md(md_alg); + unsigned char buf[MBEDTLS_PSA_MAX_EC_KEY_PAIR_LENGTH]; #if defined(MBEDTLS_ECDSA_DETERMINISTIC) - psa_algorithm_t psa_sig_md = PSA_ALG_DETERMINISTIC_ECDSA(psa_hash); + psa_algorithm_t psa_sig_md = + PSA_ALG_DETERMINISTIC_ECDSA(mbedtls_hash_info_psa_from_md(md_alg)); #else - psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA(psa_hash); + psa_algorithm_t psa_sig_md = + PSA_ALG_ECDSA(mbedtls_hash_info_psa_from_md(md_alg)); #endif size_t curve_bits; psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ctx->grp.id, &curve_bits); + size_t key_len = PSA_BITS_TO_BYTES(curve_bits); /* PSA has its own RNG */ ((void) f_rng); @@ -944,17 +892,10 @@ static int ecdsa_sign_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, return MBEDTLS_ERR_PK_BAD_INPUT_DATA; } - /* mbedtls_pk_write_key_der() expects a full PK context; - * re-construct one to make it happy */ - key.pk_info = &mbedtls_eckey_info; - key.pk_ctx = ctx; - key_len = mbedtls_pk_write_key_der(&key, buf, sizeof(buf)); - if (key_len <= 0) { - return MBEDTLS_ERR_PK_BAD_INPUT_DATA; + if (key_len > sizeof(buf)) { + return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; } - - p = buf + sizeof(buf) - key_len; - ret = find_ecdsa_private_key(&p, buf + sizeof(buf), &key_len); + ret = mbedtls_mpi_write_binary(&ctx->d, buf, key_len); if (ret != 0) { goto cleanup; } @@ -964,7 +905,7 @@ static int ecdsa_sign_wrap(void *ctx_arg, mbedtls_md_type_t md_alg, psa_set_key_algorithm(&attributes, psa_sig_md); status = psa_import_key(&attributes, - p, key_len, + buf, key_len, &key_id); if (status != PSA_SUCCESS) { ret = mbedtls_pk_error_from_psa(status); @@ -1003,8 +944,7 @@ static int ecdsa_sign_wrap(void *ctx, mbedtls_md_type_t md_alg, #endif /* MBEDTLS_USE_PSA_CRYPTO */ #endif /* MBEDTLS_PK_CAN_ECDSA_SIGN */ -#if defined(MBEDTLS_ECDSA_C) -#if defined(MBEDTLS_ECP_RESTARTABLE) +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) /* Forward declarations */ static int ecdsa_verify_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, @@ -1110,8 +1050,7 @@ static int eckey_sign_rs_wrap(void *ctx, mbedtls_md_type_t md_alg, cleanup: return ret; } -#endif /* MBEDTLS_ECP_RESTARTABLE */ -#endif /* MBEDTLS_ECDSA_C */ +#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ static int eckey_check_pair(const void *pub, const void *prv, int (*f_rng)(void *, unsigned char *, size_t), diff --git a/library/pkcs7.c b/library/pkcs7.c index 4fdbe36288..010d7066e8 100644 --- a/library/pkcs7.c +++ b/library/pkcs7.c @@ -57,7 +57,10 @@ static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end, ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC); if (ret != 0) { - ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret); + } else if ((size_t) (end - *p) != *len) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); } return ret; @@ -184,13 +187,13 @@ static int pkcs7_get_certificates(unsigned char **p, unsigned char *end, size_t len2 = 0; unsigned char *end_set, *end_cert, *start; - if ((ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED - | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) != 0) { - if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { - return 0; - } else { - return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); - } + ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED + | MBEDTLS_ASN1_CONTEXT_SPECIFIC); + if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + return 0; + } + if (ret != 0) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); } start = *p; end_set = *p + len1; @@ -213,12 +216,11 @@ static int pkcs7_get_certificates(unsigned char **p, unsigned char *end, return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; } - *p = start; - if ((ret = mbedtls_x509_crt_parse_der(certs, *p, len1)) < 0) { + if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) { return MBEDTLS_ERR_PKCS7_INVALID_CERT; } - *p = *p + len1; + *p = end_cert; /* * Since in this version we strictly support single certificate, and reaching @@ -285,7 +287,8 @@ static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer) * and unauthenticatedAttributes. **/ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end, - mbedtls_pkcs7_signer_info *signer) + mbedtls_pkcs7_signer_info *signer, + mbedtls_x509_buf *alg) { unsigned char *end_signer, *end_issuer_and_sn; int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -343,8 +346,15 @@ static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end, goto out; } - /* Assume authenticatedAttributes is nonexistent */ + /* Check that the digest algorithm used matches the one provided earlier */ + if (signer->alg_identifier.tag != alg->tag || + signer->alg_identifier.len != alg->len || + memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) { + ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO; + goto out; + } + /* Asssume authenticatedAttributes is nonexistent */ ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier); if (ret != 0) { goto out; @@ -377,7 +387,8 @@ out: * Return negative error code for failure. **/ static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end, - mbedtls_pkcs7_signer_info *signers_set) + mbedtls_pkcs7_signer_info *signers_set, + mbedtls_x509_buf *digest_alg) { unsigned char *end_set; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; @@ -397,7 +408,7 @@ static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end, end_set = *p + len; - ret = pkcs7_get_signer_info(p, end_set, signers_set); + ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg); if (ret != 0) { return ret; } @@ -412,7 +423,7 @@ static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end, goto cleanup; } - ret = pkcs7_get_signer_info(p, end_set, signer); + ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg); if (ret != 0) { mbedtls_free(signer); goto cleanup; @@ -454,7 +465,7 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, { unsigned char *p = buf; unsigned char *end = buf + buflen; - unsigned char *end_set, *end_content_info; + unsigned char *end_content_info = NULL; size_t len = 0; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_md_type_t md_alg; @@ -465,16 +476,19 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); } - end_set = p + len; + if (p + len != end) { + return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + } /* Get version of signed data */ - ret = pkcs7_get_version(&p, end_set, &signed_data->version); + ret = pkcs7_get_version(&p, end, &signed_data->version); if (ret != 0) { return ret; } /* Get digest algorithm */ - ret = pkcs7_get_digest_algorithm_set(&p, end_set, + ret = pkcs7_get_digest_algorithm_set(&p, end, &signed_data->digest_alg_identifiers); if (ret != 0) { return ret; @@ -485,12 +499,15 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, return MBEDTLS_ERR_PKCS7_INVALID_ALG; } - /* Do not expect any content */ - ret = pkcs7_get_content_info_type(&p, end_set, &end_content_info, - &signed_data->content.oid); + mbedtls_pkcs7_buf content_type; + memset(&content_type, 0, sizeof(content_type)); + ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type); if (ret != 0) { return ret; } + if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) { + return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO; + } if (p != end_content_info) { /* Determine if valid content is present */ @@ -509,13 +526,9 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; } - if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &signed_data->content.oid)) { - return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO; - } - /* Look for certificates, there may or may not be any */ mbedtls_x509_crt_init(&signed_data->certs); - ret = pkcs7_get_certificates(&p, end_set, &signed_data->certs); + ret = pkcs7_get_certificates(&p, end, &signed_data->certs); if (ret < 0) { return ret; } @@ -531,7 +544,10 @@ static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen, signed_data->no_of_crls = 0; /* Get signers info */ - ret = pkcs7_get_signers_info_set(&p, end_set, &signed_data->signers); + ret = pkcs7_get_signers_info_set(&p, + end, + &signed_data->signers, + &signed_data->digest_alg_identifiers); if (ret < 0) { return ret; } @@ -550,10 +566,9 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf, const size_t buflen) { unsigned char *p; - unsigned char *end, *end_content_info; + unsigned char *end; size_t len = 0; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int isoidset = 0; if (pkcs7 == NULL) { return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; @@ -569,34 +584,45 @@ int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf, pkcs7->raw.len = buflen; end = p + buflen; - ret = pkcs7_get_content_info_type(&p, end, &end_content_info, - &pkcs7->content_type_oid); + ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED + | MBEDTLS_ASN1_SEQUENCE); if (ret != 0) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret); + goto out; + } + + if ((size_t) (end - p) != len) { + ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH); + goto out; + } + + if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) { + if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) { + goto out; + } + p = pkcs7->raw.p; len = buflen; goto try_data; } - /* Ensure PKCS7 data uses the exact number of bytes specified in buflen */ - if (end_content_info != end) { - ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) { + /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */ + if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len) + || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len) + || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len) + || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len) + || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) { + /* OID is valid according to the spec, but unsupported */ + ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; + } else { + /* OID is invalid according to the spec */ + ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + } goto out; } - if (!MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &pkcs7->content_type_oid) - || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, &pkcs7->content_type_oid) - || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, &pkcs7->content_type_oid) - || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DIGESTED_DATA, &pkcs7->content_type_oid) - || !MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, &pkcs7->content_type_oid)) { - ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE; - goto out; - } - - if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_SIGNED_DATA, &pkcs7->content_type_oid)) { - ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; - goto out; - } - - isoidset = 1; + p += len; ret = pkcs7_get_next_content_len(&p, end, &len); if (ret != 0) { @@ -615,12 +641,6 @@ try_data: goto out; } - if (!isoidset) { - pkcs7->content_type_oid.tag = MBEDTLS_ASN1_OID; - pkcs7->content_type_oid.len = MBEDTLS_OID_SIZE(MBEDTLS_OID_PKCS7_SIGNED_DATA); - pkcs7->content_type_oid.p = (unsigned char *) MBEDTLS_OID_PKCS7_SIGNED_DATA; - } - ret = MBEDTLS_PKCS7_SIGNED_DATA; out: @@ -653,6 +673,39 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7, return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID; } + ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg); + if (ret != 0) { + return ret; + } + + md_info = mbedtls_md_info_from_type(md_alg); + if (md_info == NULL) { + return MBEDTLS_ERR_PKCS7_VERIFY_FAIL; + } + + hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1); + if (hash == NULL) { + return MBEDTLS_ERR_PKCS7_ALLOC_FAILED; + } + + /* BEGIN must free hash before jumping out */ + if (is_data_hash) { + if (datalen != mbedtls_md_get_size(md_info)) { + ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; + } else { + memcpy(hash, data, datalen); + } + } else { + ret = mbedtls_md(md_info, data, datalen, hash); + } + if (ret != 0) { + mbedtls_free(hash); + return MBEDTLS_ERR_PKCS7_VERIFY_FAIL; + } + + /* assume failure */ + ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; + /* * Potential TODOs * Currently we iterate over all signers and return success if any of them @@ -662,61 +715,30 @@ static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7, * identification and SignerIdentifier fields first. That would also allow * us to distinguish between 'no signature for key' and 'signature for key * failed to validate'. - * - * We could also cache hashes by md, so if there are several sigs all using - * the same algo we don't recalculate the hash each time. */ for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) { - ret = mbedtls_oid_get_md_alg(&signer->alg_identifier, &md_alg); - if (ret != 0) { - ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - continue; - } - - md_info = mbedtls_md_info_from_type(md_alg); - if (md_info == NULL) { - ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - continue; - } - - hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1); - if (hash == NULL) { - return MBEDTLS_ERR_PKCS7_ALLOC_FAILED; - } - /* BEGIN must free hash before jumping out */ - if (is_data_hash) { - if (datalen != mbedtls_md_get_size(md_info)) { - ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - } else { - memcpy(hash, data, datalen); - } - } else { - ret = mbedtls_md(md_info, data, datalen, hash); - } - if (ret != 0) { - ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL; - mbedtls_free(hash); - continue; - } - ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash, mbedtls_md_get_size(md_info), signer->sig.p, signer->sig.len); - mbedtls_free(hash); - /* END must free hash before jumping out */ if (ret == 0) { break; } } + mbedtls_free(hash); + /* END must free hash before jumping out */ return ret; } + int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7, const mbedtls_x509_crt *cert, const unsigned char *data, size_t datalen) { + if (data == NULL) { + return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + } return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0); } @@ -725,6 +747,9 @@ int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7, const unsigned char *hash, size_t hashlen) { + if (hash == NULL) { + return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA; + } return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1); } diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a683fdb8f7..0efebb40ce 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -81,6 +81,7 @@ #include "mbedtls/sha1.h" #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +#include "hash_info.h" #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array))) @@ -310,6 +311,9 @@ psa_status_t mbedtls_to_psa_error(int ret) case MBEDTLS_ERR_ECP_RANDOM_FAILED: return PSA_ERROR_INSUFFICIENT_ENTROPY; + case MBEDTLS_ERR_ECP_IN_PROGRESS: + return PSA_OPERATION_INCOMPLETE; + case MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED: return PSA_ERROR_CORRUPTION_DETECTED; @@ -318,6 +322,44 @@ psa_status_t mbedtls_to_psa_error(int ret) } } +/** + * \brief For output buffers which contain "tags" + * (outputs that may be checked for validity like + * hashes, MACs and signatures), fill the unused + * part of the output buffer (the whole buffer on + * error, the trailing part on success) with + * something that isn't a valid tag (barring an + * attack on the tag and deliberately-crafted + * input), in case the caller doesn't check the + * return status properly. + * + * \param output_buffer Pointer to buffer to wipe. May not be NULL + * unless \p output_buffer_size is zero. + * \param status Status of function called to generate + * output_buffer originally + * \param output_buffer_size Size of output buffer. If zero, \p output_buffer + * could be NULL. + * \param output_buffer_length Length of data written to output_buffer, must be + * less than \p output_buffer_size + */ +static void psa_wipe_tag_output_buffer(uint8_t *output_buffer, psa_status_t status, + size_t output_buffer_size, size_t output_buffer_length) +{ + size_t offset = 0; + + if (output_buffer_size == 0) { + /* If output_buffer_size is 0 then we have nothing to do. We must not + call memset because output_buffer may be NULL in this case */ + return; + } + + if (status == PSA_SUCCESS) { + offset = output_buffer_length; + } + + memset(output_buffer + offset, '!', output_buffer_size - offset); +} + @@ -1673,12 +1715,12 @@ static psa_status_t psa_start_key_creation( * * \retval #PSA_SUCCESS * The key was successfully created. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_ALREADY_EXISTS - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription * * \return If this function fails, the key slot is an invalid state. * You must call psa_fail_key_creation() to wipe and free the slot. @@ -2500,10 +2542,7 @@ exit: operation->mac_size = 0; } - if (mac_size > operation->mac_size) { - memset(&mac[operation->mac_size], '!', - mac_size - operation->mac_size); - } + psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); abort_status = psa_mac_abort(operation); @@ -2597,9 +2636,8 @@ exit: *mac_length = mac_size; operation_mac_size = 0; } - if (mac_size > operation_mac_size) { - memset(&mac[operation_mac_size], '!', mac_size - operation_mac_size); - } + + psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length); unlock_status = psa_unlock_key_slot(slot); @@ -2741,18 +2779,8 @@ static psa_status_t psa_sign_internal(mbedtls_svc_key_id_t key, exit: - /* Fill the unused part of the output buffer (the whole buffer on error, - * the trailing part on success) with something that isn't a valid signature - * (barring an attack on the signature and deliberately-crafted input), - * in case the caller doesn't check the return status properly. */ - if (status == PSA_SUCCESS) { - memset(signature + *signature_length, '!', - signature_size - *signature_length); - } else { - memset(signature, '!', signature_size); - } - /* If signature_size is 0 then we have nothing to do. We must not call - * memset because signature may be NULL in this case. */ + psa_wipe_tag_output_buffer(signature, status, signature_size, + *signature_length); unlock_status = psa_unlock_key_slot(slot); @@ -3124,7 +3152,756 @@ exit: return (status == PSA_SUCCESS) ? unlock_status : status; } +/****************************************************************/ +/* Asymmetric interruptible cryptography */ +/****************************************************************/ +static uint32_t psa_interruptible_max_ops = PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED; + +void psa_interruptible_set_max_ops(uint32_t max_ops) +{ + psa_interruptible_max_ops = max_ops; +} + +uint32_t psa_interruptible_get_max_ops(void) +{ + return psa_interruptible_max_ops; +} + +uint32_t psa_sign_hash_get_num_ops( + const psa_sign_hash_interruptible_operation_t *operation) +{ + return operation->num_ops; +} + +uint32_t psa_verify_hash_get_num_ops( + const psa_verify_hash_interruptible_operation_t *operation) +{ + return operation->num_ops; +} + +static psa_status_t psa_sign_hash_abort_internal( + psa_sign_hash_interruptible_operation_t *operation) +{ + if (operation->id == 0) { + /* The object has (apparently) been initialized but it is not (yet) + * in use. It's ok to call abort on such an object, and there's + * nothing to do. */ + return PSA_SUCCESS; + } + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = psa_driver_wrapper_sign_hash_abort(operation); + + operation->id = 0; + + /* Do not clear either the error_occurred or num_ops elements here as they + * only want to be cleared by the application calling abort, not by abort + * being called at completion of an operation. */ + + return status; +} + +psa_status_t psa_sign_hash_start( + psa_sign_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + /* Check that start has not been previously called, or operation has not + * previously errored. */ + if (operation->id != 0 || operation->error_occurred) { + return PSA_ERROR_BAD_STATE; + } + + status = psa_sign_verify_check_alg(0, alg); + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + return status; + } + + status = psa_get_and_lock_key_slot_with_policy(key, &slot, + PSA_KEY_USAGE_SIGN_HASH, + alg); + + if (status != PSA_SUCCESS) { + goto exit; + } + + if (!PSA_KEY_TYPE_IS_KEY_PAIR(slot->attr.type)) { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } + + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + /* Ensure ops count gets reset, in case of operation re-use. */ + operation->num_ops = 0; + + status = psa_driver_wrapper_sign_hash_start(operation, &attributes, + slot->key.data, + slot->key.bytes, alg, + hash, hash_length); +exit: + + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + psa_sign_hash_abort_internal(operation); + } + + unlock_status = psa_unlock_key_slot(slot); + + if (unlock_status != PSA_SUCCESS) { + operation->error_occurred = 1; + } + + return (status == PSA_SUCCESS) ? unlock_status : status; +} + + +psa_status_t psa_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + *signature_length = 0; + + /* Check that start has been called first, and that operation has not + * previously errored. */ + if (operation->id == 0 || operation->error_occurred) { + status = PSA_ERROR_BAD_STATE; + goto exit; + } + + /* Immediately reject a zero-length signature buffer. This guarantees that + * signature must be a valid pointer. */ + if (signature_size == 0) { + status = PSA_ERROR_BUFFER_TOO_SMALL; + goto exit; + } + + status = psa_driver_wrapper_sign_hash_complete(operation, signature, + signature_size, + signature_length); + + /* Update ops count with work done. */ + operation->num_ops = psa_driver_wrapper_sign_hash_get_num_ops(operation); + +exit: + + psa_wipe_tag_output_buffer(signature, status, signature_size, + *signature_length); + + if (status != PSA_OPERATION_INCOMPLETE) { + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + } + + psa_sign_hash_abort_internal(operation); + } + + return status; +} + +psa_status_t psa_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *operation) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = psa_sign_hash_abort_internal(operation); + + /* We clear the number of ops done here, so that it is not cleared when + * the operation fails or succeeds, only on manual abort. */ + operation->num_ops = 0; + + /* Likewise, failure state. */ + operation->error_occurred = 0; + + return status; +} + +static psa_status_t psa_verify_hash_abort_internal( + psa_verify_hash_interruptible_operation_t *operation) +{ + if (operation->id == 0) { + /* The object has (apparently) been initialized but it is not (yet) + * in use. It's ok to call abort on such an object, and there's + * nothing to do. */ + return PSA_SUCCESS; + } + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = psa_driver_wrapper_verify_hash_abort(operation); + + operation->id = 0; + + /* Do not clear either the error_occurred or num_ops elements here as they + * only want to be cleared by the application calling abort, not by abort + * being called at completion of an operation. */ + + return status; +} + +psa_status_t psa_verify_hash_start( + psa_verify_hash_interruptible_operation_t *operation, + mbedtls_svc_key_id_t key, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + /* Check that start has not been previously called, or operation has not + * previously errored. */ + if (operation->id != 0 || operation->error_occurred) { + return PSA_ERROR_BAD_STATE; + } + + status = psa_sign_verify_check_alg(0, alg); + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + return status; + } + + status = psa_get_and_lock_key_slot_with_policy(key, &slot, + PSA_KEY_USAGE_VERIFY_HASH, + alg); + + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + return status; + } + + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + /* Ensure ops count gets reset, in case of operation re-use. */ + operation->num_ops = 0; + + status = psa_driver_wrapper_verify_hash_start(operation, &attributes, + slot->key.data, + slot->key.bytes, + alg, hash, hash_length, + signature, signature_length); + + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + psa_verify_hash_abort_internal(operation); + } + + unlock_status = psa_unlock_key_slot(slot); + + if (unlock_status != PSA_SUCCESS) { + operation->error_occurred = 1; + } + + return (status == PSA_SUCCESS) ? unlock_status : status; +} + +psa_status_t psa_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *operation) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + /* Check that start has been called first, and that operation has not + * previously errored. */ + if (operation->id == 0 || operation->error_occurred) { + status = PSA_ERROR_BAD_STATE; + goto exit; + } + + status = psa_driver_wrapper_verify_hash_complete(operation); + + /* Update ops count with work done. */ + operation->num_ops = psa_driver_wrapper_verify_hash_get_num_ops( + operation); + +exit: + + if (status != PSA_OPERATION_INCOMPLETE) { + if (status != PSA_SUCCESS) { + operation->error_occurred = 1; + } + + psa_verify_hash_abort_internal(operation); + } + + return status; +} + +psa_status_t psa_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *operation) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + status = psa_verify_hash_abort_internal(operation); + + /* We clear the number of ops done here, so that it is not cleared when + * the operation fails or succeeds, only on manual abort. */ + operation->num_ops = 0; + + /* Likewise, failure state. */ + operation->error_occurred = 0; + + return status; +} + +/****************************************************************/ +/* Asymmetric interruptible cryptography internal */ +/* implementations */ +/****************************************************************/ + +void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops) +{ + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + /* Internal implementation uses zero to indicate infinite number max ops, + * therefore avoid this value, and set to minimum possible. */ + if (max_ops == 0) { + max_ops = 1; + } + + mbedtls_ecp_set_max_ops(max_ops); +#else + (void) max_ops; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +uint32_t mbedtls_psa_sign_hash_get_num_ops( + const mbedtls_psa_sign_hash_interruptible_operation_t *operation) +{ +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + return operation->num_ops; +#else + (void) operation; + return 0; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +uint32_t mbedtls_psa_verify_hash_get_num_ops( + const mbedtls_psa_verify_hash_interruptible_operation_t *operation) +{ + #if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + return operation->num_ops; +#else + (void) operation; + return 0; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +psa_status_t mbedtls_psa_sign_hash_start( + mbedtls_psa_sign_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, const uint8_t *key_buffer, + size_t key_buffer_size, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t required_hash_length; + + if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + if (!PSA_ALG_IS_ECDSA(alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + mbedtls_ecdsa_restart_init(&operation->restart_ctx); + + /* Ensure num_ops is zero'ed in case of context re-use. */ + operation->num_ops = 0; + + status = mbedtls_psa_ecp_load_representation(attributes->core.type, + attributes->core.bits, + key_buffer, + key_buffer_size, + &operation->ctx); + + if (status != PSA_SUCCESS) { + return status; + } + + operation->coordinate_bytes = PSA_BITS_TO_BYTES( + operation->ctx->grp.nbits); + + psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg); + operation->md_alg = mbedtls_hash_info_md_from_psa(hash_alg); + operation->alg = alg; + + /* We only need to store the same length of hash as the private key size + * here, it would be truncated by the internal implementation anyway. */ + required_hash_length = (hash_length < operation->coordinate_bytes ? + hash_length : operation->coordinate_bytes); + + if (required_hash_length > sizeof(operation->hash)) { + /* Shouldn't happen, but better safe than sorry. */ + return PSA_ERROR_CORRUPTION_DETECTED; + } + + memcpy(operation->hash, hash, required_hash_length); + operation->hash_length = required_hash_length; + + return PSA_SUCCESS; + +#else + (void) operation; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) hash; + (void) hash_length; + (void) status; + (void) required_hash_length; + + return PSA_ERROR_NOT_SUPPORTED; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +psa_status_t mbedtls_psa_sign_hash_complete( + mbedtls_psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length) +{ +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi r; + mbedtls_mpi s; + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* Ensure max_ops is set to the current value (or default). */ + mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops()); + + if (signature_size < 2 * operation->coordinate_bytes) { + status = PSA_ERROR_BUFFER_TOO_SMALL; + goto exit; + } + + if (PSA_ALG_ECDSA_IS_DETERMINISTIC(operation->alg)) { + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) + status = mbedtls_to_psa_error( + mbedtls_ecdsa_sign_det_restartable(&operation->ctx->grp, + &r, + &s, + &operation->ctx->d, + operation->hash, + operation->hash_length, + operation->md_alg, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE, + &operation->restart_ctx)); +#else /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ + } else { + status = mbedtls_to_psa_error( + mbedtls_ecdsa_sign_restartable(&operation->ctx->grp, + &r, + &s, + &operation->ctx->d, + operation->hash, + operation->hash_length, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE, + &operation->restart_ctx)); + } + + /* Hide the fact that the restart context only holds a delta of number of + * ops done during the last operation, not an absolute value. */ + operation->num_ops += operation->restart_ctx.ecp.ops_done; + + if (status == PSA_SUCCESS) { + status = mbedtls_to_psa_error( + mbedtls_mpi_write_binary(&r, + signature, + operation->coordinate_bytes) + ); + + if (status != PSA_SUCCESS) { + goto exit; + } + + status = mbedtls_to_psa_error( + mbedtls_mpi_write_binary(&s, + signature + + operation->coordinate_bytes, + operation->coordinate_bytes) + ); + + if (status != PSA_SUCCESS) { + goto exit; + } + + *signature_length = operation->coordinate_bytes * 2; + + status = PSA_SUCCESS; + } + +exit: + + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + return status; + + #else + + (void) operation; + (void) signature; + (void) signature_size; + (void) signature_length; + + return PSA_ERROR_NOT_SUPPORTED; + +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +psa_status_t mbedtls_psa_sign_hash_abort( + mbedtls_psa_sign_hash_interruptible_operation_t *operation) +{ + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + if (operation->ctx) { + mbedtls_ecdsa_free(operation->ctx); + mbedtls_free(operation->ctx); + operation->ctx = NULL; + } + + mbedtls_ecdsa_restart_free(&operation->restart_ctx); + + operation->num_ops = 0; + + return PSA_SUCCESS; + +#else + + (void) operation; + + return PSA_ERROR_NOT_SUPPORTED; + +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +psa_status_t mbedtls_psa_verify_hash_start( + mbedtls_psa_verify_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t coordinate_bytes = 0; + size_t required_hash_length = 0; + + if (!PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + return PSA_ERROR_NOT_SUPPORTED; + } + + if (!PSA_ALG_IS_ECDSA(alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + mbedtls_ecdsa_restart_init(&operation->restart_ctx); + mbedtls_mpi_init(&operation->r); + mbedtls_mpi_init(&operation->s); + + /* Ensure num_ops is zero'ed in case of context re-use. */ + operation->num_ops = 0; + + status = mbedtls_psa_ecp_load_representation(attributes->core.type, + attributes->core.bits, + key_buffer, + key_buffer_size, + &operation->ctx); + + if (status != PSA_SUCCESS) { + return status; + } + + coordinate_bytes = PSA_BITS_TO_BYTES(operation->ctx->grp.nbits); + + if (signature_length != 2 * coordinate_bytes) { + return PSA_ERROR_INVALID_SIGNATURE; + } + + status = mbedtls_to_psa_error( + mbedtls_mpi_read_binary(&operation->r, + signature, + coordinate_bytes)); + + if (status != PSA_SUCCESS) { + return status; + } + + status = mbedtls_to_psa_error( + mbedtls_mpi_read_binary(&operation->s, + signature + + coordinate_bytes, + coordinate_bytes)); + + if (status != PSA_SUCCESS) { + return status; + } + + status = mbedtls_psa_ecp_load_public_part(operation->ctx); + + if (status != PSA_SUCCESS) { + return status; + } + + /* We only need to store the same length of hash as the private key size + * here, it would be truncated by the internal implementation anyway. */ + required_hash_length = (hash_length < coordinate_bytes ? hash_length : + coordinate_bytes); + + if (required_hash_length > sizeof(operation->hash)) { + /* Shouldn't happen, but better safe than sorry. */ + return PSA_ERROR_CORRUPTION_DETECTED; + } + + memcpy(operation->hash, hash, required_hash_length); + operation->hash_length = required_hash_length; + + return PSA_SUCCESS; +#else + (void) operation; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) hash; + (void) hash_length; + (void) signature; + (void) signature_length; + (void) status; + (void) coordinate_bytes; + (void) required_hash_length; + + return PSA_ERROR_NOT_SUPPORTED; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +psa_status_t mbedtls_psa_verify_hash_complete( + mbedtls_psa_verify_hash_interruptible_operation_t *operation) +{ + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + /* Ensure max_ops is set to the current value (or default). */ + mbedtls_psa_interruptible_set_max_ops(psa_interruptible_get_max_ops()); + + status = mbedtls_to_psa_error( + mbedtls_ecdsa_verify_restartable(&operation->ctx->grp, + operation->hash, + operation->hash_length, + &operation->ctx->Q, + &operation->r, + &operation->s, + &operation->restart_ctx)); + + /* Hide the fact that the restart context only holds a delta of number of + * ops done during the last operation, not an absolute value. */ + operation->num_ops += operation->restart_ctx.ecp.ops_done; + + return status; +#else + (void) operation; + + return PSA_ERROR_NOT_SUPPORTED; + +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} + +psa_status_t mbedtls_psa_verify_hash_abort( + mbedtls_psa_verify_hash_interruptible_operation_t *operation) +{ + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + if (operation->ctx) { + mbedtls_ecdsa_free(operation->ctx); + mbedtls_free(operation->ctx); + operation->ctx = NULL; + } + + mbedtls_ecdsa_restart_free(&operation->restart_ctx); + + operation->num_ops = 0; + + mbedtls_mpi_free(&operation->r); + mbedtls_mpi_free(&operation->s); + + return PSA_SUCCESS; + +#else + (void) operation; + + return PSA_ERROR_NOT_SUPPORTED; + +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || + * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) && + * defined( MBEDTLS_ECP_RESTARTABLE ) */ +} /****************************************************************/ /* Symmetric cryptography */ @@ -4126,18 +4903,14 @@ psa_status_t psa_aead_finish(psa_aead_operation_t *operation, tag, tag_size, tag_length); exit: + + /* In case the operation fails and the user fails to check for failure or * the zero tag size, make sure the tag is set to something implausible. * Even if the operation succeeds, make sure we clear the rest of the * buffer to prevent potential leakage of anything previously placed in * the same buffer.*/ - if (tag != NULL) { - if (status != PSA_SUCCESS) { - memset(tag, '!', tag_size); - } else if (*tag_length < tag_size) { - memset(tag + *tag_length, '!', (tag_size - *tag_length)); - } - } + psa_wipe_tag_output_buffer(tag, status, tag_size, *tag_length); psa_aead_abort(operation); diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h index 2ae8fe82d6..4b24b0f68d 100644 --- a/library/psa_crypto_aead.h +++ b/library/psa_crypto_aead.h @@ -71,10 +71,10 @@ * \retval #PSA_SUCCESS Success. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * ciphertext_size is too small. - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_aead_encrypt( const psa_key_attributes_t *attributes, @@ -134,10 +134,10 @@ psa_status_t mbedtls_psa_aead_encrypt( * The cipher is not authentic. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * plaintext_size is too small. - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_aead_decrypt( const psa_key_attributes_t *attributes, diff --git a/library/psa_crypto_cipher.h b/library/psa_crypto_cipher.h index 6cc6bf6145..bf43ff08ab 100644 --- a/library/psa_crypto_cipher.h +++ b/library/psa_crypto_cipher.h @@ -59,10 +59,10 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_CIPHER(\p alg) is true). * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_cipher_encrypt_setup( mbedtls_psa_cipher_operation_t *operation, @@ -89,10 +89,10 @@ psa_status_t mbedtls_psa_cipher_encrypt_setup( * (\c PSA_ALG_XXX value such that * #PSA_ALG_IS_CIPHER(\p alg) is true). * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_cipher_decrypt_setup( mbedtls_psa_cipher_operation_t *operation, @@ -116,11 +116,11 @@ psa_status_t mbedtls_psa_cipher_decrypt_setup( * the core to be less or equal to * PSA_CIPHER_IV_MAX_SIZE. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * The size of \p iv is not acceptable for the chosen algorithm, * or the chosen algorithm does not use an IV. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_cipher_set_iv( mbedtls_psa_cipher_operation_t *operation, @@ -142,10 +142,10 @@ psa_status_t mbedtls_psa_cipher_set_iv( * \param[out] output_length On success, the number of bytes * that make up the returned output. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_cipher_update( mbedtls_psa_cipher_operation_t *operation, @@ -165,7 +165,7 @@ psa_status_t mbedtls_psa_cipher_update( * \param[out] output_length On success, the number of bytes * that make up the returned output. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * The total input size passed to this operation is not valid for * this particular algorithm. For example, the algorithm is a based @@ -176,7 +176,7 @@ psa_status_t mbedtls_psa_cipher_update( * padding, and the ciphertext does not contain valid padding. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_cipher_finish( mbedtls_psa_cipher_operation_t *operation, @@ -195,7 +195,7 @@ psa_status_t mbedtls_psa_cipher_finish( * * \param[in,out] operation Initialized cipher operation. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription */ psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation); @@ -224,10 +224,10 @@ psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation) * the returned output. Initialized to zero * by the core. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. * \retval #PSA_ERROR_INVALID_ARGUMENT @@ -275,10 +275,10 @@ psa_status_t mbedtls_psa_cipher_encrypt(const psa_key_attributes_t *attributes, * the returned output. Initialized to zero * by the core. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. * \retval #PSA_ERROR_INVALID_ARGUMENT diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 38e4bc5cca..5260cf7a7f 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -209,7 +209,7 @@ psa_status_t psa_get_and_lock_key_slot_with_policy(mbedtls_svc_key_id_t key, * \retval #PSA_SUCCESS * Success. This includes the case of a key slot that was * already fully wiped. - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot); @@ -285,9 +285,9 @@ psa_status_t mbedtls_to_psa_error(int ret); * \retval #PSA_SUCCESS The key was imported successfully. * \retval #PSA_ERROR_INVALID_ARGUMENT * The key data is not correctly formatted. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t psa_import_key_into_slot( const psa_key_attributes_t *attributes, @@ -310,12 +310,12 @@ psa_status_t psa_import_key_into_slot( * \p data * * \retval #PSA_SUCCESS The key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t psa_export_key_internal( const psa_key_attributes_t *attributes, @@ -338,12 +338,12 @@ psa_status_t psa_export_key_internal( * \p data * * \retval #PSA_SUCCESS The public key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t psa_export_public_key_internal( const psa_key_attributes_t *attributes, @@ -364,7 +364,7 @@ psa_status_t psa_export_public_key_internal( * * \retval #PSA_SUCCESS * The key was generated successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription * \retval #PSA_ERROR_NOT_SUPPORTED * Key size in bits or type not supported. * \retval #PSA_ERROR_BUFFER_TOO_SMALL @@ -399,18 +399,18 @@ psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes, * \param[out] signature_length On success, the number of bytes * that make up the returned signature value. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p signature buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of the key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription */ psa_status_t psa_sign_message_builtin( const psa_key_attributes_t *attributes, @@ -445,9 +445,9 @@ psa_status_t psa_sign_message_builtin( * \retval #PSA_ERROR_INVALID_SIGNATURE * The calculation was performed successfully, but the passed * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t psa_verify_message_builtin( const psa_key_attributes_t *attributes, @@ -475,18 +475,18 @@ psa_status_t psa_verify_message_builtin( * \param[out] signature_length On success, the number of bytes * that make up the returned signature value. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p signature buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of the key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription */ psa_status_t psa_sign_hash_builtin( const psa_key_attributes_t *attributes, @@ -519,9 +519,9 @@ psa_status_t psa_sign_hash_builtin( * \retval #PSA_ERROR_INVALID_SIGNATURE * The calculation was performed successfully, but the passed * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t psa_verify_hash_builtin( const psa_key_attributes_t *attributes, @@ -577,8 +577,8 @@ psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type, * up the returned shared secret. * \retval #PSA_SUCCESS * Success. Shared secret successfully calculated. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p alg is not a key agreement algorithm, or * \p private_key is not compatible with \p alg, @@ -588,12 +588,12 @@ psa_status_t psa_validate_unstructured_key_bit_size(psa_key_type_t type, * \p shared_secret_size is too small * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE \emptydescription */ psa_status_t psa_key_agreement_raw_builtin( const psa_key_attributes_t *attributes, @@ -606,4 +606,272 @@ psa_status_t psa_key_agreement_raw_builtin( size_t shared_secret_size, size_t *shared_secret_length); +/** + * \brief Set the maximum number of ops allowed to be executed by an + * interruptible function in a single call. + * + * \note The signature of this function is that of a PSA driver + * interruptible_set_max_ops entry point. This function behaves as an + * interruptible_set_max_ops entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param[in] max_ops The maximum number of ops to be executed in a + * single call, this can be a number from 0 to + * #PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, where 0 + * is obviously the least amount of work done per + * call. + */ +void mbedtls_psa_interruptible_set_max_ops(uint32_t max_ops); + +/** + * \brief Get the maximum number of ops allowed to be executed by an + * interruptible function in a single call. + * + * \note The signature of this function is that of a PSA driver + * interruptible_get_max_ops entry point. This function behaves as an + * interruptible_get_max_ops entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \return Maximum number of ops allowed to be executed + * by an interruptible function in a single call. + */ +uint32_t mbedtls_psa_interruptible_get_max_ops(void); + +/** + * \brief Get the number of ops that a hash signing operation has taken for the + * previous call. If no call or work has taken place, this will return + * zero. + * + * \note The signature of this function is that of a PSA driver + * sign_hash_get_num_ops entry point. This function behaves as an + * sign_hash_get_num_ops entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param operation The \c + * mbedtls_psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \return Number of ops that were completed + * in the last call to \c + * mbedtls_psa_sign_hash_complete(). + */ +uint32_t mbedtls_psa_sign_hash_get_num_ops( + const mbedtls_psa_sign_hash_interruptible_operation_t *operation); + +/** + * \brief Get the number of ops that a hash verification operation has taken for + * the previous call. If no call or work has taken place, this will + * return zero. + * + * \note The signature of this function is that of a PSA driver + * verify_hash_get_num_ops entry point. This function behaves as an + * verify_hash_get_num_ops entry point as defined in the PSA driver + * interface specification for transparent drivers. + * + * \param operation The \c + * mbedtls_psa_verify_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \return Number of ops that were completed + * in the last call to \c + * mbedtls_psa_verify_hash_complete(). + */ +uint32_t mbedtls_psa_verify_hash_get_num_ops( + const mbedtls_psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Start signing a hash or short message with a private key, in an + * interruptible manner. + * + * \note The signature of this function is that of a PSA driver + * sign_hash_start entry point. This function behaves as a + * sign_hash_start entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * \param[in] operation The \c + * mbedtls_psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key context. + * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param[in] alg A signature algorithm that is compatible with + * the type of the key. + * \param[in] hash The hash or message to sign. + * \param hash_length Size of the \p hash buffer in bytes. + * + * \retval #PSA_SUCCESS + * The operation started successfully - call \c psa_sign_hash_complete() + * with the same context to complete the operation + * \retval #PSA_ERROR_INVALID_ARGUMENT + * An unsupported, incorrectly formatted or incorrect type of key was + * used. + * \retval #PSA_ERROR_NOT_SUPPORTED Either no internal interruptible operations + * are currently supported, or the key type is currently unsupported. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * There was insufficient memory to load the key representation. + */ +psa_status_t mbedtls_psa_sign_hash_start( + mbedtls_psa_sign_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, const uint8_t *key_buffer, + size_t key_buffer_size, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length); + +/** + * \brief Continue and eventually complete the action of signing a hash or + * short message with a private key, in an interruptible manner. + * + * \note The signature of this function is that of a PSA driver + * sign_hash_complete entry point. This function behaves as a + * sign_hash_complete entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * \param[in] operation The \c + * mbedtls_psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \param[out] signature Buffer where the signature is to be written. + * \param signature_size Size of the \p signature buffer in bytes. This + * must be appropriate for the selected + * algorithm and key. + * \param[out] signature_length On success, the number of bytes that make up + * the returned signature value. + * + * \retval #PSA_SUCCESS + * Operation completed successfully + * + * \retval #PSA_OPERATION_INCOMPLETE + * Operation was interrupted due to the setting of \c + * psa_interruptible_set_max_ops(), there is still work to be done, + * please call this function again with the same operation object. + * + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of the \p signature buffer is too small. You can + * determine a sufficient buffer size by calling + * #PSA_SIGN_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) + * where \c key_type and \c key_bits are the type and bit-size + * respectively of \p key. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + */ +psa_status_t mbedtls_psa_sign_hash_complete( + mbedtls_psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +/** + * \brief Abort a sign hash operation. + * + * \note The signature of this function is that of a PSA driver sign_hash_abort + * entry point. This function behaves as a sign_hash_abort entry point as + * defined in the PSA driver interface specification for transparent + * drivers. + * + * \param[in] operation The \c + * mbedtls_psa_sign_hash_interruptible_operation_t + * to abort. + * + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + */ +psa_status_t mbedtls_psa_sign_hash_abort( + mbedtls_psa_sign_hash_interruptible_operation_t *operation); + +/** + * \brief Start reading and verifying a hash or short message, in an + * interruptible manner. + * + * \note The signature of this function is that of a PSA driver + * verify_hash_start entry point. This function behaves as a + * verify_hash_start entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * \param[in] operation The \c + * mbedtls_psa_verify_hash_interruptible_operation_t + * to use. This must be initialized first. + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key context. + * \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param[in] alg A signature algorithm that is compatible with + * the type of the key. + * \param[in] hash The hash whose signature is to be verified. + * \param hash_length Size of the \p hash buffer in bytes. + * \param[in] signature Buffer containing the signature to verify. + * \param signature_length Size of the \p signature buffer in bytes. + * + * \retval #PSA_SUCCESS + * The operation started successfully - call \c psa_sign_hash_complete() + * with the same context to complete the operation + * \retval #PSA_ERROR_INVALID_ARGUMENT + * An unsupported or incorrect type of key was used. + * \retval #PSA_ERROR_NOT_SUPPORTED + * Either no internal interruptible operations are currently supported, + * or the key type is currently unsupported. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * There was insufficient memory either to load the key representation, + * or to prepare the operation. + */ +psa_status_t mbedtls_psa_verify_hash_start( + mbedtls_psa_verify_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length); + +/** + * \brief Continue and eventually complete the action of signing a hash or + * short message with a private key, in an interruptible manner. + * + * \note The signature of this function is that of a PSA driver + * sign_hash_complete entry point. This function behaves as a + * sign_hash_complete entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * \param[in] operation The \c + * mbedtls_psa_sign_hash_interruptible_operation_t + * to use. This must be initialized first. + * + * \retval #PSA_SUCCESS + * Operation completed successfully, and the passed signature is valid. + * + * \retval #PSA_OPERATION_INCOMPLETE + * Operation was interrupted due to the setting of \c + * psa_interruptible_set_max_ops(), there is still work to be done, + * please call this function again with the same operation object. + * + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The calculation was performed successfully, but the passed + * signature is not a valid signature. + * + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + */ +psa_status_t mbedtls_psa_verify_hash_complete( + mbedtls_psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Abort a verify signed hash operation. + * + * \note The signature of this function is that of a PSA driver + * verify_hash_abort entry point. This function behaves as a + * verify_hash_abort entry point as defined in the PSA driver interface + * specification for transparent drivers. + * + * \param[in] operation The \c + * mbedtls_psa_verify_hash_interruptible_operation_t + * to abort. + * + * \retval #PSA_SUCCESS + * The operation was aborted successfully. + */ +psa_status_t mbedtls_psa_verify_hash_abort( + mbedtls_psa_verify_hash_interruptible_operation_t *operation); + #endif /* PSA_CRYPTO_CORE_H */ diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index da3cd1d5d6..b16750658f 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -66,6 +66,43 @@ psa_status_t psa_driver_wrapper_verify_hash( psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length); +/* + * Interruptible Signature functions + */ + +uint32_t psa_driver_wrapper_sign_hash_get_num_ops( + psa_sign_hash_interruptible_operation_t *operation); + +uint32_t psa_driver_wrapper_verify_hash_get_num_ops( + psa_verify_hash_interruptible_operation_t *operation); + +psa_status_t psa_driver_wrapper_sign_hash_start( + psa_sign_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, const uint8_t *key_buffer, + size_t key_buffer_size, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length); + +psa_status_t psa_driver_wrapper_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length); + +psa_status_t psa_driver_wrapper_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *operation); + +psa_status_t psa_driver_wrapper_verify_hash_start( + psa_verify_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, const uint8_t *key_buffer, + size_t key_buffer_size, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length); + +psa_status_t psa_driver_wrapper_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *operation); + +psa_status_t psa_driver_wrapper_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *operation); + /* * Key handling functions */ diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index c4ccefd757..f70d804b0f 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -404,6 +404,21 @@ cleanup: return mbedtls_to_psa_error(ret); } +psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp) +{ + int ret = 0; + + /* Check whether the public part is loaded. If not, load it. */ + if (mbedtls_ecp_is_zero(&ecp->Q)) { + ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q, + &ecp->d, &ecp->grp.G, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE); + } + + return mbedtls_to_psa_error(ret); +} + psa_status_t mbedtls_psa_ecdsa_verify_hash( const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, @@ -412,7 +427,6 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; mbedtls_ecp_keypair *ecp = NULL; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; size_t curve_bytes; mbedtls_mpi r, s; @@ -432,34 +446,39 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash( mbedtls_mpi_init(&s); if (signature_length != 2 * curve_bytes) { - ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + status = PSA_ERROR_INVALID_SIGNATURE; goto cleanup; } - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&r, - signature, - curve_bytes)); - MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&s, - signature + curve_bytes, - curve_bytes)); - - /* Check whether the public part is loaded. If not, load it. */ - if (mbedtls_ecp_is_zero(&ecp->Q)) { - MBEDTLS_MPI_CHK( - mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G, - mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE)); + status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r, + signature, + curve_bytes)); + if (status != PSA_SUCCESS) { + goto cleanup; } - ret = mbedtls_ecdsa_verify(&ecp->grp, hash, hash_length, - &ecp->Q, &r, &s); + status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s, + signature + curve_bytes, + curve_bytes)); + if (status != PSA_SUCCESS) { + goto cleanup; + } + status = mbedtls_psa_ecp_load_public_part(ecp); + if (status != PSA_SUCCESS) { + goto cleanup; + } + + status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash, + hash_length, &ecp->Q, + &r, &s)); cleanup: mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); mbedtls_ecp_keypair_free(ecp); mbedtls_free(ecp); - return mbedtls_to_psa_error(ret); + return status; } #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ diff --git a/library/psa_crypto_ecp.h b/library/psa_crypto_ecp.h index 71f9d6acca..f4ad3d2777 100644 --- a/library/psa_crypto_ecp.h +++ b/library/psa_crypto_ecp.h @@ -48,6 +48,15 @@ psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type, size_t data_length, mbedtls_ecp_keypair **p_ecp); +/** Load the public part of an internal ECP, if required. + * + * \param ecp The ECP context to load the public part for. + * + * \return PSA_SUCCESS on success, otherwise an MPI error. + */ + +psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp); + /** Import an ECP key in binary format. * * \note The signature of this function is that of a PSA driver @@ -70,9 +79,9 @@ psa_status_t mbedtls_psa_ecp_load_representation(psa_key_type_t type, * \retval #PSA_SUCCESS The ECP key was imported successfully. * \retval #PSA_ERROR_INVALID_ARGUMENT * The key data is not correctly formatted. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_ecp_import_key( const psa_key_attributes_t *attributes, @@ -111,12 +120,12 @@ psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type, * \p data * * \retval #PSA_SUCCESS The ECP public key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_ecp_export_public_key( const psa_key_attributes_t *attributes, @@ -166,17 +175,17 @@ psa_status_t mbedtls_psa_ecp_generate_key( * \param[out] signature_length On success, the number of bytes * that make up the returned signature value. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p signature buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_ECC_KEY_PAIR, \c key_bits, * \p alg) where \c key_bits is the bit-size of the ECC key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription */ psa_status_t mbedtls_psa_ecdsa_sign_hash( const psa_key_attributes_t *attributes, @@ -209,9 +218,9 @@ psa_status_t mbedtls_psa_ecdsa_sign_hash( * \retval #PSA_ERROR_INVALID_SIGNATURE * The calculation was performed successfully, but the passed * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_ecdsa_verify_hash( const psa_key_attributes_t *attributes, @@ -247,8 +256,8 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash( * up the returned shared secret. * \retval #PSA_SUCCESS * Success. Shared secret successfully calculated. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_NOT_PERMITTED + * \retval #PSA_ERROR_INVALID_HANDLE \emptydescription + * \retval #PSA_ERROR_NOT_PERMITTED \emptydescription * \retval #PSA_ERROR_INVALID_ARGUMENT * \p alg is not a key agreement algorithm, or * \p private_key is not compatible with \p alg, @@ -258,8 +267,8 @@ psa_status_t mbedtls_psa_ecdsa_verify_hash( * \p shared_secret_size is too small * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not a supported key agreement algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_key_agreement_ecdh( const psa_key_attributes_t *attributes, diff --git a/library/psa_crypto_hash.h b/library/psa_crypto_hash.h index 63874e87dc..d6bbd3feec 100644 --- a/library/psa_crypto_hash.h +++ b/library/psa_crypto_hash.h @@ -48,8 +48,8 @@ * \p alg is not supported * \retval #PSA_ERROR_BUFFER_TOO_SMALL * \p hash_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_hash_compute( psa_algorithm_t alg, @@ -88,8 +88,8 @@ psa_status_t mbedtls_psa_hash_compute( * \p alg is not supported * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_hash_setup( mbedtls_psa_hash_operation_t *operation, @@ -115,13 +115,13 @@ psa_status_t mbedtls_psa_hash_setup( * \param[in,out] target_operation The operation object to set up. * It must be initialized but not active. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BAD_STATE * The \p source_operation state is not valid (it must be active). * \retval #PSA_ERROR_BAD_STATE * The \p target_operation state is not valid (it must be inactive). - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_hash_clone( const mbedtls_psa_hash_operation_t *source_operation, @@ -147,8 +147,8 @@ psa_status_t mbedtls_psa_hash_clone( * Success. * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_hash_update( mbedtls_psa_hash_operation_t *operation, @@ -186,8 +186,8 @@ psa_status_t mbedtls_psa_hash_update( * The size of the \p hash buffer is too small. You can determine a * sufficient buffer size by calling #PSA_HASH_LENGTH(\c alg) * where \c alg is the hash algorithm that is calculated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_hash_finish( mbedtls_psa_hash_operation_t *operation, @@ -216,8 +216,8 @@ psa_status_t mbedtls_psa_hash_finish( * * \param[in,out] operation Initialized hash operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_hash_abort( mbedtls_psa_hash_operation_t *operation); diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index 21c4de6362..4f8024a9e3 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -52,8 +52,8 @@ * \p alg is not supported. * \retval #PSA_ERROR_BUFFER_TOO_SMALL * \p mac_size is too small - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_mac_compute( const psa_key_attributes_t *attributes, @@ -89,8 +89,8 @@ psa_status_t mbedtls_psa_mac_compute( * Success. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive). */ @@ -124,8 +124,8 @@ psa_status_t mbedtls_psa_mac_sign_setup( * Success. * \retval #PSA_ERROR_NOT_SUPPORTED * \p alg is not supported. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be inactive). */ @@ -158,8 +158,8 @@ psa_status_t mbedtls_psa_mac_verify_setup( * Success. * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be active). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_mac_update( mbedtls_psa_mac_operation_t *operation, @@ -200,8 +200,8 @@ psa_status_t mbedtls_psa_mac_update( * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p mac buffer is too small. A sufficient buffer size * can be determined by calling PSA_MAC_LENGTH(). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_mac_sign_finish( mbedtls_psa_mac_operation_t *operation, @@ -241,8 +241,8 @@ psa_status_t mbedtls_psa_mac_sign_finish( * \retval #PSA_ERROR_BAD_STATE * The operation state is not valid (it must be an active mac verify * operation). - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_mac_verify_finish( mbedtls_psa_mac_operation_t *operation, @@ -267,8 +267,8 @@ psa_status_t mbedtls_psa_mac_verify_finish( * * \param[in,out] operation Initialized MAC operation. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_mac_abort( mbedtls_psa_mac_operation_t *operation); diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h index c3acdd0ebf..bc24ef5d5c 100644 --- a/library/psa_crypto_rsa.h +++ b/library/psa_crypto_rsa.h @@ -61,9 +61,9 @@ psa_status_t mbedtls_psa_rsa_load_representation(psa_key_type_t type, * \retval #PSA_SUCCESS The RSA key was imported successfully. * \retval #PSA_ERROR_INVALID_ARGUMENT * The key data is not correctly formatted. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription */ psa_status_t mbedtls_psa_rsa_import_key( const psa_key_attributes_t *attributes, @@ -102,12 +102,12 @@ psa_status_t mbedtls_psa_rsa_export_key(psa_key_type_t type, * \p data. * * \retval #PSA_SUCCESS The RSA public key was exported successfully. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_rsa_export_public_key( const psa_key_attributes_t *attributes, @@ -158,17 +158,17 @@ psa_status_t mbedtls_psa_rsa_generate_key( * \param[out] signature_length On success, the number of bytes * that make up the returned signature value. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p signature buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_SIGN_OUTPUT_SIZE(\c PSA_KEY_TYPE_RSA_KEY_PAIR, \c key_bits, * \p alg) where \c key_bits is the bit-size of the RSA key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription */ psa_status_t mbedtls_psa_rsa_sign_hash( const psa_key_attributes_t *attributes, @@ -202,9 +202,9 @@ psa_status_t mbedtls_psa_rsa_sign_hash( * \retval #PSA_ERROR_INVALID_SIGNATURE * The calculation was performed successfully, but the passed * signature is not a valid signature. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription */ psa_status_t mbedtls_psa_rsa_verify_hash( const psa_key_attributes_t *attributes, @@ -237,20 +237,20 @@ psa_status_t mbedtls_psa_rsa_verify_hash( * \param[out] output_length On success, the number of bytes * that make up the returned output. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize @@ -294,21 +294,21 @@ psa_status_t mbedtls_psa_asymmetric_encrypt(const psa_key_attributes_t *attribut * \param[out] output_length On success, the number of bytes * that make up the returned output. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_BUFFER_TOO_SMALL * The size of the \p output buffer is too small. You can * determine a sufficient buffer size by calling * #PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE(\c key_type, \c key_bits, \p alg) * where \c key_type and \c key_bits are the type and bit-size * respectively of \p key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY - * \retval #PSA_ERROR_INVALID_PADDING + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_INVALID_PADDING \emptydescription * \retval #PSA_ERROR_BAD_STATE * The library has not been previously initialized by psa_crypto_init(). * It is implementation-dependent whether a failure to initialize diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index ff8ccdeae5..c8366abeb8 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -88,9 +88,9 @@ static inline int psa_key_id_is_volatile(psa_key_id_t key_id) * due to a lack of empty key slot, or available memory. * \retval #PSA_ERROR_DOES_NOT_EXIST * There is no key with key identifier \p key. - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription */ psa_status_t psa_get_and_lock_key_slot(mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot); @@ -118,9 +118,9 @@ void psa_wipe_all_key_slots(void); * associated to the returned slot. * \param[out] p_slot On success, a pointer to the slot. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_BAD_STATE + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_BAD_STATE \emptydescription */ psa_status_t psa_get_empty_key_slot(psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot); @@ -195,8 +195,8 @@ static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime) * storage, returns a pointer to the driver table * associated with the key's storage location. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription */ psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime, psa_se_drv_table_entry_t **p_drv); @@ -205,7 +205,7 @@ psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime, * * \param[in] lifetime The key lifetime attribute. * - * \retval #PSA_SUCCESS + * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_NOT_SUPPORTED The key is persistent but persistent keys * are not supported. */ diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c index 8225014392..a8ed937536 100644 --- a/library/psa_crypto_storage.c +++ b/library/psa_crypto_storage.c @@ -79,11 +79,11 @@ static psa_storage_uid_t psa_its_identifier_of_slot(mbedtls_svc_key_id_t key) * \param[out] data Buffer where the data is to be written. * \param data_size Size of the \c data buffer in bytes. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DOES_NOT_EXIST + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription */ static psa_status_t psa_crypto_storage_load( const mbedtls_svc_key_id_t key, uint8_t *data, size_t data_size) @@ -131,11 +131,11 @@ int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key) * \param data_length The number of bytes * that make up the data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_ALREADY_EXISTS - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription */ static psa_status_t psa_crypto_storage_store(const mbedtls_svc_key_id_t key, const uint8_t *data, @@ -205,10 +205,10 @@ psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key) * is to be obtained. * \param[out] data_length The number of bytes that make up the data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DOES_NOT_EXIST - * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription */ static psa_status_t psa_crypto_storage_get_data_length( const mbedtls_svc_key_id_t key, diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h index 8e108c5684..04768f8a43 100644 --- a/library/psa_crypto_storage.h +++ b/library/psa_crypto_storage.h @@ -96,14 +96,14 @@ int psa_is_key_present_in_storage(const mbedtls_svc_key_id_t key); * \param[in] data Buffer containing the key data. * \param data_length The number of bytes that make up the key data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_ALREADY_EXISTS - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_ALREADY_EXISTS \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription */ psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr, const uint8_t *data, @@ -129,11 +129,11 @@ psa_status_t psa_save_persistent_key(const psa_core_key_attributes_t *attr, * \param[out] data Pointer to an allocated key data buffer on return. * \param[out] data_length The number of bytes that make up the key data. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_DOES_NOT_EXIST + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_DOES_NOT_EXIST \emptydescription */ psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr, uint8_t **data, @@ -148,7 +148,7 @@ psa_status_t psa_load_persistent_key(psa_core_key_attributes_t *attr, * \retval #PSA_SUCCESS * The key was successfully removed, * or the key did not exist. - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_ERROR_DATA_INVALID \emptydescription */ psa_status_t psa_destroy_persistent_key(const mbedtls_svc_key_id_t key); @@ -190,9 +190,9 @@ void psa_format_key_data_for_storage(const uint8_t *data, * \param[out] attr On success, the attribute structure is filled * with the loaded key metadata. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_DATA_INVALID + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription */ psa_status_t psa_parse_key_data_from_storage(const uint8_t *storage_data, size_t storage_data_length, @@ -322,10 +322,10 @@ static inline void psa_crypto_prepare_transaction( * You may call this function multiple times during a transaction to * atomically update the transaction state. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_DATA_CORRUPT - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE - * \retval #PSA_ERROR_STORAGE_FAILURE + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription */ psa_status_t psa_crypto_save_transaction(void); @@ -339,9 +339,9 @@ psa_status_t psa_crypto_save_transaction(void); * #psa_crypto_transaction. * \retval #PSA_ERROR_DOES_NOT_EXIST * There is no ongoing transaction. - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_DATA_INVALID - * \retval #PSA_ERROR_DATA_CORRUPT + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription */ psa_status_t psa_crypto_load_transaction(void); @@ -380,8 +380,8 @@ psa_status_t psa_crypto_stop_transaction(void); * * \retval #PSA_SUCCESS * Success - * \retval #PSA_ERROR_STORAGE_FAILURE - * \retval #PSA_ERROR_INSUFFICIENT_STORAGE + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription * \retval #PSA_ERROR_NOT_PERMITTED * The entropy seed file already exists. */ diff --git a/library/sha256.c b/library/sha256.c index cb09a71ec1..23cd406c37 100644 --- a/library/sha256.c +++ b/library/sha256.c @@ -22,6 +22,23 @@ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf */ +#if defined(__aarch64__) && !defined(__ARM_FEATURE_CRYPTO) && \ + defined(__clang__) && __clang_major__ < 18 && __clang_major__ > 3 +/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged. + * + * The intrinsic declaration are guarded by predefined ACLE macros in clang: + * these are normally only enabled by the -march option on the command line. + * By defining the macros ourselves we gain access to those declarations without + * requiring -march on the command line. + * + * `arm_neon.h` could be included by any header file, so we put these defines + * at the top of this file, before any includes. + */ +#define __ARM_FEATURE_CRYPTO 1 +#define NEED_TARGET_OPTIONS +#endif /* __aarch64__ && __clang__ && + !__ARM_FEATURE_CRYPTO && __clang_major__ < 18 && __clang_major__ > 3 */ + #include "common.h" #if defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C) @@ -37,6 +54,30 @@ #if defined(__aarch64__) # if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) || \ defined(MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY) +/* *INDENT-OFF* */ +# if !defined(__ARM_FEATURE_CRYPTO) || defined(NEED_TARGET_OPTIONS) +# if defined(__clang__) +# if __clang_major__ < 4 +# error "A more recent Clang is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# endif +# pragma clang attribute push (__attribute__((target("crypto"))), apply_to=function) +# define MBEDTLS_POP_TARGET_PRAGMA +# elif defined(__GNUC__) + /* FIXME: GCC-5 annouce crypto extension, but some intrinsic are missed. + * Known miss intrinsic can be workaround. + */ +# if __GNUC__ < 6 +# error "A more recent GCC is required for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# else +# pragma GCC push_options +# pragma GCC target ("arch=armv8-a+crypto") +# define MBEDTLS_POP_TARGET_PRAGMA +# endif +# else +# error "Only GCC and Clang supported for MBEDTLS_SHA256_USE_A64_CRYPTO_*" +# endif +# endif +/* *INDENT-ON* */ # include # endif # if defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) @@ -353,8 +394,16 @@ int mbedtls_internal_sha256_process_a64_crypto(mbedtls_sha256_context *ctx, SHA256_BLOCK_SIZE) ? 0 : -1; } -#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ +#if defined(MBEDTLS_POP_TARGET_PRAGMA) +#if defined(__clang__) +#pragma clang attribute pop +#elif defined(__GNUC__) +#pragma GCC pop_options +#endif +#undef MBEDTLS_POP_TARGET_PRAGMA +#endif +#endif /* MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY */ #if !defined(MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT) #define mbedtls_internal_sha256_process_many_c mbedtls_internal_sha256_process_many diff --git a/library/sha512.c b/library/sha512.c index efcbed413f..bc92a8de21 100644 --- a/library/sha512.c +++ b/library/sha512.c @@ -22,6 +22,26 @@ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf */ +#if defined(__aarch64__) && !defined(__ARM_FEATURE_SHA512) && \ + defined(__clang__) && __clang_major__ < 18 && \ + __clang_major__ >= 13 && __clang_minor__ > 0 && __clang_patchlevel__ > 0 +/* TODO: Re-consider above after https://reviews.llvm.org/D131064 merged. + * + * The intrinsic declaration are guarded by predefined ACLE macros in clang: + * these are normally only enabled by the -march option on the command line. + * By defining the macros ourselves we gain access to those declarations without + * requiring -march on the command line. + * + * `arm_neon.h` could be included by any header file, so we put these defines + * at the top of this file, before any includes. + */ +#define __ARM_FEATURE_SHA512 1 +#define NEED_TARGET_OPTIONS +#endif /* __aarch64__ && __clang__ && + !__ARM_FEATURE_SHA512 && __clang_major__ < 18 && + __clang_major__ >= 13 && __clang_minor__ > 0 && + __clang_patchlevel__ > 0 */ + #include "common.h" #if defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA384_C) @@ -43,6 +63,47 @@ #if defined(__aarch64__) # if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) || \ defined(MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY) +/* *INDENT-OFF* */ +/* + * Best performance comes from most recent compilers, with intrinsics and -O3. + * Must compile with -march=armv8.2-a+sha3, but we can't detect armv8.2-a, and + * can't always detect __ARM_FEATURE_SHA512 (notably clang 7-12). + * + * GCC < 8 won't work at all (lacks the sha512 instructions) + * GCC >= 8 uses intrinsics, sets __ARM_FEATURE_SHA512 + * + * Clang < 7 won't work at all (lacks the sha512 instructions) + * Clang 7-12 don't have intrinsics (but we work around that with inline + * assembler) or __ARM_FEATURE_SHA512 + * Clang == 13.0.0 same as clang 12 (only seen on macOS) + * Clang >= 13.0.1 has __ARM_FEATURE_SHA512 and intrinsics + */ +# if !defined(__ARM_FEATURE_SHA512) || defined(NEED_TARGET_OPTIONS) + /* Test Clang first, as it defines __GNUC__ */ +# if defined(__clang__) +# if __clang_major__ < 7 +# error "A more recent Clang is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" +# elif __clang_major__ < 13 || \ + (__clang_major__ == 13 && __clang_minor__ == 0 && \ + __clang_patchlevel__ == 0) + /* We implement the intrinsics with inline assembler, so don't error */ +# else +# pragma clang attribute push (__attribute__((target("sha3"))), apply_to=function) +# define MBEDTLS_POP_TARGET_PRAGMA +# endif +# elif defined(__GNUC__) +# if __GNUC__ < 8 +# error "A more recent GCC is required for MBEDTLS_SHA512_USE_A64_CRYPTO_*" +# else +# pragma GCC push_options +# pragma GCC target ("arch=armv8.2-a+sha3") +# define MBEDTLS_POP_TARGET_PRAGMA +# endif +# else +# error "Only GCC and Clang supported for MBEDTLS_SHA512_USE_A64_CRYPTO_*" +# endif +# endif +/* *INDENT-ON* */ # include # endif # if defined(MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT) @@ -516,6 +577,15 @@ int mbedtls_internal_sha512_process_a64_crypto(mbedtls_sha512_context *ctx, SHA512_BLOCK_SIZE) ? 0 : -1; } +#if defined(MBEDTLS_POP_TARGET_PRAGMA) +#if defined(__clang__) +#pragma clang attribute pop +#elif defined(__GNUC__) +#pragma GCC pop_options +#endif +#undef MBEDTLS_POP_TARGET_PRAGMA +#endif + #endif /* MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT || MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY */ diff --git a/library/ssl_client.c b/library/ssl_client.c index 963f8bb7c7..ea64b216e0 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -945,16 +945,29 @@ int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */ { - mbedtls_ssl_add_hs_hdr_to_checksum(ssl, MBEDTLS_SSL_HS_CLIENT_HELLO, - msg_len); - ssl->handshake->update_checksum(ssl, buf, msg_len - binders_len); + ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, + MBEDTLS_SSL_HS_CLIENT_HELLO, + msg_len); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_add_hs_hdr_to_checksum", ret); + return ret; + } + ret = ssl->handshake->update_checksum(ssl, buf, msg_len - binders_len); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); + return ret; + } #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) if (binders_len > 0) { MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext( ssl, buf + msg_len - binders_len, buf + msg_len)); - ssl->handshake->update_checksum(ssl, buf + msg_len - binders_len, - binders_len); + ret = ssl->handshake->update_checksum(ssl, buf + msg_len - binders_len, + binders_len); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); + return ret; + } } #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 2668a05b6e..7385c6ee39 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -705,9 +705,12 @@ struct mbedtls_ssl_handshake_params { mbedtls_ssl_ciphersuite_t const *ciphersuite_info; - void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); - void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); - void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); + MBEDTLS_CHECK_RETURN_CRITICAL + int (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); + MBEDTLS_CHECK_RETURN_CRITICAL + int (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *); + MBEDTLS_CHECK_RETURN_CRITICAL + int (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); mbedtls_ssl_tls_prf_cb *tls_prf; /* @@ -1317,7 +1320,8 @@ static inline void mbedtls_ssl_handshake_set_state(mbedtls_ssl_context *ssl, MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_send_fatal_handshake_failure(mbedtls_ssl_context *ssl); -void mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl); +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl); #if defined(MBEDTLS_SSL_PROTO_TLS1_2) MBEDTLS_CHECK_RETURN_CRITICAL @@ -1328,7 +1332,8 @@ MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_handle_message_type(mbedtls_ssl_context *ssl); MBEDTLS_CHECK_RETURN_CRITICAL int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl); -void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl); +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl); /** * \brief Update record layer @@ -1461,14 +1466,16 @@ void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl, /* * Update checksum of handshake messages. */ -void mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - unsigned char const *msg, - size_t msg_len); +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl, + unsigned hs_type, + unsigned char const *msg, + size_t msg_len); -void mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - size_t total_hs_len); +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, + unsigned hs_type, + size_t total_hs_len); #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) #if !defined(MBEDTLS_USE_PSA_CRYPTO) diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 9bedc25467..d26d950864 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -2639,7 +2639,12 @@ int mbedtls_ssl_write_handshake_msg_ext(mbedtls_ssl_context *ssl, /* Update running hashes of handshake messages seen */ if (hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0) { - ssl->handshake->update_checksum(ssl, ssl->out_msg, ssl->out_msglen); + ret = ssl->handshake->update_checksum(ssl, ssl->out_msg, + ssl->out_msglen); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); + return ret; + } } } @@ -3067,12 +3072,17 @@ int mbedtls_ssl_prepare_handshake_record(mbedtls_ssl_context *ssl) return 0; } -void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) +int mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_ssl_handshake_params * const hs = ssl->handshake; if (mbedtls_ssl_is_handshake_over(ssl) == 0 && hs != NULL) { - ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen); + ret = ssl->handshake->update_checksum(ssl, ssl->in_msg, ssl->in_hslen); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); + return ret; + } } /* Handshake message is complete, increment counter */ @@ -3103,6 +3113,7 @@ void mbedtls_ssl_update_handshake_status(mbedtls_ssl_context *ssl) memset(hs_buf, 0, sizeof(mbedtls_ssl_hs_buffer)); } #endif + return 0; } /* @@ -3928,7 +3939,11 @@ int mbedtls_ssl_read_record(mbedtls_ssl_context *ssl, if (ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && update_hs_digest == 1) { - mbedtls_ssl_update_handshake_status(ssl); + ret = mbedtls_ssl_update_handshake_status(ssl); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); + return ret; + } } } else { MBEDTLS_SSL_DEBUG_MSG(2, ("reuse previously read message")); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 86f5c0b555..441089f164 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -418,8 +418,8 @@ static int tls_prf_sha256(const unsigned char *secret, size_t slen, const char *label, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen); -static void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *); -static void ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int); +static int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *, unsigned char *, size_t *); +static int ssl_calc_finished_tls_sha256(mbedtls_ssl_context *, unsigned char *, int); #endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/ @@ -430,8 +430,8 @@ static int tls_prf_sha384(const unsigned char *secret, size_t slen, const unsigned char *random, size_t rlen, unsigned char *dstbuf, size_t dlen); -static void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *); -static void ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int); +static int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *, unsigned char *, size_t *); +static int ssl_calc_finished_tls_sha384(mbedtls_ssl_context *, unsigned char *, int); #endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/ static size_t ssl_tls12_session_save(const mbedtls_ssl_session *session, @@ -444,14 +444,14 @@ static int ssl_tls12_session_load(mbedtls_ssl_session *session, size_t len); #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -static void ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t); +static int ssl_update_checksum_start(mbedtls_ssl_context *, const unsigned char *, size_t); #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -static void ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t); +static int ssl_update_checksum_sha256(mbedtls_ssl_context *, const unsigned char *, size_t); #endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/ #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -static void ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t); +static int ssl_update_checksum_sha384(mbedtls_ssl_context *, const unsigned char *, size_t); #endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/ int mbedtls_ssl_tls_prf(const mbedtls_tls_prf_types prf, @@ -788,9 +788,9 @@ void mbedtls_ssl_optimize_checksum(mbedtls_ssl_context *ssl, } } -void mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - size_t total_hs_len) +int mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, + unsigned hs_type, + size_t total_hs_len) { unsigned char hs_hdr[4]; @@ -800,84 +800,137 @@ void mbedtls_ssl_add_hs_hdr_to_checksum(mbedtls_ssl_context *ssl, hs_hdr[2] = MBEDTLS_BYTE_1(total_hs_len); hs_hdr[3] = MBEDTLS_BYTE_0(total_hs_len); - ssl->handshake->update_checksum(ssl, hs_hdr, sizeof(hs_hdr)); + return ssl->handshake->update_checksum(ssl, hs_hdr, sizeof(hs_hdr)); } -void mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl, - unsigned hs_type, - unsigned char const *msg, - size_t msg_len) +int mbedtls_ssl_add_hs_msg_to_checksum(mbedtls_ssl_context *ssl, + unsigned hs_type, + unsigned char const *msg, + size_t msg_len) { - mbedtls_ssl_add_hs_hdr_to_checksum(ssl, hs_type, msg_len); - ssl->handshake->update_checksum(ssl, msg, msg_len); + int ret; + ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, hs_type, msg_len); + if (ret != 0) { + return ret; + } + return ssl->handshake->update_checksum(ssl, msg, msg_len); } -void mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl) +int mbedtls_ssl_reset_checksum(mbedtls_ssl_context *ssl) { +#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) || \ + defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_status_t status; +#else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; +#endif +#else /* SHA-256 or SHA-384 */ ((void) ssl); +#endif /* SHA-256 or SHA-384 */ #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&ssl->handshake->fin_sha256_psa); - psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256); + status = psa_hash_abort(&ssl->handshake->fin_sha256_psa); + if (status != PSA_SUCCESS) { + return mbedtls_md_error_from_psa(status); + } + status = psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256); + if (status != PSA_SUCCESS) { + return mbedtls_md_error_from_psa(status); + } #else - mbedtls_sha256_starts(&ssl->handshake->fin_sha256, 0); + ret = mbedtls_sha256_starts(&ssl->handshake->fin_sha256, 0); + if (ret != 0) { + return ret; + } #endif #endif #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&ssl->handshake->fin_sha384_psa); - psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384); + status = psa_hash_abort(&ssl->handshake->fin_sha384_psa); + if (status != PSA_SUCCESS) { + return mbedtls_md_error_from_psa(status); + } + status = psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384); + if (status != PSA_SUCCESS) { + return mbedtls_md_error_from_psa(status); + } #else - mbedtls_sha512_starts(&ssl->handshake->fin_sha384, 1); + ret = mbedtls_sha512_starts(&ssl->handshake->fin_sha384, 1); + if (ret != 0) { + return ret; + } #endif #endif + return 0; } -static void ssl_update_checksum_start(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) +static int ssl_update_checksum_start(mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len) { -#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) +#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) || \ + defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len); + psa_status_t status; #else - mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len); + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; #endif -#endif -#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len); -#else - mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len); -#endif -#endif -#if !defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) && \ - !defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) - (void) ssl; +#else /* SHA-256 or SHA-384 */ + ((void) ssl); (void) buf; (void) len; +#endif /* SHA-256 or SHA-384 */ +#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + status = psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len); + if (status != PSA_SUCCESS) { + return mbedtls_md_error_from_psa(status); + } +#else + ret = mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len); + if (ret != 0) { + return ret; + } #endif +#endif +#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) +#if defined(MBEDTLS_USE_PSA_CRYPTO) + status = psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len); + if (status != PSA_SUCCESS) { + return mbedtls_md_error_from_psa(status); + } +#else + ret = mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len); + if (ret != 0) { + return ret; + } +#endif +#endif + return 0; } #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -static void ssl_update_checksum_sha256(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) +static int ssl_update_checksum_sha256(mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update(&ssl->handshake->fin_sha256_psa, buf, len); + return mbedtls_md_error_from_psa(psa_hash_update( + &ssl->handshake->fin_sha256_psa, buf, len)); #else - mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len); + return mbedtls_sha256_update(&ssl->handshake->fin_sha256, buf, len); #endif } #endif #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -static void ssl_update_checksum_sha384(mbedtls_ssl_context *ssl, - const unsigned char *buf, size_t len) +static int ssl_update_checksum_sha384(mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len) { #if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_update(&ssl->handshake->fin_sha384_psa, buf, len); + return mbedtls_md_error_from_psa(psa_hash_update( + &ssl->handshake->fin_sha384_psa, buf, len)); #else - mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len); + return mbedtls_sha512_update(&ssl->handshake->fin_sha384, buf, len); #endif } #endif @@ -889,19 +942,15 @@ static void ssl_handshake_params_init(mbedtls_ssl_handshake_params *handshake) #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) #if defined(MBEDTLS_USE_PSA_CRYPTO) handshake->fin_sha256_psa = psa_hash_operation_init(); - psa_hash_setup(&handshake->fin_sha256_psa, PSA_ALG_SHA_256); #else mbedtls_sha256_init(&handshake->fin_sha256); - mbedtls_sha256_starts(&handshake->fin_sha256, 0); #endif #endif #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) #if defined(MBEDTLS_USE_PSA_CRYPTO) handshake->fin_sha384_psa = psa_hash_operation_init(); - psa_hash_setup(&handshake->fin_sha384_psa, PSA_ALG_SHA_384); #else mbedtls_sha512_init(&handshake->fin_sha384); - mbedtls_sha512_starts(&handshake->fin_sha384, 1); #endif #endif @@ -971,6 +1020,8 @@ void mbedtls_ssl_session_init(mbedtls_ssl_session *session) MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_handshake_init(mbedtls_ssl_context *ssl) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + /* Clear old handshake information if present */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) if (ssl->transform_negotiate) { @@ -1038,6 +1089,13 @@ static int ssl_handshake_init(mbedtls_ssl_context *ssl) mbedtls_ssl_transform_init(ssl->transform_negotiate); #endif + /* Setup handshake checksums */ + ret = mbedtls_ssl_reset_checksum(ssl); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_checksum", ret); + return ret; + } + #if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \ defined(MBEDTLS_SSL_SRV_C) && \ defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -6285,7 +6343,10 @@ static int ssl_compute_master(mbedtls_ssl_handshake_params *handshake, if (handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) { lbl = "extended master secret"; seed = session_hash; - handshake->calc_verify(ssl, session_hash, &seed_len); + ret = handshake->calc_verify(ssl, session_hash, &seed_len); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "calc_verify", ret); + } MBEDTLS_SSL_DEBUG_BUF(3, "session hash for extended master secret", session_hash, seed_len); @@ -6513,9 +6574,9 @@ int mbedtls_ssl_set_calc_verify_md(mbedtls_ssl_context *ssl, int md) } #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl, - unsigned char *hash, - size_t *hlen) +int ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl, + unsigned char *hash, + size_t *hlen) { #if defined(MBEDTLS_USE_PSA_CRYPTO) size_t hash_size; @@ -6525,20 +6586,23 @@ void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha256")); status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed")); - return; + goto exit; } status = psa_hash_finish(&sha256_psa, hash, 32, &hash_size); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed")); - return; + goto exit; } *hlen = 32; MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen); MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify")); + +exit: + psa_hash_abort(&sha256_psa); + return mbedtls_md_error_from_psa(status); #else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_sha256_context sha256; mbedtls_sha256_init(&sha256); @@ -6546,23 +6610,28 @@ void ssl_calc_verify_tls_sha256(const mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha256")); mbedtls_sha256_clone(&sha256, &ssl->handshake->fin_sha256); - mbedtls_sha256_finish(&sha256, hash); + + ret = mbedtls_sha256_finish(&sha256, hash); + if (ret != 0) { + goto exit; + } *hlen = 32; MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen); MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify")); +exit: mbedtls_sha256_free(&sha256); + return ret; #endif /* MBEDTLS_USE_PSA_CRYPTO */ - return; } #endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */ #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl, - unsigned char *hash, - size_t *hlen) +int ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl, + unsigned char *hash, + size_t *hlen) { #if defined(MBEDTLS_USE_PSA_CRYPTO) size_t hash_size; @@ -6572,20 +6641,23 @@ void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG(2, ("=> PSA calc verify sha384")); status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed")); - return; + goto exit; } status = psa_hash_finish(&sha384_psa, hash, 48, &hash_size); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed")); - return; + goto exit; } *hlen = 48; MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated verify result", hash, *hlen); MBEDTLS_SSL_DEBUG_MSG(2, ("<= PSA calc verify")); + +exit: + psa_hash_abort(&sha384_psa); + return mbedtls_md_error_from_psa(status); #else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_sha512_context sha512; mbedtls_sha512_init(&sha512); @@ -6593,16 +6665,21 @@ void ssl_calc_verify_tls_sha384(const mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG(2, ("=> calc verify sha384")); mbedtls_sha512_clone(&sha512, &ssl->handshake->fin_sha384); - mbedtls_sha512_finish(&sha512, hash); + + ret = mbedtls_sha512_finish(&sha512, hash); + if (ret != 0) { + goto exit; + } *hlen = 48; MBEDTLS_SSL_DEBUG_BUF(3, "calculated verify result", hash, *hlen); MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc verify")); +exit: mbedtls_sha512_free(&sha512); + return ret; #endif /* MBEDTLS_USE_PSA_CRYPTO */ - return; } #endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */ @@ -7545,7 +7622,7 @@ exit: #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -static void ssl_calc_finished_tls_sha256( +static int ssl_calc_finished_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *buf, int from) { int len = 12; @@ -7556,6 +7633,7 @@ static void ssl_calc_finished_tls_sha256( psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT; psa_status_t status; #else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_sha256_context sha256; #endif @@ -7575,14 +7653,12 @@ static void ssl_calc_finished_tls_sha256( status = psa_hash_clone(&ssl->handshake->fin_sha256_psa, &sha256_psa); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed")); - return; + goto exit; } status = psa_hash_finish(&sha256_psa, padbuf, sizeof(padbuf), &hash_size); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed")); - return; + goto exit; } MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 32); #else @@ -7604,8 +7680,10 @@ static void ssl_calc_finished_tls_sha256( sha256.state, sizeof(sha256.state)); #endif - mbedtls_sha256_finish(&sha256, padbuf); - mbedtls_sha256_free(&sha256); + ret = mbedtls_sha256_finish(&sha256, padbuf); + if (ret != 0) { + goto exit; + } #endif /* MBEDTLS_USE_PSA_CRYPTO */ ssl->handshake->tls_prf(session->master, 48, sender, @@ -7616,12 +7694,21 @@ static void ssl_calc_finished_tls_sha256( mbedtls_platform_zeroize(padbuf, sizeof(padbuf)); MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished")); + +exit: +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_hash_abort(&sha256_psa); + return mbedtls_md_error_from_psa(status); +#else + mbedtls_sha256_free(&sha256); + return ret; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/ #if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) -static void ssl_calc_finished_tls_sha384( +static int ssl_calc_finished_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *buf, int from) { int len = 12; @@ -7632,6 +7719,7 @@ static void ssl_calc_finished_tls_sha384( psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT; psa_status_t status; #else + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; mbedtls_sha512_context sha512; #endif @@ -7651,14 +7739,12 @@ static void ssl_calc_finished_tls_sha384( status = psa_hash_clone(&ssl->handshake->fin_sha384_psa, &sha384_psa); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash clone failed")); - return; + goto exit; } status = psa_hash_finish(&sha384_psa, padbuf, sizeof(padbuf), &hash_size); if (status != PSA_SUCCESS) { - MBEDTLS_SSL_DEBUG_MSG(2, ("PSA hash finish failed")); - return; + goto exit; } MBEDTLS_SSL_DEBUG_BUF(3, "PSA calculated padbuf", padbuf, 48); #else @@ -7678,9 +7764,10 @@ static void ssl_calc_finished_tls_sha384( MBEDTLS_SSL_DEBUG_BUF(4, "finished sha512 state", (unsigned char *) sha512.state, sizeof(sha512.state)); #endif - mbedtls_sha512_finish(&sha512, padbuf); - - mbedtls_sha512_free(&sha512); + ret = mbedtls_sha512_finish(&sha512, padbuf); + if (ret != 0) { + goto exit; + } #endif ssl->handshake->tls_prf(session->master, 48, sender, @@ -7691,6 +7778,15 @@ static void ssl_calc_finished_tls_sha384( mbedtls_platform_zeroize(padbuf, sizeof(padbuf)); MBEDTLS_SSL_DEBUG_MSG(2, ("<= calc finished")); + +exit: +#if defined(MBEDTLS_USE_PSA_CRYPTO) + psa_hash_abort(&sha384_psa); + return mbedtls_md_error_from_psa(status); +#else + mbedtls_sha512_free(&sha512); + return ret; +#endif /* MBEDTLS_USE_PSA_CRYPTO */ } #endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA*/ @@ -7787,7 +7883,10 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl) mbedtls_ssl_update_out_pointers(ssl, ssl->transform_negotiate); - ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint); + ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret); + } /* * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites @@ -7897,7 +7996,10 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl) MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse finished")); - ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1); + ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret); + } if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index b427ae9444..fc99fdebeb 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -1090,6 +1090,7 @@ static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl, MBEDTLS_CHECK_RETURN_CRITICAL static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl) { + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); uint16_t dtls_legacy_version; @@ -1160,7 +1161,11 @@ static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl) /* Start over at ClientHello */ ssl->state = MBEDTLS_SSL_CLIENT_HELLO; - mbedtls_ssl_reset_checksum(ssl); + ret = mbedtls_ssl_reset_checksum(ssl); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret); + return ret; + } mbedtls_ssl_recv_flight_completed(ssl); @@ -3283,7 +3288,11 @@ static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) sign: #endif - ssl->handshake->calc_verify(ssl, hash, &hashlen); + ret = ssl->handshake->calc_verify(ssl, hash, &hashlen); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); + return ret; + } /* * digitally-signed struct { diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c index 929829249f..d5c8b7ce49 100644 --- a/library/ssl_tls12_server.c +++ b/library/ssl_tls12_server.c @@ -1020,7 +1020,11 @@ read_record_header: MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len); - ssl->handshake->update_checksum(ssl, buf, msg_len); + ret = ssl->handshake->update_checksum(ssl, buf, msg_len); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); + return ret; + } /* * Handshake layer: @@ -4129,7 +4133,11 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) /* Calculate hash and verify signature */ { size_t dummy_hlen; - ssl->handshake->calc_verify(ssl, hash, &dummy_hlen); + ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); + return ret; + } } if ((ret = mbedtls_pk_verify(peer_pk, @@ -4139,7 +4147,11 @@ static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) return ret; } - mbedtls_ssl_update_handshake_status(ssl); + ret = mbedtls_ssl_update_handshake_status(ssl); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); + return ret; + } MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify")); diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 1e79afab84..0dd762ef39 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1489,8 +1489,9 @@ static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl, ssl->keep_current_message = 1; ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2; - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_SERVER_HELLO, - buf, (size_t) (end - buf)); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_SERVER_HELLO, + buf, (size_t) (end - buf))); if (mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) { ret = ssl_tls13_reset_key_share(ssl); @@ -2056,8 +2057,9 @@ static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl)); } - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_SERVER_HELLO, - buf, buf_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_SERVER_HELLO, buf, + buf_len)); if (is_hrr) { MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl)); @@ -2214,8 +2216,9 @@ static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl) } #endif - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, - buf, buf_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, + buf, buf_len)); #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) { @@ -2259,8 +2262,8 @@ static int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl) ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, &buf, &buf_len)); - mbedtls_ssl_add_hs_hdr_to_checksum( - ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_hdr_to_checksum( + ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0)); MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0)); @@ -2458,8 +2461,9 @@ static int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(ssl, buf, buf + buf_len)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, - buf, buf_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, + buf, buf_len)); } else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) { ret = 0; } else { diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 4fb73f91b9..f607e364cc 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -322,8 +322,9 @@ int mbedtls_ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl) buf + buf_len, verify_buffer, verify_buffer_len)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, - buf, buf_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, + buf, buf_len)); cleanup: @@ -752,8 +753,9 @@ int mbedtls_ssl_tls13_process_certificate(mbedtls_ssl_context *ssl) /* Validate the certificate chain and set the verification results. */ MBEDTLS_SSL_PROC_CHK(ssl_tls13_validate_certificate(ssl)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE, - buf, buf_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_CERTIFICATE, buf, + buf_len)); cleanup: #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */ @@ -868,8 +870,9 @@ int mbedtls_ssl_tls13_write_certificate(mbedtls_ssl_context *ssl) buf + buf_len, &msg_len)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE, - buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_CERTIFICATE, buf, + msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len)); @@ -1070,8 +1073,9 @@ int mbedtls_ssl_tls13_write_certificate_verify(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_verify_body( ssl, buf, buf + buf_len, &msg_len)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, - buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_CERTIFICATE_VERIFY, buf, + msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len)); @@ -1171,8 +1175,8 @@ int mbedtls_ssl_tls13_process_finished_message(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_finished_message(ssl, buf, buf + buf_len)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_FINISHED, - buf, buf_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_FINISHED, buf, buf_len)); cleanup: @@ -1248,8 +1252,8 @@ int mbedtls_ssl_tls13_write_finished_message(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_finished_message_body( ssl, buf, buf + buf_len, &msg_len)); - mbedtls_ssl_add_hs_msg_to_checksum(ssl, MBEDTLS_SSL_HS_FINISHED, - buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(ssl, + MBEDTLS_SSL_HS_FINISHED, buf, msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len)); @@ -1388,7 +1392,7 @@ int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl) PSA_HASH_MAX_SIZE, &hash_len); if (ret != 0) { - MBEDTLS_SSL_DEBUG_RET(4, "mbedtls_ssl_get_handshake_transcript", ret); + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_get_handshake_transcript", ret); return ret; } @@ -1399,37 +1403,20 @@ int mbedtls_ssl_reset_transcript_for_hrr(mbedtls_ssl_context *ssl) hash_len += 4; -#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) - if (ciphersuite_info->mac == MBEDTLS_MD_SHA256) { - MBEDTLS_SSL_DEBUG_BUF(4, "Truncated SHA-256 handshake transcript", - hash_transcript, hash_len); + MBEDTLS_SSL_DEBUG_BUF(4, "Truncated handshake transcript", + hash_transcript, hash_len); -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&ssl->handshake->fin_sha256_psa); - psa_hash_setup(&ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256); -#else - mbedtls_sha256_starts(&ssl->handshake->fin_sha256, 0); -#endif + /* Reset running hash and replace it with a hash of the transcript */ + ret = mbedtls_ssl_reset_checksum(ssl); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_reset_checksum", ret); + return ret; } -#endif /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA */ -#if defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) - if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) { - MBEDTLS_SSL_DEBUG_BUF(4, "Truncated SHA-384 handshake transcript", - hash_transcript, hash_len); - -#if defined(MBEDTLS_USE_PSA_CRYPTO) - psa_hash_abort(&ssl->handshake->fin_sha384_psa); - psa_hash_setup(&ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384); -#else - mbedtls_sha512_starts(&ssl->handshake->fin_sha384, 1); -#endif + ret = ssl->handshake->update_checksum(ssl, hash_transcript, hash_len); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret); + return ret; } -#endif /* MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */ -#if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA) || \ - defined(MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA) - ssl->handshake->update_checksum(ssl, hash_transcript, hash_len); -#endif \ - /* MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA || MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA_BASED_ON_USE_PSA */ return ret; } diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 81c289aee5..6b1c4c5e6b 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -486,6 +486,7 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl, const unsigned char *ciphersuites, const unsigned char *ciphersuites_end) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; const unsigned char *identities = pre_shared_key_ext; const unsigned char *p_identity_len; size_t identities_len; @@ -521,8 +522,12 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl, MBEDTLS_SSL_CHK_BUF_READ_PTR(p_binder_len, pre_shared_key_ext_end, binders_len); binders_end = p_binder_len + binders_len; - ssl->handshake->update_checksum(ssl, pre_shared_key_ext, - identities_end - pre_shared_key_ext); + ret = ssl->handshake->update_checksum(ssl, pre_shared_key_ext, + identities_end - pre_shared_key_ext); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); + return ret; + } while (p_identity_len < identities_end && p_binder_len < binders_end) { const unsigned char *identity; @@ -530,7 +535,6 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl, uint32_t obfuscated_ticket_age; const unsigned char *binder; size_t binder_len; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int psk_type; uint16_t cipher_suite; const mbedtls_ssl_ciphersuite_t *ciphersuite_info; @@ -642,9 +646,13 @@ static int ssl_tls13_parse_pre_shared_key_ext(mbedtls_ssl_context *ssl, } /* Update the handshake transcript with the binder list. */ - ssl->handshake->update_checksum(ssl, - identities_end, - (size_t) (binders_end - identities_end)); + ret = ssl->handshake->update_checksum(ssl, + identities_end, + (size_t) (binders_end - identities_end)); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); + return ret; + } if (matched_identity == -1) { MBEDTLS_SSL_DEBUG_MSG(3, ("No matched PSK or ticket.")); return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; @@ -1590,9 +1598,13 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CLIENT_HELLO, handshake->received_extensions); - mbedtls_ssl_add_hs_hdr_to_checksum(ssl, - MBEDTLS_SSL_HS_CLIENT_HELLO, - p - buf); + ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl, + MBEDTLS_SSL_HS_CLIENT_HELLO, + p - buf); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_add_hs_hdr_to_checksum"), ret); + return ret; + } #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED) /* Update checksum with either @@ -1603,8 +1615,12 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, if (mbedtls_ssl_tls13_some_psk_enabled(ssl) && mbedtls_ssl_conf_tls13_some_psk_enabled(ssl) && (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY))) { - handshake->update_checksum(ssl, buf, - pre_shared_key_ext - buf); + ret = handshake->update_checksum(ssl, buf, + pre_shared_key_ext - buf); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); + return ret; + } ret = ssl_tls13_parse_pre_shared_key_ext(ssl, pre_shared_key_ext, pre_shared_key_ext_end, @@ -1620,7 +1636,11 @@ static int ssl_tls13_parse_client_hello(mbedtls_ssl_context *ssl, } else #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */ { - handshake->update_checksum(ssl, buf, p - buf); + ret = handshake->update_checksum(ssl, buf, p - buf); + if (0 != ret) { + MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); + return ret; + } } ret = ssl_tls13_determine_key_exchange_mode(ssl); @@ -2134,8 +2154,8 @@ static int ssl_tls13_write_server_hello(mbedtls_ssl_context *ssl) &msg_len, 0)); - mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len)); @@ -2207,8 +2227,8 @@ static int ssl_tls13_write_hello_retry_request(mbedtls_ssl_context *ssl) buf + buf_len, &msg_len, 1)); - mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl, buf_len, @@ -2306,8 +2326,8 @@ static int ssl_tls13_write_encrypted_extensions(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_encrypted_extensions_body( ssl, buf, buf + buf_len, &msg_len)); - mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len)); @@ -2439,8 +2459,8 @@ static int ssl_tls13_write_certificate_request(mbedtls_ssl_context *ssl) MBEDTLS_SSL_PROC_CHK(ssl_tls13_write_certificate_request_body( ssl, buf, buf + buf_len, &msg_len)); - mbedtls_ssl_add_hs_msg_to_checksum( - ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, msg_len); + MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, buf, msg_len)); MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg( ssl, buf_len, msg_len)); diff --git a/library/x509.c b/library/x509.c index 2865c2ef11..fc13b92133 100644 --- a/library/x509.c +++ b/library/x509.c @@ -1227,8 +1227,9 @@ static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name, * nameAssigner [0] DirectoryString OPTIONAL, * partyName [1] DirectoryString } * - * NOTE: we list all types, but only use dNSName and otherName - * of type HwModuleName, as defined in RFC 4108, at this point. + * We list all types, but use the following GeneralName types from RFC 5280: + * "dnsName", "uniformResourceIdentifier" and "hardware_module_name" + * of type "otherName", as defined in RFC 4108. */ int mbedtls_x509_get_subject_alt_name(unsigned char **p, const unsigned char *end, @@ -1397,7 +1398,19 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, } break; + /* + * uniformResourceIdentifier + */ + case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER): + { + memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); + san->type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER; + memcpy(&san->san.unstructured_name, + san_buf, sizeof(*san_buf)); + + } + break; /* * dNSName */ @@ -1408,7 +1421,17 @@ int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf, memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf)); + } + break; + /* + * RFC822 Name + */ + case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME): + { + memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name)); + san->type = MBEDTLS_X509_SAN_RFC822_NAME; + memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf)); } break; @@ -1488,13 +1511,38 @@ int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size, }/* MBEDTLS_OID_ON_HW_MODULE_NAME */ } break; + /* + * uniformResourceIdentifier + */ + case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: + { + ret = mbedtls_snprintf(p, n, "\n%s uniformResourceIdentifier : ", prefix); + MBEDTLS_X509_SAFE_SNPRINTF; + if (san.san.unstructured_name.len >= n) { + *p = '\0'; + return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; + } + memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len); + p += san.san.unstructured_name.len; + n -= san.san.unstructured_name.len; + } + break; /* * dNSName + * RFC822 Name */ case MBEDTLS_X509_SAN_DNS_NAME: + case MBEDTLS_X509_SAN_RFC822_NAME: { - ret = mbedtls_snprintf(p, n, "\n%s dNSName : ", prefix); + const char *dns_name = "dNSName"; + const char *rfc822_name = "rfc822Name"; + + ret = mbedtls_snprintf(p, n, + "\n%s %s : ", + prefix, + san.type == + MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name); MBEDTLS_X509_SAFE_SNPRINTF; if (san.san.unstructured_name.len >= n) { *p = '\0'; diff --git a/programs/.gitignore b/programs/.gitignore index 44e904a954..398152dcbc 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -64,6 +64,7 @@ test/cpp_dummy_build.cpp test/dlopen test/ecp-bench test/query_compile_time_config +test/query_included_headers test/selftest test/ssl_cert_test test/udp_proxy diff --git a/programs/Makefile b/programs/Makefile index fdfece72ac..3509fc374d 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -123,6 +123,7 @@ APPS = \ ssl/ssl_server2 \ test/benchmark \ test/query_compile_time_config \ + test/query_included_headers \ test/selftest \ test/udp_proxy \ test/zeroize \ @@ -403,6 +404,10 @@ test/query_config.o: test/query_config.c test/query_config.h $(DEP) echo " CC test/query_config.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) -c test/query_config.c -o $@ +test/query_included_headers$(EXEXT): test/query_included_headers.c $(DEP) + echo " CC test/query_included_headers.c" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/query_included_headers.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test/selftest$(EXEXT): test/selftest.c $(DEP) echo " CC test/selftest.c" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) test/selftest.c $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/programs/test/CMakeLists.txt b/programs/test/CMakeLists.txt index c3e7d2e98e..735684ebf6 100644 --- a/programs/test/CMakeLists.txt +++ b/programs/test/CMakeLists.txt @@ -3,6 +3,7 @@ set(libs ) set(executables_libs + query_included_headers selftest udp_proxy ) diff --git a/programs/test/query_included_headers.c b/programs/test/query_included_headers.c new file mode 100644 index 0000000000..383a2ffc8e --- /dev/null +++ b/programs/test/query_included_headers.c @@ -0,0 +1,41 @@ +/* Ad hoc report on included headers. */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +int main(void) +{ + + /* Which PSA platform header? */ +#if defined(PSA_CRYPTO_PLATFORM_H) + mbedtls_printf("PSA_CRYPTO_PLATFORM_H\n"); +#endif +#if defined(PSA_CRYPTO_PLATFORM_ALT_H) + mbedtls_printf("PSA_CRYPTO_PLATFORM_ALT_H\n"); +#endif + + /* Which PSA struct header? */ +#if defined(PSA_CRYPTO_STRUCT_H) + mbedtls_printf("PSA_CRYPTO_STRUCT_H\n"); +#endif +#if defined(PSA_CRYPTO_STRUCT_ALT_H) + mbedtls_printf("PSA_CRYPTO_STRUCT_ALT_H\n"); +#endif + +} diff --git a/scripts/code_style.py b/scripts/code_style.py index dd8305faf6..c31fb2949f 100755 --- a/scripts/code_style.py +++ b/scripts/code_style.py @@ -33,6 +33,14 @@ CHECK_GENERATED_FILES = "tests/scripts/check-generated-files.sh" def print_err(*args): print("Error: ", *args, file=sys.stderr) +# Print the file names that will be skipped and the help message +def print_skip(files_to_skip): + print() + print(*files_to_skip, sep=", SKIP\n", end=", SKIP\n") + print("Warning: The listed files will be skipped because\n" + "they are not known to git.") + print() + # Match FILENAME(s) in "check SCRIPT (FILENAME...)" CHECK_CALL_RE = re.compile(r"\n\s*check\s+[^\s#$&*?;|]+([^\n#$&*?;|]+)", re.ASCII) @@ -174,22 +182,27 @@ def main() -> int: parser.add_argument('-f', '--fix', action='store_true', help=('modify source files to fix the code style ' '(default: print diff, do not modify files)')) - # --files is almost useless: it only matters if there are no files + # --subset is almost useless: it only matters if there are no files # ('code_style.py' without arguments checks all files known to Git, - # 'code_style.py --files' does nothing). In particular, - # 'code_style.py --fix --files ...' is intended as a stable ("porcelain") + # 'code_style.py --subset' does nothing). In particular, + # 'code_style.py --fix --subset ...' is intended as a stable ("porcelain") # way to restyle a possibly empty set of files. - parser.add_argument('--files', action='store_true', + parser.add_argument('--subset', action='store_true', help='only check the specified files (default with non-option arguments)') parser.add_argument('operands', nargs='*', metavar='FILE', - help='files to check (if none: check files that are known to git)') + help='files to check (files MUST be known to git, if none: check all)') args = parser.parse_args() - if args.files or args.operands: - src_files = args.operands + covered = frozenset(get_src_files()) + # We only check files that are known to git + if args.subset or args.operands: + src_files = [f for f in args.operands if f in covered] + skip_src_files = [f for f in args.operands if f not in covered] + if skip_src_files: + print_skip(skip_src_files) else: - src_files = get_src_files() + src_files = list(covered) if args.fix: # Fix mode diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja index bdf331516c..aa11d4e42b 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja @@ -433,6 +433,251 @@ psa_status_t psa_driver_wrapper_verify_hash( } } +uint32_t psa_driver_wrapper_sign_hash_get_num_ops( + psa_sign_hash_interruptible_operation_t *operation ) +{ + switch( operation->id ) + { + /* If uninitialised, return 0, as no work can have been done. */ + case 0: + return 0; + + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return(mbedtls_psa_sign_hash_get_num_ops(&operation->ctx.mbedtls_ctx)); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* Add test driver tests here */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + return( PSA_ERROR_INVALID_ARGUMENT ); +} + +uint32_t psa_driver_wrapper_verify_hash_get_num_ops( + psa_verify_hash_interruptible_operation_t *operation ) +{ + switch( operation->id ) + { + /* If uninitialised, return 0, as no work can have been done. */ + case 0: + return 0; + + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return (mbedtls_psa_verify_hash_get_num_ops(&operation->ctx.mbedtls_ctx)); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* Add test driver tests here */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + } + + return( PSA_ERROR_INVALID_ARGUMENT ); +} + +psa_status_t psa_driver_wrapper_sign_hash_start( + psa_sign_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, const uint8_t *key_buffer, + size_t key_buffer_size, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( + attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + + /* Add test driver tests here */ + + /* Declared with fallback == true */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + /* Fell through, meaning no accelerator supports this operation */ + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + return( mbedtls_psa_sign_hash_start( &operation->ctx.mbedtls_ctx, + attributes, + key_buffer, key_buffer_size, + alg, hash, hash_length ) ); + break; + + /* Add cases for opaque driver here */ + + default: + /* Key is declared with a lifetime not known to us */ + ( void ) status; + return( PSA_ERROR_INVALID_ARGUMENT ); + } + + ( void ) operation; + ( void ) key_buffer; + ( void ) key_buffer_size; + ( void ) alg; + ( void ) hash; + ( void ) hash_length; + + return( status ); +} + +psa_status_t psa_driver_wrapper_sign_hash_complete( + psa_sign_hash_interruptible_operation_t *operation, + uint8_t *signature, size_t signature_size, + size_t *signature_length ) +{ + switch( operation->id ) + { + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_sign_hash_complete( &operation->ctx.mbedtls_ctx, + signature, signature_size, + signature_length ) ); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* Add test driver tests here */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + ( void ) signature; + ( void ) signature_size; + ( void ) signature_length; + + return( PSA_ERROR_INVALID_ARGUMENT ); +} + +psa_status_t psa_driver_wrapper_sign_hash_abort( + psa_sign_hash_interruptible_operation_t *operation ) +{ + switch( operation->id ) + { + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_sign_hash_abort( &operation->ctx.mbedtls_ctx ) ); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* Add test driver tests here */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + return( PSA_ERROR_INVALID_ARGUMENT ); +} + +psa_status_t psa_driver_wrapper_verify_hash_start( + psa_verify_hash_interruptible_operation_t *operation, + const psa_key_attributes_t *attributes, const uint8_t *key_buffer, + size_t key_buffer_size, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length ) +{ + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( + attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + + /* Add test driver tests here */ + + /* Declared with fallback == true */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + /* Fell through, meaning no accelerator supports this operation */ + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + return( mbedtls_psa_verify_hash_start( &operation->ctx.mbedtls_ctx, + attributes, + key_buffer, key_buffer_size, + alg, hash, hash_length, + signature, signature_length + ) ); + break; + + /* Add cases for opaque driver here */ + + default: + /* Key is declared with a lifetime not known to us */ + ( void ) status; + return( PSA_ERROR_INVALID_ARGUMENT ); + } + + ( void ) operation; + ( void ) key_buffer; + ( void ) key_buffer_size; + ( void ) alg; + ( void ) hash; + ( void ) hash_length; + ( void ) signature; + ( void ) signature_length; + + return( status ); +} + +psa_status_t psa_driver_wrapper_verify_hash_complete( + psa_verify_hash_interruptible_operation_t *operation ) +{ + switch( operation->id ) + { + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_verify_hash_complete( + &operation->ctx.mbedtls_ctx + ) ); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* Add test driver tests here */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + return( PSA_ERROR_INVALID_ARGUMENT ); +} + +psa_status_t psa_driver_wrapper_verify_hash_abort( + psa_verify_hash_interruptible_operation_t *operation ) +{ + switch( operation->id ) + { + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + return( mbedtls_psa_verify_hash_abort( &operation->ctx.mbedtls_ctx + ) ); + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* Add test driver tests here */ + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } + + return( PSA_ERROR_INVALID_ARGUMENT ); +} + /** Calculate the key buffer size required to store the key material of a key * associated with an opaque driver from input key data. * @@ -441,9 +686,9 @@ psa_status_t psa_driver_wrapper_verify_hash( * \param[in] data_length The input data length. * \param[out] key_buffer_size Minimum buffer size to contain the key material. * - * \retval #PSA_SUCCESS - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval #PSA_SUCCESS \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription */ psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( const psa_key_attributes_t *attributes, diff --git a/scripts/mbedtls_dev/ecp.py b/scripts/mbedtls_dev/ecp.py index 93cd2123ff..6370d258aa 100644 --- a/scripts/mbedtls_dev/ecp.py +++ b/scripts/mbedtls_dev/ecp.py @@ -75,3 +75,94 @@ class EcpP192R1Raw(bignum_common.ModOperationCommon, @property def is_valid(self) -> bool: return True + +class EcpP521R1Raw(bignum_common.ModOperationCommon, + EcpTarget): + """Test cases for ecp quasi_reduction().""" + test_function = "ecp_mod_p521_raw" + test_name = "ecp_mod_p521_raw" + input_style = "arch_split" + arity = 1 + + moduli = [("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + ] # type: List[str] + + input_values = [ + "0", "1", + + # Corner case: maximum canonical P521 multiplication result + ("0003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffff800" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000004"), + + # Test case for overflow during addition + ("0001efffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "000001ef" + "0000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000f000000"), + + # First 8 number generated by random.getrandbits(1042) - seed(2,2) + ("0003cc2e82523e86feac7eb7dc38f519b91751dacdbd47d364be8049a372db8f" + "6e405d93ffed9235288bc781ae66267594c9c9500925e4749b575bd13653f8dd" + "9b1f282e" + "4067c3584ee207f8da94e3e8ab73738fcf1822ffbc6887782b491044d5e34124" + "5c6e433715ba2bdd177219d30e7a269fd95bafc8f2a4d27bdcf4bb99f4bea973"), + ("00017052829e07b0829a48d422fe99a22c70501e533c91352d3d854e061b9030" + "3b08c6e33c7295782d6c797f8f7d9b782a1be9cd8697bbd0e2520e33e44c5055" + "6c71c4a6" + "6148a86fe8624fab5186ee32ee8d7ee9770348a05d300cb90706a045defc044a" + "09325626e6b58de744ab6cce80877b6f71e1f6d2ef8acd128b4f2fc15f3f57eb"), + ("00021f15a7a83ee0761ebfd2bd143fa9b714210c665d7435c1066932f4767f26" + "294365b2721dea3bf63f23d0dbe53fcafb2147df5ca495fa5a91c89b97eeab64" + "ca2ce6bc" + "5d3fd983c34c769fe89204e2e8168561867e5e15bc01bfce6a27e0dfcbf87544" + "72154e76e4c11ab2fec3f6b32e8d4b8a8f54f8ceacaab39e83844b40ffa9b9f1"), + ("000381bc2a838af8d5c44a4eb3172062d08f1bb2531d6460f0caeef038c89b38" + "a8acb5137c9260dc74e088a9b9492f258ebdbfe3eb9ac688b9d39cca91551e82" + "59cc60b1" + "7604e4b4e73695c3e652c71a74667bffe202849da9643a295a9ac6decbd4d3e2" + "d4dec9ef83f0be4e80371eb97f81375eecc1cb6347733e847d718d733ff98ff3"), + ("00034816c8c69069134bccd3e1cf4f589f8e4ce0af29d115ef24bd625dd961e6" + "830b54fa7d28f93435339774bb1e386c4fd5079e681b8f5896838b769da59b74" + "a6c3181c" + "81e220df848b1df78feb994a81167346d4c0dca8b4c9e755cc9c3adcf515a823" + "4da4daeb4f3f87777ad1f45ae9500ec9c5e2486c44a4a8f69dc8db48e86ec9c6"), + ("000397846c4454b90f756132e16dce72f18e859835e1f291d322a7353ead4efe" + "440e2b4fda9c025a22f1a83185b98f5fc11e60de1b343f52ea748db9e020307a" + "aeb6db2c" + "3a038a709779ac1f45e9dd320c855fdfa7251af0930cdbd30f0ad2a81b2d19a2" + "beaa14a7ff3fe32a30ffc4eed0a7bd04e85bfcdd0227eeb7b9d7d01f5769da05"), + ("00002c3296e6bc4d62b47204007ee4fab105d83e85e951862f0981aebc1b00d9" + "2838e766ef9b6bf2d037fe2e20b6a8464174e75a5f834da70569c018eb2b5693" + "babb7fbb" + "0a76c196067cfdcb11457d9cf45e2fa01d7f4275153924800600571fac3a5b26" + "3fdf57cd2c0064975c3747465cc36c270e8a35b10828d569c268a20eb78ac332"), + ("00009d23b4917fc09f20dbb0dcc93f0e66dfe717c17313394391b6e2e6eacb0f" + "0bb7be72bd6d25009aeb7fa0c4169b148d2f527e72daf0a54ef25c0707e33868" + "7d1f7157" + "5653a45c49390aa51cf5192bbf67da14be11d56ba0b4a2969d8055a9f03f2d71" + "581d8e830112ff0f0948eccaf8877acf26c377c13f719726fd70bddacb4deeec"), + + # Next 2 number generated by random.getrandbits(521) + ("12b84ae65e920a63ac1f2b64df6dff07870c9d531ae72a47403063238da1a1fe" + "3f9d6a179fa50f96cd4aff9261aa92c0e6f17ec940639bc2ccdf572df00790813e3"), + ("166049dd332a73fa0b26b75196cf87eb8a09b27ec714307c68c425424a1574f1" + "eedf5b0f16cdfdb839424d201e653f53d6883ca1c107ca6e706649889c0c7f38608") + ] + + @property + def arg_a(self) -> str: + # Number of limbs: 2 * N + return super().format_arg('{:x}'.format(self.int_a)).zfill(2 * self.hex_digits) + + def result(self) -> List[str]: + result = self.int_a % self.int_n + return [self.format_result(result)] + + @property + def is_valid(self) -> bool: + return True diff --git a/tests/.gitignore b/tests/.gitignore index 15fce6888b..b85d66aa46 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -13,6 +13,8 @@ data_files/hmac_drbg_seed data_files/ctr_drbg_seed data_files/entropy_seed +include/alt-extra/psa/crypto_platform_alt.h +include/alt-extra/psa/crypto_struct_alt.h include/test/instrument_record_status.h src/*.o diff --git a/tests/Makefile b/tests/Makefile index c9283c984f..26947f4b99 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -219,6 +219,7 @@ ifndef WINDOWS rm -rf $(BINARIES) *.c *.datax rm -f src/*.o src/drivers/*.o src/libmbed* rm -f include/test/instrument_record_status.h + rm -f include/alt-extra/*/*_alt.h rm -rf libtestdriver1 rm -f ../library/libtestdriver1.a else @@ -244,6 +245,10 @@ check: $(BINARIES) test: check +# Generate variants of some headers for testing +include/alt-extra/%_alt.h: ../include/%.h + perl -p -e 's/^(# *(define|ifndef) +\w+_)H\b/$${1}ALT_H/' $< >$@ + # Generate test library # Perl code that is executed to transform each original line from a library diff --git a/tests/compat.sh b/tests/compat.sh index 8f7d72c7b6..12613bfe8a 100755 --- a/tests/compat.sh +++ b/tests/compat.sh @@ -534,6 +534,16 @@ add_mbedtls_ciphersuites() esac } +# o_check_ciphersuite STANDARD_CIPHER_SUITE +o_check_ciphersuite() +{ + if [ "${O_SUPPORT_ECDH}" = "NO" ]; then + case "$1" in + *ECDH_*) SKIP_NEXT="YES" + esac + fi +} + setup_arguments() { O_MODE="" @@ -603,6 +613,11 @@ setup_arguments() ;; esac + case $($OPENSSL ciphers ALL) in + *ECDH-ECDSA*|*ECDH-RSA*) O_SUPPORT_ECDH="YES";; + *) O_SUPPORT_ECDH="NO";; + esac + if [ "X$VERIFY" = "XYES" ]; then M_SERVER_ARGS="$M_SERVER_ARGS ca_file=data_files/test-ca_cat12.crt auth_mode=required" @@ -819,7 +834,7 @@ run_client() { if [ $EXIT -eq 0 ]; then RESULT=0 else - # If the cipher isn't supported... + # If it is NULL cipher ... if grep 'Cipher is (NONE)' $CLI_OUT >/dev/null; then RESULT=1 else @@ -1033,6 +1048,7 @@ for MODE in $MODES; do start_server "OpenSSL" translate_ciphers m $M_CIPHERS for i in $ciphers; do + o_check_ciphersuite "${i%%=*}" run_client mbedTLS ${i%%=*} ${i#*=} done stop_server @@ -1042,6 +1058,7 @@ for MODE in $MODES; do start_server "mbedTLS" translate_ciphers o $O_CIPHERS for i in $ciphers; do + o_check_ciphersuite "${i%%=*}" run_client OpenSSL ${i%%=*} ${i#*=} done stop_server diff --git a/tests/configs/tls13-only.h b/tests/configs/tls13-only.h index 963086f316..38286d1fd6 100644 --- a/tests/configs/tls13-only.h +++ b/tests/configs/tls13-only.h @@ -29,10 +29,12 @@ /* Disable TLS 1.2 and 1.2-specific features */ #undef MBEDTLS_SSL_ENCRYPT_THEN_MAC #undef MBEDTLS_SSL_EXTENDED_MASTER_SECRET +#undef MBEDTLS_SSL_RENEGOTIATION #undef MBEDTLS_SSL_PROTO_TLS1_2 #undef MBEDTLS_SSL_PROTO_DTLS #undef MBEDTLS_SSL_DTLS_ANTI_REPLAY #undef MBEDTLS_SSL_DTLS_HELLO_VERIFY +#undef MBEDTLS_SSL_DTLS_SRTP #undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE #undef MBEDTLS_SSL_DTLS_CONNECTION_ID #undef MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile index 97b26dcd54..1b122ee8d6 100644 --- a/tests/data_files/Makefile +++ b/tests/data_files/Makefile @@ -140,6 +140,9 @@ test_csr_v3_all_malformed_attributes_extension_request_sequence_len1.csr.der: te test_csr_v3_all_malformed_attributes_extension_request_sequence_len2.csr.der: test_csr_v3_all.csr.der (hexdump -ve '1/1 "%.2X"' $< | sed "s/3051300B0603551D0F04/3050300B0603551D0F04/" | xxd -r -p ) > $@ +test_cert_rfc822name.crt.der: cert_example_multi.csr + $(OPENSSL) x509 -req -CA $(test_ca_crt) -CAkey $(test_ca_key_file_rsa) -extfile $(test_ca_config_file) -outform DER -extensions rfc822name_names -passin "pass:$(test_ca_pwd_rsa)" -set_serial 17 -days 3653 -sha256 -in $< > $@ + $(test_ca_key_file_rsa_alt):test-ca.opensslconf $(OPENSSL) genrsa -out $@ 2048 test-ca-alt.csr: $(test_ca_key_file_rsa_alt) $(test_ca_config_file) @@ -336,6 +339,12 @@ server5-tricky-ip-san.crt: server5.key $(OPENSSL) req -x509 -new -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS Tricky IP SAN" -set_serial 77 -config $(test_ca_config_file) -extensions tricky_ip_san -days 3650 -sha256 -key server5.key -out $@ all_final += server5-tricky-ip-san.crt +rsa_single_san_uri.crt.der: rsa_single_san_uri.key + $(OPENSSL) req -x509 -outform der -nodes -days 7300 -newkey rsa:2048 -key $< -out $@ -addext "subjectAltName = URI:urn:example.com:5ff40f78-9210-494f-8206-c2c082f0609c" -extensions 'v3_req' -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS URI SAN" + +rsa_multiple_san_uri.crt.der: rsa_multiple_san_uri.key + $(OPENSSL) req -x509 -outform der -nodes -days 7300 -newkey rsa:2048 -key $< -out $@ -addext "subjectAltName = URI:urn:example.com:5ff40f78-9210-494f-8206-c2c082f0609c, URI:urn:example.com:5ff40f78-9210-494f-8206-abcde1234567" -extensions 'v3_req' -subj "/C=UK/O=Mbed TLS/CN=Mbed TLS URI SAN" + server10-badsign.crt: server10.crt { head -n-2 $<; tail -n-2 $< | sed -e '1s/0\(=*\)$$/_\1/' -e '1s/[^_=]\(=*\)$$/0\1/' -e '1s/_/1/'; } > $@ all_final += server10-badsign.crt @@ -1266,11 +1275,15 @@ pkcs7_test_cert_3 = pkcs7-rsa-sha256-3.crt pkcs7_test_file = pkcs7_data.bin $(pkcs7_test_file): - echo -e "Hello\xd" > $@ + printf "Hello\15\n" > $@ all_final += $(pkcs7_test_file) +pkcs7_zerolendata.bin: + printf '' > $@ +all_final += pkcs7_zerolendata.bin + pkcs7_data_1.bin: - echo -e "2\xd" > $@ + printf "2\15\n" > $@ all_final += pkcs7_data_1.bin # Generate signing cert @@ -1302,6 +1315,11 @@ pkcs7-rsa-sha256-2.der: $(pkcs7_test_cert_2) $(OPENSSL) x509 -in pkcs7-rsa-sha256-2.crt -out $@ -outform DER all_final += pkcs7-rsa-sha256-2.der +# pkcs7 signature file over zero-len data +pkcs7_zerolendata_detached.der: pkcs7_zerolendata.bin pkcs7-rsa-sha256-1.key pkcs7-rsa-sha256-1.crt + $(OPENSSL) smime -sign -md sha256 -nocerts -noattr -in pkcs7_zerolendata.bin -inkey pkcs7-rsa-sha256-1.key -outform DER -binary -signer pkcs7-rsa-sha256-1.crt -out pkcs7_zerolendata_detached.der +all_final += pkcs7_zerolendata_detached.der + # pkcs7 signature file with CERT pkcs7_data_cert_signed_sha256.der: $(pkcs7_test_file) $(pkcs7_test_cert_1) $(OPENSSL) smime -sign -binary -in pkcs7_data.bin -out $@ -md sha256 -signer pkcs7-rsa-sha256-1.pem -noattr -outform DER -out $@ @@ -1345,19 +1363,31 @@ all_final += pkcs7_data_multiple_certs_signed.der # pkcs7 signature file with corrupted CERT pkcs7_data_signed_badcert.der: pkcs7_data_cert_signed_sha256.der cp pkcs7_data_cert_signed_sha256.der $@ - echo -en '\xa1' | dd of=$@ bs=1 seek=547 conv=notrunc + echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=547 conv=notrunc all_final += pkcs7_data_signed_badcert.der # pkcs7 signature file with corrupted signer info pkcs7_data_signed_badsigner.der: pkcs7_data_cert_signed_sha256.der cp pkcs7_data_cert_signed_sha256.der $@ - echo -en '\xa1' | dd of=$@ bs=1 seek=918 conv=notrunc + echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=918 conv=notrunc all_final += pkcs7_data_signed_badsigner.der +# pkcs7 signature file with invalid tag in signerInfo[1].serial after long issuer name +pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der: pkcs7_data_multiple_signed.der + cp $< $@ + echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=498 conv=notrunc +all_final += pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der + +# pkcs7 signature file with invalid tag in signerInfo[2] +pkcs7_signerInfo_2_invalid_tag.der: pkcs7_data_3_signed.der + cp $< $@ + echo 'a1' | xxd -r -p | dd of=$@ bs=1 seek=810 conv=notrunc +all_final += pkcs7_signerInfo_2_invalid_tag.der + # pkcs7 file with version 2 pkcs7_data_cert_signed_v2.der: pkcs7_data_cert_signed_sha256.der cp pkcs7_data_cert_signed_sha256.der $@ - echo -en '\x02' | dd of=$@ bs=1 seek=25 conv=notrunc + echo '02' | xxd -r -p | dd of=$@ bs=1 seek=25 conv=notrunc all_final += pkcs7_data_cert_signed_v2.der pkcs7_data_cert_encrypted.der: $(pkcs7_test_file) $(pkcs7_test_cert_1) @@ -1368,12 +1398,12 @@ all_final += pkcs7_data_cert_encrypted.der # For some interesting sizes, what happens if we make them off-by-one? pkcs7_signerInfo_issuer_invalid_size.der: pkcs7_data_cert_signed_sha256.der cp $< $@ - echo -en '\x35' | dd of=$@ seek=919 bs=1 conv=notrunc + echo '35' | xxd -r -p | dd of=$@ seek=919 bs=1 conv=notrunc all_final += pkcs7_signerInfo_issuer_invalid_size.der pkcs7_signerInfo_serial_invalid_size.der: pkcs7_data_cert_signed_sha256.der cp $< $@ - echo -en '\x15' | dd of=$@ seek=973 bs=1 conv=notrunc + echo '15' | xxd -r -p | dd of=$@ seek=973 bs=1 conv=notrunc all_final += pkcs7_signerInfo_serial_invalid_size.der # pkcs7 signature file just with signed data diff --git a/tests/data_files/pkcs7_get_signers_info_set-leak-fuzz_pkcs7-4541044530479104.der b/tests/data_files/pkcs7_get_signers_info_set-leak-fuzz_pkcs7-4541044530479104.der deleted file mode 100644 index 51aef0d092..0000000000 Binary files a/tests/data_files/pkcs7_get_signers_info_set-leak-fuzz_pkcs7-4541044530479104.der and /dev/null differ diff --git a/tests/data_files/pkcs7_get_signers_info_set-missing_free-fuzz_pkcs7-6213931373035520.der b/tests/data_files/pkcs7_get_signers_info_set-missing_free-fuzz_pkcs7-6213931373035520.der deleted file mode 100644 index ce4fb3bd49..0000000000 Binary files a/tests/data_files/pkcs7_get_signers_info_set-missing_free-fuzz_pkcs7-6213931373035520.der and /dev/null differ diff --git a/tests/data_files/pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der b/tests/data_files/pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der new file mode 100644 index 0000000000..fe5539006c Binary files /dev/null and b/tests/data_files/pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der differ diff --git a/tests/data_files/pkcs7_signerInfo_2_invalid_tag.der b/tests/data_files/pkcs7_signerInfo_2_invalid_tag.der new file mode 100644 index 0000000000..3a4287426c Binary files /dev/null and b/tests/data_files/pkcs7_signerInfo_2_invalid_tag.der differ diff --git a/tests/data_files/pkcs7_zerolendata.bin b/tests/data_files/pkcs7_zerolendata.bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data_files/pkcs7_zerolendata_detached.der b/tests/data_files/pkcs7_zerolendata_detached.der new file mode 100644 index 0000000000..2a389ab484 Binary files /dev/null and b/tests/data_files/pkcs7_zerolendata_detached.der differ diff --git a/tests/data_files/rsa_multiple_san_uri.crt.der b/tests/data_files/rsa_multiple_san_uri.crt.der new file mode 100644 index 0000000000..ac5fab2932 Binary files /dev/null and b/tests/data_files/rsa_multiple_san_uri.crt.der differ diff --git a/tests/data_files/rsa_multiple_san_uri.key b/tests/data_files/rsa_multiple_san_uri.key new file mode 100644 index 0000000000..c8c3492bb5 --- /dev/null +++ b/tests/data_files/rsa_multiple_san_uri.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCxc5q8z8XR6vH2 +1Ko29Mk3dOKpSOrX9Tb5HtmCQMoKIxnTUQrNkVeOQtiQt6XZo05cbA6Z87kWDgGJ +P/5Lxofrx13Rp1xZzZ+0AAPfvUCY5tzZwmicQWvu9st6JwTyaLTCzSt0cPTUs5Hi +hJt9RzSW6GTk5ANjjgoewOMhwh5f84JRURJ2INZjz4namBGe/9f14ZHxKWuxl5in ++z582rSEhLXrPLbaKjT3Jphff51xsusC+pP0xNqkAcrGJ+/Jk0Vk6ClRCd40ZcTB +4SkOqsZ8/uGWnradkrN74PoMMnSKKOuxlsVMPfzMkrlMbuazO4nK/osTAnoSqMUv +COBdXkTtAgMBAAECggEANVlTIQa6K3UeD546GlGXmQOcDVbtu8VuJJFgxScjVs7c +uco4nDrg/tUb9M4xn2/YZDLcZO6AK6BEV/YURsXGIV2L2DcfraQDKoOCpqZoIE/v +/8vR1YBZqbsqy2ulshdGmPZD5Tr8cGIYLui9MnnQ1rnBc4sVdb3DTyGgZ4rLxP6X +0BoHw+LQA0wwSbE/NW71qmeDSEDkSkUQISVg6Rp06U0PZaJAWtYoBNKGAsDGAhjc +vVTXE5B9d+3yOM0InCWFsM/bUvaUv/yxxTcZnVq9Lji3KwDhy63F99pUaFnV6Rf2 +3CKO3VHegWSwMcnYaBbufDqWPHuEDSlZ0nRhrbrKRQKBgQD6dQd0xPHfxIz5l+AC +1kPHIsUKPEirrJKTVHlxQwT0yVpD+yUkF95HY6NgHVHKnRP9qicqr3raIfA01VQc +y+lhXo6xUAqYsKvB9m4njERFWMTCVSVU30Klhic/s4R/1abKlvkax1SiQFIRStqC +onsZ0M1Isw69/I8Yha3mzv/gvwKBgQC1YPXnd5dZmdbe0UibBWjU5X6AQGt+oxL+ ++6EP3EfuRmYI3i3r2bdbB3ELd95f8tgV0UagmjQfFoigBsuRfbhrQEPSHMBWYpAV ++TZKxUvmpJXwLEgxcPv7VTTvxw0qL1u1s/dX6WBfEOUgVzPgcp+IJGEr1MZekTqt +P65coDpZUwKBgAmrLuiBGd1Lly2jgVBauS8c1oJ4pU2LUfVCE5Ydwjk49LUfIuXr +zfbvj8UMHLY3rifiw7RQJev5124StjaOYKoTnmqV7nLKjzbjroj0T0ZmEOJ3qwNF +wyrkrOs2oOzWcKPthBxWiZvh48krHJhicWIjv2kJEI6hC10k+/unDhW9AoGAZyRg +MeRb+OP2wHaapy0IVCi9Kwl3F2h8oOtOx8ooTWNTGq/dxUTlc6pjqnXbyww5vQ5o +72NBSHxz7SxwDqhDexnsd0tKRNV/wj8ZlKNlah8l9JH568OoR2BI3iF/ZwHPUSCq +Ax//YZAl+6IbKgOEnNKzP02cEKLdjy+rY5jqFWkCgYEAmEl4mg1IGoVDM6d3iIPP +JLz5DghV8kP++99vFrJx07D6e/uhzojR73Ye+fq69Vy0yjGXpaRPwwHfvPzDA1hm +ir7rJWsbbskR+iTn2yKvIpB1wBI1u0SQ4lnJ1ZIVJPVlh4yA29JvPT7/7/2nQ/s6 +v0N2oKrfaiKc7BjCz3eYW4Q= +-----END PRIVATE KEY----- diff --git a/tests/data_files/rsa_single_san_uri.crt.der b/tests/data_files/rsa_single_san_uri.crt.der new file mode 100644 index 0000000000..22308c6f45 Binary files /dev/null and b/tests/data_files/rsa_single_san_uri.crt.der differ diff --git a/tests/data_files/rsa_single_san_uri.key b/tests/data_files/rsa_single_san_uri.key new file mode 100644 index 0000000000..bb6c0ca6bb --- /dev/null +++ b/tests/data_files/rsa_single_san_uri.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCng06zdlkhYiBK +43H+cK+vkHYvvRA2RtWbLMw+9rV9IrdGQ+iQQ/X1SZfDl2hWUiKTpabcuGYzY38H +lXW4UXwTB36KEe7G3yF/fbvYzNsdUCAVOzNs/0EMvXJeD/Dm5CBMEsG6V0ovHmkc +c80fQYQiSxgjpWyRpKdP+z/2imGph9onuu7EWOpAXGArozlLL5OixQ2dmutsc5ap +hfgwq6za00uKsFifolRtAhiH86N0vjiAJkzZR83uBlI285sj5+EzRrtjVv+kgsLW +gLDlj3bgsuKQDfxWhe+mpy2PIJ41kqktCz1qew3wyHI2ysE+6htHYQMNbCtkRMdX +/4t1yx95AgMBAAECggEAIIhn6IK7nLgp/WFe6kOIW1h7G5pkY6YuJgz1PeU8Kilr +3sGhkSMhyZmZV+s34EvjWzl4xrUpZCGWsipcyodIyYlTEg2ZihYbs17/9IMUqwS8 +tmLhAfIw+ABzDcGaz7zOaPfbmA0L40rMrzHuTHu05dQfxAyEoWSQ+f+Z1I/bl8jy +GdXQVtqZzqJcWXbXt+3+B4f2/d7K5xzb7lv/8zhAf/zoG9srMByPa6/Do5rVas5Q +NmzJPwXngxE5dJcHsWU4FkHbSbJj0khW858MJ4o5Ddw5ZOPimqlcmpClb01wCdXf +13o2ozKGE/xq3InU7MA4ad0tLMdEM8R7yhUZ9Xe/gQKBgQDYXt4BhiamnSl1tHR8 +MiiyzkcZuVH04/A6FsnUhcbQF9iCqO9szw50k0z7DVIGS9dSY9kmMdEcpsX6m2XC +XfEsxHBm0wmJqLUGq3UzM6oDsyZG1fkTg+eMzbVO0sv4xdhJLPpmsck5yJ8t0TxB +8gIS9yNEw7+w6rZhgSRsMT+WhQKBgQDGMZ0qIdFi1Ae7ueTcBCe+cjgmTG9nXq6+ +qRokU63rPP9y8XTVD6hRmviMRl4skt0F39yGJ7janIQnOBrf2DVEX4Mcf0sY4vDJ +msDV5jkbzgbAEas0ejO4h+dpRqa4mUiU1JR/Pb1jZHNOg7ZfTw45WPqBGsLTEpAt +OsKVUgbZZQKBgCIe+8WjwS6fNC2SspfvVQm1i/Lbjbgfxf9zHor8ObkROZyJRZCU +KoRpwkcI97l0dlVQ16q1SnPJPQljPi3joKfdppggia2CxGFz4nybliEVPGEJV0kj +kP1cZ04x4eauVIhdpnNRcBlDsQ6Jo4YGwxr4jEBI2k7tBKvlsLe7IHr9AoGAeJmi +IAwaBIAvAH16lKL2qD2Ki0uBkq4buSrfHHHK59TjQEdLJ4byjk21pm3/SjJHyhZR +c1TieCw7gj3ypHlE2IkiGAohYVBe4t6HLuF7qL6yfteBjVo69LPGDdqPAs9LSj0c +61xfTQbH32PoapCJgD3zmPH20Ud/cfZKh2A1iL0CgYEAwQgGxHVo+/d3BhLQvQHt +64fE+qrZA5oWWwBh8EzR+98eOnDCF3Gm6chrEs9boOzlwxr9LU4TgiBnpyYrQCEw +AdOA9dhYz91d+chJZjKo635Y9byN9rutr3/EfqZLxWL73k1y5LNAYL+jyAab0Jsw +l2xG6PNj5rItkgO3j50qA7s= +-----END PRIVATE KEY----- diff --git a/tests/data_files/test-ca.opensslconf b/tests/data_files/test-ca.opensslconf index bd127609e0..8f8385a489 100644 --- a/tests/data_files/test-ca.opensslconf +++ b/tests/data_files/test-ca.opensslconf @@ -24,6 +24,9 @@ subjectAltName=otherName:1.2.3.4;UTF8:some other identifier [dns_alt_names] subjectAltName=DNS:example.com, DNS:example.net, DNS:*.example.org +[rfc822name_names] +subjectAltName=email:my@other.address,email:second@other.address + [alt_names] DNS.1=example.com otherName.1=1.3.6.1.5.5.7.8.4;SEQ:hw_module_name diff --git a/tests/data_files/test_cert_rfc822name.crt.der b/tests/data_files/test_cert_rfc822name.crt.der new file mode 100644 index 0000000000..cdc8189d02 Binary files /dev/null and b/tests/data_files/test_cert_rfc822name.crt.der differ diff --git a/tests/include/alt-extra/psa/crypto.h b/tests/include/alt-extra/psa/crypto.h new file mode 100644 index 0000000000..005f3aeea0 --- /dev/null +++ b/tests/include/alt-extra/psa/crypto.h @@ -0,0 +1,7 @@ +/* The goal of the include/alt-extra directory is to test what happens + * if certain files come _after_ the normal include directory. + * Make sure that if the alt-extra directory comes before the normal + * directory (so we wouldn't be achieving our test objective), the build + * will fail. + */ +#error "The normal include directory must come first in the include path" diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 7c89e7fa38..f1f53e3cad 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -388,7 +388,7 @@ armc6_build_test() msg "build: ARM Compiler 6 ($FLAGS)" ARM_TOOL_VARIANT="ult" CC="$ARMC6_CC" AR="$ARMC6_AR" CFLAGS="$FLAGS" \ - WARNING_CFLAGS='-xc -std=c99' make lib + WARNING_CFLAGS='-Werror -xc -std=c99' make lib msg "size: ARM Compiler 6 ($FLAGS)" "$ARMC6_FROMELF" -z library/*.o @@ -1978,6 +1978,7 @@ component_build_module_alt () { # aesni.c and padlock.c reference mbedtls_aes_context fields directly. scripts/config.py unset MBEDTLS_AESNI_C scripts/config.py unset MBEDTLS_PADLOCK_C + scripts/config.py unset MBEDTLS_AESCE_C # MBEDTLS_ECP_RESTARTABLE is documented as incompatible. scripts/config.py unset MBEDTLS_ECP_RESTARTABLE # You can only have one threading implementation: alt or pthread, not both. @@ -3263,6 +3264,27 @@ component_build_psa_config_file () { rm -f psa_test_config.h psa_user_config.h } +component_build_psa_alt_headers () { + msg "build: make with PSA alt headers" # ~20s + + # Generate alternative versions of the substitutable headers with the + # same content except different include guards. + make -C tests include/alt-extra/psa/crypto_platform_alt.h include/alt-extra/psa/crypto_struct_alt.h + + # Build the library and some programs. + # Don't build the fuzzers to avoid having to go through hoops to set + # a correct include path for programs/fuzz/Makefile. + make CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'" lib + make -C programs -o fuzz CFLAGS="-I ../tests/include/alt-extra -DMBEDTLS_PSA_CRYPTO_PLATFORM_FILE='\"psa/crypto_platform_alt.h\"' -DMBEDTLS_PSA_CRYPTO_STRUCT_FILE='\"psa/crypto_struct_alt.h\"'" + + # Check that we're getting the alternative include guards and not the + # original include guards. + programs/test/query_included_headers | grep -x PSA_CRYPTO_PLATFORM_ALT_H + programs/test/query_included_headers | grep -x PSA_CRYPTO_STRUCT_ALT_H + programs/test/query_included_headers | not grep -x PSA_CRYPTO_PLATFORM_H + programs/test/query_included_headers | not grep -x PSA_CRYPTO_STRUCT_H +} + component_test_m32_o0 () { # Build without optimization, so as to use portable C code (in a 32-bit # build) and not the i386-specific inline assembly. @@ -3346,6 +3368,7 @@ component_test_have_int32 () { scripts/config.py unset MBEDTLS_HAVE_ASM scripts/config.py unset MBEDTLS_AESNI_C scripts/config.py unset MBEDTLS_PADLOCK_C + scripts/config.py unset MBEDTLS_AESCE_C make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT32' msg "test: gcc, force 32-bit bignum limbs" @@ -3357,6 +3380,7 @@ component_test_have_int64 () { scripts/config.py unset MBEDTLS_HAVE_ASM scripts/config.py unset MBEDTLS_AESNI_C scripts/config.py unset MBEDTLS_PADLOCK_C + scripts/config.py unset MBEDTLS_AESCE_C make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64' msg "test: gcc, force 64-bit bignum limbs" @@ -3481,6 +3505,15 @@ component_build_armcc () { scripts/config.py baremetal # armc[56] don't support SHA-512 intrinsics scripts/config.py unset MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + + # Stop armclang warning about feature detection for A64_CRYPTO. + # With this enabled, the library does build correctly under armclang, + # but in baremetal builds (as tested here), feature detection is + # unavailable, and the user is notified via a #warning. So enabling + # this feature would prevent us from building with -Werror on + # armclang. Tracked in #7198. + scripts/config.py unset MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + scripts/config.py set MBEDTLS_HAVE_ASM make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib diff --git a/tests/scripts/depends.py b/tests/scripts/depends.py index 52ca41261e..581baad9a3 100755 --- a/tests/scripts/depends.py +++ b/tests/scripts/depends.py @@ -23,7 +23,7 @@ Test Mbed TLS with a subset of algorithms. This script can be divided into several steps: First, include/mbedtls/mbedtls_config.h or a different config file passed -in the arguments is parsed to extract any configuration options (collect_config_symbols). +in the arguments is parsed to extract any configuration options (using config.py). Then, test domains (groups of jobs, tests) are built based on predefined data collected in the DomainData class. Here, each domain has five major traits: @@ -65,6 +65,11 @@ import shutil import subprocess import sys import traceback +from typing import Union + +# Add the Mbed TLS Python library directory to the module search path +import scripts_path # pylint: disable=unused-import +import config class Colors: # pylint: disable=too-few-public-methods """Minimalistic support for colored output. @@ -74,6 +79,7 @@ that outputting start switches the text color to the desired color and stop switches the text color back to the default.""" red = None green = None + cyan = None bold_red = None bold_green = None def __init__(self, options=None): @@ -89,6 +95,7 @@ stop switches the text color back to the default.""" normal = '\033[0m' self.red = ('\033[31m', normal) self.green = ('\033[32m', normal) + self.cyan = ('\033[36m', normal) self.bold_red = ('\033[1;31m', normal) self.bold_green = ('\033[1;32m', normal) NO_COLORS = Colors(None) @@ -124,34 +131,38 @@ Remove the backup file if it was saved earlier.""" else: shutil.copy(options.config_backup, options.config) -def run_config_py(options, args): - """Run scripts/config.py with the specified arguments.""" - cmd = ['scripts/config.py'] - if options.config != 'include/mbedtls/mbedtls_config.h': - cmd += ['--file', options.config] - cmd += args - log_command(cmd) - subprocess.check_call(cmd) +def option_exists(conf, option): + return option in conf.settings -def set_reference_config(options): +def set_config_option_value(conf, option, colors, value: Union[bool, str]): + """Set/unset a configuration option, optionally specifying a value. +value can be either True/False (set/unset config option), or a string, +which will make a symbol defined with a certain value.""" + if not option_exists(conf, option): + log_line('Symbol {} was not found in {}'.format(option, conf.filename), color=colors.red) + return False + + if value is False: + log_command(['config.py', 'unset', option]) + conf.unset(option) + elif value is True: + log_command(['config.py', 'set', option]) + conf.set(option) + else: + log_command(['config.py', 'set', option, value]) + conf.set(option, value) + return True + +def set_reference_config(conf, options, colors): """Change the library configuration file (mbedtls_config.h) to the reference state. The reference state is the one from which the tested configurations are derived.""" # Turn off options that are not relevant to the tests and slow them down. - run_config_py(options, ['full']) - run_config_py(options, ['unset', 'MBEDTLS_TEST_HOOKS']) + log_command(['config.py', 'full']) + conf.adapt(config.full_adapter) + set_config_option_value(conf, 'MBEDTLS_TEST_HOOKS', colors, False) if options.unset_use_psa: - run_config_py(options, ['unset', 'MBEDTLS_USE_PSA_CRYPTO']) - -def collect_config_symbols(options): - """Read the list of settings from mbedtls_config.h. -Return them in a generator.""" - with open(options.config, encoding="utf-8") as config_file: - rx = re.compile(r'\s*(?://\s*)?#define\s+(\w+)\s*(?:$|/[/*])') - for line in config_file: - m = re.match(rx, line) - if m: - yield m.group(1) + set_config_option_value(conf, 'MBEDTLS_USE_PSA_CRYPTO', colors, False) class Job: """A job builds the library in a specific configuration and runs some tests.""" @@ -179,19 +190,16 @@ If what is False, announce that the job has failed.''' elif what is False: log_line(self.name + ' FAILED', color=colors.red) else: - log_line('starting ' + self.name) + log_line('starting ' + self.name, color=colors.cyan) - def configure(self, options): + def configure(self, conf, options, colors): '''Set library configuration options as required for the job.''' - set_reference_config(options) + set_reference_config(conf, options, colors) for key, value in sorted(self.config_settings.items()): - if value is True: - args = ['set', key] - elif value is False: - args = ['unset', key] - else: - args = ['set', key, value] - run_config_py(options, args) + ret = set_config_option_value(conf, key, colors, value) + if ret is False: + return False + return True def test(self, options): '''Run the job's build and test commands. @@ -382,11 +390,11 @@ class DomainData: return [symbol for symbol in self.all_config_symbols if re.match(regexp, symbol)] - def __init__(self, options): + def __init__(self, options, conf): """Gather data about the library and establish a list of domains to test.""" build_command = [options.make_command, 'CFLAGS=-Werror'] build_and_test = [build_command, [options.make_command, 'test']] - self.all_config_symbols = set(collect_config_symbols(options)) + self.all_config_symbols = set(conf.settings.keys()) # Find hash modules by name. hash_symbols = self.config_symbols_matching(r'MBEDTLS_(MD|RIPEMD|SHA)[0-9]+_C\Z') # Find elliptic curve enabling macros by name. @@ -442,16 +450,19 @@ A name can either be the name of a domain or the name of one specific job.""" else: return [self.jobs[name]] -def run(options, job, colors=NO_COLORS): +def run(options, job, conf, colors=NO_COLORS): """Run the specified job (a Job instance).""" subprocess.check_call([options.make_command, 'clean']) job.announce(colors, None) - job.configure(options) + if not job.configure(conf, options, colors): + job.announce(colors, False) + return False + conf.write() success = job.test(options) job.announce(colors, success) return success -def run_tests(options, domain_data): +def run_tests(options, domain_data, conf): """Run the desired jobs. domain_data should be a DomainData instance that describes the available domains and jobs. @@ -467,7 +478,7 @@ Run the jobs listed in options.tasks.""" backup_config(options) try: for job in jobs: - success = run(options, job, colors=colors) + success = run(options, job, conf, colors=colors) if not success: if options.keep_going: failures.append(job.name) @@ -533,7 +544,9 @@ def main(): default=True) options = parser.parse_args() os.chdir(options.directory) - domain_data = DomainData(options) + conf = config.ConfigFile(options.config) + domain_data = DomainData(options, conf) + if options.tasks is True: options.tasks = sorted(domain_data.domains.keys()) if options.list: @@ -542,7 +555,7 @@ def main(): print(domain_name) sys.exit(0) else: - sys.exit(0 if run_tests(options, domain_data) else 1) + sys.exit(0 if run_tests(options, domain_data, conf) else 1) except Exception: # pylint: disable=broad-except traceback.print_exc() sys.exit(3) diff --git a/tests/suites/test_suite_constant_time.function b/tests/suites/test_suite_constant_time.function index 14dc8ae5cd..a2bf3967f5 100644 --- a/tests/suites/test_suite_constant_time.function +++ b/tests/suites/test_suite_constant_time.function @@ -18,7 +18,7 @@ /* BEGIN_CASE */ void mbedtls_ct_memcmp_null() { - uint32_t x; + uint32_t x = 0; TEST_ASSERT(mbedtls_ct_memcmp(&x, NULL, 0) == 0); TEST_ASSERT(mbedtls_ct_memcmp(NULL, &x, 0) == 0); TEST_ASSERT(mbedtls_ct_memcmp(NULL, NULL, 0) == 0); diff --git a/tests/suites/test_suite_ecp.data b/tests/suites/test_suite_ecp.data index 9a13793892..3fbad92a59 100644 --- a/tests/suites/test_suite_ecp.data +++ b/tests/suites/test_suite_ecp.data @@ -1038,3 +1038,115 @@ ecp_check_order:MBEDTLS_ECP_DP_SECP256K1:"fffffffffffffffffffffffffffffffebaaedc ECP check order for CURVE448 depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED ecp_check_order:MBEDTLS_ECP_DP_CURVE448:"3fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3" + +ecp_setup #1 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192R1) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffffffffffeffffffffffffffff":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #2 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224R1) +depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED +ecp_mod_setup:"00000000ffffffffffffffffffffffffffffffff000000000000000000000001":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #3 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256R1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_mod_setup:"ffffffff00000001000000000000000000000000ffffffffffffffffffffffff":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #4 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP384R1) +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #5 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP521R1) +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecp_mod_setup:"1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #6 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP256R1) +depends_on:MBEDTLS_ECP_DP_BP256R1_ENABLED +ecp_mod_setup:"a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377":MBEDTLS_ECP_DP_BP256R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #7 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP384R1) +depends_on:MBEDTLS_ECP_DP_BP384R1_ENABLED +ecp_mod_setup:"8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53":MBEDTLS_ECP_DP_BP384R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #8 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP512R1) +depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED +ecp_mod_setup:"aadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3":MBEDTLS_ECP_DP_BP512R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #9 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE25519) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_mod_setup:"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #10 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP192K1) +depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffffffffffffffffffeffffee37":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #11 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffffffffffffffffffffffffffeffffe56d":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #12 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_SECP256K1) +depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #13 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_CURVE448) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_setup:"000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #14 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP192R1) +depends_on:MBEDTLS_ECP_DP_SECP192R1_ENABLED +ecp_mod_setup:"ffffffffffffffffffffffff99def836146bc9b1b4d22831":MBEDTLS_ECP_DP_SECP192R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #15 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP224R1) +depends_on:MBEDTLS_ECP_DP_SECP224R1_ENABLED +ecp_mod_setup:"ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d":MBEDTLS_ECP_DP_SECP224R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #16 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP256R1) +depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED +ecp_mod_setup:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551":MBEDTLS_ECP_DP_SECP256R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #17 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP384R1) +depends_on:MBEDTLS_ECP_DP_SECP384R1_ENABLED +ecp_mod_setup:"ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973":MBEDTLS_ECP_DP_SECP384R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #18 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP521R1) +depends_on:MBEDTLS_ECP_DP_SECP521R1_ENABLED +ecp_mod_setup:"1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409":MBEDTLS_ECP_DP_SECP521R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #19 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_BP256R1) +depends_on:MBEDTLS_ECP_DP_BP256R1_ENABLED +ecp_mod_setup:"a9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7":MBEDTLS_ECP_DP_BP256R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #20 MBEDTLS_ECP_MOD_COORDINATE(MBEDTLS_ECP_DP_BP384R1) +depends_on:MBEDTLS_ECP_DP_BP384R1_ENABLED +ecp_mod_setup:"8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53":MBEDTLS_ECP_DP_BP384R1:MBEDTLS_ECP_MOD_COORDINATE:0 + +ecp_setup #21 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_BP512R1) +depends_on:MBEDTLS_ECP_DP_BP512R1_ENABLED +ecp_mod_setup:"aadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069":MBEDTLS_ECP_DP_BP512R1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #22 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_CURVE25519) +depends_on:MBEDTLS_ECP_DP_CURVE25519_ENABLED +ecp_mod_setup:"1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed":MBEDTLS_ECP_DP_CURVE25519:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #23 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP192K1) +depends_on:MBEDTLS_ECP_DP_SECP192K1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffe26f2fc170f69466a74defd8d":MBEDTLS_ECP_DP_SECP192K1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #24 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP224K1) +depends_on:MBEDTLS_ECP_DP_SECP224K1_ENABLED +ecp_mod_setup:"000000010000000000000000000000000001dce8d2ec6184caf0a971769fb1f7":MBEDTLS_ECP_DP_SECP224K1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #25 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_SECP256K1) +depends_on:MBEDTLS_ECP_DP_SECP256K1_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141":MBEDTLS_ECP_DP_SECP256K1:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup #26 MBEDTLS_ECP_MOD_SCALAR(MBEDTLS_ECP_DP_CURVE448) +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_setup:"0000000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffff7cca23e9c44edb49aed63690216cc2728dc58f552378c292ab5844f3":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_SCALAR:0 + +ecp_setup_negative_test #27 Invalid Moduli Type +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffe26f2fc17f69466a74defd8d":MBEDTLS_ECP_DP_CURVE448:MBEDTLS_ECP_MOD_NONE:MBEDTLS_ERR_ECP_BAD_INPUT_DATA + +ecp_setup_negative_test #28 Invalid Curve Type +depends_on:MBEDTLS_ECP_DP_CURVE448_ENABLED +ecp_mod_setup:"fffffffffffffffffffffffe26f2fc17f69466a74defd8d":MBEDTLS_ECP_DP_NONE:MBEDTLS_ECP_MOD_SCALAR:MBEDTLS_ERR_ECP_BAD_INPUT_DATA diff --git a/tests/suites/test_suite_ecp.function b/tests/suites/test_suite_ecp.function index b9d2b5ea55..96537c2b3b 100644 --- a/tests/suites/test_suite_ecp.function +++ b/tests/suites/test_suite_ecp.function @@ -1,11 +1,12 @@ /* BEGIN_HEADER */ #include "mbedtls/ecp.h" +#include "ecp_invasive.h" #include "mbedtls/ecdsa.h" #include "mbedtls/ecdh.h" #include "bignum_core.h" -#include "bignum_mod_raw_invasive.h" #include "ecp_invasive.h" +#include "bignum_mod_raw_invasive.h" #if defined(MBEDTLS_TEST_HOOKS) && \ (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ @@ -1344,3 +1345,86 @@ exit: mbedtls_free(N); } /* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */ +void ecp_mod_p521_raw(char *input_N, + char *input_X, + char *result) +{ + mbedtls_mpi_uint *X = NULL; + mbedtls_mpi_uint *N = NULL; + mbedtls_mpi_uint *res = NULL; + size_t limbs_X; + size_t limbs_N; + size_t limbs_res; + + mbedtls_mpi_mod_modulus m; + mbedtls_mpi_mod_modulus_init(&m); + + TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0); + TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0); + TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0); + + size_t limbs = limbs_N; + size_t bytes = limbs * sizeof(mbedtls_mpi_uint); + + TEST_EQUAL(limbs_X, 2 * limbs); + TEST_EQUAL(limbs_res, limbs); + + TEST_EQUAL(mbedtls_mpi_mod_modulus_setup( + &m, N, limbs, + MBEDTLS_MPI_MOD_REP_MONTGOMERY), 0); + + TEST_EQUAL(mbedtls_ecp_mod_p521_raw(X, limbs_X), 0); + TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), 522); + mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m); + ASSERT_COMPARE(X, bytes, res, bytes); + +exit: + mbedtls_free(X); + mbedtls_free(res); + + mbedtls_mpi_mod_modulus_free(&m); + mbedtls_free(N); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */ +void ecp_mod_setup(char *input_A, int id, int ctype, int iret) +{ + int ret; + mbedtls_mpi_mod_modulus m; + mbedtls_mpi_mod_modulus_init(&m); + mbedtls_mpi_uint *p = NULL; + size_t p_limbs; + size_t bytes; + + TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0); + + ret = mbedtls_ecp_modulus_setup(&m, id, ctype); + TEST_EQUAL(ret, iret); + + if (ret == 0) { + + /* Test for limb sizes */ + TEST_EQUAL(m.limbs, p_limbs); + bytes = p_limbs * sizeof(mbedtls_mpi_uint); + + /* Test for validity of moduli by the presence of Montgomery consts */ + + TEST_ASSERT(m.rep.mont.mm != 0); + TEST_ASSERT(m.rep.mont.rr != NULL); + + + /* Compare output byte-by-byte */ + ASSERT_COMPARE(p, bytes, m.p, bytes); + + /* Test for user free-ing allocated memory */ + mbedtls_mpi_mod_modulus_free(&m); + } + +exit: + mbedtls_mpi_mod_modulus_free(&m); + mbedtls_free(p); +} +/* END_CASE */ diff --git a/tests/suites/test_suite_oid.data b/tests/suites/test_suite_oid.data index 1738841d59..b9fa6543d9 100644 --- a/tests/suites/test_suite_oid.data +++ b/tests/suites/test_suite_oid.data @@ -89,3 +89,33 @@ oid_get_md_alg_id:"2b24030201":MBEDTLS_MD_RIPEMD160 OID hash id - invalid oid oid_get_md_alg_id:"2B864886f70d0204":-1 +OID get numeric string - hardware module name +oid_get_numeric_string:"2B06010505070804":0:"1.3.6.1.5.5.7.8.4" + +OID get numeric string - multi-byte subidentifier +oid_get_numeric_string:"29903C":0:"1.1.2108" + +OID get numeric string - second component greater than 39 +oid_get_numeric_string:"81010000863A00":0:"2.49.0.0.826.0" + +OID get numeric string - multi-byte first subidentifier +oid_get_numeric_string:"8837":0:"2.999" + +OID get numeric string - empty oid buffer +oid_get_numeric_string:"":MBEDTLS_ERR_ASN1_OUT_OF_DATA:"" + +OID get numeric string - no final / all bytes have top bit set +oid_get_numeric_string:"818181":MBEDTLS_ERR_ASN1_OUT_OF_DATA:"" + +# Encodes the number 0x0400000000 as a subidentifier which overflows 32-bits +OID get numeric string - 32-bit overflow +oid_get_numeric_string:"C080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:"" + +OID get numeric string - 32-bit overflow, second subidentifier +oid_get_numeric_string:"2BC080808000":MBEDTLS_ERR_ASN1_INVALID_DATA:"" + +OID get numeric string - overlong encoding +oid_get_numeric_string:"8001":MBEDTLS_ERR_ASN1_INVALID_DATA:"" + +OID get numeric string - overlong encoding, second subidentifier +oid_get_numeric_string:"2B8001":MBEDTLS_ERR_ASN1_INVALID_DATA:"" diff --git a/tests/suites/test_suite_oid.function b/tests/suites/test_suite_oid.function index 687b2168a7..3004b65fe1 100644 --- a/tests/suites/test_suite_oid.function +++ b/tests/suites/test_suite_oid.function @@ -96,3 +96,24 @@ void oid_get_md_alg_id(data_t *oid, int exp_md_id) } } /* END_CASE */ + +/* BEGIN_CASE */ +void oid_get_numeric_string(data_t *oid, int error_ret, char *result_str) +{ + char buf[256]; + mbedtls_asn1_buf input_oid = { 0, 0, NULL }; + int ret; + + input_oid.tag = MBEDTLS_ASN1_OID; + input_oid.p = oid->x; + input_oid.len = oid->len; + + ret = mbedtls_oid_get_numeric_string(buf, sizeof(buf), &input_oid); + + if (error_ret == 0) { + TEST_ASSERT(strcmp(buf, result_str) == 0); + } else { + TEST_EQUAL(ret, error_ret); + } +} +/* END_CASE */ diff --git a/tests/suites/test_suite_pk.data b/tests/suites/test_suite_pk.data index 531a2f1e0f..01d8d2dc08 100644 --- a/tests/suites/test_suite_pk.data +++ b/tests/suites/test_suite_pk.data @@ -618,7 +618,7 @@ depends_on:MBEDTLS_PK_CAN_ECDSA_SIGN:MBEDTLS_ECP_DP_BP512R1_ENABLED pk_psa_sign:MBEDTLS_ECP_DP_BP512R1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_BRAINPOOL_P_R1):512 PSA wrapped sign: RSA PKCS1 v1.5 -depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_GENPRIME +depends_on:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_GENPRIME:MBEDTLS_PK_WRITE_C pk_psa_sign:1024:PSA_KEY_TYPE_RSA_KEY_PAIR:1024 PK Sign ext:RSA2048,PK_RSA,MD_SHA256 diff --git a/tests/suites/test_suite_pk.function b/tests/suites/test_suite_pk.function index a99b6c03bd..8b4b675b07 100644 --- a/tests/suites/test_suite_pk.function +++ b/tests/suites/test_suite_pk.function @@ -1238,12 +1238,22 @@ void pk_psa_sign(int parameter_arg, } /* Export underlying public key for re-importing in a legacy context. */ +#if defined(MBEDTLS_PK_WRITE_C) ret = mbedtls_pk_write_pubkey_der(&pk, pkey_legacy, sizeof(pkey_legacy)); TEST_ASSERT(ret >= 0); klen_legacy = (size_t) ret; /* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */ pkey_legacy_start = pkey_legacy + sizeof(pkey_legacy) - klen_legacy; +#else + ret = mbedtls_ecp_point_write_binary(&(mbedtls_pk_ec(pk)->grp), + &(mbedtls_pk_ec(pk)->Q), + MBEDTLS_ECP_PF_UNCOMPRESSED, + &klen_legacy, pkey_legacy, + sizeof(pkey_legacy)); + TEST_EQUAL(ret, 0); + pkey_legacy_start = pkey_legacy; +#endif /* MBEDTLS_PK_WRITE_C */ /* Turn PK context into an opaque one. */ TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&pk, &key_id, alg_psa, @@ -1264,12 +1274,21 @@ void pk_psa_sign(int parameter_arg, NULL, NULL) == 0); /* Export underlying public key for re-importing in a psa context. */ +#if defined(MBEDTLS_PK_WRITE_C) ret = mbedtls_pk_write_pubkey_der(&pk, pkey_psa, sizeof(pkey_psa)); TEST_ASSERT(ret >= 0); klen_psa = (size_t) ret; /* mbedtls_pk_write_pubkey_der() writes backwards in the data buffer. */ pkey_psa_start = pkey_psa + sizeof(pkey_psa) - klen_psa; +#else + psa_status_t status; + + status = psa_export_public_key(key_id, pkey_psa, sizeof(pkey_psa), + &klen_psa); + TEST_EQUAL(status, PSA_SUCCESS); + pkey_psa_start = pkey_psa; +#endif /* MBEDTLS_PK_WRITE_C */ TEST_ASSERT(klen_psa == klen_legacy); TEST_ASSERT(memcmp(pkey_psa_start, pkey_legacy_start, klen_psa) == 0); @@ -1278,8 +1297,24 @@ void pk_psa_sign(int parameter_arg, TEST_ASSERT(PSA_SUCCESS == psa_destroy_key(key_id)); mbedtls_pk_init(&pk); - TEST_ASSERT(mbedtls_pk_parse_public_key(&pk, pkey_legacy_start, - klen_legacy) == 0); + + /* If we used "pk_write" previously, then we go for a "pk_parse" here; + * otherwise if we went for "ecp_point_write_binary" then we'll go + * for a "ecp_point_read_binary" here. This allows to drop dependencies + * on "PK_WRITE" and "PK_PARSE" if required */ +#if defined(MBEDTLS_PK_WRITE_C) && defined(MBEDTLS_PK_PARSE_C) + TEST_EQUAL(mbedtls_pk_parse_public_key(&pk, pkey_legacy_start, + klen_legacy), 0); +#else + TEST_EQUAL(mbedtls_pk_setup(&pk, + mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)), 0); + TEST_EQUAL(mbedtls_ecp_group_load( + &(mbedtls_pk_ec(pk)->grp), + (mbedtls_ecp_group_id) parameter_arg), 0); + TEST_EQUAL(mbedtls_ecp_point_read_binary(&(mbedtls_pk_ec(pk)->grp), + &(mbedtls_pk_ec(pk)->Q), + pkey_legacy_start, klen_legacy), 0); +#endif TEST_ASSERT(mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, hash, sizeof(hash), sig, sig_len) == 0); diff --git a/tests/suites/test_suite_pkcs7.data b/tests/suites/test_suite_pkcs7.data index 840a24bb61..da8146bc15 100644 --- a/tests/suites/test_suite_pkcs7.data +++ b/tests/suites/test_suite_pkcs7.data @@ -38,6 +38,14 @@ PKCS7 Signed Data Parse Fail Encrypted Content #8 depends_on:MBEDTLS_SHA256_C pkcs7_parse:"data_files/pkcs7_data_cert_encrypted.der":MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE +PKCS7 Signed Data Verification Pass zero-len data +depends_on:MBEDTLS_SHA1_C:MBEDTLS_SHA256_C +pkcs7_verify:"data_files/pkcs7_zerolendata_detached.der":"data_files/pkcs7-rsa-sha256-1.der":"data_files/pkcs7_zerolendata.bin":0:0 + +PKCS7 Signed Data Verification Fail zero-len data +depends_on:MBEDTLS_SHA1_C:MBEDTLS_SHA256_C +pkcs7_verify:"data_files/pkcs7_zerolendata_detached.der":"data_files/pkcs7-rsa-sha256-2.der":"data_files/pkcs7_zerolendata.bin":0:MBEDTLS_ERR_RSA_VERIFY_FAILED + PKCS7 Signed Data Verification Pass SHA256 #9 depends_on:MBEDTLS_SHA256_C pkcs7_verify:"data_files/pkcs7_data_cert_signed_sha256.der":"data_files/pkcs7-rsa-sha256-1.der":"data_files/pkcs7_data.bin":0:0 @@ -70,13 +78,13 @@ PKCS7 Signed Data Parse Failure Corrupt signerInfo.serial #15.2 depends_on:MBEDTLS_SHA256_C pkcs7_parse:"data_files/pkcs7_signerInfo_serial_invalid_size.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO -pkcs7_get_signers_info_set error handling (6213931373035520) -depends_on:MBEDTLS_RIPEMD160_C -pkcs7_parse:"data_files/pkcs7_get_signers_info_set-missing_free-fuzz_pkcs7-6213931373035520.der":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) +PKCS7 Signed Data Parse Fail Corrupt signerInfos[2] (6213931373035520) +depends_on:MBEDTLS_SHA256_C +pkcs7_parse:"data_files/pkcs7_signerInfo_2_invalid_tag.der":MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) -pkcs7_get_signers_info_set error handling (4541044530479104) -depends_on:MBEDTLS_RIPEMD160_C -pkcs7_parse:"data_files/pkcs7_get_signers_info_set-leak-fuzz_pkcs7-4541044530479104.der": MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) +PKCS7 Signed Data Parse Fail Corrupt signerInfos[1].issuerAndSerialNumber.serialNumber, after multi-element .name (4541044530479104) +depends_on:MBEDTLS_SHA256_C +pkcs7_parse:"data_files/pkcs7_signerInfo_1_serial_invalid_tag_after_long_name.der":MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO PKCS7 Only Signed Data Parse Pass #15 depends_on:MBEDTLS_SHA256_C:MBEDTLS_RSA_C diff --git a/tests/suites/test_suite_pkcs7.function b/tests/suites/test_suite_pkcs7.function index 62f9f66b69..91fe47b897 100644 --- a/tests/suites/test_suite_pkcs7.function +++ b/tests/suites/test_suite_pkcs7.function @@ -125,7 +125,8 @@ void pkcs7_verify(char *pkcs7_file, TEST_ASSERT(file != NULL); datalen = st.st_size; - ASSERT_ALLOC(data, datalen); + /* Special-case for zero-length input so that data will be non-NULL */ + ASSERT_ALLOC(data, datalen == 0 ? 1 : datalen); buflen = fread((void *) data, sizeof(unsigned char), datalen, file); TEST_EQUAL(buflen, datalen); diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index c3561420b7..cfcdac1021 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4145,6 +4145,30 @@ PSA sign hash: deterministic ECDSA SECP384R1 SHA-256 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 sign_hash_deterministic:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":"52d92aac1fcc0fea3ecce01a9ed4bc9ac342f92470fd3f54d0d6d2fa5d2940405057a9d49a817c2b193322f05fc93ac1c7a055edac93bec0ade6814ab27b86b5295ac1ddb323818200f00c3d94d959f714f128b64a2e19628037ac009b14774f" +PSA sign hash int (ops=inf): det ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":0 + +PSA sign hash int (ops=inf) det ECDSA SECP256R1 SHA-384 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_PSA_BUILTIN_ALG_SHA_384 +sign_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":"cd40ba1b555ca5994d30ddffc4ad734b1f5c604675b0f249814aa5de3992ef3ddf4d5dc5d2aab1979ce210b560754df671363d99795475882894c048e3b986ca":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA SECP256R1 SHA-384 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_PSA_BUILTIN_ALG_SHA_384 +sign_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"49c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eee":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":"cd40ba1b555ca5994d30ddffc4ad734b1f5c604675b0f249814aa5de3992ef3ddf4d5dc5d2aab1979ce210b560754df671363d99795475882894c048e3b986ca":0 + +PSA sign hash int (ops=inf): det ECDSA SECP384R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":"52d92aac1fcc0fea3ecce01a9ed4bc9ac342f92470fd3f54d0d6d2fa5d2940405057a9d49a817c2b193322f05fc93ac1c7a055edac93bec0ade6814ab27b86b5295ac1ddb323818200f00c3d94d959f714f128b64a2e19628037ac009b14774f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA SECP384R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":"52d92aac1fcc0fea3ecce01a9ed4bc9ac342f92470fd3f54d0d6d2fa5d2940405057a9d49a817c2b193322f05fc93ac1c7a055edac93bec0ade6814ab27b86b5295ac1ddb323818200f00c3d94d959f714f128b64a2e19628037ac009b14774f":0 + PSA sign hash: RSA PKCS#1 v1.5 SHA-256, wrong hash size depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C sign_hash_fail:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015":128:PSA_ERROR_INVALID_ARGUMENT @@ -4206,9 +4230,53 @@ depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_P sign_hash_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_ERROR_INVALID_ARGUMENT PSA sign hash: deterministic ECDSA not supported -depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_DP_SECP384R1_ENABLED +depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 sign_hash_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_ERROR_NOT_SUPPORTED +PSA sign hash int (ops=inf): det ECDSA SECP256R1 SHA-256, out buf too small +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":63:PSA_SUCCESS:PSA_ERROR_BUFFER_TOO_SMALL:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA SECP256R1 SHA-256, out buf too small +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":63:PSA_SUCCESS:PSA_ERROR_BUFFER_TOO_SMALL:0 + +PSA sign hash int (ops=inf): det ECDSA SECP256R1 SHA-256, empty out buf +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0:PSA_SUCCESS:PSA_ERROR_BUFFER_TOO_SMALL:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA SECP256R1 SHA-256, empty out buf +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0:PSA_SUCCESS:PSA_ERROR_BUFFER_TOO_SMALL:0 + +PSA sign hash int (ops=inf): det ECDSA SECP256R1, invld hash alg (0) +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( 0 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_SUCCESS:PSA_ERROR_INVALID_ARGUMENT:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA SECP256R1, invld hash alg (0) +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( 0 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_SUCCESS:PSA_ERROR_INVALID_ARGUMENT:0 + +PSA sign hash int: det ECDSA SECP256R1, invld hash alg (wildcard) +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_ANY_HASH ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_ERROR_INVALID_ARGUMENT:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int: invld alg for ECC key +depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_PK_PARSE_C +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":72:PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int: ECDSA not supported +depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:!PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=inf): det ECDSA not supported +depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_SUCCESS:PSA_ERROR_NOT_SUPPORTED:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign hash int (ops=min): det ECDSA not supported +depends_on:!PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824":96:PSA_SUCCESS:PSA_ERROR_NOT_SUPPORTED:0 + PSA sign/verify hash: RSA PKCS#1 v1.5, raw depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C sign_verify_hash:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN_RAW:"616263" @@ -4249,6 +4317,54 @@ PSA sign/verify hash: deterministic ECDSA SECP384R1 SHA-256 depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 sign_verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA( PSA_ALG_SHA_256 ):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b" +PSA sign/vrfy hash int (ops=inf): rand ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int (ops=min): rand ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0 + +PSA sign/vrfy hash int (ops=inf): det ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int (ops=min): det ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0 + +PSA sign/vrfy hash int (ops=inf): rand ECDSA SECP256R1 SHA-384 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int (ops=min): rand ECDSA SECP256R1 SHA-384 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":0 + +PSA sign/vrfy hash int (ops=inf): det ECDSA SECP256R1 SHA-384 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int (ops=min): det ECDSA SECP256R1 SHA-384 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_384:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256:MBEDTLS_HAS_ALG_SHA_384_VIA_MD_OR_PSA +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_384):"59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f":0 + +PSA sign/vrfy hash int (ops=inf): rand ECDSA SECP384R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int (ops=min): rand ECDSA SECP384R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0 + +PSA sign/vrfy hash int (ops=inf): det ECDSA SECP384R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int (ops=min): det ECDSA SECP384R1 SHA-256 +depends_on:PSA_WANT_ALG_DETERMINISTIC_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_384 +sign_verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"3f5d8d9be280b5696cc5cc9f94cf8af7e6b61dd6592b2ab2b3a4c607450417ec327dcdcaed7c10053d719a0574f0a76a":PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":0 + PSA verify hash: RSA PKCS#1 v1.5 SHA-256, good signature depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY:MBEDTLS_PK_PARSE_C verify_hash:PSA_KEY_TYPE_RSA_PUBLIC_KEY:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311" @@ -4369,6 +4485,14 @@ PSA verify hash with keypair: ECDSA SECP256R1, good depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 verify_hash:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f" +PSA vrfy hash int: ECDSA SECP256R1, good +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int w/keypair: ECDSA SECP256R1, good +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + PSA verify hash: ECDSA SECP256R1, wrong signature size (correct but ASN1-encoded) depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 verify_hash_fail:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE @@ -4397,6 +4521,50 @@ PSA verify hash: invalid algorithm for ECC key depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 verify_hash_fail:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"":PSA_ERROR_INVALID_ARGUMENT +PSA vrfy hash int: ECDSA SECP256R1, wrong sig size (correct but ASN1-encoded) +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"304502206a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151022100ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int (ops=inf): ECDSA SECP256R1, wrong sig of correct size +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50e":PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int (ops=min): ECDSA SECP256R1, wrong sig of correct size +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50e":PSA_SUCCESS:PSA_ERROR_INVALID_SIGNATURE:0 + +PSA vrfy hash int: ECDSA SECP256R1, wrong sig (empty) +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"":PSA_ERROR_INVALID_SIGNATURE:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int: ECDSA SECP256R1, wrong sig (truncated) +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f5":PSA_ERROR_INVALID_SIGNATURE:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int: ECDSA SECP256R1, wrong sig (trailing junk) +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"6a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f21":PSA_ERROR_INVALID_SIGNATURE:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int: ECDSA SECP256R1, wrong sig (leading junk) +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1):"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_ALG_ECDSA_ANY:"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b":"216a3399f69421ffe1490377adf2ea1f117d81a63cf5bf22e918d51175eb259151ce95d7c26cc04e25503e2f7a1ec3573e3c2412534bb4a19b3a7811742f49f50f":PSA_ERROR_INVALID_SIGNATURE:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA vrfy hash int: invld alg for ECC key +depends_on:PSA_WANT_ALG_RSA_PSS:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +verify_hash_fail_interruptible:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_RSA_PSS(PSA_ALG_SHA_256):"":"":PSA_ERROR_NOT_SUPPORTED:PSA_ERROR_BAD_STATE:PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED + +PSA sign/vrfy hash int state test: randomized ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +interruptible_signverify_hash_state_test:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b" + +PSA sign/vrfy hash int edge case tests: randomized ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +interruptible_signverify_hash_edgecase_tests:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b" + +PSA sign/vrfy hash int ops tests: randomized ECDSA SECP256R1 SHA-256 +depends_on:PSA_WANT_ALG_ECDSA:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_PK_PARSE_C:PSA_WANT_ECC_SECP_R1_256 +interruptible_signverify_hash_ops_tests:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):"ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3a":PSA_ALG_ECDSA(PSA_ALG_SHA_256):"9ac4335b469bbd791439248504dd0d49c71349a295fee5a1c68507f45a9e1c7b" + PSA sign message: RSA PKCS#1 v1.5 SHA-256 depends_on:PSA_WANT_ALG_RSA_PKCS1V15_SIGN:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR:MBEDTLS_PK_PARSE_C sign_message_deterministic:PSA_KEY_TYPE_RSA_KEY_PAIR:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b24":PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256):"616263":"a73664d55b39c7ea6c1e5b5011724a11e1d7073d3a68f48c836fad153a1d91b6abdbc8f69da13b206cc96af6363b114458b026af14b24fab8929ed634c6a2acace0bcc62d9bb6a984afbcbfcd3a0608d32a2bae535b9cd1ecdf9dd281db1e0025c3bfb5512963ec3b98ddaa69e38bc3c84b1b61a04e5648640856aacc6fc7311" diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index c414b65fa6..182443a5e9 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1220,6 +1220,34 @@ typedef enum { INJECT_ANTICIPATE_KEY_DERIVATION_2, } ecjpake_injected_failure_t; +#if defined(MBEDTLS_ECP_RESTARTABLE) + +static void interruptible_signverify_get_minmax_completes(uint32_t max_ops, + psa_status_t expected_status, + size_t *min_completes, + size_t *max_completes) +{ + + /* This is slightly contrived, but we only really know that with a minimum + value of max_ops that a successful operation should take more than one op + to complete, and likewise that with a max_ops of + PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED, it should complete in one go. */ + if (max_ops == 0 || max_ops == 1) { + + if (expected_status == PSA_SUCCESS) { + *min_completes = 2; + } else { + *min_completes = 1; + } + + *max_completes = PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED; + } else { + *min_completes = 1; + *max_completes = 1; + } +} +#endif /* MBEDTLS_ECP_RESTARTABLE */ + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -6444,6 +6472,135 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * sign_hash_interruptible() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test interruptible sign hash with known outcomes (deterministic ECDSA + * only). + * + * 2. Test the number of calls to psa_sign_hash_complete() required are as + * expected for different max_ops values. + * + * 3. Test that the number of ops done prior to start and after abort is zero + * and that each successful stage completes some ops (this is not mandated by + * the PSA specification, but is currently the case). + * + * 4. Test that calling psa_sign_hash_get_num_ops() multiple times between + * complete() calls does not alter the number of ops returned. + */ +void sign_hash_interruptible(int key_type_arg, data_t *key_data, + int alg_arg, data_t *input_data, + data_t *output_data, int max_ops_arg) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + size_t key_bits; + unsigned char *signature = NULL; + size_t signature_size; + size_t signature_length = 0xdeadbeef; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = PSA_OPERATION_INCOMPLETE; + uint32_t num_ops = 0; + uint32_t max_ops = max_ops_arg; + size_t num_ops_prior = 0; + size_t num_completes = 0; + size_t min_completes = 0; + size_t max_completes = 0; + + psa_sign_hash_interruptible_operation_t operation = + psa_sign_hash_interruptible_operation_init(); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + key_bits = psa_get_key_bits(&attributes); + + /* Allocate a buffer which has the size advertised by the + * library. */ + signature_size = PSA_SIGN_OUTPUT_SIZE(key_type, + key_bits, alg); + TEST_ASSERT(signature_size != 0); + TEST_LE_U(signature_size, PSA_SIGNATURE_MAX_SIZE); + ASSERT_ALLOC(signature, signature_size); + + psa_interruptible_set_max_ops(max_ops); + + interruptible_signverify_get_minmax_completes(max_ops, PSA_SUCCESS, + &min_completes, &max_completes); + + num_ops_prior = psa_sign_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Start performing the signature. */ + PSA_ASSERT(psa_sign_hash_start(&operation, key, alg, + input_data->x, input_data->len)); + + num_ops_prior = psa_sign_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Continue performing the signature until complete. */ + do { + status = psa_sign_hash_complete(&operation, signature, signature_size, + &signature_length); + + num_completes++; + + if (status == PSA_SUCCESS || status == PSA_OPERATION_INCOMPLETE) { + num_ops = psa_sign_hash_get_num_ops(&operation); + /* We are asserting here that every complete makes progress + * (completes some ops), which is true of the internal + * implementation and probably any implementation, however this is + * not mandated by the PSA specification. */ + TEST_ASSERT(num_ops > num_ops_prior); + + num_ops_prior = num_ops; + + /* Ensure calling get_num_ops() twice still returns the same + * number of ops as previously reported. */ + num_ops = psa_sign_hash_get_num_ops(&operation); + + TEST_EQUAL(num_ops, num_ops_prior); + } + } while (status == PSA_OPERATION_INCOMPLETE); + + TEST_ASSERT(status == PSA_SUCCESS); + + TEST_LE_U(min_completes, num_completes); + TEST_LE_U(num_completes, max_completes); + + /* Verify that the signature is what is expected. */ + ASSERT_COMPARE(output_data->x, output_data->len, + signature, signature_length); + + PSA_ASSERT(psa_sign_hash_abort(&operation)); + + num_ops = psa_sign_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops == 0); + +exit: + + /* + * Key attributes may have been returned by psa_get_key_attributes() + * thus reset them as required. + */ + psa_reset_key_attributes(&attributes); + + psa_destroy_key(key); + mbedtls_free(signature); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void sign_hash_fail(int key_type_arg, data_t *key_data, int alg_arg, data_t *input_data, @@ -6489,6 +6646,154 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * sign_hash_fail_interruptible() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test that various failure cases for interruptible sign hash fail with the + * correct error codes, and at the correct point (at start or during + * complete). + * + * 2. Test the number of calls to psa_sign_hash_complete() required are as + * expected for different max_ops values. + * + * 3. Test that the number of ops done prior to start and after abort is zero + * and that each successful stage completes some ops (this is not mandated by + * the PSA specification, but is currently the case). + * + * 4. Check that calling complete() when start() fails and complete() + * after completion results in a BAD_STATE error. + * + * 5. Check that calling start() again after start fails results in a BAD_STATE + * error. + */ +void sign_hash_fail_interruptible(int key_type_arg, data_t *key_data, + int alg_arg, data_t *input_data, + int signature_size_arg, + int expected_start_status_arg, + int expected_complete_status_arg, + int max_ops_arg) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + size_t signature_size = signature_size_arg; + psa_status_t actual_status; + psa_status_t expected_start_status = expected_start_status_arg; + psa_status_t expected_complete_status = expected_complete_status_arg; + unsigned char *signature = NULL; + size_t signature_length = 0xdeadbeef; + uint32_t num_ops = 0; + uint32_t max_ops = max_ops_arg; + size_t num_ops_prior = 0; + size_t num_completes = 0; + size_t min_completes = 0; + size_t max_completes = 0; + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_sign_hash_interruptible_operation_t operation = + psa_sign_hash_interruptible_operation_init(); + + ASSERT_ALLOC(signature, signature_size); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + + psa_interruptible_set_max_ops(max_ops); + + interruptible_signverify_get_minmax_completes(max_ops, + expected_complete_status, + &min_completes, + &max_completes); + + num_ops_prior = psa_sign_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Start performing the signature. */ + actual_status = psa_sign_hash_start(&operation, key, alg, + input_data->x, input_data->len); + + TEST_EQUAL(actual_status, expected_start_status); + + if (expected_start_status != PSA_SUCCESS) { + /* Emulate poor application code, and call complete anyway, even though + * start failed. */ + actual_status = psa_sign_hash_complete(&operation, signature, + signature_size, + &signature_length); + + TEST_EQUAL(actual_status, PSA_ERROR_BAD_STATE); + + /* Test that calling start again after failure also causes BAD_STATE. */ + actual_status = psa_sign_hash_start(&operation, key, alg, + input_data->x, input_data->len); + + TEST_EQUAL(actual_status, PSA_ERROR_BAD_STATE); + } + + num_ops_prior = psa_sign_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Continue performing the signature until complete. */ + do { + actual_status = psa_sign_hash_complete(&operation, signature, + signature_size, + &signature_length); + + num_completes++; + + if (actual_status == PSA_SUCCESS || + actual_status == PSA_OPERATION_INCOMPLETE) { + num_ops = psa_sign_hash_get_num_ops(&operation); + /* We are asserting here that every complete makes progress + * (completes some ops), which is true of the internal + * implementation and probably any implementation, however this is + * not mandated by the PSA specification. */ + TEST_ASSERT(num_ops > num_ops_prior); + + num_ops_prior = num_ops; + } + } while (actual_status == PSA_OPERATION_INCOMPLETE); + + TEST_EQUAL(actual_status, expected_complete_status); + + /* Check that another complete returns BAD_STATE. */ + actual_status = psa_sign_hash_complete(&operation, signature, + signature_size, + &signature_length); + + TEST_EQUAL(actual_status, PSA_ERROR_BAD_STATE); + + PSA_ASSERT(psa_sign_hash_abort(&operation)); + + num_ops = psa_sign_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops == 0); + + /* The value of *signature_length is unspecified on error, but + * whatever it is, it should be less than signature_size, so that + * if the caller tries to read *signature_length bytes without + * checking the error code then they don't overflow a buffer. */ + TEST_LE_U(signature_length, signature_size); + + TEST_LE_U(min_completes, num_completes); + TEST_LE_U(num_completes, max_completes); + +exit: + psa_reset_key_attributes(&attributes); + psa_destroy_key(key); + mbedtls_free(signature); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void sign_verify_hash(int key_type_arg, data_t *key_data, int alg_arg, data_t *input_data) @@ -6559,6 +6864,178 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * sign_verify_hash_interruptible() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test that we can sign an input hash with the given key and then afterwards + * verify that signature. This is currently the only way to test non + * deterministic ECDSA, but this test can also handle deterministic. + * + * 2. Test that after corrupting the hash, the verification detects an invalid + * signature. + * + * 3. Test the number of calls to psa_sign_hash_complete() required are as + * expected for different max_ops values. + * + * 4. Test that the number of ops done prior to starting signing and after abort + * is zero and that each successful signing stage completes some ops (this is + * not mandated by the PSA specification, but is currently the case). + */ +void sign_verify_hash_interruptible(int key_type_arg, data_t *key_data, + int alg_arg, data_t *input_data, + int max_ops_arg) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + size_t key_bits; + unsigned char *signature = NULL; + size_t signature_size; + size_t signature_length = 0xdeadbeef; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = PSA_OPERATION_INCOMPLETE; + uint32_t max_ops = max_ops_arg; + uint32_t num_ops = 0; + uint32_t num_ops_prior = 0; + size_t num_completes = 0; + size_t min_completes = 0; + size_t max_completes = 0; + + psa_sign_hash_interruptible_operation_t sign_operation = + psa_sign_hash_interruptible_operation_init(); + psa_verify_hash_interruptible_operation_t verify_operation = + psa_verify_hash_interruptible_operation_init(); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + key_bits = psa_get_key_bits(&attributes); + + /* Allocate a buffer which has the size advertised by the + * library. */ + signature_size = PSA_SIGN_OUTPUT_SIZE(key_type, + key_bits, alg); + TEST_ASSERT(signature_size != 0); + TEST_LE_U(signature_size, PSA_SIGNATURE_MAX_SIZE); + ASSERT_ALLOC(signature, signature_size); + + psa_interruptible_set_max_ops(max_ops); + + interruptible_signverify_get_minmax_completes(max_ops, PSA_SUCCESS, + &min_completes, &max_completes); + + num_ops_prior = psa_sign_hash_get_num_ops(&sign_operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Start performing the signature. */ + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + num_ops_prior = psa_sign_hash_get_num_ops(&sign_operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Continue performing the signature until complete. */ + do { + + status = psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length); + + num_completes++; + + if (status == PSA_SUCCESS || status == PSA_OPERATION_INCOMPLETE) { + num_ops = psa_sign_hash_get_num_ops(&sign_operation); + /* We are asserting here that every complete makes progress + * (completes some ops), which is true of the internal + * implementation and probably any implementation, however this is + * not mandated by the PSA specification. */ + TEST_ASSERT(num_ops > num_ops_prior); + + num_ops_prior = num_ops; + } + } while (status == PSA_OPERATION_INCOMPLETE); + + TEST_ASSERT(status == PSA_SUCCESS); + + TEST_LE_U(min_completes, num_completes); + TEST_LE_U(num_completes, max_completes); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + num_ops = psa_sign_hash_get_num_ops(&sign_operation); + TEST_ASSERT(num_ops == 0); + + /* Check that the signature length looks sensible. */ + TEST_LE_U(signature_length, signature_size); + TEST_ASSERT(signature_length > 0); + + num_completes = 0; + + /* Start verification. */ + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + /* Continue performing the signature until complete. */ + do { + status = psa_verify_hash_complete(&verify_operation); + + num_completes++; + } while (status == PSA_OPERATION_INCOMPLETE); + + TEST_ASSERT(status == PSA_SUCCESS); + + TEST_LE_U(min_completes, num_completes); + TEST_LE_U(num_completes, max_completes); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + verify_operation = psa_verify_hash_interruptible_operation_init(); + + if (input_data->len != 0) { + /* Flip a bit in the input and verify that the signature is now + * detected as invalid. Flip a bit at the beginning, not at the end, + * because ECDSA may ignore the last few bits of the input. */ + input_data->x[0] ^= 1; + + /* Start verification. */ + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + /* Continue performing the signature until complete. */ + do { + status = psa_verify_hash_complete(&verify_operation); + } while (status == PSA_OPERATION_INCOMPLETE); + + TEST_ASSERT(status == PSA_ERROR_INVALID_SIGNATURE); + } + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + +exit: + /* + * Key attributes may have been returned by psa_get_key_attributes() + * thus reset them as required. + */ + psa_reset_key_attributes(&attributes); + + psa_destroy_key(key); + mbedtls_free(signature); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void verify_hash(int key_type_arg, data_t *key_data, int alg_arg, data_t *hash_data, @@ -6591,6 +7068,137 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * verify_hash_interruptible() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test interruptible verify hash with known outcomes (deterministic ECDSA + * only). + * + * 2. Test the number of calls to psa_verify_hash_complete() required are as + * expected for different max_ops values. + * + * 3. Test that the number of ops done prior to start and after abort is zero + * and that each successful stage completes some ops (this is not mandated by + * the PSA specification, but is currently the case). + * + * 4. Test that calling psa_sign_hash_get_num_ops() multiple times between + * complete() calls does not alter the number of ops returned. + * + * 5. Test that after corrupting the hash, the verification detects an invalid + * signature. + */ +void verify_hash_interruptible(int key_type_arg, data_t *key_data, + int alg_arg, data_t *hash_data, + data_t *signature_data, int max_ops_arg) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = PSA_OPERATION_INCOMPLETE; + uint32_t num_ops = 0; + uint32_t max_ops = max_ops_arg; + size_t num_ops_prior = 0; + size_t num_completes = 0; + size_t min_completes = 0; + size_t max_completes = 0; + + psa_verify_hash_interruptible_operation_t operation = + psa_verify_hash_interruptible_operation_init(); + + TEST_LE_U(signature_data->len, PSA_SIGNATURE_MAX_SIZE); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + + psa_interruptible_set_max_ops(max_ops); + + interruptible_signverify_get_minmax_completes(max_ops, PSA_SUCCESS, + &min_completes, &max_completes); + + num_ops_prior = psa_verify_hash_get_num_ops(&operation); + + TEST_ASSERT(num_ops_prior == 0); + + /* Start verification. */ + PSA_ASSERT(psa_verify_hash_start(&operation, key, alg, + hash_data->x, hash_data->len, + signature_data->x, signature_data->len) + ); + + num_ops_prior = psa_verify_hash_get_num_ops(&operation); + + TEST_ASSERT(num_ops_prior == 0); + + /* Continue performing the signature until complete. */ + do { + status = psa_verify_hash_complete(&operation); + + num_completes++; + + if (status == PSA_SUCCESS || status == PSA_OPERATION_INCOMPLETE) { + num_ops = psa_verify_hash_get_num_ops(&operation); + /* We are asserting here that every complete makes progress + * (completes some ops), which is true of the internal + * implementation and probably any implementation, however this is + * not mandated by the PSA specification. */ + TEST_ASSERT(num_ops > num_ops_prior); + + num_ops_prior = num_ops; + + /* Ensure calling get_num_ops() twice still returns the same + * number of ops as previously reported. */ + num_ops = psa_verify_hash_get_num_ops(&operation); + + TEST_EQUAL(num_ops, num_ops_prior); + } + } while (status == PSA_OPERATION_INCOMPLETE); + + TEST_ASSERT(status == PSA_SUCCESS); + + TEST_LE_U(min_completes, num_completes); + TEST_LE_U(num_completes, max_completes); + + PSA_ASSERT(psa_verify_hash_abort(&operation)); + + num_ops = psa_verify_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops == 0); + + if (hash_data->len != 0) { + /* Flip a bit in the hash and verify that the signature is now detected + * as invalid. Flip a bit at the beginning, not at the end, because + * ECDSA may ignore the last few bits of the input. */ + hash_data->x[0] ^= 1; + + /* Start verification. */ + PSA_ASSERT(psa_verify_hash_start(&operation, key, alg, + hash_data->x, hash_data->len, + signature_data->x, signature_data->len)); + + /* Continue performing the signature until complete. */ + do { + status = psa_verify_hash_complete(&operation); + } while (status == PSA_OPERATION_INCOMPLETE); + + TEST_ASSERT(status == PSA_ERROR_INVALID_SIGNATURE); + } + +exit: + psa_reset_key_attributes(&attributes); + psa_destroy_key(key); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void verify_hash_fail(int key_type_arg, data_t *key_data, int alg_arg, data_t *hash_data, @@ -6625,6 +7233,612 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * verify_hash_fail_interruptible() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test that various failure cases for interruptible verify hash fail with + * the correct error codes, and at the correct point (at start or during + * complete). + * + * 2. Test the number of calls to psa_verify_hash_complete() required are as + * expected for different max_ops values. + * + * 3. Test that the number of ops done prior to start and after abort is zero + * and that each successful stage completes some ops (this is not mandated by + * the PSA specification, but is currently the case). + * + * 4. Check that calling complete() when start() fails and complete() + * after completion results in a BAD_STATE error. + * + * 5. Check that calling start() again after start fails results in a BAD_STATE + * error. + */ +void verify_hash_fail_interruptible(int key_type_arg, data_t *key_data, + int alg_arg, data_t *hash_data, + data_t *signature_data, + int expected_start_status_arg, + int expected_complete_status_arg, + int max_ops_arg) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_status_t actual_status; + psa_status_t expected_start_status = expected_start_status_arg; + psa_status_t expected_complete_status = expected_complete_status_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + uint32_t num_ops = 0; + uint32_t max_ops = max_ops_arg; + size_t num_ops_prior = 0; + size_t num_completes = 0; + size_t min_completes = 0; + size_t max_completes = 0; + psa_verify_hash_interruptible_operation_t operation = + psa_verify_hash_interruptible_operation_init(); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + + psa_interruptible_set_max_ops(max_ops); + + interruptible_signverify_get_minmax_completes(max_ops, + expected_complete_status, + &min_completes, + &max_completes); + + num_ops_prior = psa_verify_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Start verification. */ + actual_status = psa_verify_hash_start(&operation, key, alg, + hash_data->x, hash_data->len, + signature_data->x, + signature_data->len); + + TEST_EQUAL(actual_status, expected_start_status); + + if (expected_start_status != PSA_SUCCESS) { + /* Emulate poor application code, and call complete anyway, even though + * start failed. */ + actual_status = psa_verify_hash_complete(&operation); + + TEST_EQUAL(actual_status, PSA_ERROR_BAD_STATE); + + /* Test that calling start again after failure also causes BAD_STATE. */ + actual_status = psa_verify_hash_start(&operation, key, alg, + hash_data->x, hash_data->len, + signature_data->x, + signature_data->len); + + TEST_EQUAL(actual_status, PSA_ERROR_BAD_STATE); + } + + num_ops_prior = psa_verify_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops_prior == 0); + + /* Continue performing the signature until complete. */ + do { + actual_status = psa_verify_hash_complete(&operation); + + num_completes++; + + if (actual_status == PSA_SUCCESS || + actual_status == PSA_OPERATION_INCOMPLETE) { + num_ops = psa_verify_hash_get_num_ops(&operation); + /* We are asserting here that every complete makes progress + * (completes some ops), which is true of the internal + * implementation and probably any implementation, however this is + * not mandated by the PSA specification. */ + TEST_ASSERT(num_ops > num_ops_prior); + + num_ops_prior = num_ops; + } + } while (actual_status == PSA_OPERATION_INCOMPLETE); + + TEST_EQUAL(actual_status, expected_complete_status); + + /* Check that another complete returns BAD_STATE. */ + actual_status = psa_verify_hash_complete(&operation); + TEST_EQUAL(actual_status, PSA_ERROR_BAD_STATE); + + TEST_LE_U(min_completes, num_completes); + TEST_LE_U(num_completes, max_completes); + + PSA_ASSERT(psa_verify_hash_abort(&operation)); + + num_ops = psa_verify_hash_get_num_ops(&operation); + TEST_ASSERT(num_ops == 0); + +exit: + psa_reset_key_attributes(&attributes); + psa_destroy_key(key); + PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * interruptible_signverify_hash_state_test() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test that calling the various interruptible sign and verify hash functions + * in incorrect orders returns BAD_STATE errors. + */ +void interruptible_signverify_hash_state_test(int key_type_arg, + data_t *key_data, int alg_arg, data_t *input_data) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + size_t key_bits; + unsigned char *signature = NULL; + size_t signature_size; + size_t signature_length = 0xdeadbeef; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_sign_hash_interruptible_operation_t sign_operation = + psa_sign_hash_interruptible_operation_init(); + psa_verify_hash_interruptible_operation_t verify_operation = + psa_verify_hash_interruptible_operation_init(); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + key_bits = psa_get_key_bits(&attributes); + + /* Allocate a buffer which has the size advertised by the + * library. */ + signature_size = PSA_SIGN_OUTPUT_SIZE(key_type, + key_bits, alg); + TEST_ASSERT(signature_size != 0); + TEST_LE_U(signature_size, PSA_SIGNATURE_MAX_SIZE); + ASSERT_ALLOC(signature, signature_size); + + psa_interruptible_set_max_ops(PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + /* --- Attempt completes prior to starts --- */ + TEST_EQUAL(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length), + PSA_ERROR_BAD_STATE); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + TEST_EQUAL(psa_verify_hash_complete(&verify_operation), + PSA_ERROR_BAD_STATE); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + /* --- Aborts in all other places. --- */ + psa_sign_hash_abort(&sign_operation); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + psa_interruptible_set_max_ops(1); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + TEST_EQUAL(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length), + PSA_OPERATION_INCOMPLETE); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + psa_interruptible_set_max_ops(PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + PSA_ASSERT(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length)); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + psa_interruptible_set_max_ops(1); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + TEST_EQUAL(psa_verify_hash_complete(&verify_operation), + PSA_OPERATION_INCOMPLETE); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + psa_interruptible_set_max_ops(PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + PSA_ASSERT(psa_verify_hash_complete(&verify_operation)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + /* --- Attempt double starts. --- */ + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + TEST_EQUAL(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len), + PSA_ERROR_BAD_STATE); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + TEST_EQUAL(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length), + PSA_ERROR_BAD_STATE); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + +exit: + /* + * Key attributes may have been returned by psa_get_key_attributes() + * thus reset them as required. + */ + psa_reset_key_attributes(&attributes); + + psa_destroy_key(key); + mbedtls_free(signature); + PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * interruptible_signverify_hash_edgecase_tests() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test various edge cases in the interruptible sign and verify hash + * interfaces. + */ +void interruptible_signverify_hash_edgecase_tests(int key_type_arg, + data_t *key_data, int alg_arg, data_t *input_data) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + size_t key_bits; + unsigned char *signature = NULL; + size_t signature_size; + size_t signature_length = 0xdeadbeef; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + uint8_t *input_buffer = NULL; + psa_sign_hash_interruptible_operation_t sign_operation = + psa_sign_hash_interruptible_operation_init(); + psa_verify_hash_interruptible_operation_t verify_operation = + psa_verify_hash_interruptible_operation_init(); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, + &key)); + PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + key_bits = psa_get_key_bits(&attributes); + + /* Allocate a buffer which has the size advertised by the + * library. */ + signature_size = PSA_SIGN_OUTPUT_SIZE(key_type, + key_bits, alg); + TEST_ASSERT(signature_size != 0); + TEST_LE_U(signature_size, PSA_SIGNATURE_MAX_SIZE); + ASSERT_ALLOC(signature, signature_size); + + /* --- Change function inputs mid run, to cause an error (sign only, + * verify passes all inputs to start. --- */ + + psa_interruptible_set_max_ops(1); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + TEST_EQUAL(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length), + PSA_OPERATION_INCOMPLETE); + + TEST_EQUAL(psa_sign_hash_complete(&sign_operation, signature, + 0, + &signature_length), + PSA_ERROR_BUFFER_TOO_SMALL); + + /* And test that this invalidates the operation. */ + TEST_EQUAL(psa_sign_hash_complete(&sign_operation, signature, + 0, + &signature_length), + PSA_ERROR_BAD_STATE); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + /* Trash the hash buffer in between start and complete, to ensure + * no reliance on external buffers. */ + psa_interruptible_set_max_ops(PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + input_buffer = mbedtls_calloc(1, input_data->len); + TEST_ASSERT(input_buffer != NULL); + + memcpy(input_buffer, input_data->x, input_data->len); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_buffer, input_data->len)); + + memset(input_buffer, '!', input_data->len); + mbedtls_free(input_buffer); + input_buffer = NULL; + + PSA_ASSERT(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length)); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + input_buffer = mbedtls_calloc(1, input_data->len); + TEST_ASSERT(input_buffer != NULL); + + memcpy(input_buffer, input_data->x, input_data->len); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_buffer, input_data->len, + signature, signature_length)); + + memset(input_buffer, '!', input_data->len); + mbedtls_free(input_buffer); + input_buffer = NULL; + + PSA_ASSERT(psa_verify_hash_complete(&verify_operation)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + +exit: + /* + * Key attributes may have been returned by psa_get_key_attributes() + * thus reset them as required. + */ + psa_reset_key_attributes(&attributes); + + psa_destroy_key(key); + mbedtls_free(signature); + PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ +/** + * interruptible_signverify_hash_ops_tests() test intentions: + * + * Note: This test can currently only handle ECDSA. + * + * 1. Test that setting max ops is reflected in both interruptible sign and + * verify hash + * 2. Test that changing the value of max_ops to unlimited during an operation + * causes that operation to complete in the next call. + * + * 3. Test that calling get_num_ops() between complete calls gives the same + * result as calling get_num_ops() once at the end of the operation. + */ +void interruptible_signverify_hash_ops_tests(int key_type_arg, + data_t *key_data, int alg_arg, + data_t *input_data) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + size_t key_bits; + unsigned char *signature = NULL; + size_t signature_size; + size_t signature_length = 0xdeadbeef; + uint32_t num_ops = 0; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + psa_sign_hash_interruptible_operation_t sign_operation = + psa_sign_hash_interruptible_operation_init(); + psa_verify_hash_interruptible_operation_t verify_operation = + psa_verify_hash_interruptible_operation_init(); + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, key_type); + + PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, &key)); + PSA_ASSERT(psa_get_key_attributes(key, &attributes)); + key_bits = psa_get_key_bits(&attributes); + + /* Allocate a buffer which has the size advertised by the + * library. */ + signature_size = PSA_SIGN_OUTPUT_SIZE(key_type, key_bits, alg); + + TEST_ASSERT(signature_size != 0); + TEST_LE_U(signature_size, PSA_SIGNATURE_MAX_SIZE); + ASSERT_ALLOC(signature, signature_size); + + /* Check that default max ops gets set if we don't set it. */ + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + TEST_EQUAL(psa_interruptible_get_max_ops(), + PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_size)); + + TEST_EQUAL(psa_interruptible_get_max_ops(), + PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + /* Check that max ops gets set properly. */ + + psa_interruptible_set_max_ops(0xbeef); + + TEST_EQUAL(psa_interruptible_get_max_ops(), 0xbeef); + + /* --- Ensure changing the max ops mid operation works (operation should + * complete successfully after setting max ops to unlimited --- */ + psa_interruptible_set_max_ops(1); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + TEST_EQUAL(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length), + PSA_OPERATION_INCOMPLETE); + + psa_interruptible_set_max_ops(PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + PSA_ASSERT(psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length)); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + psa_interruptible_set_max_ops(1); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + TEST_EQUAL(psa_verify_hash_complete(&verify_operation), + PSA_OPERATION_INCOMPLETE); + + psa_interruptible_set_max_ops(PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED); + + PSA_ASSERT(psa_verify_hash_complete(&verify_operation)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + /* --- Test that not calling get_num_ops inbetween complete calls does not + * result in lost ops. ---*/ + + psa_interruptible_set_max_ops(1); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + /* Continue performing the signature until complete. */ + do { + status = psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length); + + num_ops = psa_sign_hash_get_num_ops(&sign_operation); + + } while (status == PSA_OPERATION_INCOMPLETE); + + PSA_ASSERT(status); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + PSA_ASSERT(psa_sign_hash_start(&sign_operation, key, alg, + input_data->x, input_data->len)); + + /* Continue performing the signature until complete. */ + do { + status = psa_sign_hash_complete(&sign_operation, signature, + signature_size, + &signature_length); + } while (status == PSA_OPERATION_INCOMPLETE); + + PSA_ASSERT(status); + + TEST_EQUAL(num_ops, psa_sign_hash_get_num_ops(&sign_operation)); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + /* Continue performing the verification until complete. */ + do { + status = psa_verify_hash_complete(&verify_operation); + + num_ops = psa_verify_hash_get_num_ops(&verify_operation); + + } while (status == PSA_OPERATION_INCOMPLETE); + + PSA_ASSERT(status); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + + PSA_ASSERT(psa_verify_hash_start(&verify_operation, key, alg, + input_data->x, input_data->len, + signature, signature_length)); + + /* Continue performing the verification until complete. */ + do { + status = psa_verify_hash_complete(&verify_operation); + + } while (status == PSA_OPERATION_INCOMPLETE); + + PSA_ASSERT(status); + + TEST_EQUAL(num_ops, psa_verify_hash_get_num_ops(&verify_operation)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); + +exit: + /* + * Key attributes may have been returned by psa_get_key_attributes() + * thus reset them as required. + */ + psa_reset_key_attributes(&attributes); + + psa_destroy_key(key); + mbedtls_free(signature); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void sign_message_deterministic(int key_type_arg, data_t *key_data, @@ -6902,7 +8116,11 @@ void asymmetric_encrypt(int key_type_arg, output, output_size, &output_length); TEST_EQUAL(actual_status, expected_status); - TEST_EQUAL(output_length, expected_output_length); + if (actual_status == PSA_SUCCESS) { + TEST_EQUAL(output_length, expected_output_length); + } else { + TEST_LE_U(output_length, output_size); + } /* If the label is empty, the test framework puts a non-null pointer * in label->x. Test that a null pointer works as well. */ @@ -6917,7 +8135,11 @@ void asymmetric_encrypt(int key_type_arg, output, output_size, &output_length); TEST_EQUAL(actual_status, expected_status); - TEST_EQUAL(output_length, expected_output_length); + if (actual_status == PSA_SUCCESS) { + TEST_EQUAL(output_length, expected_output_length); + } else { + TEST_LE_U(output_length, output_size); + } } exit: diff --git a/tests/suites/test_suite_psa_crypto_op_fail.function b/tests/suites/test_suite_psa_crypto_op_fail.function index 046e3c3a0b..55dce8931f 100644 --- a/tests/suites/test_suite_psa_crypto_op_fail.function +++ b/tests/suites/test_suite_psa_crypto_op_fail.function @@ -221,6 +221,13 @@ void sign_fail(int key_type_arg, data_t *key_data, uint8_t input[1] = { 'A' }; uint8_t output[PSA_SIGNATURE_MAX_SIZE] = { 0 }; size_t length = SIZE_MAX; + psa_sign_hash_interruptible_operation_t sign_operation = + psa_sign_hash_interruptible_operation_init(); + + psa_verify_hash_interruptible_operation_t verify_operation = + psa_verify_hash_interruptible_operation_init(); + + PSA_INIT(); @@ -237,6 +244,13 @@ void sign_fail(int key_type_arg, data_t *key_data, psa_sign_hash(key_id, alg, input, sizeof(input), output, sizeof(output), &length)); + + TEST_STATUS(expected_status, + psa_sign_hash_start(&sign_operation, key_id, alg, + input, sizeof(input))); + + PSA_ASSERT(psa_sign_hash_abort(&sign_operation)); + if (!private_only) { /* Determine a plausible signature size to avoid an INVALID_SIGNATURE * error based on this. */ @@ -253,6 +267,13 @@ void sign_fail(int key_type_arg, data_t *key_data, psa_verify_hash(key_id, alg, input, sizeof(input), output, output_length)); + + TEST_STATUS(expected_status, + psa_verify_hash_start(&verify_operation, key_id, alg, + input, sizeof(input), + output, output_length)); + + PSA_ASSERT(psa_verify_hash_abort(&verify_operation)); } exit: diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index 01da08b54c..54080a7b86 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -122,6 +122,14 @@ X509 CRT information, Subject Alt Name + Key Usage depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA x509_cert_info:"data_files/cert_example_multi_nocn.crt":"cert. version \: 3\nserial number \: F7\:C6\:7F\:F8\:E9\:A9\:63\:F9\nissuer name \: C=NL\nsubject name \: C=NL\nissued on \: 2014-01-22 10\:04\:33\nexpires on \: 2024-01-22 10\:04\:33\nsigned using \: RSA with SHA1\nRSA key size \: 1024 bits\nbasic constraints \: CA=false\nsubject alt name \:\n dNSName \: www.shotokan-braunschweig.de\n dNSName \: www.massimo-abate.eu\n \n \nkey usage \: Digital Signature, Non Repudiation, Key Encipherment\n" +X509 CRT information, Subject Alt Name with uniformResourceIdentifier +depends_on:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA +x509_cert_info:"data_files/rsa_single_san_uri.crt.der":"cert. version \: 3\nserial number \: 6F\:75\:EB\:E9\:6D\:25\:BC\:88\:82\:62\:A3\:E0\:68\:A7\:37\:3B\:EC\:75\:8F\:9C\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS URI SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS URI SAN\nissued on \: 2023-02-14 10\:38\:05\nexpires on \: 2043-02-09 10\:38\:05\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name \:\n uniformResourceIdentifier \: urn\:example.com\:5ff40f78-9210-494f-8206-c2c082f0609c\nkey usage \: Digital Signature, Non Repudiation, Key Encipherment\n" + +X509 CRT information, Subject Alt Name with two uniformResourceIdentifiers +depends_on:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA +x509_cert_info:"data_files/rsa_multiple_san_uri.crt.der":"cert. version \: 3\nserial number \: 08\:E2\:93\:18\:91\:26\:D8\:46\:88\:90\:10\:4F\:B5\:86\:CB\:C4\:78\:E6\:EA\:0D\nissuer name \: C=UK, O=Mbed TLS, CN=Mbed TLS URI SAN\nsubject name \: C=UK, O=Mbed TLS, CN=Mbed TLS URI SAN\nissued on \: 2023-02-14 10\:37\:50\nexpires on \: 2043-02-09 10\:37\:50\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name \:\n uniformResourceIdentifier \: urn\:example.com\:5ff40f78-9210-494f-8206-c2c082f0609c\n uniformResourceIdentifier \: urn\:example.com\:5ff40f78-9210-494f-8206-abcde1234567\nkey usage \: Digital Signature, Non Repudiation, Key Encipherment\n" + X509 CRT information, RSA Certificate Policy any depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA x509_cert_info:"data_files/test-ca-any_policy.crt":"cert. version \: 3\nserial number \: 00\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nissued on \: 2019-03-21 16\:40\:59\nexpires on \: 2029-03-21 16\:40\:59\nsigned using \: RSA with SHA-256\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\ncertificate policies \: Any Policy\n" @@ -168,7 +176,7 @@ x509_cert_info:"data_files/server3.crt":"cert. version \: 3\nserial number X509 CRT information Bitstring in subject name depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA -x509_cert_info:"data_files/bitstring-in-dn.pem":"cert. version \: 3\nserial number \: 02\nissuer name \: CN=Test CA 01, ST=Ecnivorp, C=XX, emailAddress=tca@example.com, O=Test CA Authority\nsubject name \: C=XX, O=tca, ST=Ecnivorp, OU=TCA, CN=Client, emailAddress=client@example.com, serialNumber=7101012255, uniqueIdentifier=?7101012255\nissued on \: 2015-03-11 12\:06\:51\nexpires on \: 2025-03-08 12\:06\:51\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name \:\n \next key usage \: TLS Web Client Authentication\n" +x509_cert_info:"data_files/bitstring-in-dn.pem":"cert. version \: 3\nserial number \: 02\nissuer name \: CN=Test CA 01, ST=Ecnivorp, C=XX, emailAddress=tca@example.com, O=Test CA Authority\nsubject name \: C=XX, O=tca, ST=Ecnivorp, OU=TCA, CN=Client, emailAddress=client@example.com, serialNumber=7101012255, uniqueIdentifier=?7101012255\nissued on \: 2015-03-11 12\:06\:51\nexpires on \: 2025-03-08 12\:06\:51\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name \:\n rfc822Name \: client@example.com\next key usage \: TLS Web Client Authentication\n" X509 CRT information Non-ASCII string in issuer name and subject name depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA @@ -198,6 +206,10 @@ X509 SAN parsing, unsupported otherName name depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_PK_CAN_ECDSA_SOME:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA x509_parse_san:"data_files/server5-unsupported_othername.crt":"" +X509 SAN parsing rfc822Name +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_256_VIA_MD_OR_PSA_BASED_ON_USE_PSA +x509_parse_san:"data_files/test_cert_rfc822name.crt.der":"type \: 1\nrfc822Name \: my@other.address\ntype \: 1\nrfc822Name \: second@other.address\n" + X509 CRL information #1 depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA:MBEDTLS_RSA_C:!MBEDTLS_X509_REMOVE_INFO mbedtls_x509_crl_info:"data_files/crl_expired.pem":"CRL version \: 1\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nthis update \: 2011-02-20 10\:24\:19\nnext update \: 2011-02-20 11\:24\:19\nRevoked certificates\:\nserial number\: 01 revocation date\: 2011-02-12 14\:44\:07\nserial number\: 03 revocation date\: 2011-02-12 14\:44\:07\nsigned using \: RSA with SHA1\n" @@ -2550,7 +2562,7 @@ X509 OID numstring #4 (larger number) x509_oid_numstr:"2a864886f70d":"1.2.840.113549":15:14 X509 OID numstring #5 (arithmetic overflow) -x509_oid_numstr:"2a8648f9f8f7f6f5f4f3f2f1f001":"":100:MBEDTLS_ERR_OID_BUF_TOO_SMALL +x509_oid_numstr:"2a8648f9f8f7f6f5f4f3f2f1f001":"":100:MBEDTLS_ERR_ASN1_INVALID_DATA X509 CRT keyUsage #1 (no extension, expected KU) depends_on:MBEDTLS_RSA_C:MBEDTLS_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index 3454da352f..f6e4a0625e 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -279,7 +279,18 @@ int verify_parse_san(mbedtls_x509_subject_alternative_name *san, *p++ = san->san.unstructured_name.p[i]; } break;/* MBEDTLS_X509_SAN_DNS_NAME */ - + case (MBEDTLS_X509_SAN_RFC822_NAME): + ret = mbedtls_snprintf(p, n, "\nrfc822Name : "); + MBEDTLS_X509_SAFE_SNPRINTF; + if (san->san.unstructured_name.len >= n) { + *p = '\0'; + return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; + } + n -= san->san.unstructured_name.len; + for (i = 0; i < san->san.unstructured_name.len; i++) { + *p++ = san->san.unstructured_name.p[i]; + } + break;/* MBEDTLS_X509_SAN_RFC822_NAME */ default: /* * Should not happen.