From 279d28fb8780534ef8e8f5cfaa20e9b178b1e58e Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Mon, 5 Aug 2024 18:04:10 +0100 Subject: [PATCH 01/10] First attempt to define key formats and options --- doc/crypto/api/keys/management.rst | 301 +++++++++++++++++++++++++++++ doc/crypto/api/keys/types.rst | 4 +- doc/crypto/api/ops/signature.rst | 2 +- doc/crypto/appendix/history.rst | 3 + doc/crypto/terms | 10 + 5 files changed, 317 insertions(+), 3 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index b6a7391c..cdaf8614 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -7,6 +7,307 @@ Key management functions ======================== +.. _key-data-formats: + +Key data formats +---------------- + +Outside of the key store, keys are exchanged using defined data formats. +These formats are used to import and export keys, or to input public asymmetric keys to key agreement or PAKE operations. + +The |API| defines the default data format for each standard key types, to be used for these operations. +These data formats are defined in the *Key format* section of each key type in :secref:`key-types`. + +Some application use cases require key data to be in other standard formats. +:code:`psa_import_formatted_key()` and :code:`psa_export_formatted_key()` allow data in these formats to be used directly with the |API|. + +Some key data formats have options for how the key data is represented. +For example, + +* Data layouts used in X.509 certificates, such as RSAPublicKey, can be encoded using ASCII-based PEM or binary DER. +* Elliptic curve keys can be specified using a curve identifier and the key value, or by providing for full set of curve parameters and the key value. +* Elliptic curve public keys can use a compressed or uncompressed representation for the point on the curve. + +These options need to be specified by the application, or a default used, when formatting key data for export. +When importing a key, the formatted data includes information that indicates the formatting options, so the options do not need to be provided by the application. + +The |API| defines elements for some common key data formats and format options. +Implementations are permitted to define additional key data formats and options. + +.. typedef:: uint32_t psa_key_data_format_t + + .. summary:: + Encoding of a key data format. + + Key data formats are specified in the |API| using values of this type. + + `PSA_KEY_FORMAT_DEFAULT` (value ``0``) indicates the default data format for the key type. + +.. macro:: PSA_KEY_FORMAT_DEFAULT + :definition: ((psa_key_data_format_t) 0) + + .. summary:: + Key data format value indicating the default data format. + + The default data formats are specified for each key type in the :secref:`key-types` chapter. + + .. todo:: Non-default options with default key data format? + + Determine if it is permitted to specify non-default options when requesting the default format. + +.. macro:: PSA_KEY_FORMAT_RSA_PUBLIC_KEY + :definition: /* implementation-defined value */ + + .. summary:: + The *RSAPublicKey* key data format for RSA public keys. + + This is the default key data format for RSA public keys. + + .. todo:: Provide normative reference for RSAPublicKey, in RFC 8017 + + .. subsection:: Compatible key types + + * `PSA_KEY_TYPE_RSA_KEY_PAIR` (public key) + * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` + + .. subsection:: Key data format options + + * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) + * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + +.. macro:: PSA_KEY_FORMAT_EC_POINT + :definition: /* implementation-defined value */ + + .. summary:: + The *ECPoint* key data format for Weierstrass elliptic curve public keys. + + This is the default key data format for Weierstrass elliptic curve public keys. + + .. todo:: Provide normative reference for ECPoint, in SEC1 + + .. todo:: What about Edwards and Montgomery curves? + + Do we need another format for X25519, Ed25519, X448, and Ed25519 keys? - or is 'default' format sufficient for these keys? + + .. subsection:: Compatible key types + + * `PSA_KEY_TYPE_ECC_KEY_PAIR` (public key) + * `PSA_KEY_TYPE_ECC_PUBLIC_KEY` + + .. subsection:: Key data format options + + * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (default) + * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` + +.. macro:: PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO + :definition: /* implementation-defined value */ + + .. summary:: + The *SubjectPublicKeyInfo* key data format for RSA and elliptic curve public keys. + + .. todo:: Provide normative reference for SubjectPublicKeyInfo, in RFC 5280 + + .. todo:: Options for SubjectPublicKeyInfo + + * Do we want to define an option to use the EC curve identifier, or the curve domain parameters in the SubjectPublicKey? + + .. subsection:: Compatible key types + + * `PSA_KEY_TYPE_ECC_KEY_PAIR` (public key) + * `PSA_KEY_TYPE_ECC_PUBLIC_KEY` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` (public key) + * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` + + .. subsection:: Key data format options + + * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) + * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (for EC keys, default) + * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` (for EC keys) + +.. macro:: PSA_KEY_FORMAT_RSA_PRIVATE_KEY + :definition: /* implementation-defined value */ + + .. summary:: + The *RSAPrivateKey* key data format for RSA key-pairs. + + This is the default key data format for RSA key-pairs. + + .. todo:: Provide normative reference for RSAPrivateKey, in RFC 8017 + + .. subsection:: Compatible key types + + * `PSA_KEY_TYPE_RSA_KEY_PAIR` + + .. subsection:: Key data format options + + * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) + * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + +.. macro:: PSA_KEY_FORMAT_EC_PRIVATE_KEY + :definition: /* implementation-defined value */ + + .. summary:: + The *ECPrivateKey* key data format for elliptic curve key-pairs. + + .. todo:: Provide normative reference for ECPrivateKey, in RFC 5915 + + .. todo:: Options for ECPrivateKey + + * Do we want to define an option to use the EC curve identifier, or the curve domain parameters in the ECPrivateKey? + * Do we want to define an option to include the public key in the ECPrivateKey? + + .. subsection:: Compatible key types + + * `PSA_KEY_TYPE_ECC_KEY_PAIR` + + .. subsection:: Key data format options + + * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) + * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (default) + * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` () + +.. macro:: PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY + :definition: /* implementation-defined value */ + + .. summary:: + The *OneAsymmetricKey* key data format for RSA and elliptic curve key-pairs. + + .. todo:: Provide normative reference for OneAsymmetricKey (previously PrivateKeyInfo), in RFC 5958 + + .. todo:: Options for OneAsymmetricKey + + Similar to ECPrivateKey: + + * Do we want to define an option to use the EC curve identifier, or the curve domain parameters in ECPrivateKey? + * Do we want to define an option to include the public key in the OneAsymmetricKey? + + .. subsection:: Compatible key types + + * `PSA_KEY_TYPE_ECC_KEY_PAIR` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` + + .. subsection:: Key data format options + + * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) + * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (for EC keys, default) + * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` (for EC keys) + +.. typedef:: uint32_t psa_key_data_format_option_t + + .. summary:: + Encoding of formatting options for a key data format. + + Key data format options are specified in the |API| using values of this type. + When multiple format options are required, the options are combined using bitwise-OR. + + `PSA_KEY_FORMAT_OPTIONS_DEFAULT` (value ``0``) indicates the default data format options for the key data format. + +.. macro:: PSA_KEY_FORMAT_OPTIONS_DEFAULT + :definition: ((psa_key_data_format_option_t) 0) + + .. summary:: + Key data format option value indicating the default options. + + The default format options are specified by each key data format. + +.. macro:: PSA_KEY_FORMAT_OPTION_PUBLIC_KEY + :definition: /* implementation-defined value */ + + .. summary:: + Key data format option to produce key data corresponding to the public key of a key pair. + + This option is only applicable to an asymmetric key data format. + This option has no effect on the result when used with a public-key. + When used with a key-pair: + + * If this option is present, the public-key part of the key-pair is used. + * If this option is not present, the private-key part of a key-pair is used. + + This option is applicable to all key data formats for asymmetric key types. + The option can be combined using a bitwise-OR with any other key data format option applicable to asymmetric keys. + + .. todo:: Decide if a separate API for exporting formatted public keys is better + + This option acts differently to the other defined options: + + * It is effectively redundant if the key format is a public-key type format, and the key is a key-pair. + Unless we require agreement between key type and key format, in which case this option is mandatory when using a private-key with a public-key format. + * It is necessarily useful if used with the default data format, as that works on whatever the key object is (key-pair or public-key). + Or with any other data format that can represent either a public key or a private key --- Are there any? + +.. macro:: PSA_KEY_FORMAT_OPTION_DER_ENCODING + :definition: /* implementation-defined value */ + + .. summary:: + Key data format option to encode the key data using :term:`DER` encoding. + + This is the default encoding option for applicable key data formats. + + See also `PSA_KEY_FORMAT_OPTION_PEM_ENCODING`. + + .. todo:: Add normative reference for DER either here, or in glossary. + + .. subsection:: Applicable key data formats + + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` + * `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + +.. macro:: PSA_KEY_FORMAT_OPTION_PEM_ENCODING + :definition: /* implementation-defined value */ + + .. summary:: + Key data format option to encode the key data using :term:`PEM` encoding. + + See also `PSA_KEY_FORMAT_OPTION_DER_ENCODING`. + + .. todo:: Add normative reference for PEM either here, or in glossary. + + .. subsection:: Applicable key data formats + + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` + * `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + +.. macro:: PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT + :definition: /* implementation-defined value */ + + .. summary:: + Key data format option to encode elliptic curve points in uncompressed form. + + This is default encoding of elliptic curve points for key data formats that include an elliptic curve public key. + + See also `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT`. + + .. subsection:: Applicable key data formats + + * `PSA_KEY_FORMAT_EC_POINT` + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + +.. macro:: PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT + :definition: /* implementation-defined value */ + + .. summary:: + Key data format option to encode elliptic curve points in compressed form. + + See also `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT`. + + .. subsection:: Applicable key data formats + + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_EC_POINT` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + .. _key-creation: Key creation diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index ea18391c..f873649e 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -621,7 +621,7 @@ RSA keys .. subsection:: Key format - The data format for import and export of a key-pair is the non-encrypted DER encoding of the representation defined by in :RFC-title:`8017` as ``RSAPrivateKey``, version ``0``. + The data format for import and export of a key-pair is the non-encrypted :term:`DER` encoding of the representation defined by in :RFC-title:`8017` as ``RSAPrivateKey``, version ``0``. .. code-block:: none @@ -686,7 +686,7 @@ RSA keys .. subsection:: Key format - The data format for import and export of a public key is the DER encoding of the representation defined by :RFC-title:`3279#2.3.1` as ``RSAPublicKey``. + The data format for import and export of a public key is the :term:`DER` encoding of the representation defined by :RFC-title:`3279#2.3.1` as ``RSAPublicKey``. .. code-block:: none diff --git a/doc/crypto/api/ops/signature.rst b/doc/crypto/api/ops/signature.rst index d802a9ea..9ad7ba62 100644 --- a/doc/crypto/api/ops/signature.rst +++ b/doc/crypto/api/ops/signature.rst @@ -57,7 +57,7 @@ Asymmetric signature algorithms This signature scheme is defined by :RFC-title:`8017#8.2` under the name RSASSA-PKCS1-v1_5. - The ``hash`` parameter to `psa_sign_hash()` or `psa_verify_hash()` is used as :math:`T` from step 3 onwards in the message encoding algorithm ``EMSA-PKCS1-V1_5-ENCODE()`` in :RFC:`8017#9.2`. :math:`T` is normally the DER encoding of the *DigestInfo* structure produced by step 2 in the message encoding algorithm, but it can be any byte string within the available length. + The ``hash`` parameter to `psa_sign_hash()` or `psa_verify_hash()` is used as :math:`T` from step 3 onwards in the message encoding algorithm ``EMSA-PKCS1-V1_5-ENCODE()`` in :RFC:`8017#9.2`. :math:`T` is normally the :term:`DER` encoding of the *DigestInfo* structure produced by step 2 in the message encoding algorithm, but it can be any byte string within the available length. The wildcard key policy :code:`PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_ANY_HASH)` also permits a key to be used with the `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` signature algorithm. diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index 772524bf..e787012b 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -33,6 +33,9 @@ Changes to the API See :secref:`asymmetric-key-encoding` and :secref:`appendix-specdef-key-values`. +* Added key data formats and formatting options for key export and import. + See :secref:`key-data-formats`. + Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/crypto/terms b/doc/crypto/terms index fdcfed71..8eb0f171 100644 --- a/doc/crypto/terms +++ b/doc/crypto/terms @@ -186,3 +186,13 @@ application instances. See :secref:`isolation`. + +.. term:: Distinguished Encoding Rules + :abbr: DER + + DER is a binary encoding format used for X.509 certificates and keys. + +.. term:: PEM + + Originally "Privacy Enhanced Mail". + PEM is an ASCII-based encoding format used for X.509 certificates and keys. From aeecc3e907c15e8c2b05d5fe125322bd3da5e7bb Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Tue, 6 Aug 2024 23:39:25 +0100 Subject: [PATCH 02/10] Second draft of key formats: * Decided to do public key export via a dedicated function * Removed ECPoint as a format * Required public keys in key pair formats * Added options for domain parameters * Individual boolean options override defaults instead of providing both option elements * Added references for everything * Defined new terms for ASN.1, DER and PEM --- doc/crypto/api/keys/management.rst | 288 ++++++++++++++--------------- doc/crypto/api/keys/types.rst | 4 +- doc/crypto/appendix/history.rst | 2 +- doc/crypto/references | 54 +++++- doc/crypto/terms | 13 +- 5 files changed, 197 insertions(+), 164 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index cdaf8614..a8e916d4 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -7,250 +7,246 @@ Key management functions ======================== -.. _key-data-formats: +.. _key-formats: -Key data formats ----------------- +Key formats +----------- -Outside of the key store, keys are exchanged using defined data formats. +Outside of the key store, keys are exchanged using defined formats. These formats are used to import and export keys, or to input public asymmetric keys to key agreement or PAKE operations. -The |API| defines the default data format for each standard key types, to be used for these operations. -These data formats are defined in the *Key format* section of each key type in :secref:`key-types`. +The |API| defines the default format for each standard key type, to be used for these operations. +These formats are defined in the *Key format* section of each key type in :secref:`key-types`. Some application use cases require key data to be in other standard formats. -:code:`psa_import_formatted_key()` and :code:`psa_export_formatted_key()` allow data in these formats to be used directly with the |API|. +:code:`psa_import_formatted_key()`, :code:`psa_export_formatted_key()`, and :code:`psa_export_formatted_public_key()` allow data in these formats to be used directly with the |API|. -Some key data formats have options for how the key data is represented. +Some key formats have options for how the key data is represented. For example, -* Data layouts used in X.509 certificates, such as RSAPublicKey, can be encoded using ASCII-based PEM or binary DER. +* Data layouts used in X.509 certificates, such as RSAPublicKey, can be encoded using :term:`DER` or :term:`PEM`. * Elliptic curve keys can be specified using a curve identifier and the key value, or by providing for full set of curve parameters and the key value. * Elliptic curve public keys can use a compressed or uncompressed representation for the point on the curve. These options need to be specified by the application, or a default used, when formatting key data for export. When importing a key, the formatted data includes information that indicates the formatting options, so the options do not need to be provided by the application. -The |API| defines elements for some common key data formats and format options. -Implementations are permitted to define additional key data formats and options. +The |API| defines elements for some common key formats and format options. +Implementations are permitted to define additional key formats and options. -.. typedef:: uint32_t psa_key_data_format_t +.. typedef:: uint32_t psa_key_format_t .. summary:: - Encoding of a key data format. + Encoding of a key format. - Key data formats are specified in the |API| using values of this type. + Key formats are specified in the |API| using values of this type. - `PSA_KEY_FORMAT_DEFAULT` (value ``0``) indicates the default data format for the key type. + `PSA_KEY_FORMAT_DEFAULT` (value ``0``) indicates the default format for the key type. .. macro:: PSA_KEY_FORMAT_DEFAULT - :definition: ((psa_key_data_format_t) 0) + :definition: ((psa_key_format_t) 0) .. summary:: - Key data format value indicating the default data format. + Key format value indicating the default format. - The default data formats are specified for each key type in the :secref:`key-types` chapter. + The default formats are specified for each key type in the :secref:`key-types` chapter. - .. todo:: Non-default options with default key data format? + Non-default options can be specified with the default format, when appropriate for the key type. - Determine if it is permitted to specify non-default options when requesting the default format. + .. todo:: Describe options that can be used with keys in the default format. .. macro:: PSA_KEY_FORMAT_RSA_PUBLIC_KEY :definition: /* implementation-defined value */ .. summary:: - The *RSAPublicKey* key data format for RSA public keys. + The *RSAPublicKey* key format for RSA public keys. - This is the default key data format for RSA public keys. + RSAPublicKey is defined by :RFC-title:`8017#A.1.1`. - .. todo:: Provide normative reference for RSAPublicKey, in RFC 8017 + This is the default key format for RSA public keys. + + When exporting a key in this format, the output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. .. subsection:: Compatible key types - * `PSA_KEY_TYPE_RSA_KEY_PAIR` (public key) * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) - .. subsection:: Key data format options + .. subsection:: Key format options - * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) - * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + * `PSA_KEY_FORMAT_OPTION_PEM` -.. macro:: PSA_KEY_FORMAT_EC_POINT +.. macro:: PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO :definition: /* implementation-defined value */ .. summary:: - The *ECPoint* key data format for Weierstrass elliptic curve public keys. - - This is the default key data format for Weierstrass elliptic curve public keys. - - .. todo:: Provide normative reference for ECPoint, in SEC1 - - .. todo:: What about Edwards and Montgomery curves? - - Do we need another format for X25519, Ed25519, X448, and Ed25519 keys? - or is 'default' format sufficient for these keys? - - .. subsection:: Compatible key types - - * `PSA_KEY_TYPE_ECC_KEY_PAIR` (public key) - * `PSA_KEY_TYPE_ECC_PUBLIC_KEY` - - .. subsection:: Key data format options - - * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (default) - * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` + The *SubjectPublicKeyInfo* key format for RSA and elliptic curve public keys. -.. macro:: PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO - :definition: /* implementation-defined value */ + SubjectPublicKeyInfo is defined by :RFC-title:`5280#4.1`. + The following documents define the encoding of SubjectPublicKeyInfo elements, depending on the type of key: - .. summary:: - The *SubjectPublicKeyInfo* key data format for RSA and elliptic curve public keys. + * :RFC-title:`8017` defines the details for RSA keys. + * :RFC-title:`5480` defines the details for Weierstrass elliptic curve keys. + * :RFC-title:`8410` defines the details for Montgomery and Edwards elliptic curve keys. - .. todo:: Provide normative reference for SubjectPublicKeyInfo, in RFC 5280 + When exporting a key in this format, the output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - .. todo:: Options for SubjectPublicKeyInfo + When exporting a Weierstrass elliptic curve key in this format: - * Do we want to define an option to use the EC curve identifier, or the curve domain parameters in the SubjectPublicKey? + * The *ECPoint* containing the key value is uncompressed by default. + For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. + * The *ECParameters* element uses a *namedCurve* by default. + To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. .. subsection:: Compatible key types - * `PSA_KEY_TYPE_ECC_KEY_PAIR` (public key) * `PSA_KEY_TYPE_ECC_PUBLIC_KEY` - * `PSA_KEY_TYPE_RSA_KEY_PAIR` (public key) + * `PSA_KEY_TYPE_ECC_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) - .. subsection:: Key data format options + .. subsection:: Key format options - * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) - * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` - * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (for EC keys, default) - * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` (for EC keys) + * `PSA_KEY_FORMAT_OPTION_PEM` + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) .. macro:: PSA_KEY_FORMAT_RSA_PRIVATE_KEY :definition: /* implementation-defined value */ .. summary:: - The *RSAPrivateKey* key data format for RSA key-pairs. + The *RSAPrivateKey* key format for RSA key-pairs. - This is the default key data format for RSA key-pairs. + RSAPrivateKey is defined by :RFC-title:`8017#A.1.2`. - .. todo:: Provide normative reference for RSAPrivateKey, in RFC 8017 + This is the default key format for RSA key-pairs. + + When exporting a key in this format, the output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. .. subsection:: Compatible key types * `PSA_KEY_TYPE_RSA_KEY_PAIR` - .. subsection:: Key data format options + .. subsection:: Key format options - * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) - * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` + * `PSA_KEY_FORMAT_OPTION_PEM` .. macro:: PSA_KEY_FORMAT_EC_PRIVATE_KEY :definition: /* implementation-defined value */ .. summary:: - The *ECPrivateKey* key data format for elliptic curve key-pairs. + The *ECPrivateKey* key format for elliptic curve key-pairs. + + ECPrivateKey is defined by :RFC-title:`5915#3`. + :RFC:`5915` includes the encoding of Weierstrass elliptic curve key-pairs. + See :RFC-title:`8410` for the encoding of Montgomery and Edwards elliptic curve key-pairs. + + When exporting a key in this format: - .. todo:: Provide normative reference for ECPrivateKey, in RFC 5915 + * The public key is always included in the output. + * The output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - .. todo:: Options for ECPrivateKey + When exporting a Weierstrass elliptic curve key in this format: - * Do we want to define an option to use the EC curve identifier, or the curve domain parameters in the ECPrivateKey? - * Do we want to define an option to include the public key in the ECPrivateKey? + * The *ECPoint* containing the key value is uncompressed by default. + For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. + * The *ECParameters* element uses a *namedCurve* by default. + To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. .. subsection:: Compatible key types * `PSA_KEY_TYPE_ECC_KEY_PAIR` - .. subsection:: Key data format options + .. subsection:: Key format options - * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) - * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` - * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (default) - * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` () + * `PSA_KEY_FORMAT_OPTION_PEM` + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) .. macro:: PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY :definition: /* implementation-defined value */ .. summary:: - The *OneAsymmetricKey* key data format for RSA and elliptic curve key-pairs. + The *OneAsymmetricKey* key format for RSA and elliptic curve key-pairs. - .. todo:: Provide normative reference for OneAsymmetricKey (previously PrivateKeyInfo), in RFC 5958 + .. todo:: Decide if this format should be named ``PSA_KEY_FORMAT_PKCS8`` instead. - .. todo:: Options for OneAsymmetricKey + Or if this should be a synonym? + Note that OneAsymmetricKey is identical to PrivateKeyInfo (PKCS#8) if version==1, but extends it when version==2. - Similar to ECPrivateKey: + OneAsymmetricKey is defined by :RFC-title:`5958`. + OneAsymmetricKey is an update to the PKCS#8 *PrivateKeyInfo* format defined by :RFC-title:`5208`. + Encoding of specific key types is defined in other documents: - * Do we want to define an option to use the EC curve identifier, or the curve domain parameters in ECPrivateKey? - * Do we want to define an option to include the public key in the OneAsymmetricKey? + * :RFC-title:`8017` defines the encoding of RSA keys. + * :RFC-title:`5915` defines the encoding of Weierstrass elliptic curve keys. + * :RFC-title:`8410` defines the encoding of Montgomery and Edwards elliptic curve keys. - .. subsection:: Compatible key types - - * `PSA_KEY_TYPE_ECC_KEY_PAIR` - * `PSA_KEY_TYPE_RSA_KEY_PAIR` + .. todo:: OneAsymmetricKey also supports encryption and authentication of the key data. - .. subsection:: Key data format options + Provide the necessary references, and link to the related key wrapping/unwrapping APIs. - * `PSA_KEY_FORMAT_OPTION_DER_ENCODING` (default) - * `PSA_KEY_FORMAT_OPTION_PEM_ENCODING` - * `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT` (for EC keys, default) - * `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT` (for EC keys) + When exporting a key in this format: -.. typedef:: uint32_t psa_key_data_format_option_t + * The public key is always included in the output. + * The output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - .. summary:: - Encoding of formatting options for a key data format. + When exporting a Weierstrass elliptic curve key in this format: - Key data format options are specified in the |API| using values of this type. - When multiple format options are required, the options are combined using bitwise-OR. + * The *ECPoint* containing the key value is uncompressed by default. + For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. + * The *ECParameters* element uses a *namedCurve* by default. + To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. - `PSA_KEY_FORMAT_OPTIONS_DEFAULT` (value ``0``) indicates the default data format options for the key data format. + .. subsection:: Compatible key types -.. macro:: PSA_KEY_FORMAT_OPTIONS_DEFAULT - :definition: ((psa_key_data_format_option_t) 0) + * `PSA_KEY_TYPE_ECC_KEY_PAIR` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` - .. summary:: - Key data format option value indicating the default options. + .. subsection:: Key format options - The default format options are specified by each key data format. + * `PSA_KEY_FORMAT_OPTION_PEM` + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) -.. macro:: PSA_KEY_FORMAT_OPTION_PUBLIC_KEY - :definition: /* implementation-defined value */ +.. typedef:: uint32_t psa_key_format_option_t .. summary:: - Key data format option to produce key data corresponding to the public key of a key pair. + Encoding of formatting options for a key format. - This option is only applicable to an asymmetric key data format. - This option has no effect on the result when used with a public-key. - When used with a key-pair: - - * If this option is present, the public-key part of the key-pair is used. - * If this option is not present, the private-key part of a key-pair is used. + Key format options are specified in the |API| using values of this type. + When multiple format options are required, the options are combined using bitwise-OR. - This option is applicable to all key data formats for asymmetric key types. - The option can be combined using a bitwise-OR with any other key data format option applicable to asymmetric keys. + `PSA_KEY_FORMAT_OPTIONS_DEFAULT` (value ``0``) indicates the default format options for the key format. - .. todo:: Decide if a separate API for exporting formatted public keys is better +.. macro:: PSA_KEY_FORMAT_OPTIONS_DEFAULT + :definition: ((psa_key_format_option_t) 0) - This option acts differently to the other defined options: + .. summary:: + Key format option value indicating the default options. - * It is effectively redundant if the key format is a public-key type format, and the key is a key-pair. - Unless we require agreement between key type and key format, in which case this option is mandatory when using a private-key with a public-key format. - * It is necessarily useful if used with the default data format, as that works on whatever the key object is (key-pair or public-key). - Or with any other data format that can represent either a public key or a private key --- Are there any? + The default format options are specified by each key format. -.. macro:: PSA_KEY_FORMAT_OPTION_DER_ENCODING +.. macro:: PSA_KEY_FORMAT_OPTION_PEM :definition: /* implementation-defined value */ .. summary:: - Key data format option to encode the key data using :term:`DER` encoding. + Key format option to encode the key data using :term:`PEM` encoding. - This is the default encoding option for applicable key data formats. + By default, key formats that are defined using :term:`ASN.1` use the binary :term:`DER` encoding for key export. + The `PSA_KEY_FORMAT_OPTION_PEM` option results in using the ASCII :term:`PEM` encoding instead. - See also `PSA_KEY_FORMAT_OPTION_PEM_ENCODING`. + PEM encoding is defined by :RFC-title:`7468`. - .. todo:: Add normative reference for DER either here, or in glossary. + .. note:: + Some key formats use PEM labels that are not described in :RFC:`7468`, but are used in other tools that produce and consume PEM-encoded data. - .. subsection:: Applicable key data formats + .. subsection:: Related key formats * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` @@ -258,53 +254,37 @@ Implementations are permitted to define additional key data formats and options. * `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` -.. macro:: PSA_KEY_FORMAT_OPTION_PEM_ENCODING +.. macro:: PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED :definition: /* implementation-defined value */ .. summary:: - Key data format option to encode the key data using :term:`PEM` encoding. + Key format option to encode Weierstrass elliptic curve points in compressed form. - See also `PSA_KEY_FORMAT_OPTION_DER_ENCODING`. + By default, Weierstrass elliptic curve points are encoded in uncompressed form for key export. + The `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option results in using compressed form instead. - .. todo:: Add normative reference for PEM either here, or in glossary. + The compressed and uncompressed ECPoint format is defined by :cite-title:`SEC1` §2.3.3. - .. subsection:: Applicable key data formats + .. subsection:: Related key formats * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` - * `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` - * `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` -.. macro:: PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT +.. macro:: PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN :definition: /* implementation-defined value */ .. summary:: - Key data format option to encode elliptic curve points in uncompressed form. - - This is default encoding of elliptic curve points for key data formats that include an elliptic curve public key. - - See also `PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT`. + Key format option to output the Weierstrass elliptic curve domain parameters in the key format. - .. subsection:: Applicable key data formats - - * `PSA_KEY_FORMAT_EC_POINT` - * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` - * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` - * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` - -.. macro:: PSA_KEY_FORMAT_OPTION_EC_COMPRESSED_POINT - :definition: /* implementation-defined value */ - - .. summary:: - Key data format option to encode elliptic curve points in compressed form. + By default, key formats that include the *ECParameters* element specify a *namedCurve* for key export. + The `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option results in specifying the full domain parameters for the elliptic curve instead. - See also `PSA_KEY_FORMAT_OPTION_EC_UNCOMPRESSED_POINT`. + The ECParameters format is defined by :RFC-title:`5480#2.1.1`. - .. subsection:: Applicable key data formats + .. subsection:: Related key formats * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` - * `PSA_KEY_FORMAT_EC_POINT` * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index f873649e..2c77c187 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -621,7 +621,7 @@ RSA keys .. subsection:: Key format - The data format for import and export of a key-pair is the non-encrypted :term:`DER` encoding of the representation defined by in :RFC-title:`8017` as ``RSAPrivateKey``, version ``0``. + The data format for import and export of a key-pair is the non-encrypted :term:`DER` encoding of the representation defined by in :RFC-title:`8017#A.1.2` as ``RSAPrivateKey``, version ``0``. .. code-block:: none @@ -686,7 +686,7 @@ RSA keys .. subsection:: Key format - The data format for import and export of a public key is the :term:`DER` encoding of the representation defined by :RFC-title:`3279#2.3.1` as ``RSAPublicKey``. + The data format for import and export of a public key is the :term:`DER` encoding of the representation defined by :RFC-title:`8017#A.1.1` as ``RSAPublicKey``. .. code-block:: none diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index e787012b..cb71bafe 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -34,7 +34,7 @@ Changes to the API See :secref:`asymmetric-key-encoding` and :secref:`appendix-specdef-key-values`. * Added key data formats and formatting options for key export and import. - See :secref:`key-data-formats`. + See :secref:`key-formats`. Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/crypto/references b/doc/crypto/references index 196e15df..b72fab6a 100644 --- a/doc/crypto/references +++ b/doc/crypto/references @@ -178,12 +178,6 @@ :publication: March 1998 :url: tools.ietf.org/html/rfc2315.html -.. reference:: RFC3279 - :title: Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile - :author: IETF - :publication: April 2002 - :url: tools.ietf.org/html/rfc3279.html - .. reference:: RFC3610 :title: Counter with CBC-MAC (CCM) :author: IETF @@ -396,3 +390,51 @@ :author: Thread Group :publication: July 2022 :url: www.threadgroup.org/ThreadSpec + +.. reference:: RFC5208 + :title: Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2 + :author: IETF + :publication: May 2008 + :url: tools.ietf.org/html/rfc5208.html + +.. reference:: RFC5280 + :title: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile + :author: IETF + :publication: May 2008 + :url: tools.ietf.org/html/rfc5280.html + +.. reference:: RFC5480 + :title: Elliptic Curve Cryptography Subject Public Key Information + :author: IETF + :publication: March 2009 + :url: tools.ietf.org/html/rfc5480.html + +.. reference:: RFC5958 + :title: Asymmetric Key Packages + :author: IETF + :publication: August 2010 + :url: tools.ietf.org/html/rfc5958.html + +.. reference:: RFC7468 + :title: Textual Encodings of PKIX, PKCS, and CMS Structures + :author: IETF + :publication: April 2015 + :url: tools.ietf.org/html/rfc7468.html + +.. reference:: RFC8410 + :title: Algorithm Identifiers for Ed25519, Ed448, X25519, and X448 for Use in the Internet X.509 Public Key Infrastructure + :author: IETF + :publication: August 2018 + :url: tools.ietf.org/html/rfc8410.html + +.. reference:: X.680 + :title: Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation + :author: ITU + :publication: February 2021 + :url: itu.int/itu-t/recommendations/rec.aspx?rec=x.680 + +.. reference:: X.690 + :title: Information Technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER) + :author: ITU + :publication: February 2021 + :url: itu.int/itu-t/recommendations/rec.aspx?rec=x.690 diff --git a/doc/crypto/terms b/doc/crypto/terms index 8eb0f171..bd79730a 100644 --- a/doc/crypto/terms +++ b/doc/crypto/terms @@ -187,12 +187,23 @@ See :secref:`isolation`. +.. term:: ASN.1 + + Abstract Syntax Notation One (ASN.1) is a language for defining data structures for cross-platform interchange. + It is used in the definition of many common key and certificate formats. + + ASN.1 is defined by :cite-title:`X.680`. + .. term:: Distinguished Encoding Rules :abbr: DER - DER is a binary encoding format used for X.509 certificates and keys. + A binary encoding of structures defined using :term:`ASN.1`, that is used for X.509 certificate and key interchange formats. + + DER is defined by :cite-title:`X.690`. .. term:: PEM Originally "Privacy Enhanced Mail". PEM is an ASCII-based encoding format used for X.509 certificates and keys. + + PEM is defined by :RFC-title:`7468`. From 1b425a56fd1aa755435a035c8a038a0fa3d24be9 Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Wed, 7 Aug 2024 17:07:25 +0100 Subject: [PATCH 03/10] Described options for default key formats --- doc/crypto/api/keys/management.rst | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index a8e916d4..e0aefbda 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -51,9 +51,16 @@ Implementations are permitted to define additional key formats and options. The default formats are specified for each key type in the :secref:`key-types` chapter. - Non-default options can be specified with the default format, when appropriate for the key type. + Some options can be specified with the default format, when appropriate for the key type. + See the description of each format option for details. - .. todo:: Describe options that can be used with keys in the default format. + .. subsection:: Compatible key types + + All key types can be used with the default format. + + .. subsection:: Key format options + + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) .. macro:: PSA_KEY_FORMAT_RSA_PUBLIC_KEY :definition: /* implementation-defined value */ @@ -246,6 +253,9 @@ Implementations are permitted to define additional key formats and options. .. note:: Some key formats use PEM labels that are not described in :RFC:`7468`, but are used in other tools that produce and consume PEM-encoded data. + This option is not applicable to the default key format. + To export a PEM-encoded key, use the appropriate format specifier. + .. subsection:: Related key formats * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` @@ -265,6 +275,8 @@ Implementations are permitted to define additional key formats and options. The compressed and uncompressed ECPoint format is defined by :cite-title:`SEC1` §2.3.3. + This option can be used with the default key format, when exporting elliptic curve public keys. + .. subsection:: Related key formats * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` @@ -282,6 +294,8 @@ Implementations are permitted to define additional key formats and options. The ECParameters format is defined by :RFC-title:`5480#2.1.1`. + This option is not applicable to the default key format. + .. subsection:: Related key formats * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` From 7b4c9d675d2ebc6d0e2377ccff3b7dc278f3e6f3 Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Wed, 7 Aug 2024 17:07:40 +0100 Subject: [PATCH 04/10] Progressed understanding of outstanding issues --- doc/crypto/api/keys/management.rst | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index e0aefbda..030a2bea 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -180,12 +180,13 @@ Implementations are permitted to define additional key formats and options. .. summary:: The *OneAsymmetricKey* key format for RSA and elliptic curve key-pairs. - .. todo:: Decide if this format should be named ``PSA_KEY_FORMAT_PKCS8`` instead. + .. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead? - Or if this should be a synonym? - Note that OneAsymmetricKey is identical to PrivateKeyInfo (PKCS#8) if version==1, but extends it when version==2. + Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo. - OneAsymmetricKey is defined by :RFC-title:`5958`. + Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey? + + OneAsymmetricKey is defined by :RFC-title:`5958#2`. OneAsymmetricKey is an update to the PKCS#8 *PrivateKeyInfo* format defined by :RFC-title:`5208`. Encoding of specific key types is defined in other documents: @@ -193,10 +194,6 @@ Implementations are permitted to define additional key formats and options. * :RFC-title:`5915` defines the encoding of Weierstrass elliptic curve keys. * :RFC-title:`8410` defines the encoding of Montgomery and Edwards elliptic curve keys. - .. todo:: OneAsymmetricKey also supports encryption and authentication of the key data. - - Provide the necessary references, and link to the related key wrapping/unwrapping APIs. - When exporting a key in this format: * The public key is always included in the output. @@ -221,6 +218,11 @@ Implementations are permitted to define additional key formats and options. * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) +.. todo:: RFC 5958/PKCS#8 also supports encryption and authentication of the key data. + + This would either be a *EncryptedPrivateKeyInfo* structure (PKCS#8) or one of the CMS content types. + This requires one or more additional format specifiers. + .. typedef:: uint32_t psa_key_format_option_t .. summary:: From 11b4298b5b5d2836a2ec6d34b9d869d8a1c64b6d Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Wed, 7 Aug 2024 21:03:51 +0100 Subject: [PATCH 05/10] Added psa_import_formatted_key() * Open issue regarding handling of encoded policy in key data --- doc/crypto/api/keys/management.rst | 155 ++++++++++++++++++++++++++--- doc/crypto/appendix/history.rst | 7 +- 2 files changed, 148 insertions(+), 14 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index 030a2bea..4f8e314e 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -180,11 +180,11 @@ Implementations are permitted to define additional key formats and options. .. summary:: The *OneAsymmetricKey* key format for RSA and elliptic curve key-pairs. - .. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead? + .. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead? - Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo. + Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo. - Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey? + Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey? OneAsymmetricKey is defined by :RFC-title:`5958#2`. OneAsymmetricKey is an update to the PKCS#8 *PrivateKeyInfo* format defined by :RFC-title:`5208`. @@ -311,7 +311,7 @@ Key creation New keys can be created in the following ways: -* `psa_import_key()` creates a key from a data buffer provided by the application. +* `psa_import_key()` and `psa_import_formatted_key()` create a key from a data buffer provided by the application. * `psa_generate_key()` and `psa_generate_key_custom()` create a key from randomly generated data. * `psa_key_derivation_output_key()` and `psa_key_derivation_output_key_custom()` create a key from data generated by a pseudorandom derivation process. See :secref:`kdf`. * `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_ .. param:: const uint8_t * data Buffer containing the key data. The content of this buffer is interpreted according to the type declared in ``attributes``. - - All implementations must support at least the format described in the *Key format* section of the chosen key type. - 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. .. param:: size_t data_length Size of the ``data`` buffer in bytes. .. 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_ The key is extracted from the provided ``data`` buffer. Its location, policy, and type are taken from ``attributes``. - 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. - - Implementations must reject an attempt to import a key of size ``0``. + 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. - This function supports any output from `psa_export_key()`. Each key type in :secref:`key-types` describes the expected format of keys. + This function supports any output from `psa_export_key()`. + The default format is defined in the *Key format* section for each key type. + Other key formats can be imported using `psa_import_formatted_key()`. - 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. + Implementations can optionally support other formats in calls to `psa_import_key()`, in addition to the default format. .. note:: 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. + .. admonition:: Implementation note + + 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. + + It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated. + +.. function:: psa_import_formatted_key + + .. summary:: + Import a key in a specified format. + * The key type can be `PSA_KEY_TYPE_NONE`. If either is nonzero, it must match the corresponding attribute of the source key. + + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. + + Depending on the specified key format, and the attributes encoded in the key data, some of the key attributes can be optional. + + The following attributes are required for formats that do not specify a key type: + + * When the format does not specify a key type: the key type in ``attributes`` determines how the ``data`` buffer is interpreted. + * 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. + + The following attributes must be set for keys used in cryptographic operations: + + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + * The key usage flags, see :secref:`key-usage-flags`. + + 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)`. + + The following attributes must be set for keys that do not use the default volatile lifetime: + + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. + + The following attributes are optional: + + * If the key size is nonzero, it must be equal to the key size determined from ``data``. + + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. + .. param:: psa_key_format_t format + The format of the key data. + One of the ``PSA_KEY_FORMAT_XXX`` values, or an implementation-specific format. + .. param:: const uint8_t * data + Buffer containing the key data. + The content of this buffer is interpreted according to the key format ``format``. + The type declared in ``attributes`` is used if the format and key data do not specify a key type. + .. param:: size_t data_length + Size of the ``data`` buffer in bytes. + .. param:: psa_key_id_t * key + On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the 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_NOT_SUPPORTED + The following conditions can result in this error: + + * The key format is not supported by the implementation. + * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: + + * The key type is invalid, or is `PSA_KEY_TYPE_NONE` when a type is required. + * The key size is nonzero, and is incompatible with the key data in ``data``. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + * The key format is invalid. + * The key data is not correctly formatted for the key format or the key type. + .. retval:: PSA_ERROR_NOT_PERMITTED + The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. + + 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``. + + If the format is `PSA_KEY_FORMAT_DEFAULT`, this is equivalent to call to `psa_import_key()`. + + For non-default key formats, the key format either specifies the key type, or the formatted data encodes the key type. + 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. + 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`. + + 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. + + 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())`: + + * 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``. + * If both permit the same algorithm or wildcard-based algorithm, the resulting key has the same permitted algorithm. + * 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. + * If the policies do not permit any algorithm in common, this function fails with the status :code:`PSA_ERROR_INVALID_ARGUMENT`. + + As a result, the new key cannot be used for operations that were not permitted by the imported key data. + + .. todo:: The proposed constraints on key policy are probably too strict. + + * 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. + * Many of the formats include an optional *KeyUsage* element that defines a set of permitted uses. + These partially map onto |API| usage flags. + + 1. What to do if the format does not include a algorithm identifier? + 2. What to do if the algorithm identifier is too general for the algorithm encodings in |API|? + 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? + 4. If a *KeyUsage* is **not** provided, do we just use the ``attributes`` usage flags? + 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? + + Implementations can define implementation-specific formats that may have other behaviors relating to ``attributes``. + + .. note:: + The |API| does not support asymmetric private key objects outside of a key pair. + When importing a private key, the corresponding key-pair type is created. + 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. + + .. admonition:: Implementation note + + 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. + + It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated. + .. struct:: psa_custom_key_parameters_t :type: diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index cb71bafe..c4d06a3e 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -33,8 +33,11 @@ Changes to the API See :secref:`asymmetric-key-encoding` and :secref:`appendix-specdef-key-values`. -* Added key data formats and formatting options for key export and import. - See :secref:`key-formats`. +* Added support for non-default key formats: + + - Added definitions for key formats and and formatting options. + See :secref:`key-formats`. + - Added `psa_import_formatted_key()` to import keys in other formats. Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ From ea1b94af7ce6cfee17d6b49df749e0edc199b3fd Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Mon, 12 Aug 2024 23:06:29 +0100 Subject: [PATCH 06/10] Added formatted key export functions --- doc/crypto/api/keys/management.rst | 285 ++++++++++++++++++++++++++++- 1 file changed, 275 insertions(+), 10 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index 4f8e314e..50f7d602 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -12,6 +12,24 @@ Key management functions Key formats ----------- +.. todo:: Consider Splitting this chapter up (before the final 1.3 release) + + With the additions of: + + * Formatted key import/export + * Interruptible public key export + * Interruptible key generation + * Extended key generation + * Key wrapping and unwrapping (this could alternatively be put in with 'Operations') + + This chapter is getting very large as a 'hold-all' for key-related functions. + + Consider splitting this up: + + 1. Non-default key formats, key import and export (or even separate those into formats and import/export) + 2. Key wrap/unwrap (and associated specialized formats and algorithms) + 3. General key management: [random] key generation, copying, purging, destroying + Outside of the key store, keys are exchanged using defined formats. These formats are used to import and export keys, or to input public asymmetric keys to key agreement or PAKE operations. @@ -231,9 +249,9 @@ Implementations are permitted to define additional key formats and options. Key format options are specified in the |API| using values of this type. When multiple format options are required, the options are combined using bitwise-OR. - `PSA_KEY_FORMAT_OPTIONS_DEFAULT` (value ``0``) indicates the default format options for the key format. + `PSA_KEY_FORMAT_OPTION_DEFAULT` (value ``0``) indicates the default format options for the key format. -.. macro:: PSA_KEY_FORMAT_OPTIONS_DEFAULT +.. macro:: PSA_KEY_FORMAT_OPTION_DEFAULT :definition: ((psa_key_format_option_t) 0) .. summary:: @@ -418,7 +436,6 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ .. summary:: Import a key in a specified format. - * The key type can be `PSA_KEY_TYPE_NONE`. If either is nonzero, it must match the corresponding attribute of the source key. .. param:: const psa_key_attributes_t * attributes The attributes for the new key. @@ -498,7 +515,7 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ 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``. - If the format is `PSA_KEY_FORMAT_DEFAULT`, this is equivalent to call to `psa_import_key()`. + If the format is `PSA_KEY_FORMAT_DEFAULT`, this is equivalent to calling `psa_import_key()`. For non-default key formats, the key format either specifies the key type, or the formatted data encodes the key type. 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. @@ -963,17 +980,22 @@ Key export .. retval:: PSA_ERROR_BAD_STATE The library requires initializing by a call to `psa_crypto_init()`. + Extract a key from the key store into a data buffer using the default key format. + If the key is not a public-key type, then the policy on the key must have the usage flag `PSA_KEY_USAGE_EXPORT` set. + The output of this function can be passed to `psa_import_key()` to create an equivalent object. - If the implementation of `psa_import_key()` supports other formats beyond the format specified here, the output from `psa_export_key()` must use the representation specified in :secref:`key-types`, not the originally imported representation. + If the implementation supports importing non-default key formats, the output from `psa_export_key()` must use the default representation specified in :secref:`key-types`, not the originally imported representation. For standard key types, the output format is defined in the relevant *Key format* section in :secref:`key-types`. - The policy on the key must have the usage flag `PSA_KEY_USAGE_EXPORT` set. + To export a key in another format, use `psa_export_formatted_key()`. + + To export the public key from a key-pair, use `psa_export_public_key()` or `psa_export_formatted_public_key()`. .. function:: psa_export_public_key .. summary:: - Export a public key or the public part of a key pair in binary format. + Export a public key or the public part of a key-pair in binary format. .. param:: psa_key_id_t key Identifier of the key to export. @@ -1015,13 +1037,183 @@ Key export .. retval:: PSA_ERROR_BAD_STATE The library requires initializing by a call to `psa_crypto_init()`. + Extract a public key, or a public part of a key-pair, from the key store into a data buffer using the default key format. + The output of this function can be passed to `psa_import_key()` to create an object that is equivalent to the public key. - If the implementation of `psa_import_key()` supports other formats beyond the format specified here, the output from `psa_export_public_key()` must use the representation specified in :secref:`key-types`, not the originally imported representation. + If the implementation supports importing non-default key formats, the output from `psa_export_public_key()` must use the default representation specified in :secref:`key-types`, not the originally imported representation. For standard key types, the output format is defined in the relevant *Key format* section in :secref:`key-types`. + To export a public key in another format, use `psa_export_formatted_public_key()`. + + Exporting a public key object or the public part of a key-pair is always permitted, regardless of the key's usage flags. + +.. function:: psa_export_formatted_key + + .. summary:: + Export a key in a specified format. + + .. param:: psa_key_format_t format + The required export format. + One of the ``PSA_KEY_FORMAT_XXX`` values, or an implementation-specific format. + .. param:: psa_key_format_option_t options + Formatting options to use. + One of the ``PSA_KEY_FORMAT_OPTION_XXX`` values, an implementation-specific option, or a bitwise-or of them. + .. param:: psa_key_id_t key + Identifier of the key to export. + It must permit the usage `PSA_KEY_USAGE_EXPORT`, unless it is a public key. + .. param:: uint8_t * data + Buffer where the key data is to be written. + .. param:: size_t data_size + Size of the ``data`` buffer in bytes. + This must be appropriate for the key: + + * The required output size is :code:`PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE(format, options, type, bits)`, where ``format`` is the key format, ``options`` is the format options, ``type`` is the key type, and ``bits`` is the key size in bits. + * `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE` evaluates to the maximum output size of any supported public key or key pair, in any supported combination of key format and options. + * `PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE` evaluates to the maximum output size of any supported key pair, in any supported combination of key format and options. + * `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE` evaluates to the maximum output size of any supported public key, in any supported combination of key format and options. + * This API defines no maximum size for symmetric keys. Arbitrarily large data items can be stored in the key store, for example certificates that correspond to a stored private key or input material for key derivation. + + .. param:: size_t * data_length + On success, the number of bytes that make up the key data. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + The first ``(*data_length)`` bytes of ``data`` contain the exported key. + .. retval:: PSA_ERROR_INVALID_HANDLE + ``key`` is not a valid key identifier. + .. retval:: PSA_ERROR_NOT_PERMITTED + The key does not have the `PSA_KEY_USAGE_EXPORT` flag. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: - Exporting a public key object or the public part of a key pair is always permitted, regardless of the key's usage flags. + * The key format is not valid. + * The key format is not applicable to the key type. + * The key format option is not applicable to the key format. + + .. todo:: + Decide on appropriate behavior if the format option does not match the key type. + My preference is to ignore the option if the key format does not use that option when encoding the provided key type. + + If the option is never applicable to the format, that should (I think) be an error. + However, that means that format options cannot have overlapping values, even if they never apply to the same format? + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: + + * The key's storage location does not support export of the key. + * The implementation does not support export of keys with this key type. + * The implementation does not support key export in the requested key format or format options. + .. retval:: PSA_ERROR_BUFFER_TOO_SMALL + The size of the ``data`` buffer is too small. + `PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE()`, `PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE`, `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE`, or `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE` can be used to determine a sufficient buffer size. + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. + + Extract a key from the key store into a data buffer using a specified key format. + The output contains the key value, and, depending on the format, some of the key attributes. + If the key is not a public-key type, then the policy on the key must have the usage flag `PSA_KEY_USAGE_EXPORT` set. + + If :code:`format==PSA_KEY_FORMAT_DEFAULT` and :code:`options==PSA_KEY_FORMAT_OPTION_DEFAULT`, this is equivalent to calling `psa_export_key()`. + Some of the options can be used with the default key format for some key types, see `PSA_KEY_FORMAT_DEFAULT`. + + For standard key types, the default output format is defined in the relevant *Key format* section in :secref:`key-types`. + Other key formats are defined in :secref:`key-formats`. + + Some key formats can optionally include additional content or use different encodings. + These can be selected by using one or more of the ``PSA_KEY_FORMAT_OPTION_XXX`` values. + + The output of this function can be passed to `psa_import_formatted_key()`, specifying the same format, to create an equivalent key object. + + To export the public key from a key-pair, use `psa_export_public_key()` or `psa_export_formatted_public_key()`. + +.. function:: psa_export_formatted_public_key + + .. summary:: + Export a public key or the public part of a key-pair in a specified format. + + .. param:: psa_key_format_t format + The required export format. + One of the ``PSA_KEY_FORMAT_XXX`` values, or an implementation-specific format. + .. param:: psa_key_format_option_t options + Formatting options to use. + One of the ``PSA_KEY_FORMAT_OPTION_XXX`` values, an implementation-specific option, or a bitwise-or of them. + .. param:: psa_key_id_t key + Identifier of the key to export. + .. param:: uint8_t * data + Buffer where the key data is to be written. + .. param:: size_t data_size + Size of the ``data`` buffer in bytes. + This must be appropriate for the key: + + * The required output size is :code:`PSA_EXPORT_FORMATTED_PUBLIC_KEY_OUTPUT_SIZE(format, options, type, bits)`, where ``format`` is the key format, ``options`` is the format options, ``type`` is the key type, and ``bits`` is the key size in bits. + * `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE` evaluates to the maximum output size of any supported public key or public part of a key pair, in any supported combination of key format and options. + * `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE` evaluates to the maximum output size of any supported public key or key pair, in any supported combination of key format and options. + + .. param:: size_t * data_length + On success, the number of bytes that make up the key data. + + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + The first ``(*data_length)`` bytes of ``data`` contain the exported public key. + .. retval:: PSA_ERROR_INVALID_HANDLE + ``key`` is not a valid key identifier. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: + + * The key is neither a public key nor a key pair. + * The key format is not valid. + * The key format is not applicable to the key type. + * The key format option is not applicable to the key format. + + .. todo:: + Decide on appropriate behavior if the format option does not match the key type. + My preference is to ignore the option if the key format does not use that option when encoding the provided key type. + + If the option is never applicable to the format, that should (I think) be an error. + However, that means that format options cannot have overlapping values, even if they never apply to the same format? + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: + + * The key's storage location does not support export of the key. + * The implementation does not support export of keys with this key type. + * The implementation does not support public key export in the requested key format or format options. + .. retval:: PSA_ERROR_BUFFER_TOO_SMALL + The size of the ``data`` buffer is too small. + `PSA_EXPORT_FORMATTED_PUBLIC_KEY_OUTPUT_SIZE()`, `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE`, or `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE` can be used to determine a sufficient buffer size. + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. + + Extract a public key, or a public part of a key-pair, from the key store into a data buffer using a specified key format. + The output contains the public-key value, and, depending on the format, some of the key attributes. + + If :code:`format==PSA_KEY_FORMAT_DEFAULT` and :code:`options==PSA_KEY_FORMAT_OPTION_DEFAULT`, this is equivalent to calling `psa_export_public_key()`. + Some of the options can be used with the default key format for some key types, see `PSA_KEY_FORMAT_DEFAULT`. + + The output of this function can be passed to `psa_import_key()` to create an object that is equivalent to the public key. + + For standard key types, the default output format is defined in the *Key format* section for the applicable public-key type in :secref:`key-types`. + Other key formats are defined in :secref:`key-formats`. + + Some key formats can optionally include additional content or use different encodings. + These can be selected by using one or more of the ``PSA_KEY_FORMAT_OPTION_XXX`` values. + + The output of this function can be passed to `psa_import_formatted_key()`, specifying the same format, to create an equivalent public-key object. + + Exporting a public key object or the public part of a key-pair is always permitted, regardless of the key's usage flags. .. macro:: PSA_EXPORT_KEY_OUTPUT_SIZE :definition: /* implementation-defined value */ @@ -1035,7 +1227,7 @@ Key export The size of the key in bits. .. return:: - If the parameters are valid and supported, return a buffer size in bytes that guarantees that `psa_export_key()` or `psa_export_public_key()` will not fail with :code:`PSA_ERROR_BUFFER_TOO_SMALL`. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or ``0``. If the parameters are not valid, the return value is unspecified. + If the parameters are valid and supported, return a buffer size in bytes that guarantees that `psa_export_key()` will not fail with :code:`PSA_ERROR_BUFFER_TOO_SMALL`. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or ``0``. If the parameters are not valid, the return value is unspecified. The following code illustrates how to allocate enough memory to export a key by querying the key type and size at runtime. @@ -1128,3 +1320,76 @@ Key export This value must be a sufficient buffer size when calling `psa_export_key()` or `psa_export_public_key()` to export any asymmetric key pair or public key that is supported by the implementation, regardless of the exact key type and key size. See also `PSA_EXPORT_KEY_PAIR_MAX_SIZE`, `PSA_EXPORT_PUBLIC_KEY_MAX_SIZE`, and `PSA_EXPORT_KEY_OUTPUT_SIZE()`. + + +.. macro:: PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient output buffer size for `psa_export_formatted_key()`. + + .. param:: format + A supported key format. + .. param:: options + A set of supported key format options. + .. param:: key_type + A supported key type. + .. param:: key_bits + The size of the key in bits. + + .. return:: + If the parameters are valid and supported, return a buffer size in bytes that guarantees that `psa_export_formatted_key()` will not fail with :code:`PSA_ERROR_BUFFER_TOO_SMALL`. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or ``0``. If the parameters are not valid, the return value is unspecified. + + See also `PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE`, `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE`, and `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE`. + +.. macro:: PSA_EXPORT_FORMATTED_PUBLIC_KEY_OUTPUT_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient output buffer size for `psa_export_formatted_public_key()`. + + .. param:: format + A supported public-key format. + .. param:: options + A set of supported key format options. + .. param:: key_type + A public key or key pair key type. + .. param:: key_bits + The size of the key in bits. + + .. return:: + If the parameters are valid and supported, return a buffer size in bytes that guarantees that `psa_export_formatted_public_key()` will not fail with :code:`PSA_ERROR_BUFFER_TOO_SMALL`. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or ``0``. If the parameters are not valid, the return value is unspecified. + + If the parameters are valid and supported, it is recommended that this macro returns the same result as :code:`PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE(format, options, PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(key_type), key_bits)`. + + See also `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE` and `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE`. + +.. macro:: PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient buffer size for exporting any formatted asymmetric key pair. + + This value must be a sufficient buffer size when calling `psa_export_formatted_key()` to export any asymmetric key pair that is supported by the implementation, regardless of the exact key type, key size, key format, and format options. + + See also `PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE()`, `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE`, and `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE`. + +.. macro:: PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient buffer size for exporting any formatted asymmetric public key. + + This value must be a sufficient buffer size when calling `psa_export_formatted_key()` or `psa_export_formatted_public_key()` to export any asymmetric public key that is supported by the implementation, regardless of the exact key type, key size, key format, and format options. + + See also `PSA_EXPORT_FORMATTED_PUBLIC_KEY_OUTPUT_SIZE()`, `PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE()`, `PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE`, and `PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE`. + +.. macro:: PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE + :definition: /* implementation-defined value */ + + .. summary:: + Sufficient buffer size for exporting any formatted asymmetric key pair or public key. + + This value must be a sufficient buffer size when calling `psa_export_formatted_key()` or `psa_export_formatted_public_key()` to export any asymmetric key pair or public key that is supported by the implementation, regardless of the exact key type, key size, key format, and format options. + + See also `PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE`, `PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE`, and `PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE()`. From 088256c5fa9b1a1b805d9806aa1a339264ed29b6 Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Mon, 12 Aug 2024 23:15:47 +0100 Subject: [PATCH 07/10] Add cross references to key formats from applicable key types. --- doc/crypto/api/keys/types.rst | 54 ++++++++++++++++++++------------- doc/crypto/appendix/history.rst | 2 ++ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index 2c77c187..25974770 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -117,7 +117,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -157,7 +157,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -225,7 +225,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -250,7 +250,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -275,7 +275,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -320,7 +320,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -365,7 +365,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -406,7 +406,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. The parity bits in each 64-bit DES key element must be correct. .. subsection:: Key derivation @@ -459,7 +459,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -496,7 +496,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -523,7 +523,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -550,7 +550,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -577,7 +577,7 @@ Symmetric keys .. subsection:: Key format - The data format for import and export of the key is the raw bytes of the key. + The default data format for import and export of the key is the raw bytes of the key. .. subsection:: Key derivation @@ -621,7 +621,7 @@ RSA keys .. subsection:: Key format - The data format for import and export of a key-pair is the non-encrypted :term:`DER` encoding of the representation defined by in :RFC-title:`8017#A.1.2` as ``RSAPrivateKey``, version ``0``. + The default data format for import and export of a key-pair is the non-encrypted :term:`DER` encoding of the representation defined by in :RFC-title:`8017#A.1.2` as ``RSAPrivateKey``, version ``0``. .. code-block:: none @@ -643,6 +643,9 @@ RSA keys See `PSA_KEY_TYPE_RSA_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. + RSA key-pairs can also be imported from and exported using the `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` and `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` key formats. + See :secref:`key-formats`. + .. subsection:: Key generation A call to `psa_generate_key()` will generate an RSA key-pair with the default public exponent of ``65537``. The modulus :math:`n=pq` is a product of two probabilistic primes :math:`p\ \text{and}\ q`, where :math:`2^{r-1} \le n < 2^r` and :math:`r` is the bit size specified in the attributes. @@ -686,7 +689,7 @@ RSA keys .. subsection:: Key format - The data format for import and export of a public key is the :term:`DER` encoding of the representation defined by :RFC-title:`8017#A.1.1` as ``RSAPublicKey``. + The default data format for import and export of a public key is the :term:`DER` encoding of the representation defined by :RFC-title:`8017#A.1.1` as ``RSAPublicKey``. .. code-block:: none @@ -694,6 +697,9 @@ RSA keys modulus INTEGER, -- n publicExponent INTEGER } -- e + RSA public keys can also be imported from and exported using the `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` and `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` key formats. + See :secref:`key-formats`. + .. macro:: PSA_KEY_TYPE_IS_RSA :definition: /* specification-defined value */ @@ -821,7 +827,7 @@ The curve type affects the key format, the key derivation procedure, and the alg .. subsection:: Key format - The data format for import and export of the key-pair depends on the type of elliptic curve. + The default data format for import and export of the key-pair depends on the type of elliptic curve. :numref:`tab-ecc-key-pair-format` shows the format for each type of elliptic curve key-pair. See `PSA_KEY_TYPE_ECC_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. @@ -851,6 +857,9 @@ The curve type affects the key format, the key derivation procedure, and the alg This is a 32-byte string for Edwards25519, and a 57-byte string for Edwards448. + Elliptic curve key-pairs can also be imported from and exported using the `PSA_KEY_FORMAT_EC_PRIVATE_KEY` and `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` key formats. + See :secref:`key-formats`. + .. subsection:: Key derivation The key derivation method used when calling `psa_key_derivation_output_key()` depends on the type of elliptic curve. @@ -939,7 +948,7 @@ The curve type affects the key format, the key derivation procedure, and the alg .. subsection:: Key format - The data format for import and export of the public key depends on the type of elliptic curve. + The default data format for import and export of the public key depends on the type of elliptic curve. :numref:`tab-ecc-public-key-format` shows the format for each type of elliptic curve public key. .. list-table:: Public key formats for elliptic curve keys @@ -970,6 +979,9 @@ The curve type affects the key format, the key derivation procedure, and the alg This is a 32-byte string for Edwards25519, and a 57-byte string for Edwards448. + Elliptic curve public keys can also be imported from and exported using the `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` key format. + See :secref:`key-formats`. + .. macro:: PSA_ECC_FAMILY_SECP_K1 :definition: ((psa_ecc_family_t) 0x17) @@ -1215,7 +1227,7 @@ Diffie Hellman keys .. subsection:: Key format - The data format for import and export of the key-pair is the representation of the private key :math:`x` as a big-endian byte string. + The default data format for import and export of the key-pair is the representation of the private key :math:`x` as a big-endian byte string. The length of the byte string is the private key size in bytes, and leading zeroes are not stripped. See `PSA_KEY_TYPE_DH_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. @@ -1250,7 +1262,7 @@ Diffie Hellman keys .. subsection:: Key format - The data format for export of the public key is the representation of the public key :math:`y = g^x\!\mod p` as a big-endian byte string. + The default data format for export of the public key is the representation of the public key :math:`y = g^x\!\mod p` as a big-endian byte string. The length of the byte string is the length of the base prime :math:`p` in bytes. .. macro:: PSA_DH_FAMILY_RFC7919 @@ -1372,7 +1384,7 @@ SPAKE2+ keys A SPAKE2+ key-pair consists of the two values :math:`w0` and :math:`w1`, which result from the SPAKE2+ registration phase, see :secref:`spake2p-registration`. :math:`w0` and :math:`w1` are scalars in the same range as an elliptic curve private key from the group used as the SPAKE2+ primitive group. - The data format for import and export of the key-pair is the concatenation of the formatted values for :math:`w0` and :math:`w1`, using the standard formats for elliptic curve keys used by the |API|. + The default data format for import and export of the key-pair is the concatenation of the formatted values for :math:`w0` and :math:`w1`, using the default formats for elliptic curve keys used by the |API|. For example, for SPAKE2+ over P-256 (secp256r1), the output from :code:`psa_export_key()` would be the concatenation of: * The P-256 private key :math:`w0`. @@ -1431,7 +1443,7 @@ SPAKE2+ keys :math:`w0` is a scalar in the same range as a elliptic curve private key from the group used as the SPAKE2+ primitive group. :math:`L` is a point on the curve, similar to a public key from the same group, corresponding to the :math:`w1` value in the key pair. - The data format for import and export of the public key is the concatenation of the formatted values for :math:`w0` and :math:`L`, using the standard formats for elliptic curve keys used by the |API|. + The default data format for import and export of the public key is the concatenation of the formatted values for :math:`w0` and :math:`L`, using the default formats for elliptic curve keys used by the |API|. For example, for SPAKE2+ over P-256 (secp256r1), the output from :code:`psa_export_public_key()` would be the concatenation of: * The P-256 private key :math:`w0`. diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index c4d06a3e..9c97ad81 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -38,6 +38,8 @@ Changes to the API - Added definitions for key formats and and formatting options. See :secref:`key-formats`. - Added `psa_import_formatted_key()` to import keys in other formats. + - Added `psa_export_formatted_key()` and `psa_export_formatted_public_key()` to export keys in other formats. + - Added ``PSA_EXPORT_FORMATTED_XXX`` support macros to evaluate buffer sizes for the formatted export functions. Clarifications and fixes ~~~~~~~~~~~~~~~~~~~~~~~~ From f7501a24e52fdce3213ac47745506d22ce16620e Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Wed, 4 Sep 2024 12:31:59 +0100 Subject: [PATCH 08/10] Update canonical header file --- doc/crypto/api.db/psa/crypto.h | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/doc/crypto/api.db/psa/crypto.h b/doc/crypto/api.db/psa/crypto.h index 8cc8cf5c..c4cbc118 100644 --- a/doc/crypto/api.db/psa/crypto.h +++ b/doc/crypto/api.db/psa/crypto.h @@ -10,6 +10,8 @@ typedef /* implementation-defined type */ psa_hash_operation_t; typedef /* implementation-defined type */ psa_key_attributes_t; typedef /* implementation-defined type */ psa_key_derivation_operation_t; typedef uint16_t psa_key_derivation_step_t; +typedef uint32_t psa_key_format_option_t; +typedef uint32_t psa_key_format_t; typedef uint32_t psa_key_id_t; typedef uint32_t psa_key_lifetime_t; typedef uint32_t psa_key_location_t; @@ -224,6 +226,16 @@ typedef struct psa_custom_key_parameters_t { #define PSA_ERROR_INSUFFICIENT_ENTROPY ((psa_status_t)-148) #define PSA_ERROR_INVALID_PADDING ((psa_status_t)-150) #define PSA_EXPORT_ASYMMETRIC_KEY_MAX_SIZE /* implementation-defined value */ +#define PSA_EXPORT_FORMATTED_ASYMMETRIC_KEY_MAX_SIZE \ + /* implementation-defined value */ +#define PSA_EXPORT_FORMATTED_KEY_OUTPUT_SIZE(format, options, key_type, key_bits) \ + /* implementation-defined value */ +#define PSA_EXPORT_FORMATTED_KEY_PAIR_MAX_SIZE \ + /* implementation-defined value */ +#define PSA_EXPORT_FORMATTED_PUBLIC_KEY_MAX_SIZE \ + /* implementation-defined value */ +#define PSA_EXPORT_FORMATTED_PUBLIC_KEY_OUTPUT_SIZE(format, options, key_type, key_bits) \ + /* implementation-defined value */ #define PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, key_bits) \ /* implementation-defined value */ #define PSA_EXPORT_KEY_PAIR_MAX_SIZE /* implementation-defined value */ @@ -255,6 +267,19 @@ typedef struct psa_custom_key_parameters_t { #define PSA_KEY_DERIVATION_OPERATION_INIT /* implementation-defined value */ #define PSA_KEY_DERIVATION_UNLIMITED_CAPACITY \ /* implementation-defined value */ +#define PSA_KEY_FORMAT_DEFAULT ((psa_key_format_t) 0) +#define PSA_KEY_FORMAT_EC_PRIVATE_KEY /* implementation-defined value */ +#define PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY /* implementation-defined value */ +#define PSA_KEY_FORMAT_OPTION_DEFAULT ((psa_key_format_option_t) 0) +#define PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED \ + /* implementation-defined value */ +#define PSA_KEY_FORMAT_OPTION_PEM /* implementation-defined value */ +#define PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN \ + /* implementation-defined value */ +#define PSA_KEY_FORMAT_RSA_PRIVATE_KEY /* implementation-defined value */ +#define PSA_KEY_FORMAT_RSA_PUBLIC_KEY /* implementation-defined value */ +#define PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO \ + /* implementation-defined value */ #define PSA_KEY_ID_NULL ((psa_key_id_t)0) #define PSA_KEY_ID_USER_MAX ((psa_key_id_t)0x3fffffff) #define PSA_KEY_ID_USER_MIN ((psa_key_id_t)0x00000001) @@ -499,6 +524,18 @@ psa_status_t psa_copy_key(psa_key_id_t source_key, psa_key_id_t * target_key); psa_status_t psa_crypto_init(void); psa_status_t psa_destroy_key(psa_key_id_t key); +psa_status_t psa_export_formatted_key(psa_key_format_t format, + psa_key_format_option_t options, + psa_key_id_t key, + uint8_t * data, + size_t data_size, + size_t * data_length); +psa_status_t psa_export_formatted_public_key(psa_key_format_t format, + psa_key_format_option_t options, + psa_key_id_t key, + uint8_t * data, + size_t data_size, + size_t * data_length); psa_status_t psa_export_key(psa_key_id_t key, uint8_t * data, size_t data_size, @@ -558,6 +595,11 @@ psa_status_t psa_hash_update(psa_hash_operation_t * operation, psa_status_t psa_hash_verify(psa_hash_operation_t * operation, const uint8_t * hash, size_t hash_length); +psa_status_t psa_import_formatted_key(const psa_key_attributes_t * attributes, + psa_key_format_t format, + const uint8_t * data, + size_t data_length, + psa_key_id_t * key); psa_status_t psa_import_key(const psa_key_attributes_t * attributes, const uint8_t * data, size_t data_length, From ff008553dc379461d00f53c924c2e60b91086a89 Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Fri, 6 Sep 2024 12:02:52 +0100 Subject: [PATCH 09/10] Reorganise the key management chapter --- doc/crypto/api/keys/management.rst | 1179 ++++++++++++++-------------- 1 file changed, 591 insertions(+), 588 deletions(-) diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index 50f7d602..ec23af30 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -7,687 +7,725 @@ Key management functions ======================== -.. _key-formats: +.. _key-creation: -Key formats ------------ +Key creation +------------ -.. todo:: Consider Splitting this chapter up (before the final 1.3 release) +New keys can be created in the following ways: - With the additions of: +* `psa_import_key()` and `psa_import_formatted_key()` create a key from a data buffer provided by the application. + See :secref:`key-import`. +* `psa_generate_key()` and `psa_generate_key_custom()` create a key from randomly generated data. + See :secref:`key-generation`. +* `psa_key_derivation_output_key()` and `psa_key_derivation_output_key_custom()` create a key from data generated by a pseudorandom derivation process. + See :secref:`kdf`. +* `psa_key_agreement()` creates a key from the shared secret result of a key agreement process. + See :secref:`key-agreement`. +* `psa_pake_get_shared_key()` creates a key from the shared secret result of a password-authenticated key exchange. + See :secref:`pake`. +* `psa_copy_key()` duplicates an existing key with a different lifetime or with a more restrictive usage policy. + See :secref:`key-duplication`. - * Formatted key import/export - * Interruptible public key export - * Interruptible key generation - * Extended key generation - * Key wrapping and unwrapping (this could alternatively be put in with 'Operations') +When creating a key, the attributes for the new key are specified in a `psa_key_attributes_t` object. +Each key creation function defines how it uses the attributes. - This chapter is getting very large as a 'hold-all' for key-related functions. +.. note:: - Consider splitting this up: + The attributes for a key are immutable after the key has been created. - 1. Non-default key formats, key import and export (or even separate those into formats and import/export) - 2. Key wrap/unwrap (and associated specialized formats and algorithms) - 3. General key management: [random] key generation, copying, purging, destroying + The application must set the key algorithm policy and the appropriate key usage flags in the attributes in order for the key to be used in any cryptographic operations. -Outside of the key store, keys are exchanged using defined formats. -These formats are used to import and export keys, or to input public asymmetric keys to key agreement or PAKE operations. +.. _key-generation: -The |API| defines the default format for each standard key type, to be used for these operations. -These formats are defined in the *Key format* section of each key type in :secref:`key-types`. +Key generation +-------------- -Some application use cases require key data to be in other standard formats. -:code:`psa_import_formatted_key()`, :code:`psa_export_formatted_key()`, and :code:`psa_export_formatted_public_key()` allow data in these formats to be used directly with the |API|. +.. function:: psa_generate_key -Some key formats have options for how the key data is represented. -For example, + .. summary:: + Generate a key or key pair. -* Data layouts used in X.509 certificates, such as RSAPublicKey, can be encoded using :term:`DER` or :term:`PEM`. -* Elliptic curve keys can be specified using a curve identifier and the key value, or by providing for full set of curve parameters and the key value. -* Elliptic curve public keys can use a compressed or uncompressed representation for the point on the curve. + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. -These options need to be specified by the application, or a default used, when formatting key data for export. -When importing a key, the formatted data includes information that indicates the formatting options, so the options do not need to be provided by the application. + The following attributes are required for all keys: -The |API| defines elements for some common key formats and format options. -Implementations are permitted to define additional key formats and options. + * The key type. It must not be an asymmetric public key. + * The key size. It must be a valid size for the key type. -.. typedef:: uint32_t psa_key_format_t + The following attributes must be set for keys used in cryptographic operations: - .. summary:: - Encoding of a key format. + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + * The key usage flags, see :secref:`key-usage-flags`. - Key formats are specified in the |API| using values of this type. + The following attributes must be set for keys that do not use the default volatile lifetime: - `PSA_KEY_FORMAT_DEFAULT` (value ``0``) indicates the default format for the key type. + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. -.. macro:: PSA_KEY_FORMAT_DEFAULT - :definition: ((psa_key_format_t) 0) + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. - .. summary:: - Key format value indicating the default format. + .. param:: psa_key_id_t * key + On success, an identifier for the newly created key. + For persistent keys, this is the key identifier defined in ``attributes``. + `PSA_KEY_ID_NULL` on failure. - The default formats are specified for each key type in the :secref:`key-types` chapter. + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the 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_NOT_SUPPORTED + The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: - Some options can be specified with the default format, when appropriate for the key type. - See the description of each format option for details. + * The key type is invalid, or is an asymmetric public key type. + * The key size is not valid for the key type. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + .. retval:: PSA_ERROR_NOT_PERMITTED + The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. - .. subsection:: Compatible key types + The key is generated randomly. Its location, policy, type and size are taken from ``attributes``. - All key types can be used with the default format. + Implementations must reject an attempt to generate a key of size ``0``. - .. subsection:: Key format options + The key type definitions in :secref:`key-types` provide specific details relating to generation of the key. - * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + .. note:: -.. macro:: PSA_KEY_FORMAT_RSA_PUBLIC_KEY - :definition: /* implementation-defined value */ + This function is equivalent to calling `psa_generate_key_custom()` with the production parameters `PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` (``custom_data`` is ignored). + +.. struct:: psa_custom_key_parameters_t + :type: .. summary:: - The *RSAPublicKey* key format for RSA public keys. + Custom production parameters for key generation or key derivation. - RSAPublicKey is defined by :RFC-title:`8017#A.1.1`. + .. field:: uint32_t flags + Flags to control the key production process. + ``0`` for the default production parameters. - This is the default key format for RSA public keys. + .. note:: - When exporting a key in this format, the output is :term:`DER` encoded by default. - For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. + Future versions of the specification, and implementations, may add other fields in this structure. - .. subsection:: Compatible key types + The interpretation of this structure depends on the type of the key. :numref:`tab-custom-key-parameters` shows the custom production parameters for each type of key. See the key type definitions for details of the valid parameter values. - * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` - * `PSA_KEY_TYPE_RSA_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) + .. list-table:: Custom key parameters + :name: tab-custom-key-parameters + :widths: 1 4 + :header-rows: 1 - .. subsection:: Key format options + * - Key type + - Custom key parameters - * `PSA_KEY_FORMAT_OPTION_PEM` + * - RSA -.. macro:: PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO - :definition: /* implementation-defined value */ + - Use the production parameters to select an exponent value that is different from the default value of ``65537``. - .. summary:: - The *SubjectPublicKeyInfo* key format for RSA and elliptic curve public keys. + See `PSA_KEY_TYPE_RSA_KEY_PAIR`. - SubjectPublicKeyInfo is defined by :RFC-title:`5280#4.1`. - The following documents define the encoding of SubjectPublicKeyInfo elements, depending on the type of key: + * - Other key types + - Reserved for future use. - * :RFC-title:`8017` defines the details for RSA keys. - * :RFC-title:`5480` defines the details for Weierstrass elliptic curve keys. - * :RFC-title:`8410` defines the details for Montgomery and Edwards elliptic curve keys. + ``flags`` must be ``0``. - When exporting a key in this format, the output is :term:`DER` encoded by default. - For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. +.. macro:: PSA_CUSTOM_KEY_PARAMETERS_INIT + :definition: { 0 } - When exporting a Weierstrass elliptic curve key in this format: + .. summary:: + The default production parameters for key generation or key derivation. - * The *ECPoint* containing the key value is uncompressed by default. - For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. - * The *ECParameters* element uses a *namedCurve* by default. - To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. + Calling `psa_generate_key_custom()` or `psa_key_derivation_output_key_custom()` with :code:`custom == PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` is equivalent to calling `psa_generate_key()` or `psa_key_derivation_output_key()` + respectively. - .. subsection:: Compatible key types +.. function:: psa_generate_key_custom - * `PSA_KEY_TYPE_ECC_PUBLIC_KEY` - * `PSA_KEY_TYPE_ECC_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) - * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` - * `PSA_KEY_TYPE_RSA_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) + .. summary:: + Generate a key or key pair using custom production parameters. - .. subsection:: Key format options + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. - * `PSA_KEY_FORMAT_OPTION_PEM` - * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) - * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) + The following attributes are required for all keys: -.. macro:: PSA_KEY_FORMAT_RSA_PRIVATE_KEY - :definition: /* implementation-defined value */ + * The key type. It must not be an asymmetric public key. + * The key size. It must be a valid size for the key type. - .. summary:: - The *RSAPrivateKey* key format for RSA key-pairs. + The following attributes must be set for keys used in cryptographic operations: - RSAPrivateKey is defined by :RFC-title:`8017#A.1.2`. + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + * The key usage flags, see :secref:`key-usage-flags`. - This is the default key format for RSA key-pairs. + The following attributes must be set for keys that do not use the default volatile lifetime: - When exporting a key in this format, the output is :term:`DER` encoded by default. - For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. - .. subsection:: Compatible key types + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. - * `PSA_KEY_TYPE_RSA_KEY_PAIR` + .. param:: const psa_custom_key_parameters_t * custom + Customized production parameters for the key generation. - .. subsection:: Key format options + When this is `PSA_CUSTOM_KEY_PARAMETERS_INIT` with ``custom_data_length == 0``, this function is equivalent to `psa_generate_key()`. + .. param:: const uint8_t * custom_data + A buffer containing additional variable-sized production parameters. + .. param:: size_t custom_data_length + Length of ``custom_data`` in bytes. + .. param:: mbedtls_svc_key_id_t * key + On success, an identifier for the newly created key. + For persistent keys, this is the key identifier defined in ``attributes``. + `PSA_KEY_ID_NULL` on failure. - * `PSA_KEY_FORMAT_OPTION_PEM` + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the 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_NOT_SUPPORTED + The following conditions can result in this error: -.. macro:: PSA_KEY_FORMAT_EC_PRIVATE_KEY - :definition: /* implementation-defined value */ + * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + * The production parameters are not supported by the implementation. + .. retval:: PSA_ERROR_INVALID_ARGUMENT + The following conditions can result in this error: - .. summary:: - The *ECPrivateKey* key format for elliptic curve key-pairs. + * The key type is invalid, or is an asymmetric public key type. + * The key size is not valid for the key type. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + * The production parameters are invalid. + .. retval:: PSA_ERROR_NOT_PERMITTED + The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. - ECPrivateKey is defined by :RFC-title:`5915#3`. - :RFC:`5915` includes the encoding of Weierstrass elliptic curve key-pairs. - See :RFC-title:`8410` for the encoding of Montgomery and Edwards elliptic curve key-pairs. + Use this function to provide explicit production parameters when generating a key. + See the description of `psa_generate_key()` for the operation of this function with the default production parameters. - When exporting a key in this format: + The key is generated randomly. Its location, policy, type and size are taken from ``attributes``. - * The public key is always included in the output. - * The output is :term:`DER` encoded by default. - For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. + Implementations must reject an attempt to generate a key of size ``0``. - When exporting a Weierstrass elliptic curve key in this format: + See the documentation of `psa_custom_key_parameters_t` for a list of non-default production parameters. See the key type definitions in :secref:`key-types` for details of the custom production parameters used for key generation. - * The *ECPoint* containing the key value is uncompressed by default. - For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. - * The *ECParameters* element uses a *namedCurve* by default. - To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. +.. _key-duplication: - .. subsection:: Compatible key types - - * `PSA_KEY_TYPE_ECC_KEY_PAIR` +Key duplication +--------------- - .. subsection:: Key format options +.. function:: psa_copy_key - * `PSA_KEY_FORMAT_OPTION_PEM` - * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) - * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) + .. summary:: + Make a copy of a key. -.. macro:: PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY - :definition: /* implementation-defined value */ + .. param:: psa_key_id_t source_key + The key to copy. + It must permit the usage `PSA_KEY_USAGE_COPY`. + If a private or secret key is being copied outside of a secure element it must also permit `PSA_KEY_USAGE_EXPORT`. + .. param:: const psa_key_attributes_t * attributes + The attributes for the new key. - .. summary:: - The *OneAsymmetricKey* key format for RSA and elliptic curve key-pairs. + The following attributes must be set for keys used in cryptographic operations: - .. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead? + * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. + * The key usage flags, see :secref:`key-usage-flags`. - Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo. + These flags are combined with the source key policy so that both sets of restrictions apply, as described in the documentation of this function. - Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey? + The following attributes must be set for keys that do not use the default volatile lifetime: - OneAsymmetricKey is defined by :RFC-title:`5958#2`. - OneAsymmetricKey is an update to the PKCS#8 *PrivateKeyInfo* format defined by :RFC-title:`5208`. - Encoding of specific key types is defined in other documents: + * The key lifetime, see :secref:`key-lifetimes`. + * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. - * :RFC-title:`8017` defines the encoding of RSA keys. - * :RFC-title:`5915` defines the encoding of Weierstrass elliptic curve keys. - * :RFC-title:`8410` defines the encoding of Montgomery and Edwards elliptic curve keys. + The following attributes are optional: - When exporting a key in this format: + * If the key type has a non-default value, it must be equal to the source key type. + * If the key size is nonzero, it must be equal to the source key size. - * The public key is always included in the output. - * The output is :term:`DER` encoded by default. - For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. + .. note:: + This is an input parameter: it is not updated with the final key attributes. + The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. - When exporting a Weierstrass elliptic curve key in this format: + .. param:: psa_key_id_t * target_key + On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. - * The *ECPoint* containing the key value is uncompressed by default. - For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. - * The *ECParameters* element uses a *namedCurve* by default. - To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If the new key is persistent, the key material and the key's metadata have been saved to persistent storage. + .. retval:: PSA_ERROR_INVALID_HANDLE + ``source_key`` is not a valid key identifier. + .. 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 following conditions can result in this error: - .. subsection:: Compatible key types + * ``attributes`` specifies a key type or key size which does not match the attributes of ``source key``. + * The lifetime or identifier in ``attributes`` are invalid. + * The key policies from ``source_key`` and those specified in ``attributes`` are incompatible. + .. retval:: PSA_ERROR_NOT_SUPPORTED + The following conditions can result in this error: - * `PSA_KEY_TYPE_ECC_KEY_PAIR` - * `PSA_KEY_TYPE_RSA_KEY_PAIR` + * The ``source key`` storage location does not support copying to the target key's storage location. + * The key attributes, as a whole, are not supported in the target key's storage location. + .. retval:: PSA_ERROR_NOT_PERMITTED + The following conditions can result in this error: - .. subsection:: Key format options + * ``source_key`` does not have the `PSA_KEY_USAGE_COPY` usage flag. + * ``source_key`` does not have the `PSA_KEY_USAGE_EXPORT` usage flag, and the location of ``target_key`` is outside the security boundary of the ``source_key`` storage location. + * The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY + .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. - * `PSA_KEY_FORMAT_OPTION_PEM` - * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) - * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) + Copy key material from one location to another. Its location is taken from ``attributes``, its policy is the intersection of the policy in ``attributes`` and the source key policy, and its type and size are taken from the source key. -.. todo:: RFC 5958/PKCS#8 also supports encryption and authentication of the key data. + This function is primarily useful to copy a key from one location to another, as it populates a key using the material from another key which can have a different lifetime. - This would either be a *EncryptedPrivateKeyInfo* structure (PKCS#8) or one of the CMS content types. - This requires one or more additional format specifiers. + This function can be used to share a key with a different party, subject to implementation-defined restrictions on key sharing. -.. typedef:: uint32_t psa_key_format_option_t + The policy on the source key must have the usage flag `PSA_KEY_USAGE_COPY` set. This flag is sufficient to permit the copy if the key has the lifetime `PSA_KEY_LIFETIME_VOLATILE` or `PSA_KEY_LIFETIME_PERSISTENT`. Some secure elements do not provide a way to copy a key without making it extractable from the secure element. If a key is located in such a secure element, then the key must have both usage flags `PSA_KEY_USAGE_COPY` and `PSA_KEY_USAGE_EXPORT` in order to make a copy of the key outside the secure element. - .. summary:: - Encoding of formatting options for a key format. + The resulting key can only be used in a way that conforms to both the policy of the original key and the policy specified in the ``attributes`` parameter: - Key format options are specified in the |API| using values of this type. - When multiple format options are required, the options are combined using bitwise-OR. + * 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``. + * If both permit the same algorithm or wildcard-based algorithm, the resulting key has the same permitted algorithm. + * 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. + * If the policies do not permit any algorithm in common, this function fails with the status :code:`PSA_ERROR_INVALID_ARGUMENT`. - `PSA_KEY_FORMAT_OPTION_DEFAULT` (value ``0``) indicates the default format options for the key format. + As a result, the new key cannot be used for operations that were not permitted on the source key. -.. macro:: PSA_KEY_FORMAT_OPTION_DEFAULT - :definition: ((psa_key_format_option_t) 0) + The effect of this function on implementation-defined attributes is implementation-defined. - .. summary:: - Key format option value indicating the default options. +.. _key-destruction: - The default format options are specified by each key format. +Key destruction +--------------- -.. macro:: PSA_KEY_FORMAT_OPTION_PEM - :definition: /* implementation-defined value */ +.. function:: psa_destroy_key .. summary:: - Key format option to encode the key data using :term:`PEM` encoding. + Destroy a key. - By default, key formats that are defined using :term:`ASN.1` use the binary :term:`DER` encoding for key export. - The `PSA_KEY_FORMAT_OPTION_PEM` option results in using the ASCII :term:`PEM` encoding instead. + .. param:: psa_key_id_t key + Identifier of the key to erase. + If this is `PSA_KEY_ID_NULL`, do nothing and return :code:`PSA_SUCCESS`. - PEM encoding is defined by :RFC-title:`7468`. + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + If ``key`` was a valid key identifier, then the key material that it referred to has been erased. + Alternatively, ``key`` was `PSA_KEY_ID_NULL`. + .. retval:: PSA_ERROR_NOT_PERMITTED + The key cannot be erased because it is read-only, either due to a policy or due to physical restrictions. + .. retval:: PSA_ERROR_INVALID_HANDLE + ``key`` is neither a valid key identifier, nor `PSA_KEY_ID_NULL`. + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + There was an failure in communication with the cryptoprocessor. The key material might still be present in the cryptoprocessor. + .. retval:: PSA_ERROR_STORAGE_FAILURE + The storage operation failed. Implementations must make a best effort to erase key material even in this situation, however, it might be impossible to guarantee that the key material is not recoverable in such cases. + .. retval:: PSA_ERROR_DATA_CORRUPT + The storage is corrupted. Implementations must make a best effort to erase key material even in this situation, however, it might be impossible to guarantee that the key material is not recoverable in such cases. + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + An unexpected condition which is not a storage corruption or a communication failure occurred. The cryptoprocessor might have been compromised. + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. - .. note:: - Some key formats use PEM labels that are not described in :RFC:`7468`, but are used in other tools that produce and consume PEM-encoded data. + This function destroys a key from both volatile memory and, if applicable, non-volatile storage. Implementations must make a best effort to ensure that that the key material cannot be recovered. - This option is not applicable to the default key format. - To export a PEM-encoded key, use the appropriate format specifier. + This function also erases any metadata such as policies and frees resources associated with the key. - .. subsection:: Related key formats + Destroying the key makes the key identifier invalid, and the key identifier must not be used again by the application. - * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` - * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` - * `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` - * `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` - * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + If a key is currently in use in a multi-part operation, then destroying the key will cause the multi-part operation to fail. -.. macro:: PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED - :definition: /* implementation-defined value */ +.. function:: psa_purge_key .. summary:: - Key format option to encode Weierstrass elliptic curve points in compressed form. + Remove non-essential copies of key material from memory. - By default, Weierstrass elliptic curve points are encoded in uncompressed form for key export. - The `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option results in using compressed form instead. + .. param:: psa_key_id_t key + Identifier of the key to purge. - The compressed and uncompressed ECPoint format is defined by :cite-title:`SEC1` §2.3.3. + .. return:: psa_status_t + .. retval:: PSA_SUCCESS + Success. + The key material has been removed from memory, if the key material is not currently required. + .. retval:: PSA_ERROR_INVALID_HANDLE + ``key`` is not a valid key identifier. + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE + .. retval:: PSA_ERROR_STORAGE_FAILURE + .. retval:: PSA_ERROR_DATA_CORRUPT + .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_CORRUPTION_DETECTED + .. retval:: PSA_ERROR_BAD_STATE + The library requires initializing by a call to `psa_crypto_init()`. - This option can be used with the default key format, when exporting elliptic curve public keys. + For keys that have been created with the `PSA_KEY_USAGE_CACHE` usage flag, an implementation is permitted to make additional copies of the key material that are not in storage and not for the purpose of ongoing operations. - .. subsection:: Related key formats + This function will remove these extra copies of the key material from memory. - * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` - * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` - * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + This function is not required to remove key material from memory in any of the following situations: -.. macro:: PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN - :definition: /* implementation-defined value */ + * The key is currently in use in a cryptographic operation. + * The key is volatile. - .. summary:: - Key format option to output the Weierstrass elliptic curve domain parameters in the key format. + See also :secref:`key-material`. - By default, key formats that include the *ECParameters* element specify a *namedCurve* for key export. - The `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option results in specifying the full domain parameters for the elliptic curve instead. +.. _key-formats: - The ECParameters format is defined by :RFC-title:`5480#2.1.1`. +Key formats +----------- - This option is not applicable to the default key format. +Outside of the key store, keys are exchanged using defined formats. +These formats are used to import and export keys, or to input public asymmetric keys to key agreement or PAKE operations. - .. subsection:: Related key formats +The |API| defines the default format for each standard key type, to be used for these operations. +The default formats are defined in the *Key format* section of each key type in :secref:`key-types`. - * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` - * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` - * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` +Some application use cases require key data to be in other standard formats. +:code:`psa_import_formatted_key()`, :code:`psa_export_formatted_key()`, and :code:`psa_export_formatted_public_key()` allow data in these formats to be used directly with the |API|. -.. _key-creation: +Some key formats have options for how the key data is represented. +For example, -Key creation ------------- +* Data layouts used in X.509 certificates, such as RSAPublicKey, can be encoded using :term:`DER` or :term:`PEM`. +* Elliptic curve keys can be specified using a curve identifier and the key value, or by providing for full set of curve parameters and the key value. +* Elliptic curve public keys can use a compressed or uncompressed representation for the point on the curve. -New keys can be created in the following ways: +These options need to be specified by the application, or a default used, when formatting key data for export. +When importing a key, the formatted data includes information that indicates the formatting options, so the options do not need to be provided by the application. -* `psa_import_key()` and `psa_import_formatted_key()` create a key from a data buffer provided by the application. -* `psa_generate_key()` and `psa_generate_key_custom()` create a key from randomly generated data. -* `psa_key_derivation_output_key()` and `psa_key_derivation_output_key_custom()` create a key from data generated by a pseudorandom derivation process. See :secref:`kdf`. -* `psa_key_agreement()` creates a key from the shared secret result of a key agreement process. See :secref:`key-agreement`. -* `psa_pake_get_shared_key()` creates a key from the shared secret result of a password-authenticated key exchange. See :secref:`pake`. -* `psa_copy_key()` duplicates an existing key with a different lifetime or with a more restrictive usage policy. +The |API| defines elements for some common key formats and format options. +Implementations are permitted to define additional key formats and options. -When creating a key, the attributes for the new key are specified in a `psa_key_attributes_t` object. Each key creation function defines how it uses the attributes. +.. typedef:: uint32_t psa_key_format_t -.. note:: + .. summary:: + Encoding of a key format. - The attributes for a key are immutable after the key has been created. + Key formats are specified in the |API| using values of this type. - The application must set the key algorithm policy and the appropriate key usage flags in the attributes in order for the key to be used in any cryptographic operations. + `PSA_KEY_FORMAT_DEFAULT` (value ``0``) indicates the default format for the key type. -.. function:: psa_import_key +.. macro:: PSA_KEY_FORMAT_DEFAULT + :definition: ((psa_key_format_t) 0) .. summary:: - Import a key in binary format. + Key format value indicating the default format. - .. param:: const psa_key_attributes_t * attributes - The attributes for the new key. + The default formats are specified for each key type in the :secref:`key-types` chapter. - The following attributes are required for all keys: + Some options can be specified with the default format, when appropriate for the key type. + See the description of each format option for details. - * The key type determines how the ``data`` buffer is interpreted. + .. subsection:: Compatible key types - The following attributes must be set for keys used in cryptographic operations: + All key types can be used with the default format. - * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. - * The key usage flags, see :secref:`key-usage-flags`. + .. subsection:: Key format options - The following attributes must be set for keys that do not use the default volatile lifetime: + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) - * The key lifetime, see :secref:`key-lifetimes`. - * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. +.. macro:: PSA_KEY_FORMAT_RSA_PUBLIC_KEY + :definition: /* implementation-defined value */ - The following attributes are optional: + .. summary:: + The *RSAPublicKey* key format for RSA public keys. - * If the key size is nonzero, it must be equal to the key size determined from ``data``. + RSAPublicKey is defined by :RFC-title:`8017#A.1.1`. - .. note:: - This is an input parameter: it is not updated with the final key attributes. - The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. + This is the default key format for RSA public keys. - .. param:: const uint8_t * data - Buffer containing the key data. - The content of this buffer is interpreted according to the type declared in ``attributes``. - .. param:: size_t data_length - Size of the ``data`` buffer in bytes. - .. param:: psa_key_id_t * key - On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. + When exporting a key in this format, the output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - .. return:: psa_status_t - .. retval:: PSA_SUCCESS - Success. - If the 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_NOT_SUPPORTED - The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. - .. retval:: PSA_ERROR_INVALID_ARGUMENT - The following conditions can result in this error: + .. subsection:: Compatible key types - * The key type is invalid. - * The key size is nonzero, and is incompatible with the key data in ``data``. - * The key lifetime is invalid. - * The key identifier is not valid for the key lifetime. - * The key usage flags include invalid values. - * The key's permitted-usage algorithm is invalid. - * The key attributes, as a whole, are invalid. - * The key data is not correctly formatted for the key type. - .. retval:: PSA_ERROR_NOT_PERMITTED - The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. - .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY - .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE - .. retval:: PSA_ERROR_COMMUNICATION_FAILURE - .. retval:: PSA_ERROR_STORAGE_FAILURE - .. retval:: PSA_ERROR_DATA_CORRUPT - .. retval:: PSA_ERROR_DATA_INVALID - .. retval:: PSA_ERROR_CORRUPTION_DETECTED - .. retval:: PSA_ERROR_BAD_STATE - The library requires initializing by a call to `psa_crypto_init()`. + * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) - The key is extracted from the provided ``data`` buffer. Its location, policy, and type are taken from ``attributes``. + .. subsection:: Key format options - 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. + * `PSA_KEY_FORMAT_OPTION_PEM` - This function supports any output from `psa_export_key()`. - The default format is defined in the *Key format* section for each key type. - Other key formats can be imported using `psa_import_formatted_key()`. +.. macro:: PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO + :definition: /* implementation-defined value */ - Implementations can optionally support other formats in calls to `psa_import_key()`, in addition to the default format. + .. summary:: + The *SubjectPublicKeyInfo* key format for RSA and elliptic curve public keys. - .. note:: - 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. + SubjectPublicKeyInfo is defined by :RFC-title:`5280#4.1`. + The following documents define the encoding of SubjectPublicKeyInfo elements, depending on the type of key: - .. admonition:: Implementation note + * :RFC-title:`8017` defines the details for RSA keys. + * :RFC-title:`5480` defines the details for Weierstrass elliptic curve keys. + * :RFC-title:`8410` defines the details for Montgomery and Edwards elliptic curve keys. - 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. + When exporting a key in this format, the output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated. + When exporting a Weierstrass elliptic curve key in this format: -.. function:: psa_import_formatted_key + * The *ECPoint* containing the key value is uncompressed by default. + For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. + * The *ECParameters* element uses a *namedCurve* by default. + To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. - .. summary:: - Import a key in a specified format. + .. subsection:: Compatible key types - .. param:: const psa_key_attributes_t * attributes - The attributes for the new key. + * `PSA_KEY_TYPE_ECC_PUBLIC_KEY` + * `PSA_KEY_TYPE_ECC_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) + * `PSA_KEY_TYPE_RSA_PUBLIC_KEY` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` (when used with :code:`psa_export_formatted_public_key()`) - Depending on the specified key format, and the attributes encoded in the key data, some of the key attributes can be optional. + .. subsection:: Key format options - The following attributes are required for formats that do not specify a key type: + * `PSA_KEY_FORMAT_OPTION_PEM` + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) - * When the format does not specify a key type: the key type in ``attributes`` determines how the ``data`` buffer is interpreted. - * 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. +.. macro:: PSA_KEY_FORMAT_RSA_PRIVATE_KEY + :definition: /* implementation-defined value */ - The following attributes must be set for keys used in cryptographic operations: + .. summary:: + The *RSAPrivateKey* key format for RSA key-pairs. - * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. - * The key usage flags, see :secref:`key-usage-flags`. + RSAPrivateKey is defined by :RFC-title:`8017#A.1.2`. - 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)`. + This is the default key format for RSA key-pairs. - The following attributes must be set for keys that do not use the default volatile lifetime: + When exporting a key in this format, the output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - * The key lifetime, see :secref:`key-lifetimes`. - * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. + .. subsection:: Compatible key types - The following attributes are optional: + * `PSA_KEY_TYPE_RSA_KEY_PAIR` - * If the key size is nonzero, it must be equal to the key size determined from ``data``. + .. subsection:: Key format options - .. note:: - This is an input parameter: it is not updated with the final key attributes. - The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. - .. param:: psa_key_format_t format - The format of the key data. - One of the ``PSA_KEY_FORMAT_XXX`` values, or an implementation-specific format. - .. param:: const uint8_t * data - Buffer containing the key data. - The content of this buffer is interpreted according to the key format ``format``. - The type declared in ``attributes`` is used if the format and key data do not specify a key type. - .. param:: size_t data_length - Size of the ``data`` buffer in bytes. - .. param:: psa_key_id_t * key - On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. + * `PSA_KEY_FORMAT_OPTION_PEM` - .. return:: psa_status_t - .. retval:: PSA_SUCCESS - Success. - If the 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_NOT_SUPPORTED - The following conditions can result in this error: +.. macro:: PSA_KEY_FORMAT_EC_PRIVATE_KEY + :definition: /* implementation-defined value */ - * The key format is not supported by the implementation. - * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. - .. retval:: PSA_ERROR_INVALID_ARGUMENT - The following conditions can result in this error: + .. summary:: + The *ECPrivateKey* key format for elliptic curve key-pairs. - * The key type is invalid, or is `PSA_KEY_TYPE_NONE` when a type is required. - * The key size is nonzero, and is incompatible with the key data in ``data``. - * The key lifetime is invalid. - * The key identifier is not valid for the key lifetime. - * The key usage flags include invalid values. - * The key's permitted-usage algorithm is invalid. - * The key attributes, as a whole, are invalid. - * The key format is invalid. - * The key data is not correctly formatted for the key format or the key type. - .. retval:: PSA_ERROR_NOT_PERMITTED - The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. - .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY - .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE - .. retval:: PSA_ERROR_COMMUNICATION_FAILURE - .. retval:: PSA_ERROR_STORAGE_FAILURE - .. retval:: PSA_ERROR_DATA_CORRUPT - .. retval:: PSA_ERROR_DATA_INVALID - .. retval:: PSA_ERROR_CORRUPTION_DETECTED - .. retval:: PSA_ERROR_BAD_STATE - The library requires initializing by a call to `psa_crypto_init()`. + ECPrivateKey is defined by :RFC-title:`5915#3`. + :RFC:`5915` includes the encoding of Weierstrass elliptic curve key-pairs. + See :RFC-title:`8410` for the encoding of Montgomery and Edwards elliptic curve key-pairs. - 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``. + When exporting a key in this format: - If the format is `PSA_KEY_FORMAT_DEFAULT`, this is equivalent to calling `psa_import_key()`. + * The public key is always included in the output. + * The output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - For non-default key formats, the key format either specifies the key type, or the formatted data encodes the key type. - 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. - 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`. + When exporting a Weierstrass elliptic curve key in this format: - 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. + * The *ECPoint* containing the key value is uncompressed by default. + For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. + * The *ECParameters* element uses a *namedCurve* by default. + To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. - 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())`: + .. subsection:: Compatible key types - * 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``. - * If both permit the same algorithm or wildcard-based algorithm, the resulting key has the same permitted algorithm. - * 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. - * If the policies do not permit any algorithm in common, this function fails with the status :code:`PSA_ERROR_INVALID_ARGUMENT`. + * `PSA_KEY_TYPE_ECC_KEY_PAIR` - As a result, the new key cannot be used for operations that were not permitted by the imported key data. + .. subsection:: Key format options - .. todo:: The proposed constraints on key policy are probably too strict. + * `PSA_KEY_FORMAT_OPTION_PEM` + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) - * 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. - * Many of the formats include an optional *KeyUsage* element that defines a set of permitted uses. - These partially map onto |API| usage flags. +.. macro:: PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY + :definition: /* implementation-defined value */ - 1. What to do if the format does not include a algorithm identifier? - 2. What to do if the algorithm identifier is too general for the algorithm encodings in |API|? - 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? - 4. If a *KeyUsage* is **not** provided, do we just use the ``attributes`` usage flags? - 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? + .. summary:: + The *OneAsymmetricKey* key format for RSA and elliptic curve key-pairs. - Implementations can define implementation-specific formats that may have other behaviors relating to ``attributes``. + .. todo:: Should this be named ``PSA_KEY_FORMAT_PKCS8`` instead? - .. note:: - The |API| does not support asymmetric private key objects outside of a key pair. - When importing a private key, the corresponding key-pair type is created. - 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. + Technically I think not: PKCS#8 defines both *PrivateKeyInfo* and *EncryptedPrivateKeyInfo*, OneAsymmetricKey (version 1) is synonymous with PrivateKeyInfo. - .. admonition:: Implementation note + Perhaps ``PSA_KEY_FORMAT_PRIVATE_KEY_INFO`` could be a synonym of OneAsymmetricKey? - 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. + OneAsymmetricKey is defined by :RFC-title:`5958#2`. + OneAsymmetricKey is an update to the PKCS#8 *PrivateKeyInfo* format defined by :RFC-title:`5208`. + Encoding of specific key types is defined in other documents: - It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated. + * :RFC-title:`8017` defines the encoding of RSA keys. + * :RFC-title:`5915` defines the encoding of Weierstrass elliptic curve keys. + * :RFC-title:`8410` defines the encoding of Montgomery and Edwards elliptic curve keys. -.. struct:: psa_custom_key_parameters_t - :type: + When exporting a key in this format: - .. summary:: - Custom production parameters for key generation or key derivation. + * The public key is always included in the output. + * The output is :term:`DER` encoded by default. + For output that is :term:`PEM` encoded, use the `PSA_KEY_FORMAT_OPTION_PEM` option. - .. field:: uint32_t flags - Flags to control the key production process. - ``0`` for the default production parameters. + When exporting a Weierstrass elliptic curve key in this format: - .. note:: + * The *ECPoint* containing the key value is uncompressed by default. + For the compressed encoding, use the `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option. + * The *ECParameters* element uses a *namedCurve* by default. + To output specified domain parameters instead, use the `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option. - Future versions of the specification, and implementations, may add other fields in this structure. + .. subsection:: Compatible key types - The interpretation of this structure depends on the type of the key. :numref:`tab-custom-key-parameters` shows the custom production parameters for each type of key. See the key type definitions for details of the valid parameter values. + * `PSA_KEY_TYPE_ECC_KEY_PAIR` + * `PSA_KEY_TYPE_RSA_KEY_PAIR` - .. list-table:: Custom key parameters - :name: tab-custom-key-parameters - :widths: 1 4 - :header-rows: 1 + .. subsection:: Key format options - * - Key type - - Custom key parameters + * `PSA_KEY_FORMAT_OPTION_PEM` + * `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` (for Weierstrass elliptic curve keys) + * `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` (for Weierstrass elliptic curve keys) - * - RSA +.. todo:: RFC 5958/PKCS#8 also supports encryption and authentication of the key data. - - Use the production parameters to select an exponent value that is different from the default value of ``65537``. + This would either be a *EncryptedPrivateKeyInfo* structure (PKCS#8) or one of the CMS content types. + This requires one or more additional format specifiers. - See `PSA_KEY_TYPE_RSA_KEY_PAIR`. +.. typedef:: uint32_t psa_key_format_option_t - * - Other key types - - Reserved for future use. + .. summary:: + Encoding of formatting options for a key format. - ``flags`` must be ``0``. + Key format options are specified in the |API| using values of this type. + When multiple format options are required, the options are combined using bitwise-OR. -.. macro:: PSA_CUSTOM_KEY_PARAMETERS_INIT - :definition: { 0 } + `PSA_KEY_FORMAT_OPTION_DEFAULT` (value ``0``) indicates the default format options for the key format. + +.. macro:: PSA_KEY_FORMAT_OPTION_DEFAULT + :definition: ((psa_key_format_option_t) 0) .. summary:: - The default production parameters for key generation or key derivation. + Key format option value indicating the default options. - Calling `psa_generate_key_custom()` or `psa_key_derivation_output_key_custom()` with :code:`custom == PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` is equivalent to calling `psa_generate_key()` or `psa_key_derivation_output_key()` - respectively. + The default format options are specified by each key format. -.. function:: psa_generate_key +.. macro:: PSA_KEY_FORMAT_OPTION_PEM + :definition: /* implementation-defined value */ .. summary:: - Generate a key or key pair. + Key format option to encode the key data using :term:`PEM` encoding. - .. param:: const psa_key_attributes_t * attributes - The attributes for the new key. + By default, key formats that are defined using :term:`ASN.1` use the binary :term:`DER` encoding for key export. + The `PSA_KEY_FORMAT_OPTION_PEM` option results in using the ASCII :term:`PEM` encoding instead. - The following attributes are required for all keys: + PEM encoding is defined by :RFC-title:`7468`. - * The key type. It must not be an asymmetric public key. - * The key size. It must be a valid size for the key type. + .. note:: + Some key formats use PEM labels that are not described in :RFC:`7468`, but are used in other tools that produce and consume PEM-encoded data. - The following attributes must be set for keys used in cryptographic operations: + This option is not applicable to the default key format. + To export a PEM-encoded key, use the appropriate format specifier. - * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. - * The key usage flags, see :secref:`key-usage-flags`. + .. subsection:: Related key formats - The following attributes must be set for keys that do not use the default volatile lifetime: + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_RSA_PRIVATE_KEY` + * `PSA_KEY_FORMAT_RSA_PUBLIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` - * The key lifetime, see :secref:`key-lifetimes`. - * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. +.. macro:: PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED + :definition: /* implementation-defined value */ - .. note:: - This is an input parameter: it is not updated with the final key attributes. - The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. + .. summary:: + Key format option to encode Weierstrass elliptic curve points in compressed form. - .. param:: psa_key_id_t * key - On success, an identifier for the newly created key. - For persistent keys, this is the key identifier defined in ``attributes``. - `PSA_KEY_ID_NULL` on failure. + By default, Weierstrass elliptic curve points are encoded in uncompressed form for key export. + The `PSA_KEY_FORMAT_OPTION_EC_POINT_COMPRESSED` option results in using compressed form instead. - .. return:: psa_status_t - .. retval:: PSA_SUCCESS - Success. - If the 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_NOT_SUPPORTED - The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. - .. retval:: PSA_ERROR_INVALID_ARGUMENT - The following conditions can result in this error: + The compressed and uncompressed ECPoint format is defined by :cite-title:`SEC1` §2.3.3. - * The key type is invalid, or is an asymmetric public key type. - * The key size is not valid for the key type. - * The key lifetime is invalid. - * The key identifier is not valid for the key lifetime. - * The key usage flags include invalid values. - * The key's permitted-usage algorithm is invalid. - * The key attributes, as a whole, are invalid. - .. retval:: PSA_ERROR_NOT_PERMITTED - The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. - .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY - .. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY - .. retval:: PSA_ERROR_COMMUNICATION_FAILURE - .. retval:: PSA_ERROR_CORRUPTION_DETECTED - .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE - .. retval:: PSA_ERROR_STORAGE_FAILURE - .. retval:: PSA_ERROR_DATA_CORRUPT - .. retval:: PSA_ERROR_DATA_INVALID - .. retval:: PSA_ERROR_BAD_STATE - The library requires initializing by a call to `psa_crypto_init()`. + This option can be used with the default key format, when exporting elliptic curve public keys. + + .. subsection:: Related key formats + + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` - The key is generated randomly. Its location, policy, type and size are taken from ``attributes``. +.. macro:: PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN + :definition: /* implementation-defined value */ - Implementations must reject an attempt to generate a key of size ``0``. + .. summary:: + Key format option to output the Weierstrass elliptic curve domain parameters in the key format. - The key type definitions in :secref:`key-types` provide specific details relating to generation of the key. + By default, key formats that include the *ECParameters* element specify a *namedCurve* for key export. + The `PSA_KEY_FORMAT_OPTION_SPECIFIED_EC_DOMAIN` option results in specifying the full domain parameters for the elliptic curve instead. - .. note:: + The ECParameters format is defined by :RFC-title:`5480#2.1.1`. - This function is equivalent to calling `psa_generate_key_custom()` with the production parameters `PSA_CUSTOM_KEY_PARAMETERS_INIT` and ``custom_data_length == 0`` (``custom_data`` is ignored). + This option is not applicable to the default key format. -.. function:: psa_generate_key_custom + .. subsection:: Related key formats + + * `PSA_KEY_FORMAT_EC_PRIVATE_KEY` + * `PSA_KEY_FORMAT_ONE_ASYMMETRIC_KEY` + * `PSA_KEY_FORMAT_SUBJECT_PUBLIC_KEY_INFO` + +.. _key-import: + +Key import +---------- + +.. function:: psa_import_key .. summary:: - Generate a key or key pair using custom production parameters. + Import a key in binary format. .. param:: const psa_key_attributes_t * attributes The attributes for the new key. The following attributes are required for all keys: - * The key type. It must not be an asymmetric public key. - * The key size. It must be a valid size for the key type. + * The key type determines how the ``data`` buffer is interpreted. The following attributes must be set for keys used in cryptographic operations: @@ -699,22 +737,21 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ * The key lifetime, see :secref:`key-lifetimes`. * The key identifier is required for a key with a persistent lifetime, see :secref:`key-identifiers`. + The following attributes are optional: + + * If the key size is nonzero, it must be equal to the key size determined from ``data``. + .. note:: This is an input parameter: it is not updated with the final key attributes. The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. - .. param:: const psa_custom_key_parameters_t * custom - Customized production parameters for the key generation. - - When this is `PSA_CUSTOM_KEY_PARAMETERS_INIT` with ``custom_data_length == 0``, this function is equivalent to `psa_generate_key()`. - .. param:: const uint8_t * custom_data - A buffer containing additional variable-sized production parameters. - .. param:: size_t custom_data_length - Length of ``custom_data`` in bytes. - .. param:: mbedtls_svc_key_id_t * key - On success, an identifier for the newly created key. - For persistent keys, this is the key identifier defined in ``attributes``. - `PSA_KEY_ID_NULL` on failure. + .. param:: const uint8_t * data + Buffer containing the key data. + The content of this buffer is interpreted according to the type declared in ``attributes``. + .. param:: size_t data_length + Size of the ``data`` buffer in bytes. + .. param:: psa_key_id_t * key + On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. .. return:: psa_status_t .. retval:: PSA_SUCCESS @@ -723,61 +760,70 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ .. 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_NOT_SUPPORTED - The following conditions can result in this error: - - * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. - * The production parameters are not supported by the implementation. + The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. .. retval:: PSA_ERROR_INVALID_ARGUMENT The following conditions can result in this error: - * The key type is invalid, or is an asymmetric public key type. - * The key size is not valid for the key type. + * The key type is invalid. + * The key size is nonzero, and is incompatible with the key data in ``data``. * The key lifetime is invalid. * The key identifier is not valid for the key lifetime. * The key usage flags include invalid values. * The key's permitted-usage algorithm is invalid. * The key attributes, as a whole, are invalid. - * The production parameters are invalid. + * The key data is not correctly formatted for the key type. .. retval:: PSA_ERROR_NOT_PERMITTED The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY - .. retval:: PSA_ERROR_INSUFFICIENT_ENTROPY - .. retval:: PSA_ERROR_COMMUNICATION_FAILURE - .. retval:: PSA_ERROR_CORRUPTION_DETECTED .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE .. retval:: PSA_ERROR_STORAGE_FAILURE .. retval:: PSA_ERROR_DATA_CORRUPT .. retval:: PSA_ERROR_DATA_INVALID + .. retval:: PSA_ERROR_CORRUPTION_DETECTED .. retval:: PSA_ERROR_BAD_STATE The library requires initializing by a call to `psa_crypto_init()`. - Use this function to provide explicit production parameters when generating a key. - See the description of `psa_generate_key()` for the operation of this function with the default production parameters. + The key is extracted from the provided ``data`` buffer. Its location, policy, and type are taken from ``attributes``. - The key is generated randomly. Its location, policy, type and size are taken from ``attributes``. + 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. - Implementations must reject an attempt to generate a key of size ``0``. + This function supports any output from `psa_export_key()`. + The default format is defined in the *Key format* section for each key type. + Other key formats can be imported using `psa_import_formatted_key()`. - See the documentation of `psa_custom_key_parameters_t` for a list of non-default production parameters. See the key type definitions in :secref:`key-types` for details of the custom production parameters used for key generation. + Implementations can optionally support other formats in calls to `psa_import_key()`, in addition to the default format. -.. function:: psa_copy_key + .. note:: + 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. + + .. admonition:: Implementation note + + 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. + + It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated. + +.. function:: psa_import_formatted_key .. summary:: - Make a copy of a key. + Import a key in a specified format. - .. param:: psa_key_id_t source_key - The key to copy. - It must permit the usage `PSA_KEY_USAGE_COPY`. - If a private or secret key is being copied outside of a secure element it must also permit `PSA_KEY_USAGE_EXPORT`. .. param:: const psa_key_attributes_t * attributes The attributes for the new key. + Depending on the specified key format, and the attributes encoded in the key data, some of the key attributes can be optional. + + The following attributes are required for formats that do not specify a key type: + + * When the format does not specify a key type: the key type in ``attributes`` determines how the ``data`` buffer is interpreted. + * 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. + The following attributes must be set for keys used in cryptographic operations: * The key permitted-algorithm policy, see :secref:`permitted-algorithms`. * The key usage flags, see :secref:`key-usage-flags`. - These flags are combined with the source key policy so that both sets of restrictions apply, as described in the documentation of this function. + 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)`. The following attributes must be set for keys that do not use the default volatile lifetime: @@ -786,41 +832,48 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ The following attributes are optional: - * If the key type has a non-default value, it must be equal to the source key type. - * If the key size is nonzero, it must be equal to the source key size. + * If the key size is nonzero, it must be equal to the key size determined from ``data``. .. note:: This is an input parameter: it is not updated with the final key attributes. The final attributes of the new key can be queried by calling `psa_get_key_attributes()` with the key's identifier. - - .. param:: psa_key_id_t * target_key + .. param:: psa_key_format_t format + The format of the key data. + One of the ``PSA_KEY_FORMAT_XXX`` values, or an implementation-specific format. + .. param:: const uint8_t * data + Buffer containing the key data. + The content of this buffer is interpreted according to the key format ``format``. + The type declared in ``attributes`` is used if the format and key data do not specify a key type. + .. param:: size_t data_length + Size of the ``data`` buffer in bytes. + .. param:: psa_key_id_t * key On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. .. return:: psa_status_t .. retval:: PSA_SUCCESS Success. - If the new key is persistent, the key material and the key's metadata have been saved to persistent storage. - .. retval:: PSA_ERROR_INVALID_HANDLE - ``source_key`` is not a valid key identifier. + If the 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 following conditions can result in this error: - - * ``attributes`` specifies a key type or key size which does not match the attributes of ``source key``. - * The lifetime or identifier in ``attributes`` are invalid. - * The key policies from ``source_key`` and those specified in ``attributes`` are incompatible. .. retval:: PSA_ERROR_NOT_SUPPORTED The following conditions can result in this error: - * The ``source key`` storage location does not support copying to the target key's storage location. - * The key attributes, as a whole, are not supported in the target key's storage location. - .. retval:: PSA_ERROR_NOT_PERMITTED + * The key format is not supported by the implementation. + * The key attributes, as a whole, are not supported, either by the implementation in general or in the specified storage location. + .. retval:: PSA_ERROR_INVALID_ARGUMENT The following conditions can result in this error: - * ``source_key`` does not have the `PSA_KEY_USAGE_COPY` usage flag. - * ``source_key`` does not have the `PSA_KEY_USAGE_EXPORT` usage flag, and the location of ``target_key`` is outside the security boundary of the ``source_key`` storage location. - * The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. + * The key type is invalid, or is `PSA_KEY_TYPE_NONE` when a type is required. + * The key size is nonzero, and is incompatible with the key data in ``data``. + * The key lifetime is invalid. + * The key identifier is not valid for the key lifetime. + * The key usage flags include invalid values. + * The key's permitted-usage algorithm is invalid. + * The key attributes, as a whole, are invalid. + * The key format is invalid. + * The key data is not correctly formatted for the key format or the key type. + .. retval:: PSA_ERROR_NOT_PERMITTED + The implementation does not permit creating a key with the specified attributes due to some implementation-specific policy. .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY .. retval:: PSA_ERROR_INSUFFICIENT_STORAGE .. retval:: PSA_ERROR_COMMUNICATION_FAILURE @@ -831,101 +884,51 @@ When creating a key, the attributes for the new key are specified in a `psa_key_ .. retval:: PSA_ERROR_BAD_STATE The library requires initializing by a call to `psa_crypto_init()`. - Copy key material from one location to another. Its location is taken from ``attributes``, its policy is the intersection of the policy in ``attributes`` and the source key policy, and its type and size are taken from the source key. + 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``. - This function is primarily useful to copy a key from one location to another, as it populates a key using the material from another key which can have a different lifetime. + If the format is `PSA_KEY_FORMAT_DEFAULT`, this is equivalent to calling `psa_import_key()`. - This function can be used to share a key with a different party, subject to implementation-defined restrictions on key sharing. + For non-default key formats, the key format either specifies the key type, or the formatted data encodes the key type. + 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. + 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`. - The policy on the source key must have the usage flag `PSA_KEY_USAGE_COPY` set. This flag is sufficient to permit the copy if the key has the lifetime `PSA_KEY_LIFETIME_VOLATILE` or `PSA_KEY_LIFETIME_PERSISTENT`. Some secure elements do not provide a way to copy a key without making it extractable from the secure element. If a key is located in such a secure element, then the key must have both usage flags `PSA_KEY_USAGE_COPY` and `PSA_KEY_USAGE_EXPORT` in order to make a copy of the key outside the secure element. + 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. - The resulting key can only be used in a way that conforms to both the policy of the original key and the policy specified in the ``attributes`` parameter: + 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())`: * 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``. * If both permit the same algorithm or wildcard-based algorithm, the resulting key has the same permitted algorithm. * 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. * If the policies do not permit any algorithm in common, this function fails with the status :code:`PSA_ERROR_INVALID_ARGUMENT`. - As a result, the new key cannot be used for operations that were not permitted on the source key. - - The effect of this function on implementation-defined attributes is implementation-defined. - -.. _key-destruction: - -Key destruction ---------------- - -.. function:: psa_destroy_key - - .. summary:: - Destroy a key. - - .. param:: psa_key_id_t key - Identifier of the key to erase. - If this is `PSA_KEY_ID_NULL`, do nothing and return :code:`PSA_SUCCESS`. - - .. return:: psa_status_t - .. retval:: PSA_SUCCESS - Success. - If ``key`` was a valid key identifier, then the key material that it referred to has been erased. - Alternatively, ``key`` was `PSA_KEY_ID_NULL`. - .. retval:: PSA_ERROR_NOT_PERMITTED - The key cannot be erased because it is read-only, either due to a policy or due to physical restrictions. - .. retval:: PSA_ERROR_INVALID_HANDLE - ``key`` is neither a valid key identifier, nor `PSA_KEY_ID_NULL`. - .. retval:: PSA_ERROR_COMMUNICATION_FAILURE - There was an failure in communication with the cryptoprocessor. The key material might still be present in the cryptoprocessor. - .. retval:: PSA_ERROR_STORAGE_FAILURE - The storage operation failed. Implementations must make a best effort to erase key material even in this situation, however, it might be impossible to guarantee that the key material is not recoverable in such cases. - .. retval:: PSA_ERROR_DATA_CORRUPT - The storage is corrupted. Implementations must make a best effort to erase key material even in this situation, however, it might be impossible to guarantee that the key material is not recoverable in such cases. - .. retval:: PSA_ERROR_DATA_INVALID - .. retval:: PSA_ERROR_CORRUPTION_DETECTED - An unexpected condition which is not a storage corruption or a communication failure occurred. The cryptoprocessor might have been compromised. - .. retval:: PSA_ERROR_BAD_STATE - The library requires initializing by a call to `psa_crypto_init()`. - - This function destroys a key from both volatile memory and, if applicable, non-volatile storage. Implementations must make a best effort to ensure that that the key material cannot be recovered. - - This function also erases any metadata such as policies and frees resources associated with the key. - - Destroying the key makes the key identifier invalid, and the key identifier must not be used again by the application. - - If a key is currently in use in a multi-part operation, then destroying the key will cause the multi-part operation to fail. - -.. function:: psa_purge_key - - .. summary:: - Remove non-essential copies of key material from memory. + As a result, the new key cannot be used for operations that were not permitted by the imported key data. - .. param:: psa_key_id_t key - Identifier of the key to purge. + .. todo:: The proposed constraints on key policy are probably too strict. - .. return:: psa_status_t - .. retval:: PSA_SUCCESS - Success. - The key material has been removed from memory, if the key material is not currently required. - .. retval:: PSA_ERROR_INVALID_HANDLE - ``key`` is not a valid key identifier. - .. retval:: PSA_ERROR_COMMUNICATION_FAILURE - .. retval:: PSA_ERROR_STORAGE_FAILURE - .. retval:: PSA_ERROR_DATA_CORRUPT - .. retval:: PSA_ERROR_DATA_INVALID - .. retval:: PSA_ERROR_CORRUPTION_DETECTED - .. retval:: PSA_ERROR_BAD_STATE - The library requires initializing by a call to `psa_crypto_init()`. + * 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. + * Many of the formats include an optional *KeyUsage* element that defines a set of permitted uses. + These partially map onto |API| usage flags. - For keys that have been created with the `PSA_KEY_USAGE_CACHE` usage flag, an implementation is permitted to make additional copies of the key material that are not in storage and not for the purpose of ongoing operations. + 1. What to do if the format does not include a algorithm identifier? + 2. What to do if the algorithm identifier is too general for the algorithm encodings in |API|? + 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? + 4. If a *KeyUsage* is **not** provided, do we just use the ``attributes`` usage flags? + 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? - This function will remove these extra copies of the key material from memory. + Implementations can define implementation-specific formats that may have other behaviors relating to ``attributes``. - This function is not required to remove key material from memory in any of the following situations: + .. note:: + The |API| does not support asymmetric private key objects outside of a key pair. + When importing a private key, the corresponding key-pair type is created. + 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. - * The key is currently in use in a cryptographic operation. - * The key is volatile. + .. admonition:: Implementation note - See also :secref:`key-material`. + 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. + It is recommended that implementations reject key data if it might be erroneous, for example, if it is the wrong type or is truncated. .. _key-export: From 1e2d1ef13cf993be96c4d2eec579adccf8f27fdf Mon Sep 17 00:00:00 2001 From: Andrew Thoelke Date: Fri, 6 Sep 2024 12:04:56 +0100 Subject: [PATCH 10/10] Fix header file output ordering --- doc/crypto/api/ops/pake.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/crypto/api/ops/pake.rst b/doc/crypto/api/ops/pake.rst index 016ddec5..8cd2ebde 100644 --- a/doc/crypto/api/ops/pake.rst +++ b/doc/crypto/api/ops/pake.rst @@ -2,7 +2,7 @@ .. SPDX-License-Identifier: CC-BY-SA-4.0 AND LicenseRef-Patent-license .. header:: psa/crypto - :seq: 30 + :seq: 29 .. _pake: