Skip to content

Commit 281ab13

Browse files
committed
Added psa_import_formatted_key()
* Open issue regarding handling of encoded policy in key data
1 parent d79e4e9 commit 281ab13

File tree

2 files changed

+148
-14
lines changed

2 files changed

+148
-14
lines changed

doc/crypto/api/keys/management.rst

Lines changed: 143 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,11 @@ Implementations are permitted to define additional key formats and options.
180180
.. summary::
181181
The *OneAsymmetricKey* key format for RSA and elliptic curve key-pairs.
182182

183-
.. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead?
183+
.. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead?
184184

185-
Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo.
185+
Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo.
186186

187-
Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey?
187+
Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey?
188188

189189
OneAsymmetricKey is defined by :RFC-title:`5958#2`.
190190
OneAsymmetricKey is an update to the PKCS#8 *PrivateKeyInfo* format defined by :RFC-title:`5208`.
@@ -311,7 +311,7 @@ Key creation
311311

312312
New keys can be created in the following ways:
313313

314-
* `psa_import_key()` creates a key from a data buffer provided by the application.
314+
* `psa_import_key()` and `psa_import_formatted_key()` create a key from a data buffer provided by the application.
315315
* `psa_generate_key()` creates a key from randomly generated data.
316316
* `psa_key_derivation_output_key()` creates a key from data generated by a pseudorandom derivation process. See :secref:`kdf`.
317317
* `psa_key_agreement()` creates a key from the shared secret result of a key agreement process. See :secref:`key-agreement`.
@@ -359,9 +359,6 @@ When creating a key, the attributes for the new key are specified in a `psa_key_
359359
.. param:: const uint8_t * data
360360
Buffer containing the key data.
361361
The content of this buffer is interpreted according to the type declared in ``attributes``.
362-
363-
All implementations must support at least the format described in the *Key format* section of the chosen key type.
364-
Implementations can support other formats, but be conservative in interpreting the key data: it is recommended that implementations reject content if it might be erroneous, for example, if it is the wrong type or is truncated.
365362
.. param:: size_t data_length
366363
Size of the ``data`` buffer in bytes.
367364
.. param:: psa_key_id_t * key
@@ -400,17 +397,151 @@ When creating a key, the attributes for the new key are specified in a `psa_key_
400397

401398
The key is extracted from the provided ``data`` buffer. Its location, policy, and type are taken from ``attributes``.
402399

403-
The provided key data determines the key size. The attributes can optionally specify a key size; in this case it must match the size determined from the key data. A key size of ``0`` in ``attributes`` --- the default value --- indicates that the key size is solely determined by the key data.
404-
405-
Implementations must reject an attempt to import a key of size ``0``.
400+
The key data determines the key size. :code:``psa_get_key_bits(attributes)`` must either match the determined key size or be ``0``. Implementations must reject an attempt to import a key of size zero.
406401

407-
This function supports any output from `psa_export_key()`. Each key type in :secref:`key-types` describes the expected format of keys.
402+
This function supports any output from `psa_export_key()`.
403+
The default format is defined in the *Key format* section for each key type.
404+
Other key formats can be imported using `psa_import_formatted_key()`.
408405

409-
This specification defines a single format for each key type. Implementations can optionally support other formats in addition to the standard format. It is recommended that implementations that support other formats ensure that the formats are clearly unambiguous, to minimize the risk that an invalid input is accidentally interpreted according to a different format.
406+
Implementations can optionally support other formats in calls to `psa_import_key()`, in addition to the default format.
410407

411408
.. note::
412409
The |API| does not support asymmetric private key objects outside of a key pair. To import a private key, the ``attributes`` must specify the corresponding key pair type. Depending on the key type, either the import format contains the public key data or the implementation will reconstruct the public key from the private key as needed.
413410

