diff --git a/doc/crypto/api/keys/management.rst b/doc/crypto/api/keys/management.rst index 94f7b296..06a69162 100644 --- a/doc/crypto/api/keys/management.rst +++ b/doc/crypto/api/keys/management.rst @@ -50,7 +50,7 @@ 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 :secref:`key_formats` for the chosen type. + 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. @@ -88,7 +88,7 @@ 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()`. - This function supports any output from `psa_export_key()`. Refer to :secref:`key_formats` for the format of keys. + This function supports any output from `psa_export_key()`. Each key type in :secref:`key-types` describes the expected format of keys. The 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`` indicates that the key size is solely determined by the key data. @@ -366,10 +366,9 @@ Key export 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_formats`, not the originally imported representation. - - For standard key types, the output format is defined in :secref:`key_formats`. + 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. + 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. .. function:: psa_export_public_key @@ -419,9 +418,9 @@ Key export 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_formats`, not the originally imported representation. + 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. - For standard key types, the output format is defined in :secref:`key_formats`. + For standard key types, the output format is defined in the relevant *Key format* section in :secref:`key-types`. Exporting a public key object or the public part of a key pair is always permitted, regardless of the key's usage flags. @@ -530,189 +529,3 @@ 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()`. - - -.. _key_formats: - -Key formats ------------ - -This section defines the format of the key data that an implementation is required to support when importing and exporting keys. Keys can be imported using `psa_import_key()`, and exported using `psa_export_key()` or `psa_export_public_key()`. The public key formats are also used for the key agreement functions, see :secref:`key-agreement`. - -.. list-table:: Standard key formats - :name: std-key-formats - :class: longtable - :header-rows: 1 - :widths: 2,5 - - * - Key type - - Key type details and format - - * - DES - - `PSA_KEY_TYPE_DES`, 64 bits. - - The key data consists of 8 bytes. The parity bits must be correct. - - * - 2-key 3DES - - 3-key 3DES - - `PSA_KEY_TYPE_DES`, 128 bits. - - `PSA_KEY_TYPE_DES`, 192 bits. - - The key data is the concatenation of the two or three DES keys. - - * - Other symmetric keys - - * AES - * ARC4 - * ARIA - * CAMELLIA - * ChaCha20 - * HMAC - * SM4 - * Secrets for derivation - * Password hashes - - - `PSA_KEY_TYPE_AES` - - `PSA_KEY_TYPE_ARC4` - - `PSA_KEY_TYPE_ARIA` - - `PSA_KEY_TYPE_CAMELLIA` - - `PSA_KEY_TYPE_CHACHA20` - - `PSA_KEY_TYPE_HMAC` - - `PSA_KEY_TYPE_SM4` - - `PSA_KEY_TYPE_DERIVE` - - `PSA_KEY_TYPE_PASSWORD_HASH` - - The key data is the raw bytes of the key. - - * - RSA key pair - - `PSA_KEY_TYPE_RSA_KEY_PAIR` - - The key data is the non-encrypted DER encoding of the representation defined by in :RFC-title:`8017` as ``RSAPrivateKey``, version ``0``. - - .. code-block:: none - - RSAPrivateKey ::= SEQUENCE { - version INTEGER, -- must be 0 - modulus INTEGER, -- n - publicExponent INTEGER, -- e - privateExponent INTEGER, -- d - prime1 INTEGER, -- p - prime2 INTEGER, -- q - exponent1 INTEGER, -- d mod (p-1) - exponent2 INTEGER, -- d mod (q-1) - coefficient INTEGER, -- (inverse of q) mod p - } - - .. note:: - - Although it is possible to define an RSA key pair or private key using a subset of these elements, the output from `psa_export_key()` for an RSA key pair must include all of these elements. - - * - RSA public key - - `PSA_KEY_TYPE_RSA_PUBLIC_KEY` - - The key data is the DER encoding of the representation defined by :RFC-title:`3279#2.3.1` as ``RSAPublicKey``. - - .. code-block:: none - - RSAPublicKey ::= SEQUENCE { - modulus INTEGER, -- n - publicExponent INTEGER } -- e - - * - Weierstrass Elliptic curve key pair - - :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family)`, where ``ecc_family`` designates a Weierstrass curve family. - - The key data is the content of the ``privateKey`` field of the ``ECPrivateKey`` format defined by :RFC-title:`5915`. - - This is a :math:`\lceil{m/8}\rceil`-byte string in big-endian order, where :math:`m` is the key size in bits. - - * - Weierstrass Elliptic curve public key - - :code:`PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_family)`, where ``ecc_family`` designates a Weierstrass curve family. - - The key data is the uncompressed representation of an elliptic curve point as an octet string defined in :cite-title:`SEC1` §2.3.3. - If :math:`m` is the bit size associated with the curve, i.e. the bit size of :math:`q` for a curve over :math:`\mathbb{F}_q`, then the representation of point :math:`P` consists of: - - * The byte ``0x04``; - * :math:`x_P` as a :math:`\lceil{m/8}\rceil`-byte string, big-endian; - * :math:`y_P` as a :math:`\lceil{m/8}\rceil`-byte string, big-endian. - - * - Montgomery Elliptic curve key pair - - :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)` - - The key data is the scalar value of the 'private key' in little-endian order as defined by :RFC-title:`7748#6`. The value must have the forced bits set to zero or one as specified by ``decodeScalar25519()`` and ``decodeScalar448()`` in :RFC:`7748#5`. - - This is a :math:`\lceil{m/8}\rceil`-byte string where :math:`m` is the key size in bits. This is 32 bytes for Curve25519, and 56 bytes for Curve448. - - * - Montgomery Elliptic curve public key - - :code:`PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_MONTGOMERY)` - - The key data is the scalar value of the 'public key' in little-endian order as defined by :RFC-title:`7748#6`. This is a :math:`\lceil{m/8}\rceil`-byte string where :math:`m` is the key size in bits. - - * This is 32 bytes for Curve25519, computed as ``X25519(private_key, 9)``. - * This is 56 bytes for Curve448, computed as ``X448(private_key, 5)``. - - * - Twisted Edwards Elliptic curve key pair - - :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS)` - - The key data is the private key, as defined by :RFC-title:`8032`. - - This is a 32-byte string for Edwards25519, and a 57-byte string for Edwards448. - - * - Twisted Edwards Elliptic curve public key - - :code:`PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_TWISTED_EDWARDS)` - - The key data is the public key, as defined by :RFC-title:`8032`. - - This is a 32-byte string for Edwards25519, and a 57-byte string for Edwards448. - - * - Finite-field Diffie-Hellman key pair - - :code:`PSA_KEY_TYPE_DH_KEY_PAIR(dh_family)` where ``dh_family`` designates any Diffie-Hellman family. - - The key data 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. - - * - Finite-field Diffie-Hellman public key - - :code:`PSA_KEY_TYPE_DH_PUBLIC_KEY(dh_family)` where ``dh_family`` designates any Diffie-Hellman family. - - The key data 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. - - * - SPAKE2+ key pair - - :code:`PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(ecc_family)` where ``ecc_family`` designates an elliptic curve family. - - The key 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. - - For the |API|, the default format for a SPAKE2+ 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|. - 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`. - This is a 32-byte big-endian encoding of the integer :math:`w0`. - * The P-256 private key :math:`w1`. - This is a 32-byte big-endian encoding of the integer :math:`w1`. - - * - SPAKE2+ public key - - :code:`PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(ecc_family)` where ``ecc_family`` designates an elliptic curve family. - - The public key consists of the two values :math:`w0` and :math:`L`, which result from the SPAKE2+ registration phase, see :secref:`spake2p-registration`. - :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. - - For the |API|, the default format for a SPAKE2+ 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|. - 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`. - This is a 32-byte big-endian encoding of the integer :math:`w0`. - * The P-256 public key :math:`L`. - This is a 65-byte concatenation of: - - - The byte ``0x04``. - - The 32-byte big-endian encoding of the x-coordinate of :math:`L`. - - The 32-byte big-endian encoding of the y-coordinate of :math:`L`. diff --git a/doc/crypto/api/keys/types.rst b/doc/crypto/api/keys/types.rst index 5d816902..71e0adca 100644 --- a/doc/crypto/api/keys/types.rst +++ b/doc/crypto/api/keys/types.rst @@ -103,13 +103,25 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_HKDF` (non-secret inputs) - | `PSA_ALG_HKDF_EXPAND` (non-secret inputs) - | `PSA_ALG_HKDF_EXTRACT` (non-secret inputs) - | `PSA_ALG_SP800_108_COUNTER_HMAC` (non-secret inputs) - | `PSA_ALG_SP800_108_COUNTER_CMAC` (non-secret inputs) - | `PSA_ALG_TLS12_PRF` (non-secret inputs) - | `PSA_ALG_TLS12_PSK_TO_MS` (non-secret inputs) + A key of this type can also be used as a non-secret input to the following key-derivation algorithms: + + .. hlist:: + + * `PSA_ALG_HKDF` + * `PSA_ALG_HKDF_EXPAND` + * `PSA_ALG_HKDF_EXTRACT` + * `PSA_ALG_SP800_108_COUNTER_HMAC` + * `PSA_ALG_SP800_108_COUNTER_CMAC` + * `PSA_ALG_TLS12_PRF` + * `PSA_ALG_TLS12_PSK_TO_MS` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_HMAC :definition: ((psa_key_type_t)0x1100) @@ -138,8 +150,18 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_HMAC` - | `PSA_ALG_SP800_108_COUNTER_HMAC` (secret input) + .. hlist:: + + * `PSA_ALG_HMAC` + * `PSA_ALG_SP800_108_COUNTER_HMAC` (secret input) + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_DERIVE :definition: ((psa_key_type_t)0x1200) @@ -157,11 +179,23 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_HKDF` (secret input) - | `PSA_ALG_HKDF_EXPAND` (secret input) - | `PSA_ALG_HKDF_EXTRACT` (secret input) - | `PSA_ALG_TLS12_PRF` (secret input) - | `PSA_ALG_TLS12_PSK_TO_MS` (secret input) + A key of this type can be used as the secret input to the following key-derivation algorithms: + + .. hlist:: + + * `PSA_ALG_HKDF` + * `PSA_ALG_HKDF_EXPAND` + * `PSA_ALG_HKDF_EXTRACT` + * `PSA_ALG_TLS12_PRF` + * `PSA_ALG_TLS12_PSK_TO_MS` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_PASSWORD :definition: ((psa_key_type_t)0x1203) @@ -182,8 +216,20 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_PBKDF2_HMAC()` (password input) - | `PSA_ALG_PBKDF2_AES_CMAC_PRF_128` (password input) + A key of this type can be used as the password input to the following key-stretching algorithms: + + .. hlist:: + + * `PSA_ALG_PBKDF2_HMAC` + * `PSA_ALG_PBKDF2_AES_CMAC_PRF_128` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_PASSWORD_HASH :definition: ((psa_key_type_t)0x1205) @@ -195,8 +241,20 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_PBKDF2_HMAC()` (key output and verification) - | `PSA_ALG_PBKDF2_AES_CMAC_PRF_128` (key output and verification) + A key of this type can be used to output or verify the result of the following key-stretching algorithms: + + .. hlist:: + + * `PSA_ALG_PBKDF2_HMAC` + * `PSA_ALG_PBKDF2_AES_CMAC_PRF_128` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_PEPPER :definition: ((psa_key_type_t)0x1206) @@ -208,8 +266,20 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_PBKDF2_HMAC()` (salt input) - | `PSA_ALG_PBKDF2_AES_CMAC_PRF_128` (salt input) + A key of this type can be used as the salt input to the following key-stretching algorithms: + + .. hlist:: + + * `PSA_ALG_PBKDF2_HMAC` + * `PSA_ALG_PBKDF2_AES_CMAC_PRF_128` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_AES :definition: ((psa_key_type_t)0x2400) @@ -233,18 +303,28 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_CBC_MAC` - | `PSA_ALG_CMAC` - | `PSA_ALG_CTR` - | `PSA_ALG_CFB` - | `PSA_ALG_OFB` - | `PSA_ALG_XTS` - | `PSA_ALG_CBC_NO_PADDING` - | `PSA_ALG_CBC_PKCS7` - | `PSA_ALG_ECB_NO_PADDING` - | `PSA_ALG_CCM` - | `PSA_ALG_GCM` - | `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + .. hlist:: + + * `PSA_ALG_CBC_MAC` + * `PSA_ALG_CMAC` + * `PSA_ALG_CTR` + * `PSA_ALG_CFB` + * `PSA_ALG_OFB` + * `PSA_ALG_XTS` + * `PSA_ALG_CBC_NO_PADDING` + * `PSA_ALG_CBC_PKCS7` + * `PSA_ALG_ECB_NO_PADDING` + * `PSA_ALG_CCM` + * `PSA_ALG_GCM` + * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_ARIA :definition: ((psa_key_type_t)0x2406) @@ -268,18 +348,28 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_CBC_MAC` - | `PSA_ALG_CMAC` - | `PSA_ALG_CTR` - | `PSA_ALG_CFB` - | `PSA_ALG_OFB` - | `PSA_ALG_XTS` - | `PSA_ALG_CBC_NO_PADDING` - | `PSA_ALG_CBC_PKCS7` - | `PSA_ALG_ECB_NO_PADDING` - | `PSA_ALG_CCM` - | `PSA_ALG_GCM` - | `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + .. hlist:: + + * `PSA_ALG_CBC_MAC` + * `PSA_ALG_CMAC` + * `PSA_ALG_CTR` + * `PSA_ALG_CFB` + * `PSA_ALG_OFB` + * `PSA_ALG_XTS` + * `PSA_ALG_CBC_NO_PADDING` + * `PSA_ALG_CBC_PKCS7` + * `PSA_ALG_ECB_NO_PADDING` + * `PSA_ALG_CCM` + * `PSA_ALG_GCM` + * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_DES :definition: ((psa_key_type_t)0x2301) @@ -302,15 +392,33 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_CBC_MAC` - | `PSA_ALG_CMAC` - | `PSA_ALG_CTR` - | `PSA_ALG_CFB` - | `PSA_ALG_OFB` - | `PSA_ALG_XTS` - | `PSA_ALG_CBC_NO_PADDING` - | `PSA_ALG_CBC_PKCS7` - | `PSA_ALG_ECB_NO_PADDING` + .. hlist:: + + * `PSA_ALG_CBC_MAC` + * `PSA_ALG_CMAC` + * `PSA_ALG_CTR` + * `PSA_ALG_CFB` + * `PSA_ALG_OFB` + * `PSA_ALG_XTS` + * `PSA_ALG_CBC_NO_PADDING` + * `PSA_ALG_CBC_PKCS7` + * `PSA_ALG_ECB_NO_PADDING` + + .. subsection:: Key format + + The 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 + + A call to `psa_key_derivation_output_key()` will construct a single 64-bit DES key using the following process: + + 1. Draw an 8-byte string. + #. Set/clear the parity bits in each byte. + #. If the result is a forbidden weak key, discard the result and return to step 1. + #. Output the string. + + For 2-key 3DES and 3-key 3DES, this process is repeated to derive the 2nd and 3rd keys, as required. .. macro:: PSA_KEY_TYPE_CAMELLIA :definition: ((psa_key_type_t)0x2403) @@ -334,18 +442,28 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_CBC_MAC` - | `PSA_ALG_CMAC` - | `PSA_ALG_CTR` - | `PSA_ALG_CFB` - | `PSA_ALG_OFB` - | `PSA_ALG_XTS` - | `PSA_ALG_CBC_NO_PADDING` - | `PSA_ALG_CBC_PKCS7` - | `PSA_ALG_ECB_NO_PADDING` - | `PSA_ALG_CCM` - | `PSA_ALG_GCM` - | `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + .. hlist:: + + * `PSA_ALG_CBC_MAC` + * `PSA_ALG_CMAC` + * `PSA_ALG_CTR` + * `PSA_ALG_CFB` + * `PSA_ALG_OFB` + * `PSA_ALG_XTS` + * `PSA_ALG_CBC_NO_PADDING` + * `PSA_ALG_CBC_PKCS7` + * `PSA_ALG_ECB_NO_PADDING` + * `PSA_ALG_CCM` + * `PSA_ALG_GCM` + * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_SM4 :definition: ((psa_key_type_t)0x2405) @@ -361,18 +479,28 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_CBC_MAC` - | `PSA_ALG_CMAC` - | `PSA_ALG_CTR` - | `PSA_ALG_CFB` - | `PSA_ALG_OFB` - | `PSA_ALG_XTS` - | `PSA_ALG_CBC_NO_PADDING` - | `PSA_ALG_CBC_PKCS7` - | `PSA_ALG_ECB_NO_PADDING` - | `PSA_ALG_CCM` - | `PSA_ALG_GCM` - | `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + .. hlist:: + + * `PSA_ALG_CBC_MAC` + * `PSA_ALG_CMAC` + * `PSA_ALG_CTR` + * `PSA_ALG_CFB` + * `PSA_ALG_OFB` + * `PSA_ALG_XTS` + * `PSA_ALG_CBC_NO_PADDING` + * `PSA_ALG_CBC_PKCS7` + * `PSA_ALG_ECB_NO_PADDING` + * `PSA_ALG_CCM` + * `PSA_ALG_GCM` + * `PSA_ALG_SP800_108_COUNTER_CMAC` (secret input) + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_ARC4 :definition: ((psa_key_type_t)0x2002) @@ -389,7 +517,17 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_STREAM_CIPHER` + .. hlist:: + + * `PSA_ALG_STREAM_CIPHER` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw :math:`m/8` bytes of output and use these as the key data, where :math:`m` is the bit-size of the key. .. macro:: PSA_KEY_TYPE_CHACHA20 :definition: ((psa_key_type_t)0x2004) @@ -405,8 +543,18 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_STREAM_CIPHER` - | `PSA_ALG_CHACHA20_POLY1305` + .. hlist:: + + * `PSA_ALG_STREAM_CIPHER` + * `PSA_ALG_CHACHA20_POLY1305` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw 32 bytes of output and use these as the key data. .. macro:: PSA_KEY_TYPE_XCHACHA20 :definition: ((psa_key_type_t)0x2007) @@ -422,9 +570,18 @@ Symmetric keys .. subsection:: Compatible algorithms - | `PSA_ALG_STREAM_CIPHER` - | `PSA_ALG_XCHACHA20_POLY1305` + .. hlist:: + + * `PSA_ALG_STREAM_CIPHER` + * `PSA_ALG_XCHACHA20_POLY1305` + + .. subsection:: Key format + + The data format for import and export of the key is the raw bytes of the key. + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will draw 32 bytes of output and use these as the key data. .. _asymmetric-keys: @@ -453,12 +610,42 @@ RSA keys .. subsection:: Compatible algorithms - | `PSA_ALG_RSA_OAEP` - | `PSA_ALG_RSA_PKCS1V15_CRYPT` - | `PSA_ALG_RSA_PKCS1V15_SIGN` - | `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` - | `PSA_ALG_RSA_PSS` - | `PSA_ALG_RSA_PSS_ANY_SALT` + .. hlist:: + + * `PSA_ALG_RSA_OAEP` + * `PSA_ALG_RSA_PKCS1V15_CRYPT` + * `PSA_ALG_RSA_PKCS1V15_SIGN` + * `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` + * `PSA_ALG_RSA_PSS` + * `PSA_ALG_RSA_PSS_ANY_SALT` + + .. 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``. + + .. code-block:: none + + RSAPrivateKey ::= SEQUENCE { + version INTEGER, -- must be 0 + modulus INTEGER, -- n + publicExponent INTEGER, -- e + privateExponent INTEGER, -- d + prime1 INTEGER, -- p + prime2 INTEGER, -- q + exponent1 INTEGER, -- d mod (p-1) + exponent2 INTEGER, -- d mod (q-1) + coefficient INTEGER, -- (inverse of q) mod p + } + + .. note:: + + Although it is possible to define an RSA key pair or private key using a subset of these elements, the output from `psa_export_key()` for an RSA key pair must include all of these elements. + + See `PSA_KEY_TYPE_RSA_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. + + .. subsection:: Key derivation + + The method used by `psa_key_derivation_output_key()` to derive an RSA key-pair is :term:`implementation defined`. .. macro:: PSA_KEY_TYPE_RSA_PUBLIC_KEY :definition: ((psa_key_type_t)0x4001) @@ -470,12 +657,25 @@ RSA keys .. subsection:: Compatible algorithms - | `PSA_ALG_RSA_OAEP` (encryption only) - | `PSA_ALG_RSA_PKCS1V15_CRYPT` (encryption only) - | `PSA_ALG_RSA_PKCS1V15_SIGN` (signature verification only) - | `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` (signature verification only) - | `PSA_ALG_RSA_PSS` (signature verification only) - | `PSA_ALG_RSA_PSS_ANY_SALT` (signature verification only) + .. hlist:: + :columns: 1 + + * `PSA_ALG_RSA_OAEP` (encryption only) + * `PSA_ALG_RSA_PKCS1V15_CRYPT` (encryption only) + * `PSA_ALG_RSA_PKCS1V15_SIGN` (signature verification only) + * `PSA_ALG_RSA_PKCS1V15_SIGN_RAW` (signature verification only) + * `PSA_ALG_RSA_PSS` (signature verification only) + * `PSA_ALG_RSA_PSS_ANY_SALT` (signature verification only) + + .. 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``. + + .. code-block:: none + + RSAPublicKey ::= SEQUENCE { + modulus INTEGER, -- n + publicExponent INTEGER } -- e .. macro:: PSA_KEY_TYPE_IS_RSA :definition: /* specification-defined value */ @@ -491,6 +691,42 @@ RSA keys Elliptic Curve keys ------------------- +Elliptic curve keys are grouped into families of related curves. +A keys for a specific curve is specified by a combination of the elliptic curve family and the bit-size of the key. + +There are three categories of elliptic curve key, shown in :numref:`tab-ecc-groups`. +The curve type affects the key format, the key derivation procedure, and the algorithms which the key can be used with. + +.. list-table:: Types of elliptic curve key + :name: tab-ecc-groups + :align: left + :widths: 1 4 + :header-rows: 1 + + * - Curve type + - Curve families + + * - Weierstrass + - `PSA_ECC_FAMILY_SECP_K1` + + `PSA_ECC_FAMILY_SECP_R1` + + `PSA_ECC_FAMILY_SECP_R2` + + `PSA_ECC_FAMILY_SECT_K1` + + `PSA_ECC_FAMILY_SECT_R1` + + `PSA_ECC_FAMILY_SECT_R2` + + `PSA_ECC_FAMILY_BRAINPOOL_P_R1` + + `PSA_ECC_FAMILY_FRP` + * - Montgomery + - `PSA_ECC_FAMILY_MONTGOMERY` + * - Twisted Edwards + - `PSA_ECC_FAMILY_TWISTED_EDWARDS` + .. typedef:: uint8_t psa_ecc_family_t .. summary:: @@ -516,16 +752,118 @@ Elliptic Curve keys .. summary:: Elliptic curve key pair: both the private and public key. - The size of an elliptic curve key is the bit size associated with the curve, that is, the bit size of :math:`q`` for a curve over a field :math:`\mathbb{F}_q`. See the documentation of each elliptic curve family for details. - .. param:: curve A value of type `psa_ecc_family_t` that identifies the ECC curve family to be used. + The size of an elliptic curve key is the bit size associated with the curve, that is, the bit size of :math:`q`` for a curve over a field :math:`\mathbb{F}_q`. + See the documentation of each elliptic curve family for details. + .. subsection:: Compatible algorithms - elliptic curve key pairs can be used in Asymmetric signature and Key agreement algorithms. + :numref:`tab-ecc-key-pair-algorithms` shows the compatible algorithms for each type of elliptic curve key-pair. + + .. list-table:: Compatible algorithms for elliptic curve key-pairs + :name: tab-ecc-key-pair-algorithms + :class: longtable + :widths: 1,4 + :header-rows: 1 + + * - Curve type + - Compatible algorithms + * - Weierstrass + - Weierstrass curve key-pairs can be used in asymmetric signature and key agreement algorithms. + + `PSA_ALG_DETERMINISTIC_ECDSA` - The set of compatible algorithms depends on the elliptic curve key family. See the elliptic curve family for details. + `PSA_ALG_ECDSA` + + `PSA_ALG_ECDSA_ANY` + + `PSA_ALG_ECDH` + * - Montgomery + - Montgomery curve key-pairs can only be used in key agreement algorithms. + + `PSA_ALG_ECDH` + * - Twisted Edwards + - Twisted Edwards curve key-pairs can only be used in asymmetric signature algorithms. + + `PSA_ALG_PURE_EDDSA` + + `PSA_ALG_ED25519PH` (Edwards25519 only) + + `PSA_ALG_ED448PH` (Edwards448 only) + + .. subsection:: Key format + + The 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()`. + + .. list-table:: Key-pair formats for elliptic curve keys + :name: tab-ecc-key-pair-format + :class: longtable + :widths: 1,4 + :header-rows: 1 + + * - Curve type + - Key pair format + * - Weierstrass + - The key data is the content of the ``privateKey`` field of the ``ECPrivateKey`` format defined by :RFC-title:`5915`. + + This is a :math:`\lceil{m/8}\rceil`-byte string in big-endian order, where :math:`m` is the key size in bits. + + * - Montgomery + - The key data is the scalar value of the 'private key' in little-endian order as defined by :RFC-title:`7748#6`. + The value must have the forced bits set to zero or one as specified by ``decodeScalar25519()`` and ``decodeScalar448()`` in :RFC:`7748#5`. + + This is a :math:`\lceil{m/8}\rceil`-byte string where :math:`m` is the key size in bits. + This is 32 bytes for Curve25519, and 56 bytes for Curve448. + + * - Twisted Edwards + - The key data is the private key, as defined by :RFC-title:`8032`. + + This is a 32-byte string for Edwards25519, and a 57-byte string for Edwards448. + + .. subsection:: Key derivation + + The key derivation method used when calling `psa_key_derivation_output_key()` depends on the type of elliptic curve. + :numref:`tab-ecc-key-derivation` shows the derivation method for each type of elliptic curve key. + + .. list-table:: Key derivation for elliptic curve keys + :name: tab-ecc-key-derivation + :class: longtable + :widths: 1,4 + :header-rows: 1 + + * - Curve type + - Key derivation + * - Weierstrass + - A Weierstrass elliptic curve private key is :math:`d \in [1, N - 1]`, where :math:`N` is the order of the curve's base point for ECC. + + Let :math:`m` be the bit size of :math:`N`, such that :math:`2^{m-1} \leq N < 2^m`. This function generates the private key using the following process: + + 1. Draw a byte string of length :math:`\lceil{m/8}\rceil` bytes. + #. If :math:`m` is not a multiple of 8, set the most significant :math:`8 * \lceil{m/8}\rceil - m`` bits of the first byte in the string to zero. + #. Convert the string to integer :math:`k` by decoding it as a big-endian byte-string. + #. If :math:`k > N-2`, discard the result and return to step 1. + #. Output :math:`d = k + 1` as the private key. + + This method allows compliance to NIST standards, specifically the methods titled *Key-Pair Generation by Testing Candidates* in :cite:`SP800-56A` §5.6.1.2.2 or :cite-title:`FIPS186-4` §B.4.2. + + * - Montgomery + - Draw a byte string whose length is determined by the curve, and set the mandatory bits accordingly. + That is: + + * Curve25519 (`PSA_ECC_FAMILY_MONTGOMERY`, 255 bits): draw a 32-byte string and process it as specified in :RFC-title:`7748#5`. + * Curve448 (`PSA_ECC_FAMILY_MONTGOMERY`, 448 bits): draw a 56-byte string and process it as specified in :RFC:`7748#5`. + + * - Twisted Edwards + - Draw a byte string whose length is determined by the curve, and use this as the private key. + That is: + + * Ed25519 (`PSA_ECC_FAMILY_MONTGOMERY`, 255 bits): draw a 32-byte string. + * Ed448 (`PSA_ECC_FAMILY_MONTGOMERY`, 448 bits): draw a 57-byte string. .. macro:: PSA_KEY_TYPE_ECC_PUBLIC_KEY :definition: /* specification-defined value */ @@ -540,9 +878,71 @@ Elliptic Curve keys .. subsection:: Compatible algorithms - Elliptic curve public keys can be used for verification in Asymmetric signature algorithms. + :numref:`tab-ecc-public-key-algorithms` shows the compatible algorithms for each type of elliptic curve public key. - The set of compatible algorithms depends on the elliptic curve key family. See each elliptic curve family for details. + .. note:: + + For key agreement, the public key of the peer is provided to the |API| as a buffer. + This avoids the need to import the public key data that is received from the peer, just to carry out the key agreement algorithm. + + .. list-table:: Compatible algorithms for elliptic curve public keys + :name: tab-ecc-public-key-algorithms + :class: longtable + :widths: 1,4 + :header-rows: 1 + + * - Curve type + - Compatible algorithms + * - Weierstrass + - Weierstrass curve public keys can be used in asymmetric signature algorithms. + + `PSA_ALG_DETERMINISTIC_ECDSA` + + `PSA_ALG_ECDSA` + + `PSA_ALG_ECDSA_ANY` + + * - Twisted Edwards + - Twisted Edwards curve public key can only be used in asymmetric signature algorithms. + + `PSA_ALG_PURE_EDDSA` + + `PSA_ALG_ED25519PH` (Edwards25519 only) + + `PSA_ALG_ED448PH` (Edwards448 only) + + .. subsection:: Key format + + The 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 + :name: tab-ecc-public-key-format + :class: longtable + :widths: 1,4 + :header-rows: 1 + + * - Curve type + - Public key format + * - Weierstrass + - The key data is the uncompressed representation of an elliptic curve point as an octet string defined in :cite-title:`SEC1` §2.3.3. + If :math:`m` is the bit size associated with the curve, i.e. the bit size of :math:`q` for a curve over :math:`\mathbb{F}_q`, then the representation of point :math:`P` consists of: + + * The byte ``0x04``; + * :math:`x_P` as a :math:`\lceil{m/8}\rceil`-byte string, big-endian; + * :math:`y_P` as a :math:`\lceil{m/8}\rceil`-byte string, big-endian. + + * - Montgomery + - The key data is the scalar value of the 'public key' in little-endian order as defined by :RFC-title:`7748#6`. + This is a :math:`\lceil{m/8}\rceil`-byte string where :math:`m` is the key size in bits. + + * This is 32 bytes for Curve25519, computed as ``X25519(private_key, 9)``. + * This is 56 bytes for Curve448, computed as ``X448(private_key, 5)``. + + * - Twisted Edwards + - The key data is the public key, as defined by :RFC-title:`8032`. + + This is a 32-byte string for Edwards25519, and a 57-byte string for Edwards448. .. macro:: PSA_ECC_FAMILY_SECP_K1 :definition: ((psa_ecc_family_t) 0x17) @@ -558,13 +958,6 @@ Elliptic Curve keys They are defined in :cite-title:`SEC2`. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_SECP_R1 :definition: ((psa_ecc_family_t) 0x12) @@ -581,13 +974,6 @@ Elliptic Curve keys They are defined in :cite:`SEC2`. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_SECP_R2 :definition: ((psa_ecc_family_t) 0x1b) @@ -601,13 +987,6 @@ Elliptic Curve keys It is defined in the superseded :cite-title:`SEC2v1`. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_SECT_K1 :definition: ((psa_ecc_family_t) 0x27) @@ -628,13 +1007,6 @@ Elliptic Curve keys .. warning:: The 163-bit curve sect163k1 is weak and deprecated and is only recommended for use in legacy applications. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_SECT_R1 :definition: ((psa_ecc_family_t) 0x22) @@ -654,13 +1026,6 @@ Elliptic Curve keys .. warning:: The 163-bit curve sect163r1 is weak and deprecated and is only recommended for use in legacy applications. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_SECT_R2 :definition: ((psa_ecc_family_t) 0x2b) @@ -676,13 +1041,6 @@ Elliptic Curve keys .. warning:: The 163-bit curve sect163r2 is weak and deprecated and is only recommended for use in legacy applications. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_BRAINPOOL_P_R1 :definition: ((psa_ecc_family_t) 0x30) @@ -704,13 +1062,6 @@ Elliptic Curve keys .. warning:: The 160-bit curve brainpoolP160r1 is weak and deprecated and is only recommended for use in legacy applications. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_FRP :definition: ((psa_ecc_family_t) 0x33) @@ -723,13 +1074,6 @@ Elliptic Curve keys This is defined by :cite-title:`FRP`. - .. subsection:: Compatible algorithms - - | `PSA_ALG_DETERMINISTIC_ECDSA` - | `PSA_ALG_ECDSA` - | `PSA_ALG_ECDSA_ANY` - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_MONTGOMERY :definition: ((psa_ecc_family_t) 0x41) @@ -743,10 +1087,6 @@ Elliptic Curve keys Curve25519 is defined in :cite-title:`Curve25519`. Curve448 is defined in :cite-title:`Curve448`. - .. subsection:: Compatible algorithms - - | `PSA_ALG_ECDH` (key pair only) - .. macro:: PSA_ECC_FAMILY_TWISTED_EDWARDS :definition: ((psa_ecc_family_t) 0x42) @@ -760,13 +1100,6 @@ Elliptic Curve keys Edwards25519 is defined in :cite-title:`Ed25519`. Edwards448 is defined in :cite-title:`Curve448`. - .. subsection:: Compatible algorithms - - | `PSA_ALG_PURE_EDDSA` - | `PSA_ALG_ED25519PH` (Edwards25519 only) - | `PSA_ALG_ED448PH` (Edwards448 only) - - .. macro:: PSA_KEY_TYPE_IS_ECC :definition: /* specification-defined value */ @@ -841,7 +1174,31 @@ Diffie Hellman keys .. subsection:: Compatible algorithms - | `PSA_ALG_FFDH` + .. hlist:: + + * `PSA_ALG_FFDH` + + .. 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 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()`. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will use the following process, defined in *Key-Pair Generation by Testing Candidates* in :cite-title:`SP800-56A` §5.6.1.1.4. + + A Diffie-Hellman private key is :math:`x \in [1, p - 1]`, where :math:`p` is the group's prime modulus. + Let :math:`m` be the bit size of :math:`p`, such that :math:`2^{m-1} \leq p < 2^m`. + + This function generates the private key using the following process: + + 1. Draw a byte string of length :math:`\lceil{m/8}\rceil` bytes. + #. If :math:`m` is not a multiple of 8, set the most significant :math:`8 * \lceil{m/8}\rceil - m`` bits of the first byte in the string to zero. + #. Convert the string to integer :math:`k` by decoding it as a big-endian byte-string. + #. If :math:`k > p-2`, discard the result and return to step 1. + #. Output :math:`x = k + 1` as the private key. .. macro:: PSA_KEY_TYPE_DH_PUBLIC_KEY :definition: /* specification-defined value */ @@ -854,7 +1211,12 @@ Diffie Hellman keys .. subsection:: Compatible algorithms - None. Finite-field Diffie-Hellman public keys are exported to use in a key agreement algorithm, and the peer key is provided to the `PSA_ALG_FFDH` key agreement algorithm as a buffer of key data. + None: Finite-field Diffie-Hellman public keys are exported to use in a key agreement algorithm, and the peer key is provided to the `PSA_ALG_FFDH` key agreement algorithm as a buffer of key data. + + .. 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 length of the byte string is the length of the base prime :math:`p` in bytes. .. macro:: PSA_DH_FAMILY_RFC7919 :definition: ((psa_dh_family_t) 0x03) @@ -964,9 +1326,47 @@ SPAKE2+ keys .. subsection:: Compatible algorithms - | `PSA_ALG_SPAKE2P_HMAC` - | `PSA_ALG_SPAKE2P_CMAC` - | `PSA_ALG_SPAKE2P_MATTER` + .. hlist:: + + * `PSA_ALG_SPAKE2P_HMAC` + * `PSA_ALG_SPAKE2P_CMAC` + * `PSA_ALG_SPAKE2P_MATTER` + + .. subsection:: Key format + + 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|. + 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`. + This is a 32-byte big-endian encoding of the integer :math:`w0`. + * The P-256 private key :math:`w1`. + This is a 32-byte big-endian encoding of the integer :math:`w1`. + + See `PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY` for the data format used when exporting the public key with `psa_export_public_key()`. + + .. subsection:: Key derivation + + A call to `psa_key_derivation_output_key()` will use the following process, which follows the recommendations for the registration process in :rfc-title:`9383`, and matches the specification of this process in :cite-title:`MATTER`. + + The derivation of SPAKE2+ keys extracts :math:`\lceil{log_2(p)/8}\rceil+8` bytes from the PBKDF for each of :math:`w0s` and :math:`w1s`, where :math:`p` is the prime factor of the order of the elliptic curve group. + The following sizes are used for extracting :math:`w0s` and :math:`w1s`, depending on the elliptic curve: + + * P-256: 40 bytes + * P-384: 56 bytes + * P-521: 74 bytes + * edwards25519: 40 bytes + * edwards448: 64 bytes + + The calculation of :math:`w0`, :math:`w1`, and :math:`L` then proceeds as described in :rfc:`9383`. + + .. admonition:: Implementation note + + The values of :math:`w0` and :math:`w1` are required as part of the SPAKE2+ key pair. + + It is :scterm:`implementation defined` whether :math:`L` is computed during key derivation, and stored as part of the key pair; or only computed when required from the key pair. .. macro:: PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY :definition: /* specification-defined value */ @@ -984,9 +1384,29 @@ SPAKE2+ keys .. subsection:: Compatible algorithms - | `PSA_ALG_SPAKE2P_HMAC` (verification only) - | `PSA_ALG_SPAKE2P_CMAC` (verification only) - | `PSA_ALG_SPAKE2P_MATTER` (verification only) + .. hlist:: + + * `PSA_ALG_SPAKE2P_HMAC` (verification only) + * `PSA_ALG_SPAKE2P_CMAC` (verification only) + * `PSA_ALG_SPAKE2P_MATTER` (verification only) + + .. subsection:: Key format + + A SPAKE2+ public key consists of the two values :math:`w0` and :math:`L`, which result from the SPAKE2+ registration phase, see :secref:`spake2p-registration`. + :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|. + 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`. + This is a 32-byte big-endian encoding of the integer :math:`w0`. + * The P-256 public key :math:`L`. + This is a 65-byte concatenation of: + + - The byte ``0x04``. + - The 32-byte big-endian encoding of the x-coordinate of :math:`L`. + - The 32-byte big-endian encoding of the y-coordinate of :math:`L`. .. macro:: PSA_KEY_TYPE_IS_SPAKE2P :definition: /* specification-defined value */ diff --git a/doc/crypto/api/ops/key-agreement.rst b/doc/crypto/api/ops/key-agreement.rst index ff63cdbb..024a7eb2 100644 --- a/doc/crypto/api/ops/key-agreement.rst +++ b/doc/crypto/api/ops/key-agreement.rst @@ -131,7 +131,7 @@ Standalone key agreement Identifier of the private key to use. It must permit the usage `PSA_KEY_USAGE_DERIVE`. .. param:: const uint8_t * peer_key - Public key of the peer. The peer key data is parsed with the type :code:`PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type)` where ``type`` is the type of ``private_key``, and with the same bit-size as ``private_key``. The peer key must be in the format that `psa_import_key()` accepts for this public key type. These formats are described in :secref:`key_formats`. + Public key of the peer. The peer key data is parsed with the type :code:`PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type)` where ``type`` is the type of ``private_key``, and with the same bit-size as ``private_key``. The peer key must be in the format that `psa_import_key()` accepts for this public key type. These formats are described with the public key type in :secref:`key-types`. .. param:: size_t peer_key_length Size of ``peer_key`` in bytes. .. param:: psa_algorithm_t alg @@ -219,7 +219,7 @@ Standalone key agreement Identifier of the private key to use. It must permit the usage `PSA_KEY_USAGE_DERIVE`. .. param:: const uint8_t * peer_key - Public key of the peer. The peer key data is parsed with the type :code:`PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type)` where ``type`` is the type of ``private_key``, and with the same bit-size as ``private_key``. The peer key must be in the format that `psa_import_key()` accepts for this public key type. These formats are described in :secref:`key_formats`. + Public key of the peer. The peer key data is parsed with the type :code:`PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type)` where ``type`` is the type of ``private_key``, and with the same bit-size as ``private_key``. The peer key must be in the format that `psa_import_key()` accepts for this public key type. These formats are described with the public key type in :secref:`key-types`. .. param:: size_t peer_key_length Size of ``peer_key`` in bytes. .. param:: uint8_t * output @@ -290,7 +290,7 @@ Combining key agreement and key derivation Identifier of the private key to use. It must permit the usage `PSA_KEY_USAGE_DERIVE`. .. param:: const uint8_t * peer_key - Public key of the peer. The peer key data is parsed with the type :code:`PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type)` where ``type`` is the type of ``private_key``, and with the same bit-size as ``private_key``. The peer key must be in the format that `psa_import_key()` accepts for this public key type. These formats are described in :secref:`key_formats`. + Public key of the peer. The peer key data is parsed with the type :code:`PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(type)` where ``type`` is the type of ``private_key``, and with the same bit-size as ``private_key``. The peer key must be in the format that `psa_import_key()` accepts for this public key type. These formats are described with the public key type in :secref:`key-types`. .. param:: size_t peer_key_length Size of ``peer_key`` in bytes. diff --git a/doc/crypto/api/ops/key-derivation.rst b/doc/crypto/api/ops/key-derivation.rst index fe31fc8e..d201dceb 100644 --- a/doc/crypto/api/ops/key-derivation.rst +++ b/doc/crypto/api/ops/key-derivation.rst @@ -917,139 +917,12 @@ Key derivation functions If this function returns an error status other than :code:`PSA_ERROR_INSUFFICIENT_DATA`, the operation enters an error state and must be aborted by calling `psa_key_derivation_abort()`. - How much output is produced and consumed from the operation, and how the key is derived, depends on the key type. :numref:`std-key-derivation` describes the required key derivation procedures for standard key derivation algorithms. Implementations can use other methods for implementation-specific algorithms. + How much output is produced and consumed from the operation, and how the key is derived, depends on the key type. The key derivation procedures for standard key derivation algorithms are described in the *Key derivation* section of each key definition in :secref:`key-types`. Implementations can use other methods for implementation-specific algorithms. .. rationale:: Permitting implementation defined methods for algorithms not specified in the |API| permits implementations to use other appropriate procedures in cases where interoperability with other implementations is not required. - .. list-table:: Standard key derivation process - :name: std-key-derivation - :class: longtable - :header-rows: 1 - :widths: 2,5 - - * - Key type - - Key type details and derivation procedure - - * - AES - - ARC4 - - ARIA - - CAMELLIA - - ChaCha20 - - SM4 - - Secrets for derivation - - HMAC - - Password hashes - - - `PSA_KEY_TYPE_AES` - - `PSA_KEY_TYPE_ARC4` - - `PSA_KEY_TYPE_ARIA` - - `PSA_KEY_TYPE_CAMELLIA` - - `PSA_KEY_TYPE_CHACHA20` - - `PSA_KEY_TYPE_SM4` - - `PSA_KEY_TYPE_DERIVE` - - `PSA_KEY_TYPE_HMAC` - - `PSA_KEY_TYPE_PASSWORD_HASH` - - For key types for which the key is an arbitrary sequence of bytes of a given size, this function is functionally equivalent to calling `psa_key_derivation_output_bytes()` and passing the resulting output to `psa_import_key()`. However, this function has a security benefit: if the implementation provides an isolation boundary then the key material is not exposed outside the isolation boundary. As a consequence, for these key types, this function always consumes exactly ``key_bits/8`` bytes from the operation. - - * - DES - - `PSA_KEY_TYPE_DES`, 64 bits. - - This function generates a key using the following process: - - 1. Draw an 8-byte string. - #. Set/clear the parity bits in each byte. - #. If the result is a forbidden weak key, discard the result and return to step 1. - #. Output the string. - - * - 2-key 3DES - - 3-key 3DES - - `PSA_KEY_TYPE_DES`, 192 bits. - - `PSA_KEY_TYPE_DES`, 128 bits. - - The two or three keys are generated by repeated application of the process used to generate a DES key. - - For example, for 3-key 3DES, if the first 8 bytes specify a weak key and the next 8 bytes do not, discard the first 8 bytes, use the next 8 bytes as the first key, and continue reading output from the operation to derive the other two keys. - - * - Finite-field Diffie-Hellman keys - - ECC keys on a Weierstrass elliptic curve - - - :code:`PSA_KEY_TYPE_DH_KEY_PAIR(dh_family)` where ``dh_family`` designates any Diffie-Hellman family. - - :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family)` where ``ecc_family`` designates a Weierstrass curve family. - - These key types require the generation of a private key :math:`d \in [1, N - 1]`, where :math:`N` is the boundary of the private key domain: :math:`N` is the prime :math:`p` for Diffie-Hellman, or the order of the curve's base point for ECC. - - Let :math:`m` be the bit size of :math:`N`, such that :math:`2^{m-1} \leq N < 2^m`. This function generates the private key using the following process: - - 1. Draw a byte string of length :math:`\lceil{m/8}\rceil` bytes. - #. If :math:`m` is not a multiple of 8, set the most significant :math:`8 * \lceil{m/8}\rceil - m`` bits of the first byte in the string to zero. - #. Convert the string to integer :math:`k` by decoding it as a big-endian byte-string. - #. If :math:`k > N-2`, discard the result and return to step 1. - #. Output :math:`d = k + 1` as the private key. - - This method allows compliance to NIST standards, specifically the methods titled *Key-Pair Generation by Testing Candidates* in the following publications: - - * :cite-title:`SP800-56A` §5.6.1.1.4 for Diffie-Hellman keys. - * :cite:`SP800-56A` §5.6.1.2.2 or :cite-title:`FIPS186-4` §B.4.2 for elliptic curve keys. - - * - ECC keys on a Montgomery elliptic curve - - :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY)` - - This function always draws a byte string whose length is determined by the curve, and sets the mandatory bits accordingly. That is: - - * Curve25519 (`PSA_ECC_FAMILY_MONTGOMERY`, 255 bits): draw a 32-byte string and process it as specified in :RFC-title:`7748#5`. - * Curve448 (`PSA_ECC_FAMILY_MONTGOMERY`, 448 bits): draw a 56-byte string and process it as specified in :RFC:`7748#5`. - - * - SPAKE2+ key pairs - - :code:`PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(ecc_family)` where ``ecc_family`` designates an elliptic curve family. - - The SPAKE2+ key derivation process follows the recommendations for the registration process in :rfc-title:`9383`, and matches the specification of this process in :cite-title:`MATTER`. - - The derivation of SPAKE2+ keys extracts :math:`\lceil{log_2(p)/8}\rceil+8` bytes from the PBKDF for each of :math:`w0s` and :math:`w1s`, where :math:`p` is the prime factor of the order of the elliptic curve group. - The following sizes are used for extracting :math:`w0s` and :math:`w1s`, depending on the elliptic curve: - - * P-256: 40 bytes - * P-384: 56 bytes - * P-521: 74 bytes - * edwards25519: 40 bytes - * edwards448: 64 bytes - - The calculation of :math:`w0`, :math:`w1`, and :math:`L` then proceeds as described in :rfc:`9383`. - - .. admonition:: Implementation note - - The values of :math:`w0` and :math:`w1` are required as part of the SPAKE2+ key pair. - - It is :scterm:`implementation defined` whether :math:`L` is computed during key derivation, and stored as part of the key pair; or only computed when required from the key pair. - - - * - *Other key types* - - This includes `PSA_KEY_TYPE_RSA_KEY_PAIR`. - - The way in which the operation output is consumed is implementation-defined. - For algorithms that take an input step `PSA_KEY_DERIVATION_INPUT_SECRET`, the input to that step must be provided with `psa_key_derivation_input_key()`. Future versions of this specification might include additional restrictions on the derived key based on the attributes and strength of the secret key. .. function:: psa_key_derivation_verify_bytes diff --git a/doc/crypto/api/ops/pake.rst b/doc/crypto/api/ops/pake.rst index 9c4584cb..11373b97 100644 --- a/doc/crypto/api/ops/pake.rst +++ b/doc/crypto/api/ops/pake.rst @@ -100,9 +100,9 @@ A PAKE primitive is required when constructing a PAKE cipher-suite object, `psa_ Input and output during the operation can involve group elements and scalar values: * The format for group elements is the same as that for public keys on the specific elliptic curve. - See :secref:`key_formats`. + See *Key format* within the definition of `PSA_KEY_TYPE_ECC_PUBLIC_KEY()`. * The format for scalars is the same as that for private keys on the specific elliptic curve. - See :secref:`key_formats`. + See *Key format* within the definition of `PSA_KEY_TYPE_ECC_KEY_PAIR()`. .. macro:: PSA_PAKE_PRIMITIVE_TYPE_DH @@ -118,9 +118,9 @@ A PAKE primitive is required when constructing a PAKE cipher-suite object, `psa_ Input and output during the operation can involve group elements and scalar values: * The format for group elements is the same as that for public keys in the specific Diffie-Hellman group. - See :secref:`key_formats`. + See *Key format* within the definition of `PSA_KEY_TYPE_DH_PUBLIC_KEY()`. * The format for scalars is the same as that for private keys in the specific Diffie-Hellman group. - See :secref:`key_formats`. + See *Key format* within the definition of `PSA_KEY_TYPE_DH_PUBLIC_KEY()`. .. typedef:: uint8_t psa_pake_family_t diff --git a/doc/crypto/appendix/history.rst b/doc/crypto/appendix/history.rst index 5e6a4064..58167286 100644 --- a/doc/crypto/appendix/history.rst +++ b/doc/crypto/appendix/history.rst @@ -25,6 +25,7 @@ Other changes ~~~~~~~~~~~~~ * Integrated the PAKE Extension with the main specification for the |API|. +* Moved the documentation of key formats and key derivation procedures to sub-sections within each key type. Changes between *1.2.0* and *1.2.1* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -77,7 +78,7 @@ Clarifications and fixes Other changes ~~~~~~~~~~~~~ -* Moved the documentation of supported key import/export formats to a separate section of the specification. See :secref:`key_formats`. +* Moved the documentation of supported key import/export formats to a separate section of the specification. Changes between *1.1.0* and *1.1.1* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^