diff --git a/include/psa/crypto_builtin_composites.h b/include/psa/crypto_builtin_composites.h index b7f0b1162..0f1220de9 100644 --- a/include/psa/crypto_builtin_composites.h +++ b/include/psa/crypto_builtin_composites.h @@ -107,4 +107,59 @@ 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) + mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx); +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + size_t MBEDTLS_PRIVATE(curve_bytes); + psa_algorithm_t MBEDTLS_PRIVATE(alg); + mbedtls_md_type_t MBEDTLS_PRIVATE(md_alg); + const uint8_t *MBEDTLS_PRIVATE(hash); + size_t MBEDTLS_PRIVATE(hash_length); + + mbedtls_mpi MBEDTLS_PRIVATE(r); + mbedtls_mpi MBEDTLS_PRIVATE(s); + +#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA */ + +} mbedtls_psa_sign_hash_interruptible_operation_t; + +#define MBEDTLS_PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, 0, 0, { 0 }, \ + { 0 } } + +/* 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) + mbedtls_ecdsa_context *MBEDTLS_PRIVATE(ctx); +#if defined(MBEDTLS_ECP_RESTARTABLE) + mbedtls_ecdsa_restart_ctx MBEDTLS_PRIVATE(restart_ctx); +#endif /* MBEDTLS_ECP_RESTARTABLE */ + + size_t MBEDTLS_PRIVATE(curve_bytes); + const uint8_t *MBEDTLS_PRIVATE(hash); + size_t MBEDTLS_PRIVATE(hash_length); + + mbedtls_mpi MBEDTLS_PRIVATE(r); + mbedtls_mpi MBEDTLS_PRIVATE(s); + +#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA */ + +} mbedtls_psa_verify_hash_interruptible_operation_t; + +#define MBEDTLS_VERIFY_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { { 0 }, { 0 }, 0, 0, 0, { 0 }, \ + { 0 } } + + + #endif /* PSA_CRYPTO_BUILTIN_COMPOSITES_H */ diff --git a/include/psa/crypto_driver_contexts_composites.h b/include/psa/crypto_driver_contexts_composites.h index bcd000e70..1b95814f9 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_struct.h b/include/psa/crypto_struct.h index bd20937e5..8874e97a2 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -506,10 +506,12 @@ struct psa_sign_hash_interruptible_operation_s { * 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); + size_t MBEDTLS_PRIVATE(num_ops); }; -#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, 0 } +#define PSA_SIGN_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0 } static inline struct psa_sign_hash_interruptible_operation_s psa_sign_hash_interruptible_operation_init(void) @@ -535,10 +537,12 @@ struct psa_verify_hash_interruptible_operation_s { * 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); + size_t MBEDTLS_PRIVATE(num_ops); }; -#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, 0 } +#define PSA_VERIFY_HASH_INTERRUPTIBLE_OPERATION_INIT { 0, { 0 }, 0 } static inline struct psa_verify_hash_interruptible_operation_s psa_verify_hash_interruptible_operation_init(void) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a21f6d963..b31d51b4b 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; @@ -3360,7 +3364,424 @@ psa_status_t psa_verify_hash_abort( return PSA_SUCCESS; } +/****************************************************************/ +/* Asymmetric interruptible cryptography internal */ +/* implementations */ +/****************************************************************/ +static uint32_t mbedtls_psa_interruptible_max_ops = + PSA_INTERRUPTIBLE_MAX_OPS_UNLIMITED; + +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_psa_interruptible_max_ops = max_ops; + 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_interruptible_get_max_ops(void) +{ + return mbedtls_psa_interruptible_max_ops; +} + +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->restart_ctx.ecp.ops_done; +#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->restart_ctx.ecp.ops_done; +#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; + + if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + if (PSA_ALG_IS_ECDSA(alg)) { + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + +#if !defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) + if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif + + /* Ensure default is set even if + * mbedtls_psa_interruptible_get_max_ops() has not been called. */ + mbedtls_ecp_set_max_ops(mbedtls_psa_interruptible_get_max_ops()); + + 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; + } + + mbedtls_ecdsa_restart_init(&operation->restart_ctx); + + mbedtls_mpi_init(&operation->r); + mbedtls_mpi_init(&operation->s); + + operation->curve_bytes = PSA_BITS_TO_BYTES( + operation->ctx->grp.pbits); + + 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; + + operation->hash = hash; + operation->hash_length = hash_length; + +#else + (void) operation; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) hash; + (void) 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 ) */ + } else { + status = PSA_ERROR_INVALID_ARGUMENT; + } + } else { + status = PSA_ERROR_NOT_SUPPORTED; + } + + return status; +} + +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) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + if (signature_size < 2 * operation->curve_bytes) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + + 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, + &operation->r, + &operation->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) */ + return PSA_ERROR_NOT_SUPPORTED; +#endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */ + } else { + + status = mbedtls_to_psa_error( + mbedtls_ecdsa_sign_restartable(&operation->ctx->grp, + &operation->r, + &operation->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)); + } + + if (status != PSA_SUCCESS) { + return status; + } else { + status = mbedtls_to_psa_error( + mbedtls_mpi_write_binary(&operation->r, + signature, + operation->curve_bytes)); + + if (status != PSA_SUCCESS) { + return status; + } + + status = mbedtls_to_psa_error( + mbedtls_mpi_write_binary(&operation->s, + signature + + operation->curve_bytes, + operation->curve_bytes)); + + if (status != PSA_SUCCESS) { + return status; + } + + *signature_length = operation->curve_bytes * 2; + + return PSA_SUCCESS; + } + #else + + (void) operation; + (void) status; + (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); + } + + mbedtls_ecdsa_restart_free(&operation->restart_ctx); + + 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 ) */ +} + +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; + + if (PSA_KEY_TYPE_IS_ECC(attributes->core.type)) { + if (PSA_ALG_IS_ECDSA(alg)) { + +#if (defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)) && \ + defined(MBEDTLS_ECP_RESTARTABLE) + + /* Ensure default is set even if + * mbedtls_psa_interruptible_get_max_ops() has not been called. */ + mbedtls_ecp_set_max_ops(mbedtls_psa_interruptible_get_max_ops()); + + 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->curve_bytes = PSA_BITS_TO_BYTES( + operation->ctx->grp.pbits); + + + if (signature_length != 2 * operation->curve_bytes) { + return PSA_ERROR_INVALID_SIGNATURE; + } + + mbedtls_mpi_init(&operation->r); + status = mbedtls_to_psa_error( + mbedtls_mpi_read_binary(&operation->r, + signature, + operation->curve_bytes)); + + if (status != PSA_SUCCESS) { + return status; + } + + mbedtls_mpi_init(&operation->s); + status = mbedtls_to_psa_error( + mbedtls_mpi_read_binary(&operation->s, + signature + + operation->curve_bytes, + operation->curve_bytes)); + + if (status != PSA_SUCCESS) { + return status; + } + + /* Check whether the public part is loaded. If not, load it. */ + if (mbedtls_ecp_is_zero(&operation->ctx->Q)) { + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + ret = mbedtls_ecp_mul(&operation->ctx->grp, + &operation->ctx->Q, + &operation->ctx->d, + &operation->ctx->grp.G, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE); + + if (ret != 0) { + return mbedtls_to_psa_error(ret); + } + } + + mbedtls_ecdsa_restart_init(&operation->restart_ctx); + + operation->hash = hash; + operation->hash_length = hash_length; +#else + (void) operation; + (void) key_buffer; + (void) key_buffer_size; + (void) alg; + (void) hash; + (void) hash_length; + (void) signature; + (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 ) */ + } else { + status = PSA_ERROR_INVALID_ARGUMENT; + } + } else { + status = PSA_ERROR_NOT_SUPPORTED; + } + + return status; +} + +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) + + return 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)); + +#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); + } + + mbedtls_ecdsa_restart_free(&operation->restart_ctx); + + 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 */ diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 38e4bc5cc..2f3cb6458 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -606,4 +606,303 @@ 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. + * + * \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 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. + * + * \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 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 so + * far. If the operation has completed, then this will represent the + * number of ops required for the entire operation. After initialization + * or calling psa_sign_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. + * + * \note The signature of this function is that of a PSA driver + * sign_get_num_ops entry point. This function behaves as a + * sign_get_num_ops 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. + * + * \return Number of ops that the operation has taken so + * far. + */ +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 + * so far. If the operation has completed, then this will represent the + * number of ops required for the entire operation. After initialization + * or calling 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. + * + * \note The signature of this function is that of a PSA driver + * verify_get_num_ops entry point. This function behaves as a + * verify_get_num_ops 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. + * + * \return Number of ops that the operation has taken so + * far. + */ +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. + * + * \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 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. + * + * \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 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 + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_CORRUPTION_DETECTED + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY + */ +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. + * + * \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 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. + * + * \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 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 to load the key representation. + */ +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. + * + * \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 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 + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + */ +psa_status_t mbedtls_psa_verify_hash_complete( + mbedtls_psa_verify_hash_interruptible_operation_t *operation); + +/** + * \brief Abort a verify signed 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 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/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.c.jinja index e1f7b1fe8..6093fdf81 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 @@ -435,12 +435,12 @@ psa_status_t psa_driver_wrapper_verify_hash( void psa_driver_wrapper_interruptible_set_max_ops( uint32_t max_ops ) { - ( void ) max_ops; + mbedtls_psa_interruptible_set_max_ops( max_ops ); } uint32_t psa_driver_wrapper_interruptible_get_max_ops( void ) { - return( PSA_ERROR_INVALID_ARGUMENT ); + return mbedtls_psa_interruptible_get_max_ops( ); } uint32_t psa_driver_wrapper_sign_hash_get_num_ops( @@ -449,12 +449,13 @@ uint32_t psa_driver_wrapper_sign_hash_get_num_ops( switch( operation->id ) { 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) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - - /* Add cases for opaque driver here */ + /* Add test driver tests here */ #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -469,15 +470,17 @@ uint32_t psa_driver_wrapper_verify_hash_get_num_ops( switch( operation->id ) { 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) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - - /* Add cases for opaque driver here */ + /* Add test driver tests here */ #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + } return( PSA_ERROR_INVALID_ARGUMENT ); @@ -491,7 +494,8 @@ psa_status_t psa_driver_wrapper_sign_hash_start( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + PSA_KEY_LIFETIME_GET_LOCATION( + attributes->core.lifetime ); switch( location ) { @@ -511,6 +515,10 @@ psa_status_t psa_driver_wrapper_sign_hash_start( /* 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 */ @@ -539,12 +547,13 @@ psa_status_t psa_driver_wrapper_sign_hash_complete( 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) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - - /* Add cases for opaque driver here */ + /* Add test driver tests here */ #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -563,12 +572,11 @@ psa_status_t psa_driver_wrapper_sign_hash_abort( 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) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - - /* Add cases for opaque driver here */ + /* Add test driver tests here */ #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -586,8 +594,8 @@ psa_status_t psa_driver_wrapper_verify_hash_start( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_location_t location = - PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( + attributes->core.lifetime ); switch( location ) { @@ -607,6 +615,12 @@ psa_status_t psa_driver_wrapper_verify_hash_start( /* 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 */ @@ -635,12 +649,13 @@ psa_status_t psa_driver_wrapper_verify_hash_complete( 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) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - - /* Add cases for opaque driver here */ + /* Add test driver tests here */ #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ @@ -655,12 +670,12 @@ psa_status_t psa_driver_wrapper_verify_hash_abort( 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) - case MBEDTLS_TEST_TRANSPARENT_DRIVER_ID: - - /* Add cases for opaque driver here */ + /* Add test driver tests here */ #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */