-
Notifications
You must be signed in to change notification settings - Fork 28
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
Add support for interruptible signature calculation and verification #107
base: main
Are you sure you want to change the base?
Conversation
Note also that the API naming is 'the best idea so far', and is not fixed until we issue the 1.2 specification. If you have suggestions for better/different names or terminology, please comment and let me know. |
Need to also add these functions to the list of APIs that require the SIGN and VERIFY usage flags in |
Provide interruptible operations for message and hash signature calculation and verification. Reworked information in this section of the API relating to the behavior of different types of signature algorithm, consolidating this to the section introduction.
38009f7
to
6443569
Compare
Rebased this PR, now that #177 has been merged. I have also reworked the introduction of Interruptible operations to the Functionality chapter, following the restructuring that was introduced by the addition of the PAKE operation. |
I've also attached a new PDF render (see the main PR description above) |
* Align permitted errors with the single-part functions * Introduce the max_ops APIs
Although we worked hard during API development to avoid having collisions in the first 31 characters of API identifiers (minimum requirement for a C99 implementation), we missed the collisions between However, the 31-significant character requirement is for 'external identifiers', and I am not sure that type names are considered to be 'external' rather than 'internal' (for which a 63 significant character requirement holds)? |
The identifier length maybe-problem comes back again, but harder with the additional interruptible operations required for #198. See my comment. |
The exact phrase “external identifier” isn't defined in C99 or C11, but “external name” is: “As discussed in 5.2.4.1, an implementation may limit the number of significant > |
Revisiting the naming of the API elements, after considering an interruptible API for key agreement use cases (#198). For those functions, there are no expected multi-part operations, so we dispense with However....It would be ideal if the naming patterns for multi-part and interruptible APIs were distinct, so that it is immediately apparent when reading code which of these types of API patterns is being used. To achieve that, it would be better to begin an interruptible operation with a function suffix like That would suggest that we rename the above APIs to So perhaps we could instead do Using Options
Place your votes, thoughts, or other suggestions below... |
That's the pattern I'd like: setup-update*-finish for data-driven multistep, start-complete for computation-driven multistep. I don't have a good idea to offer (yet?), but I would prefer a consistent abbreviation (even if it's non-obvious like Given the length constraint, we have to consider key derivation. Even though Mbed TLS doesn't need interruptible ECC derivation at the moment, the API should include it. I guess this is the starting point?
|
Hmmm. And that concept for key derivation suggests that the pattern for interruptible signature could be entirely different? It is not the operation that is interruptible, it is individual functions. . If the interruptible function is an operation function, then the interruptible state is a bit like an satellite object to the multi-part operation state. If we follow that idea, then we would end up with a rather different API for sign/verify message - but the sign/verify hash would almost exactly match the beta API in Mbed TLS. (Sorry @paul-elliott-arm - I know you're working on turning this current PR into code right now...). The simplest addition would be to provide an interruptible version of
However, this does not work for signature algorithms that require complex computation with the key prior to digesting the message, and the Crypto API design does not permit an implementation to refer to application memory buffers outside of the call that supplies the buffer (i.e. So, better would be for interruptible sign/verify message to be additional functions (and interruptible state objects) for the suggested multi-part sign/verify-message API from #98. Something like this:
If this approach is used, then:
But, there are more state objects, and interruptible message signing involves three state objects, making the application code somewhat more complex. |
I actually quite like the simplicity of this approach. Given the various stages for sign/verify message are basically going to be compulsary, do we necessarily have to have seperate state objects? I presume we would be adding these new message interfaces, but would return |
My assumption is that the footprint of a multi-part sign-message operation object is significantly smaller than that of an interruptible sign-message operation - so having the interruptible state in a separate object is valuable for implementations or application that do not support or use the interruptibile interfaces. Keeping the interruptible sign-hash separate from the interruptible sign-message is probably valuable for the same reason - interruptible sign-hash does not need to store the hash internal state at any point. If these assumptions are not, in fact, correct, because the signature computation state is of a similar size to the internal hash state (only one is required at any one time), then we could consider collapsing all of the 'sign' objects back into a single type. But instead of reverting to the API in the current PR content, we include the multi-part sign message operation functionality so that there is no need to distinguish the multi-part operation functions from the interruptible multi-part operation functions. |
However, this would again make the interruptible signature API different in pattern to the other interruptible interfaces. How much is it worth being able to code the use of an interruptible version of an API without having to double check the state object name, or function names, because the pattern is always the same? Once there is a single exception, then a developer can never be sure unless they learn every instance (or consult the docs). |
That assumption is very likely false if you're talking total memory consumption: the intermediate state of an ECC calculation is likely to be significantly larger than the intermediate state of a hash calculation. Note that I'm referring to the total memory consumption: in Mbed TLS, |
I would prefer to have a consistent infix in function names, just so that people who aren't interested in the functionality (which is most users) can ignore it in a function index. In today's call, we suggested
|
Even a short infix like |
so, the sort of agreed parts would look like this:
|
Use psa_kdf_iop_* for key derivation or psa_derive_key_iop_* for key derivation. remove operation from structs. Instead of Use new key agreement operation (pass in key attributes, key and buffer containing public key, outputs key) not raw. |
I am admittedly presuming here that we are using pure key agreement here, not chained with a derivation as the new interface seems to do. |
Yes, chaining is easy to do with an output key - just use that as the input key for the kdf. |
I think we should remove |
For key agreement, the
So perhaps:
However, I can't quite decide if maybe the key attributes could be passed in to |
Doh, yes, I agree, copypasta'd myself. |
* Operation objects are now psa_xxx_iop_t, initialization PSA_XXX_IOP_INIT etc. * Operation and support functions use 'iop' as an infix instead of 'interruptible'
Require that one of psa_xxx_iop_hash() or psa_xxx_iop_update() MUST be called in an interruptible signature operation.
I've updated the PR with the revised naming scheme, and tidied up a couple of loose ends. This might be just about ready? I note that the introduction of the simpler interruptible operations (see#198) for key generation, key export, and key agreement suggests that the current overview of interruptible operations (in the Functionality chapter) portrays the worst-case complexity of interruptible signature. I think it would be better to use the simpler iops to demonstrate the pattern, and indicate how more complex operations can use the setup/complete pattern multiple times? |
I am happy to address that in a separate PR with the additional interruptible APIs, rather than extend/prolong this already-substantial PR. |
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 fine to me.
Add a new class of 'interruptible operation' to the API. These allow complex calculations to be broken into smaller steps, e.g. for asymmetric signature algorithms, to enable bounded latency operation of the API in constrained execution environments.
Operations for interruptible signature and interruptible verification have been introduced. These pick up the main concepts from the experimental interruptible hash signature and verification API added to mbedtls, but adapt the API to also support message signature functionality.
In the process of adding the API, I have reworked much of the material relating to different algorithm behaviors (hash-and-sign, message-signature and specialized algorithms). There is no quick way to reverse engineer a 'nice' set of commits for the many changes and additions to §10.7, so the PR is presented pretty much 'all in one go'.
If it is easier to read the end result than the diff, Asymmetric signature is on page 256 in this draft PDF: IHI0086-PSA_Certified_Crypto_API-1.3.0-interruptible-signature-draft2.pdf
The previous drafts:* IHI0086-PSA_Certified_Crypto_API-1.2.0-draft-interruptible-api.pdf.* IHI0086-PSA_Certified_Crypto_API-1.3.0-interruptible-signature-draft.pdf.The remaining todos have now been resolved.
Some of the rationale behind the design and naming of the API is written up in #98.
Fixes #23