diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 0998a498d..c833d7220 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -817,6 +817,144 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation); /**@}*/ +/** \defgroup aead Authenticated encryption with associated data (AEAD) + * @{ + */ + +/** The type of the state data structure for multipart AEAD operations. + * + * This is an implementation-defined \c struct. Applications should not + * make any assumptions about the content of this structure except + * as directed by the documentation of a specific implementation. */ +typedef struct psa_aead_operation_s psa_aead_operation_t; + +/** Set the key for a multipart authenticated encryption operation. + * + * The sequence of operations to authenticate-and-encrypt a message + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Call psa_aead_encrypt_setup() to specify the algorithm and key. + * The key remains associated with the operation even if the content + * of the key slot changes. + * -# Call either psa_aead_generate_iv() or psa_aead_set_iv() to + * generate or set the IV (initialization vector). You should use + * psa_encrypt_generate_iv() unless the protocol you are implementing + * requires a specific IV value. + * -# Call psa_aead_update_ad() to pass the associated data that is + * to be authenticated but not encrypted. You may omit this step if + * there is no associated data. + * -# Call psa_aead_update() zero, one or more times, passing a fragment + * of the data to encrypt each time. + * -# Call psa_aead_finish(). + * + * The application may call psa_aead_abort() at any time after the operation + * has been initialized with psa_aead_encrypt_setup(). + * + * After a successful call to psa_aead_setup(), the application must + * eventually destroy the operation through one of the following means: + * - A failed call to psa_aead_generate_iv(), psa_aead_set_iv(), + * psa_aead_update_ad() or psa_aead_update(). + * - A call to psa_aead_final() or psa_aead_abort(). + * + * \param operation + * \param alg The AEAD algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_AEAD(alg) is true). + * + * \retval PSA_SUCCESS + * Success. + * \retval PSA_ERROR_EMPTY_SLOT + * \retval PSA_ERROR_NOT_PERMITTED + * \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 an AEAD algorithm. + * \retval PSA_ERROR_INSUFFICIENT_MEMORY + * \retval PSA_ERROR_COMMUNICATION_FAILURE + * \retval PSA_ERROR_HARDWARE_FAILURE + * \retval PSA_ERROR_TAMPERING_DETECTED + */ +psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation, + psa_key_slot_t key, + psa_algorithm_t alg); + +/** Set the key for a multipart authenticated decryption operation. + * + * The sequence of operations to authenticated and decrypt a message + * is as follows: + * -# Allocate an operation object which will be passed to all the functions + * listed here. + * -# Call psa_aead_decrypt_setup() to specify the algorithm and key. + * The key remains associated with the operation even if the content + * of the key slot changes. + * -# Call psa_aead_set_iv() to pass the initialization vector (IV) + * for the authenticated decryption. + * -# Call psa_aead_update_ad() to pass the associated data that is + * to be authenticated but not encrypted. You may omit this step if + * there is no associated data. + * -# Call psa_aead_update() zero, one or more times, passing a fragment + * of the data to decrypt each time. + * -# Call psa_aead_finish(). + * + * The application may call psa_aead_abort() at any time after the operation + * has been initialized with psa_aead_decrypt_setup(). + * + * After a successful call to psa_decrypt_setup(), the application must + * eventually destroy the operation through one of the following means: + * - A failed call to psa_aead_update(). + * - A call to psa_cipher_final() or psa_cipher_abort(). + * + * \param operation + * \param alg The cipher algorithm to compute (\c PSA_ALG_XXX value + * such that #PSA_ALG_IS_CIPHER(alg) is true). + * + * \retval PSA_SUCCESS + * Success. + * \retval PSA_ERROR_EMPTY_SLOT + * \retval PSA_ERROR_NOT_PERMITTED + * \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 cipher algorithm. + * \retval PSA_ERROR_INSUFFICIENT_MEMORY + * \retval PSA_ERROR_COMMUNICATION_FAILURE + * \retval PSA_ERROR_HARDWARE_FAILURE + * \retval PSA_ERROR_TAMPERING_DETECTED + */ +psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation, + psa_key_slot_t key, + psa_algorithm_t alg); + +psa_status_t psa_aead_generate_iv(psa_aead_operation_t *operation, + unsigned char *iv, + size_t iv_size, + size_t *iv_length); + +psa_status_t psa_aead_set_iv(psa_aead_operation_t *operation, + const unsigned char *iv, + size_t iv_length); + +psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation, + const uint8_t *input, + size_t input_length); + +psa_status_t psa_aead_update(psa_aead_operation_t *operation, + const uint8_t *input, + size_t input_length); + +psa_status_t psa_aead_finish(psa_aead_operation_t *operation, + uint8_t *tag, + size_t tag_size, + size_t *tag_length); + +psa_status_t psa_aead_verify(psa_aead_operation_t *operation, + uint8_t *tag, + size_t tag_length); + +psa_status_t psa_aead_abort(psa_aead_operation_t *operation); + +/**@}*/ + /** \defgroup asymmetric Asymmetric cryptography * @{ */ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index ffa835e15..9e70512d7 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -105,4 +105,17 @@ struct psa_cipher_operation_s } ctx; }; +struct psa_aead_operation_s +{ + psa_algorithm_t alg; + int key_set : 1; + int iv_set : 1; + int ad_set : 1; + uint8_t iv_size; + uint8_t block_size; + union + { + } ctx; +}; + #endif /* PSA_CRYPTO_STRUCT_H */