Skip to content

Commit

Permalink
First draft of PSA interruptable 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 13, 2022
1 parent 52f83dc commit e3295ff
Showing 1 changed file with 327 additions and 2 deletions.
329 changes: 327 additions & 2 deletions include/psa/crypto_extra.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ psa_status_t mbedtls_psa_inject_entropy(const uint8_t *seed,
*/
#define PSA_KEY_TYPE_DSA_KEY_PAIR ((psa_key_type_t)0x7002)

/** Whether a key type is a DSA key (pair or public-only). */
/** Whether a key type is an DSA key (pair or public-only). */
#define PSA_KEY_TYPE_IS_DSA(type) \
(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type) == PSA_KEY_TYPE_DSA_PUBLIC_KEY)

Expand Down Expand Up @@ -1287,7 +1287,7 @@ static void psa_pake_cs_set_hash( psa_pake_cipher_suite_t *cipher_suite,
* Implementation details can change in future versions without notice. */
typedef struct psa_pake_operation_s psa_pake_operation_t;

/** Return an initial value for a PAKE operation object.
/** Return an initial value for an PAKE operation object.
*/
static psa_pake_operation_t psa_pake_operation_init( void );

Expand Down Expand Up @@ -1901,6 +1901,331 @@ 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
{
unsigned 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.
*
* 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.
*
* 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. Lower (non-zero) values mean signature
* functions will block for a lesser 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 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 this 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,
const unsigned char *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,
unsigned char *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,
const unsigned char *hash,
size_t hash_length,
const unsigned char *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 );

/**
* \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 );

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit e3295ff

Please sign in to comment.