Skip to content

Commit

Permalink
First draft of PSA interruptible ECC signing design
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Elliott <[email protected]>
  • Loading branch information
paul-elliott-arm committed Sep 14, 2022
1 parent 52f83dc commit dae46e1
Showing 1 changed file with 332 additions and 0 deletions.
332 changes: 332 additions & 0 deletions include/psa/crypto_extra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,338 @@ static inline struct psa_pake_operation_s psa_pake_operation_init( void )
return( v );
}

/**
* \brief The context for PSA interruptable signing.
*
* \note Contents not yet designed as implementation specific.
*
*/
struct psa_sign_interruptible_context_s
{
size_t num_ops;
};

typedef struct psa_sign_interruptible_context_s psa_sign_interruptible_context;

/**
* \brief Set the maximum number of basic operations done
* in a row.
*
* \note This value defaults to 0 (which means
* unlimited).
*
* \note If more operations are needed to complete a
* computation, #PSA_ERROR_IN_PROGRESS will be
* returned by the function performing the
* computation. It is then the caller's
* responsibility to either call again with the
* same parameters until it returns 0 or an error
* code; or to free the relevant context if the
* operation is to be aborted.
*
* \note It is strictly required that all input
* parameters and the restart context be the same
* on successive calls for the same operation,
* but output parameters need not be the same;
* they must not be used until the function
* finally returns 0.
*
* This only applies to functions whose
* documentation mentions they may return
* #PSA_ERROR_IN_PROGRESS.
*
* \param max_ops Maximum number of basic operations done in
* a row. Passing zero here has the same
* effect as passing the maximum value - i.e the
* operation will be done in one go. Lower
* (non-zero) values mean signature functions
* will block for a lesser maximum amount of time
* and conversely larger values will mean
* blocking for a larger maximum amount of time.
* The effect of changing this value will depend
* on the key used, the curve used and the
* underlying implementation, so we provide /c
* psa_sign_interruptible_get_num_ops() in order
* to help with tuning this value.
*
*/
void psa_sign_interruptible_set_max_ops( unsigned max_ops );

/**
* \brief Get the number of basic operations that an
* operation took to complete.
*
* This is a helper provided to help you tune the
* value passed to \c
* psa_sign_interruptible_set_max_ops().
*
* This only applies to functions whose
* documentation mentions they may return
* #PSA_ERROR_IN_PROGRESS.
*
* \param ctx The \c psa_sign_interruptible_context to use.
* This must be initialized first.
*
*/
unsigned psa_sign_interruptible_get_num_ops(
psa_sign_interruptible_context *ctx );

/**
* \brief Start signing a hash or short message with a
* private key, in an interruptible manner.
*
* \see \c psa_sign_hash_complete()
*
* \note This function combined with \c
* psa_sign_hash_complete() is equivalent to
* \c psa_sign_hash() but it can return early and
* restart according to the limit set with \c
* psa_sign_interruptible_set_max_ops() to reduce
* blocking.
*
* \note Users should call \c psa_sign_hash_complete()
* 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_ERROR_IN_PROGRESS if there is more work to
* do.
*
* \param ctx The \c psa_sign_interruptible_context 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 (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 parameters to complete the operation
*
* \retval #PSA_ERROR_INVALID_HANDLE
* \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_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_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.
*/
int psa_sign_hash_start( psa_sign_interruptible_context *ctx,
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
uint8_t *hash,
size_t hash_length );

/**
* \brief Complete the action of signing a hash or short
* message with a private key, in an interruptible
* manner.
*
* \see \c psa_sign_hash_start()
*
* \note This function combined with \c
* psa_sign_hash_start() is equivalent to
* \c psa_sign_hash() but it can return early and
* restart according to the limit set with \c
* psa_sign_interruptible_set_max_ops() to reduce
* blocking.
*
* \note Users should call this function on the same
* context with the same parameters until \c it
* either returns 0 or an error. This function
* will return #PSA_ERROR_IN_PROGRESS if there is
* more work to do.
*
* \param ctx The \c psa_sign_interruptible_context 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[in] 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_ERROR_IN_PROGRESS
* Operation was interrupted due to the setting of \c
* psa_sign_interruptible_set_max_ops(), there is still work to be done,
* please call this function again with the same parameters.
*
* \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_DATA_CORRUPT
* \retval #PSA_ERROR_DATA_INVALID
* \retval #PSA_ERROR_INSUFFICIENT_ENTROPY
* \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.
*/
int psa_sign_hash_complete( psa_sign_interruptible_context *ctx,
uint8_t *signature, size_t signature_size,
size_t *signature_len );

/**
* \brief Start reading and verifying a hash or short
* message, in an interruptible manner.
*
* \see \c psa_verify_hash_complete()
*
* \note This function combined with \c
* psa_verify_hash_complete() is equivalent to
* \c psa_verify_hash() but it can return early
* and restart according to the limit set with \c
* psa_sign_interruptible_set_max_ops() to reduce
* blocking.
*
* \note Users should call \c psa_verify_hash_complete()
* on the same context after a successful call to
* this function this until \c
* psa_verify_hash_complete() either returns 0 or
* an error. \c psa_verify_hash_complete() will
* return #PSA_ERROR_IN_PROGRESS if there is more
* work to do.
*
* \param ctx The \c psa_sign_interruptible_context 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_VERIFY_HASH.
* \param alg A signature algorithm (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 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() to complete the operation()
*
* \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_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.
*/
int psa_verify_hash_start( psa_sign_interruptible_context *ctx,
mbedtls_svc_key_id_t key,
psa_algorithm_t alg,
uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_length );

/**
* \brief 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()
*
* \note This function combined with \c
* psa_verify_hash_start() is equivalent to
* \c psa_verify_hash() but it can return early and
* restart according to the limit set with \c
* psa_sign_interruptible_set_max_ops() to reduce
* blocking.
*
* \note Users should call this function on the same
* context with the same parameters until \c it
* either returns 0 or an error. This function
* will return #PSA_ERROR_IN_PROGRESS if there is
* more work to do.
*
* \param ctx The \c psa_sign_interruptible_context 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_ERROR_IN_PROGRESS
* Operation was interrupted due to the setting of \c
* psa_sign_interruptible_set_max_ops(), there is still work to be done,
* please call this function again with the same parameters.
*
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_NOT_PERMITTED
* \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_INSUFFICIENT_ENTROPY
* \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.
*/
int psa_verify_hash_complete( psa_sign_interruptible_context *ctx );

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit dae46e1

Please sign in to comment.