-
Notifications
You must be signed in to change notification settings - Fork 96
New function psa_hash_clone #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -921,6 +921,33 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, | |
*/ | ||
psa_status_t psa_hash_abort(psa_hash_operation_t *operation); | ||
|
||
/** Clone a hash operation. | ||
* | ||
* This function copies the state of an ongoing hash operation to | ||
* a new operation object. In other words, this function is equivalent | ||
* to calling psa_hash_setup() on \p target_operation with the same | ||
* algorithm that \p source_operation was set up for, then | ||
* psa_hash_update() on \p target_operation with the same input that | ||
* that was passed to \p source_operation. After this function returns, the | ||
* two objects are independent, i.e. subsequent calls involving one of | ||
* the objects do not affect the other object. | ||
* | ||
* \param[in] source_operation The active hash operation to clone. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be documented that this should be initialized and active. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't the current wording sufficent? Active implies initialized. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was an oversight on my side, because I was expecting the wording to be "The XXX. Must be YYY." instead of "The YYY XXX". I'd prefer the former, but that's not a blocker. |
||
* \param[in,out] target_operation The operation object to set up. | ||
* It must be initialized but not active. | ||
* | ||
* \retval #PSA_SUCCESS | ||
* \retval #PSA_ERROR_BAD_STATE | ||
* \p source_operation is not an active hash operation. | ||
* \retval #PSA_ERROR_BAD_STATE | ||
* \p target_operation is active. | ||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE | ||
* \retval #PSA_ERROR_HARDWARE_FAILURE | ||
* \retval #PSA_ERROR_TAMPERING_DETECTED | ||
*/ | ||
psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation, | ||
psa_hash_operation_t *target_operation); | ||
|
||
/**@}*/ | ||
|
||
/** \defgroup MAC Message authentication codes | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1924,6 +1924,92 @@ exit: | |
} | ||
/* END_CASE */ | ||
|
||
/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */ | ||
void hash_clone_source_state( ) | ||
{ | ||
psa_algorithm_t alg = PSA_ALG_SHA_256; | ||
unsigned char hash[PSA_HASH_MAX_SIZE]; | ||
psa_hash_operation_t op_source = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT; | ||
size_t hash_len; | ||
|
||
PSA_ASSERT( psa_crypto_init( ) ); | ||
PSA_ASSERT( psa_hash_setup( &op_source, alg ) ); | ||
|
||
PSA_ASSERT( psa_hash_setup( &op_setup, alg ) ); | ||
PSA_ASSERT( psa_hash_setup( &op_finished, alg ) ); | ||
PSA_ASSERT( psa_hash_finish( &op_finished, | ||
hash, sizeof( hash ), &hash_len ) ); | ||
PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) ); | ||
PSA_ASSERT( psa_hash_abort( &op_aborted ) ); | ||
|
||
TEST_EQUAL( psa_hash_clone( &op_source, &op_setup ), | ||
PSA_ERROR_BAD_STATE ); | ||
|
||
PSA_ASSERT( psa_hash_clone( &op_source, &op_init ) ); | ||
PSA_ASSERT( psa_hash_finish( &op_init, | ||
hash, sizeof( hash ), &hash_len ) ); | ||
PSA_ASSERT( psa_hash_clone( &op_source, &op_finished ) ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at this, I noticed that the documentation doesn't indicate the abstract state of a hash context after it has been terminated (through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't critical to understanding the current behavior, and other types of operation should use consistent terminology, so I'll do that in a later writing pass. Tracked internally at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. |
||
PSA_ASSERT( psa_hash_finish( &op_finished, | ||
hash, sizeof( hash ), &hash_len ) ); | ||
PSA_ASSERT( psa_hash_clone( &op_source, &op_aborted ) ); | ||
PSA_ASSERT( psa_hash_finish( &op_aborted, | ||
hash, sizeof( hash ), &hash_len ) ); | ||
|
||
exit: | ||
psa_hash_abort( &op_source ); | ||
psa_hash_abort( &op_init ); | ||
psa_hash_abort( &op_setup ); | ||
psa_hash_abort( &op_finished ); | ||
psa_hash_abort( &op_aborted ); | ||
mbedtls_psa_crypto_free( ); | ||
} | ||
/* END_CASE */ | ||
|
||
/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */ | ||
void hash_clone_target_state( ) | ||
{ | ||
psa_algorithm_t alg = PSA_ALG_SHA_256; | ||
unsigned char hash[PSA_HASH_MAX_SIZE]; | ||
psa_hash_operation_t op_init = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_setup = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_finished = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_aborted = PSA_HASH_OPERATION_INIT; | ||
psa_hash_operation_t op_target = PSA_HASH_OPERATION_INIT; | ||
size_t hash_len; | ||
|
||
PSA_ASSERT( psa_crypto_init( ) ); | ||
|
||
PSA_ASSERT( psa_hash_setup( &op_setup, alg ) ); | ||
PSA_ASSERT( psa_hash_setup( &op_finished, alg ) ); | ||
PSA_ASSERT( psa_hash_finish( &op_finished, | ||
hash, sizeof( hash ), &hash_len ) ); | ||
PSA_ASSERT( psa_hash_setup( &op_aborted, alg ) ); | ||
PSA_ASSERT( psa_hash_abort( &op_aborted ) ); | ||
|
||
PSA_ASSERT( psa_hash_clone( &op_setup, &op_target ) ); | ||
PSA_ASSERT( psa_hash_finish( &op_target, | ||
hash, sizeof( hash ), &hash_len ) ); | ||
|
||
TEST_EQUAL( psa_hash_clone( &op_init, &op_target ), PSA_ERROR_BAD_STATE ); | ||
TEST_EQUAL( psa_hash_clone( &op_finished, &op_target ), | ||
PSA_ERROR_BAD_STATE ); | ||
TEST_EQUAL( psa_hash_clone( &op_aborted, &op_target ), | ||
PSA_ERROR_BAD_STATE ); | ||
|
||
exit: | ||
psa_hash_abort( &op_target ); | ||
psa_hash_abort( &op_init ); | ||
psa_hash_abort( &op_setup ); | ||
psa_hash_abort( &op_finished ); | ||
psa_hash_abort( &op_aborted ); | ||
mbedtls_psa_crypto_free( ); | ||
} | ||
/* END_CASE */ | ||
|
||
/* BEGIN_CASE */ | ||
void mac_operation_init( ) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything else wouldn't make sense, but we might still mention here that the target context is active and in the same internal state as the source after a successful call to this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a paragraph of English text that defines the behavior of the function.