-
Notifications
You must be signed in to change notification settings - Fork 96
Disallow use of invalid contexts #58
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
Disallow use of invalid contexts #58
Conversation
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.
- The implementation needs a design discussion about how to cope with bad-state errors. We have an unresolved question about the API spec at https://github.com/ARMmbed/psa-crypto/issues/45 (private link).
- The tests don't cover all the cases that I'd expect. They're missing some bad-state cases for MAC and cipher.
- Some of the tests need restructuring.
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.
Looks ok to me besides the comments already made by Gilles. Are there any additional dependencies that need to be updated (e.g. example repo , usage by tls, etc..)?
Rebasing to address review feedback, extend tests, and fix #10. |
0b2f1f2
to
5d0a2d3
Compare
Rebased. Previous branch at https://github.com/Patater/mbed-crypto/tree/disallow-invalid-context-1 |
I'm looking into some memory leaks. In general, if you start a cipher operation, and some internal memory is allocated on your behalf (e.g. AES context created), and then you call finish twice and get a |
wouldn't the first call to finish de-allocate the resources? |
That's not true. All bets are off if you have a bad state because the object was corrupted or never initialized. But if you've correctly initialized the object and subsequently only ever modified it through API functions, then abort is guaranteed to succeed. |
@NirSonnenschein Yes, it likely would. Good point. I'll change my example. How about if you call cipher finish without first setting an IV? Finish would fail with |
Thanks for the clarification, Gilles. I'll switch from using memset to all 0 between bad order tests and use abort instead. Also note that one isn't guaranteed to get BAD_STATE if the context is corrupt or never initialized, so I'm not sure why we should be concerned, as per your comment: #58 (comment), about calling abort if BAD_STATE is encountered in these sorts of "well-formed" situations. Can we conclude that it is OK to call abort on BAD_STATE? Are there cases we shouldn't call abort given we've gotten a BAD_STATE? |
#58 (comment) was about calling abort internally, not about calling it from the application. I distinguished two cases: well-formed situations, where it's debatable whether the right behavior is to abort or to not modify the object, and non-well-formed situations, where abort could make things worse. In application code, you should always initialize your memory, and you should always call abort unless you have a guarantee that the object is in its initial state (e.g. because you never set it up or the last function that you applied to it was a finish function). |
Rebase incoming to switch from memset to abort between bad order tests. |
5d0a2d3
to
1128d08
Compare
Rebased. Previous branch at https://github.com/Patater/mbed-crypto/tree/disallow-invalid-context-3 |
Forgot to apply a fixup commit. Rebasing again. |
1128d08
to
ace8e02
Compare
Rebased to apply fixup commit. Previous branch at https://github.com/Patater/mbed-crypto/tree/disallow-invalid-context-4 |
All done rebasing. Ready to review. |
Added commits to address #58 (comment) Will apply as fixup with a rebase if review goes well |
This is getting a bit too messy. I'm going to have to rebase before review. |
fbea691
to
53d9509
Compare
Rebased to apply fixups and make some style improvements. Previous branch at https://github.com/Patater/mbed-crypto/tree/disallow-invalid-context-5 |
Rebasing done. |
Will rebase to apply fixup commit now |
2cad8f1
to
ff9d2bc
Compare
CI passed. Ready for review. |
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.
psa_mac_update
is not consistent with the other update/finish functions wrt an argument in initial state: it calls abort. This is not an absolute blocker because we still haven't decided what behavior the specification will mandate, but I'd prefer the implementation to be consistent.
PSA_ERROR_BAD_STATE ); | ||
PSA_ASSERT( psa_hash_abort( &operation ) ); | ||
|
||
/* Call update without calling setup beforehand. */ |
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.
Technically, you're calling update after abort. This is equivalent to update without setup only if abort behaves correctly.
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.
Would you recommend we call both abort and memset the context to 0? I'm depending on abort setting the context to 0, and if it doesn't, the test will fail.
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.
If abort works properly, it doesn't matter. It's only a matter of how hard it will be to investigate a test failure that is ultimately due to abort returning the expected status but not having done its job properly.
I would prefer to make each unit test independent. But it's also good to have a stress test where a single object is reused.
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've raised #66 to add targeted abort tests.
Ensure that when doing MAC operations out of order, PSA_ERROR_BAD_STATE is returned as documented in crypto.h and the PSA Crypto specification.
Ensure that when doing cipher operations out of order, PSA_ERROR_BAD_STATE is returned as documented in crypto.h and the PSA Crypto specification.
If a hash context has not been set up, fail with PSA_ERROR_BAD_STATE as documented in crypto.h and the PSA Crypto specification.
Extend hash bad order test in line with the new bad order tests for MAC and cipher, covering more cases and making comments and test layout consistent. Ensure that when doing hash operations out of order, PSA_ERROR_BAD_STATE is returned as documented in crypto.h and the PSA Crypto specification.
Calling psa_*_setup() twice on a MAC, cipher, or hash context should result in a PSA_ERROR_BAD_STATE error because the operation has already been set up. Fixes ARMmbed#10
Rebasing to address review feedback. |
0cbb8c7
to
36ee5d0
Compare
Rebased. Previous branch at https://github.com/Patater/mbed-crypto/tree/disallow-invalid-context-9 |
In places where we detect a context is in a bad state and there is no sensitive data to clear, simply return PSA_ERROR_BAD_STATE and don't abort on behalf of the application. The application will choose what to do when it gets a bad state error. The motivation for this change is that an application should decide what to do when it misuses the API and encounters a PSA_ERROR_BAD_STATE error. The library should not attempt to abort on behalf of the application, as that may not be the correct thing to do in all circumstances.
ee32d9f
to
e236c2a
Compare
Rebased to add a commit that returns bad state without aborting in more cases. Previous branch at https://github.com/Patater/mbed-crypto/tree/disallow-invalid-context-12 |
@@ -6529,7 +6529,7 @@ static void ssl_calc_finished_tls_sha256( | |||
unsigned char padbuf[32]; | |||
#if defined(MBEDTLS_USE_PSA_CRYPTO) | |||
size_t hash_size; | |||
psa_hash_operation_t sha256_psa; | |||
psa_hash_operation_t sha256_psa = PSA_HASH_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.
Using PSA_HASH_OPERATION_INIT
, psa_hash_operation_init();
or simply = 0
are all valid ways to do initialisation, right?
What are the advantages of different methods? In particular, why are we using on line 1449 and 1492 psa_hash_operation_init();
and PSA_HASH_OPERATION_INIT
here?
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.
{0}
and INIT
(macro) can be used to initialize global variables, but init()
(function) can't. {0}
is generic but some compilers warn that this implicitly initializes other fields to 0. init()
is the only one that's typed, so you'll get an error if you use it in the wrong context. memset
to 0 is also defined as equivalent because it allows applications to use e.g. calloc
, and in practice it produces the same value as {0}
on virtually all platforms.
In most cases, the choice is indifferent.
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.
PSA_HASH_OPERATION_INIT
is all static, so you can use it for static globals. The inline function can be used where functions can be used, which is a few less places, but it uses the static initializer under-the-hood. = {0}
is usually ok, but some compilers will complain about missing field initializers.
I personally prefer using the macro everywhere, but previous authors inside library/ssl_tls.c liked the function. There is no functional difference in this case.
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.
Looks good to me!
CI failure is only FreeBSD timing test, a known-flaky test. |
Disallow use of MAC, hash, and cipher contexts that haven't been set up (i.e. has a
*_setup()
function called on them).