411+
.. admonition:: Implementation note
412+
413+
It is recommended that implementations that support other formats ensure that the formats are clearly unambiguous, to minimize the risk that an invalid input is accidentally interpreted according to a different format.
414+
415+
It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated.
416+
417+
.. function:: psa_import_formatted_key
418+
419+
.. summary::
420+
Import a key in a specified format.
421+
* The key type can be `PSA_KEY_TYPE_NONE`. If either is nonzero, it must match the corresponding attribute of the source key.
422+
423+
.. param:: const psa_key_attributes_t * attributes
424+
The attributes for the new key.
425+
426+
Depending on the specified key format, and the attributes encoded in the key data, some of the key attributes can be optional.
427+
428+
The following attributes are required for formats that do not specify a key type:
429+
430+
* When the format does not specify a key type: the key type in ``attributes`` determines how the ``data`` buffer is interpreted.
431+
* When the format does specify a key type: if the key type in ``attributes`` has a non-default value, it must be equal to the determined key type.
432+
433+
The following attributes must be set for keys used in cryptographic operations:
434+
435+
* The key permitted-algorithm policy, see :secref:`permitted-algorithms`.
436+
* The key usage flags, see :secref:`key-usage-flags`.
437+
438+
These attributes are combined with any policy that is encoded in the key data, so that both sets of restrictions apply :issue:`(this needs further thought & discussion)`.
439+
440+
The following attributes must be set for keys that do not use the default volatile lifetime:
441+
442+
* The key lifetime, see :secref:`key-lifetimes`.
443+
* The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`.
444+
445+
The following attributes are optional:
446+
447+
* If the key size is nonzero, it must be equal to the key size determined from ``data``.
448+
449+
.. note::
450+
This is an input parameter: it is not updated with the final key attributes.
451+
The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier.
452+
.. param:: psa_key_format_t format
453+
The format of the key data.
454+
One of the ``PSA_KEY_FORMAT_XXX`` values, or an implementation-specific format.
455+
.. param:: const uint8_t * data
456+
Buffer containing the key data.
457+
The content of this buffer is interpreted according to the key format ``format``.
458+
The type declared in ``attributes`` is used if the format and key data do not specify a key type.
459+
.. param:: size_t data_length
460+
Size of the ``data`` buffer in bytes.
461+
.. param:: psa_key_id_t * key
462+
On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure.
463+
464+
.. return:: psa_status_t
465+
.. retval:: PSA_SUCCESS
466+
Success.
467+
If the key is persistent, the key material and the key's metadata have been saved to persistent storage.
468+
.. retval:: PSA_ERROR_ALREADY_EXISTS
469+
This is an attempt to create a persistent key, and there is already a persistent key with the given identifier.
470+
.. retval:: PSA_ERROR_NOT_SUPPORTED
471+
The following conditions can result in this error:
472+
473+
* The key format is not supported by the implementation.
474+
* The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location.
475+
.. retval:: PSA_ERROR_INVALID_ARGUMENT
476+
The following conditions can result in this error:
477+
478+
* The key type is invalid, or is `PSA_KEY_TYPE_NONE` when a type is required.
479+
* The key size is nonzero, and is incompatible with the key data in ``data``.
480+
* The key lifetime is invalid.
481+
* The key identifier is not valid for the key lifetime.
482+
* The key usage flags include invalid values.
483+
* The key's permitted-usage algorithm is invalid.
484+
* The key attributes, as a whole, are invalid.
485+
* The key format is invalid.
486+
* The key data is not correctly formatted for the key format or the key type.
487+
.. retval:: PSA_ERROR_NOT_PERMITTED
488+
The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy.
489+
.. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
490+
.. retval:: PSA_ERROR_INSUFFICIENT_STORAGE
491+
.. retval:: PSA_ERROR_COMMUNICATION_FAILURE
492+
.. retval:: PSA_ERROR_STORAGE_FAILURE
493+
.. retval:: PSA_ERROR_DATA_CORRUPT
494+
.. retval:: PSA_ERROR_DATA_INVALID
495+
.. retval:: PSA_ERROR_CORRUPTION_DETECTED
496+
.. retval:: PSA_ERROR_BAD_STATE
497+
The library requires initializing by a call to `psa_crypto_init()`.
498+
499+
The key is extracted from the provided ``data`` buffer, which is interpreted according to the specified key format. Its location is taken from ``attributes``, its type and policy are determined by the ``format``, the ``data``, and the ``attributes``.
500+
501+
If the format is `PSA_KEY_FORMAT_DEFAULT`, this is equivalent to call to `psa_import_key()`.
502+
503+
For non-default key formats, the key format either specifies the key type, or the formatted data encodes the key type.
504+
For example, `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` is always an RSA key pair, while the `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` format includes a data element that specifies whether it is an RSA or elliptic curve key-pair.
505+
If the key type is determined by the format and the data, then :code:``psa_get_key_type(attributes)`` must either match the determined key type or be `PSA_KEY_TYPE_NONE`.
506+
507+
The key data determines the key size.
508+
:code:``psa_get_key_bits(attributes)`` must either match the determined key size or be ``0``.
509+
Implementations must reject an attempt to import a key of size zero.
510+
511+
The resulting key can only be used in a way that conforms to both the policy included in the key data, and the policy specified in the ``attributes`` parameter :issue:`(the following is place-holder cut and paste from psa_copy_key())`:
512+
513+
* The usage flags on the resulting key are the bitwise-and of the usage flags on the source policy and the usage flags in ``attributes``.
514+
* If both permit the same algorithm or wildcard-based algorithm, the resulting key has the same permitted algorithm.
515+
* If either of the policies permits an algorithm and the other policy permits a wildcard-based permitted algorithm that includes this algorithm, the resulting key uses this permitted algorithm.
516+
* If the policies do not permit any algorithm in common, this function fails with the status :code:`PSA_ERROR_INVALID_ARGUMENT`.
517+
518+
As a result, the new key cannot be used for operations that were not permitted by the imported key data.
519+
520+
.. todo:: The proposed constraints on key policy are probably too strict.
521+
522+
* Most of the X.509 formats include a mandatory *AlgorithmIdentifier* element which does constrain the algorithm, *almost* well enough to match a |API| permitted algorithm encoding.
523+
* Many of the formats include an optional *KeyUsage* element that defines a set of permitted uses.
524+
These partially map onto |API| usage flags.
525+
526+
1. What to do if the format does not include a algorithm identifier?
527+
2. What to do if the algorithm identifier is too general for the algorithm encodings in |API|?
528+
3. If a *KeyUsage* is provided, do we take an intersection with the ``attributes`` usage flags? - what about when there is no 1:1 mapping?
529+
4. If a *KeyUsage* is **not** provided, do we just use the ``attributes`` usage flags?
530+
5. Are some |API| usage flags specific to the |API|, or to the application use of the key store. For example USAGE_EXPORT, USAGE_COPY, USAGE_CACHE?
531+
532+
Implementations can define implementation-specific formats that may have other behaviors relating to ``attributes``.
533+
534+
.. note::
535+
The |API| does not support asymmetric private key objects outside of a key pair.
536+
When importing a private key, the corresponding key-pair type is created.
537+
If the imported key data does not contain the public key, then the implementation will reconstruct the public key from the private key as needed.
538+
539+
.. admonition:: Implementation note
540+
541+
It is recommended that implementation-specific formats are clearly unambiguous, to minimize the risk that an invalid input is accidentally interpreted according to a different format.
542+
543+
It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated.
544+
414545
.. function:: psa_generate_key
415546

416547
.. summary::

doc/crypto/appendix/history.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ Changes to the API
2121

2222
* Added `PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE` to evaluate the export buffer size for any asymmetric key pair or public key.
2323

24-
* Added key data formats and formatting options for key export and import.
25-
See :secref:`key-formats`.
24+
* Added support for non-default key formats:
25+
26+
- Added definitions for key formats and and formatting options.
27+
See :secref:`key-formats`.
28+
- Added `psa_import_formatted_key()` to import keys in other formats.
2629

2730
Clarifications and fixes
2831
~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)