-
Notifications
You must be signed in to change notification settings - Fork 98
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
Key wrapping API proposal #364
base: development
Are you sure you want to change the base?
Key wrapping API proposal #364
Conversation
This was implicitly conveyed by the general requirement of initializing attribute structure and by declaring \p attributes to be an in-out parameter, but it is better to make this explicit.
include/psa/crypto.h
Outdated
* They are used as follows: | ||
* - The key type and size may be 0. If either is | ||
* nonzero, it must match the corresponding | ||
* attribute of the source key. |
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.
You have used both source key and \p data which I believe both refer to the key to unwrap.
I would prefer consistency as it is quite hard to understand.
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.
fixed
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.
Thanks
include/psa/crypto.h
Outdated
* must match the location embedded in \p data. | ||
* If the wrapped key has the usage | ||
* flag #PSA_KEY_USAGE_COPY, then the location | ||
* embedded in \p data is ignored. |
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 believe that from this description the caller must set attributes -> location.
So the caller needs to call psa_get_wrapped_key_attributes
Is there a reason why they should not be able to leave it unset and use the one in the wrapped key?
And potentiall not offer psa_get_wrapped_key_attributes?
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'd prefer not to have psa_get_wrapped_key_attributes
, but I added it because I couldn't find a better way.
“Leave unset” works for the key type and the key size because for those 0 is not a valid value, so it's interpreted as unset. But for lifetimes, 0 is a valid value, indicating a volatile key: keys are volatile by default, you only need to specify a lifetime explicitly if you want the key to live longer. If a wrapped key is non-copyable and persistent, attempting to unwrap it as volatile should fail.
Likewise, for the policy, 0 means “you can't do anything”. That's not the same thing as “use whatever is in the wrapped data”.
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.
Ok - good answer.
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.
Good use cases. How about one or moe of these options as alternatives:
- Permit
attributes == NULL
- this indicates that the key should be unwrapped exactly as it was wrapped. No override attributes. - Define a special lifetime value to mean
ANY
- i.e. "as wrapped" - Permit usage flags of MAX_UINT32 - and rely on the 'constrain to wrapped key policy' behaviour to replicate the wrapped key usage flags in the unwrapped key.
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.
Permit attributes == NULL
Doesn't help if you want to use the wrapped policy but specify a different lifetime or id, which I think is a very common use case.
Permit usage flags of MAX_UINT32
That does in fact work for the usage flags, but not for the algorithm. It could be added as a feature for the algorithm.
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 second bullet implies that we define (within the new structured framework) a special lifetime value, e.g.
#define PSA_KEY_LIFETIME_UNSPECIFIED ((psa_key_lifetime_t) 0x0000007f)
This value is only valid in attributes passed to psa_unwrap_key_with_policy()
to indicate that the key should be unwrapped into the same lifetime that it was wrapped from.
You could also support all of the above mechanisms:
- If you want to restore a backed up key, just pass
attributes = NULL
. (Volatile keys might have a different key handle/id after unwrapping) - If you want to move the key then initialise the attributes, set the wildcard usage flags (
PSA_KEY_USAGE_UNSPECIFIED
- all bits 1, not all known bits one: only valid for unwrapping/copying), and set the lifetime/id for the desired location - If you you want to limit the policy, but maintain the lifetime, then initialise the attributes, set the usage flags, and set the lifetime to
PSA_KEY_LIFETIME_UNSPECIFIED
(only valid for unwrap).
For (1), it would be possible to just use UNSPECIFIED
for both the usage flags and the lifetime, but I suspect that the compact attributes = NULL
form might be a common usage?
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.
Instead of *_UNSPECIFIED
, other terms could be *_AS_SOURCE
or *_ORIGINAL
.
include/psa/crypto.h
Outdated
* &handle) | ||
* psa_reset_key_attributes(&attributes); | ||
* \endcode | ||
* |
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.
Is it worth adding a line checking if the copy permission is set.
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.
Why would the calling code check the copy permission? I'd expect typical application code to either expect a copyable key and specify a location here, or not expect a copyable key and not specify the location. Neither case calls for checking the copy permission in the application code.
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.
Yes you are probably right for IOT.
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.
Apporved follwing discussion with giles
* is used. If this key exists, it must be private to the device, i.e. it | ||
* must not be shared with any other device or entity. | ||
*/ | ||
#define PSA_KEY_ID_WRAP_BOUND ((psa_app_key_id_t)0x80000062) |
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.
Is there any particular significance to the value chosen? - why MIN_UINT32 + 0x62?
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.
Not enamoured with the name, as we haven't used "bound" anywhere else in the API or documentation. Is PSA_KEY_ID_WRAP_BUILT_IN
any better, or worse?
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.
0x80000000 is the start of the range reserved for ids defined by PSA.
0x80000000 + 'b'
(for “bound”) because why not.
I'm very open to naming suggestions. Once a few people have made theirs I'll do a pass of renaming stuff with an eye to consistency and the other eye to comprehensibility.
Do we also need a usage flag for WRAP and UNWRAP, as well as the defined flags for a key being exporting in wrapped form? Keys used as wrapping keys in |
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.
A few corrections and comments
* One or both of \p handle and \p wrapping_key is not a valid | ||
* handle to a key. | ||
* \retval #PSA_ERROR_NOT_PERMITTED | ||
* The key \p handle does not have the #PSA_KEY_USAGE_BACKUP flag. |
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.
copy-pasta: presume PSA_KEY_USAGE_EXPORT_WRAPPED
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.
This issue is still present.
include/psa/crypto.h
Outdated
* \retval #PSA_ERROR_INVALID_SIGNATURE | ||
* \p data is not a valid wrapped key for \p wrapping_key. | ||
* \retval #PSA_ERROR_NOT_SUPPORTED | ||
* Some of the metadata in either \p attributes or \p data is |
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.
There is no metadata in data
for this API.
include/psa/crypto_values.h
Outdated
* described in SP 800-38F, but replacing uses of AES with the 128-bit | ||
* block cipher that the key is for. | ||
*/ | ||
#define PSA_ALG_NIST_KW ((psa_algorithm_t)0x0a401003) |
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.
This does not satisfy PSA_ALG_IS_KEY_WRAP()
- the category should be 0x0e000000
?
include/psa/crypto_values.h
Outdated
* described in SP 800-38F, but replacing uses of AES with the 128-bit | ||
* block cipher that the key is for. | ||
*/ | ||
#define PSA_ALG_NIST_KWP ((psa_algorithm_t)0x0a401005) |
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.
This does not satisfy PSA_ALG_IS_KEY_WRAP()
- the category should be 0x0e000000
?
* is used. If this key exists, it must be private to the device, i.e. it | ||
* must not be shared with any other device or entity. | ||
*/ | ||
#define PSA_KEY_ID_WRAP_BOUND ((psa_app_key_id_t)0x80000062) |
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.
Not enamoured with the name, as we haven't used "bound" anywhere else in the API or documentation. Is PSA_KEY_ID_WRAP_BUILT_IN
any better, or worse?
* policy. In practical terms, the key material is encrypted, and | ||
* the key data and metadata are authenticated together. | ||
*/ | ||
#define PSA_KEY_USAGE_BACKUP ((psa_key_usage_t)0x00000020) |
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 we used PSA_KEY_ID_WRAP_BOUND
then I would be inclined to make this PSA_KEY_USAGE_EXPORT_BOUND
or perhaps PSA_KEY_USAGE_WRAP_BOUND
.
BACKUP
is quite cute, but then we should use 'backup' in the wrap-with-policy API name and the built-in wrap-with-policy binding key to strengthen the association of these API elements.
Declare functions to wrap and unwrap a key together with its metadata, in an unspecified vendor-specific format but with an explicitly specified key. Declare a corresponding usage flag.
Declare a key binding key that implementations are encouraged to provide.
Declare functions to wrap and unwrap key material in standard formats. Declare an algorithm category for key wrapping. Declare a corresponding usage flag.
Using attributes with psa_key_unwrap_with_policy() is inconvenient. When unwrapping a key to its original location (a straightforward restore from backup), there's no reason to specify any attributes. When unwrapping a key in a different location and possibly restricting its policy, the new attributes are generally a refinement of the old ones. Remove the attributes argument from psa_key_unwrap_with_policy() and provide another function to unwrap to a volatile location. The application can then use existing functions to manipulate the key, including psa_get_key_attributes() and psa_copy_key().
8d63d5d
to
c3177d4
Compare
@MarcusJGStreets @athoelke I pushed an update with a rewritten history that should resolve all your comments and cover what we discussed orally today, other than the naming. The original version is in https://github.com/gilles-peskine-arm/mbed-crypto/tree/psa-wrap-api-1
I'll subsequently make another update to fix the terminology issues (which includes finding a decent name for |
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.
Still some oopses in the usage flag association with the APIs.
* The format of the wrapped data is implementation-dependent. It may depend | ||
* both on the choice of wrapping key and on the type of key to wrap. | ||
* | ||
* The policy on the key must have the usage flag |
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.
Need to specify which key needs this policy?
* both on the choice of wrapping key and on the type of key to wrap. | ||
* | ||
* The policy on the key must have the usage flag | ||
* #PSA_KEY_USAGE_EXPORT_WRAPPED set. |
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_KEY_USAGE_BACKUP for this API
* One or both of \p handle and \p wrapping_key is not a valid | ||
* handle to a key. | ||
* \retval #PSA_ERROR_NOT_PERMITTED | ||
* The key \p handle does not have the #PSA_KEY_USAGE_BACKUP flag. |
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.
This issue is still present.
Hi @gilles-peskine-arm - thanks for the update.
The usage flag naming gets interesting now that we have "can be wrapped" and "can use to wrap" policy flags. It is clear there are two categories of flags:
I wonder now if we should have named these categories of flag separately to make it easier to distinguish can-wrap-with from can-be-wrapped. |
This is a first draft of the key wrapping API for PSA Cryptography 1.x.
This pull request only provides function prototypes and associated macro definitions. Tests and implementations will come later.
I implemented the proposal discussed in private. I'm not attached to function/macro names if you have better suggestions. The API comprises: