-
Notifications
You must be signed in to change notification settings - Fork 97
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?
Changes from 3 commits
6669753
da79e92
3cb715b
ec1b1ba
341ab2c
d29bc2d
fa0b197
c3177d4
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 |
---|---|---|
|
@@ -348,7 +348,9 @@ static size_t psa_get_key_bits(const psa_key_attributes_t *attributes); | |
* you must call psa_reset_key_attributes() to free these resources. | ||
* | ||
* \param[in] handle Handle to the key to query. | ||
* \param[in,out] attributes On success, the attributes of the key. | ||
* \param[in,out] attributes On entry, this structure must be in a | ||
* valid state. | ||
* On success, the attributes of the key. | ||
* On failure, equivalent to a | ||
* freshly-initialized structure. | ||
* | ||
|
@@ -852,6 +854,135 @@ psa_status_t psa_export_public_key(psa_key_handle_t handle, | |
size_t data_size, | ||
size_t *data_length); | ||
|
||
/** | ||
* \brief Export a key and its metadata in wrapped form. | ||
* | ||
* A wrapped form of the key object preserves the confidentiality and | ||
* authenticity of the key material and the authenticity of the key | ||
* policy. In practical terms, the key material is encrypted, and | ||
* the key data and metadata are authenticated together. | ||
* | ||
* 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 | ||
* #PSA_KEY_USAGE_EXPORT_WRAPPED set. | ||
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. #PSA_KEY_USAGE_BACKUP for this API |
||
* | ||
* \param wrapping_key Handle to the key to wrap with. | ||
* \param handle Handle to the key to export in wrapped form. | ||
* \param[out] data Buffer where the wrapped key data is to be written. | ||
* \param data_size Size of the \p data buffer in bytes. | ||
* \param[out] data_length On success, the number of bytes | ||
* that make up the wrapped key data. | ||
* | ||
* \retval #PSA_SUCCESS | ||
* \retval #PSA_ERROR_INVALID_HANDLE | ||
* 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. | ||
* \retval #PSA_ERROR_INVALID_ARGUMENT | ||
* \p wrapping_key does not support wrapping keys with metadata. | ||
* \retval #PSA_ERROR_NOT_SUPPORTED | ||
* \p wrapping_key does not support wrapping the key designated | ||
* by \p handle. | ||
* \retval #PSA_ERROR_BUFFER_TOO_SMALL | ||
* The size of the \p data buffer is too small. You can determine a | ||
* sufficient buffer size by calling | ||
* #PSA_WRAP_KEY_WITH_POLICY_OUTPUT_SIZE(\c type, \c bits) | ||
* where \c type is the key type of \p handle | ||
* and \c bits is the key size of \p handle in bits. | ||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE | ||
* \retval #PSA_ERROR_HARDWARE_FAILURE | ||
* \retval #PSA_ERROR_CORRUPTION_DETECTED | ||
* \retval #PSA_ERROR_STORAGE_FAILURE | ||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY | ||
* \retval #PSA_ERROR_BAD_STATE | ||
* The library has not been previously initialized by psa_crypto_init(). | ||
* It is implementation-dependent whether a failure to initialize | ||
* results in this error code. | ||
*/ | ||
psa_status_t psa_wrap_key_with_policy(psa_key_handle_t wrapping_key, | ||
psa_key_handle_t handle, | ||
uint8_t *data, | ||
size_t data_size, | ||
size_t *data_length); | ||
|
||
/** | ||
* \brief Import a wrapped key with its metadata. | ||
* | ||
* This function supports any output from psa_wrap_key_with_policy(). | ||
* For symmetric wrapping, you must unwrap with the same key that was | ||
* used to wrap. For asymmetric wrapping where the wrapping operation uses | ||
* a public key and the unwrapping operation uses the corresponding private | ||
* key, you must unwrap with the corresponding unwrapping key. | ||
* | ||
* \param wrapping_key Handle to the key to unwrap with. | ||
* \param[in] attributes The attributes for the new key. | ||
* 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 wrapped key data. | ||
* - The key location (the lifetime and, for | ||
* persistent keys, the key identifier) is | ||
* used directly. | ||
* If the wrapped key does not have the usage | ||
* flag #PSA_KEY_USAGE_COPY, then the location | ||
* 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 commentThe reason will be displayed to describe this comment to others. Learn more. I believe that from this description the caller must set attributes -> location. Is there a reason why they should not be able to leave it unset and use the one in the wrapped key? 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. I'd prefer not to have “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 commentThe 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 commentThe 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:
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.
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.
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 commentThe 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.
This value is only valid in attributes passed to You could also support all of the above mechanisms:
For (1), it would be possible to just use 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. Instead of |
||
* - The policy constraints (usage flags and | ||
* algorithm policy) are combined from | ||
* the wrapped key data and \p attributes so that | ||
* both sets of restrictions apply. The | ||
* policy restrictions are calculated in the | ||
* same way as in psa_copy_key(). | ||
* \param[in] data Buffer containing the wrapped key material. | ||
* The expected format of this buffer depends | ||
* on the wrapping key. | ||
* \param data_length Size of the \p data buffer in bytes. | ||
* \param[out] handle On success, a handle to the newly created key. | ||
* \c 0 on failure. | ||
* | ||
* \retval #PSA_SUCCESS | ||
* Success. | ||
* If the unwrapped key is persistent, the key material and the | ||
* key's metadata have been saved to persistent storage. | ||
* \retval #PSA_ERROR_ALREADY_EXISTS | ||
* This is an attempt to create a persistent key, and there is | ||
* already a persistent key with the given identifier. | ||
* \retval #PSA_ERROR_INVALID_ARGUMENT | ||
* The key attributes, as a whole, are invalid. | ||
* \retval #PSA_ERROR_INVALID_ARGUMENT | ||
* The key data is not correctly formatted. | ||
* \retval #PSA_ERROR_INVALID_ARGUMENT | ||
* The size in \p attributes is nonzero and does not match the size | ||
* of the key data. | ||
* \retval #PSA_ERROR_INVALID_ARGUMENT | ||
* \p wrapping_key does not support unwrapping keys with metadata. | ||
* \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 | ||
* not supported. | ||
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY | ||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE | ||
* \retval #PSA_ERROR_COMMUNICATION_FAILURE | ||
* \retval #PSA_ERROR_STORAGE_FAILURE | ||
* \retval #PSA_ERROR_HARDWARE_FAILURE | ||
* \retval #PSA_ERROR_CORRUPTION_DETECTED | ||
* \retval #PSA_ERROR_BAD_STATE | ||
* The library has not been previously initialized by psa_crypto_init(). | ||
* It is implementation-dependent whether a failure to initialize | ||
* results in this error code. | ||
*/ | ||
psa_status_t psa_unwrap_key_with_policy(psa_key_handle_t wrapping_key, | ||
const psa_key_attributes_t *attributes, | ||
const uint8_t *data, | ||
size_t data_length, | ||
psa_key_handle_t *handle); | ||
|
||
|
||
|
||
/**@}*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1606,6 +1606,19 @@ | |
*/ | ||
#define PSA_KEY_USAGE_COPY ((psa_key_usage_t)0x00000002) | ||
|
||
/** Whether the key object may be saved outside the device in wrapped form. | ||
* This is also known as key binding. | ||
* | ||
* This flag allows the use of psa_wrap_key_with_policy() on the given key, | ||
* with any suitable wrapping key. | ||
* | ||
* A wrapped form of the key object preserves the confidentiality and | ||
* authenticity of the key material and the authenticity of the key | ||
* 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 commentThe reason will be displayed to describe this comment to others. Learn more. If we used
|
||
|
||
/** Whether the key may be used to encrypt a message. | ||
* | ||
* This flag allows the key to be used for a symmetric encryption operation, | ||
|
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?