|
| 1 | +Key Encapsulation |
| 2 | +================= |
| 3 | + |
| 4 | +Elliptic Curve Integrated Encryption Scheme |
| 5 | +------------------------------------------- |
| 6 | + |
| 7 | +The Elliptic Curve Integrated Encryption Scheme was fist proposed by Shoup, then improved by Ballare and Rogaway. |
| 8 | + |
| 9 | +The original specification permitted a number of variants. This specification only defines the version specified in [SEC1], that is with the use of labels and with the label size defined in bytes. |
| 10 | + |
| 11 | +It is possible that some applications may need to use older versions to interoperate with legacy systems. |
| 12 | +While the application can always implement this using the other algorithm functions provided, however, an implementation may choose to add these as a convenience in the implementation numbering space. |
| 13 | + |
| 14 | +.. macro:: PSA_ALG_ECIES_SEC1 |
| 15 | + :definition: ((psa_algorithm_t)0x09yyyxxxx) |
| 16 | + |
| 17 | + .. summary:: |
| 18 | + The Elliptic Curve Integrated Encryption Scheme. |
| 19 | + |
| 20 | + This algorithm can only be used when combined with a key derivation operation using `PSA_ALG_ENCAPSULATION()` in a call to `psa_encapsulate()` |
| 21 | + |
| 22 | + When used as a key's permitted-algorithm policy, the following uses are permitted: |
| 23 | + |
| 24 | + * In a call to `psa_encapsulate()` or `psa_decapsulate()`, with any combined key establishment and key derivation algorithm constructed with `PSA_ALG_ECIES`. |
| 25 | + |
| 26 | + This encapsulation scheme is defined by :cite-title:`SEC1` §5.5.1 under the name Elliptic Curve Integrated Encryption Scheme. |
| 27 | + |
| 28 | + This uses Cofactor ECDH. |
| 29 | + |
| 30 | + .. subsection:: Compatible key types |
| 31 | + |
| 32 | + | :code:`PSA_KEY_TYPE_ECC_KEY_PAIR(family)` |
| 33 | +
|
| 34 | + where ``family`` is a Weierstrass or Montgomery Elliptic curve family. That is, one of the following values: |
| 35 | + |
| 36 | + * ``PSA_ECC_FAMILY_SECT_XX`` |
| 37 | + * ``PSA_ECC_FAMILY_SECP_XX`` |
| 38 | + * `PSA_ECC_FAMILY_FRP` |
| 39 | + * `PSA_ECC_FAMILY_BRAINPOOL_P_R1` |
| 40 | + * `PSA_ECC_FAMILY_MONTGOMERY` |
| 41 | + |
| 42 | +.. macro:: PSA_ALG_ENCAPSULATION |
| 43 | + :definition: /* specification-defined value */ |
| 44 | +
|
| 45 | + .. summary:: |
| 46 | + Macro to build a combined algorithm that chains a key encapsulation with a key derivation. |
| 47 | + |
| 48 | + .. param:: ka_alg |
| 49 | + A encapsulation algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_ENCAPSULATION(ka_alg)` is true. |
| 50 | + .. param:: kdf_alg |
| 51 | + A key derivation algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_KEY_DERIVATION(kdf_alg)` is true. |
| 52 | + |
| 53 | + .. return:: |
| 54 | + The corresponding encapsulation and derivation algorithm. |
| 55 | + |
| 56 | + Unspecified if ``ka_alg`` is not a supported key establishment algorithm or ``kdf_alg`` is not a supported key derivation algorithm. |
| 57 | + |
| 58 | + A combined encapsulation algorithm is used in a call to `psa_encapsulate()`. |
| 59 | + |
| 60 | + The component parts of a encapsulation algorithm can be extracted using `PSA_ALG_ENCAPSULATION_GET_BASE()` and `PSA_ALG_ENCAPSULATION_GET_KDF()`. |
| 61 | + |
| 62 | + .. subsection:: Compatible key types |
| 63 | + |
| 64 | + The resulting combined encapsulation algorithm is compatible with the same key types as the raw encapsulation algorithm used to construct it. |
| 65 | + |
| 66 | +.. _encapsulation-algorithms: |
| 67 | + |
| 68 | +Encapsulation Algorithms |
| 69 | +------------------------ |
| 70 | +.. function:: psa_encapsulate |
| 71 | + |
| 72 | + .. summary:: |
| 73 | + Generate a new key pair and a use that to encapsulate a new symmetric key, emitting it both as a key object and an encapsulation to send to a counter party along with the public key from the ephemeral key pair. |
| 74 | + |
| 75 | + .. param:: const psa_key_id_t * counterparty_key |
| 76 | + The identifier for the public key of the peer. You must have previously imported this key using `psa_import_key()`, and specified the key attributes for the public key type corresponding to the type required for the encapsulation, and the usage usage `PSA_KEY_USAGE_ENCAPSULATE`. |
| 77 | + |
| 78 | + .. param:: uint8_t * ephemeral_public_key |
| 79 | + Buffer where the ephemeral public key key is to be written, ready to be sent to the counterparty. The content of the buffer will be in the same format as `psa_export_key()` for a key of the same type as ``counterparty_key``. |
| 80 | + |
| 81 | + .. param:: size_t ephemeral_public_key_size |
| 82 | + Size of the ``ephemeral_public_key`` buffer in bytes. |
| 83 | + This must be at least :code:`PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(alg)`. |
| 84 | + A buffer of at least :code:`PSA_EXPORT_PUBLIC_KEY_MAX_OUTPUT_SIZE`. is guaranteed not to fail due to buffer size for any supported encapsulation algorithm. |
| 85 | + |
| 86 | + .. param:: psa_algorithm_t alg |
| 87 | + The ful encapsulation algorithm to use: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_ENCAPSULATION(alg)` is true and :code:`PSA_ALG_IS_RAW_ENCAPSULATION(alg)` is false . |
| 88 | + |
| 89 | + .. param:: const psa_key_attributes_t * attributes |
| 90 | + The attributes for the new symmetric key. |
| 91 | + This function uses the attributes as follows: |
| 92 | + |
| 93 | + * The key type is required. It cannot be an asymmetric public key. |
| 94 | + * The key size is required. It must be a valid size for the key type. |
| 95 | + * The key permitted-algorithm policy is required for keys that will be used for a cryptographic operation, see :secref:`permitted-algorithms`. |
| 96 | + * The key usage flags define what operations are permitted with the key, see :secref:`key-usage-flags`. |
| 97 | + * The key lifetime and identifier are required for a persistent key. |
| 98 | + |
| 99 | + .. note:: |
| 100 | + 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. |
| 101 | + |
| 102 | + .. param:: psa_key_id_t * output_key |
| 103 | + On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. |
| 104 | + |
| 105 | + .. param:: uint8_t * encapsulation |
| 106 | + Buffer where the encapsulated key is to be written, ready to be sent to the counterparty. |
| 107 | + |
| 108 | + .. param:: size_t encapsulation_size |
| 109 | + Size of the ``encapsulation`` buffer in bytes. |
| 110 | + This must be at least :code:`PSA_ENCAPSULATION_OUTPUT_SIZE(alg)`. |
| 111 | + A buffer of at least :code:`PSA_ENCAPSULATION_MAX_OUTPUT_SIZE`. is guaranteed not to fail due to buffer size for any supported encapsulation algorithm. |
| 112 | + |
| 113 | + .. param:: size_t * encapsulation_length |
| 114 | + On success, the number of bytes that make up the hash value. This is always :code:`PSA_ENCAPSULATION_OUTPUT_SIZE(alg)`. |
| 115 | + |
| 116 | + .. return:: psa_status_t |
| 117 | + |
| 118 | + .. retval:: PSA_SUCCESS |
| 119 | + Success. |
| 120 | + The bytes of ``encapsulation`` contain the encapsulated key, the bytes of ``ephemeral_public_key`` contain the public key and ``output_key`` contains the identifier for the key to be used to encrypt the message. |
| 121 | + |
| 122 | + .. retval:: PSA_ERROR_NOT_SUPPORTED |
| 123 | + The following conditions can result in this error: |
| 124 | + |
| 125 | + * ``alg`` is not supported or is not an encapsulation algorithm. |
| 126 | + |
| 127 | + .. retval:: PSA_ERROR_INVALID_ARGUMENT |
| 128 | + The following conditions can result in this error: |
| 129 | + |
| 130 | + * ``alg`` is not a encapsulation algorithm. |
| 131 | + |
| 132 | + .. retval:: PSA_ERROR_BUFFER_TOO_SMALL |
| 133 | + The size of the ``encapsulation`` or the ``ephemeral_public_key`` buffer is too small. |
| 134 | + |
| 135 | + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY |
| 136 | + |
| 137 | + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE |
| 138 | + |
| 139 | + .. retval:: PSA_ERROR_CORRUPTION_DETECTED |
| 140 | + |
| 141 | + .. retval:: PSA_ERROR_BAD_STATE |
| 142 | + The library requires initializing by a call to `psa_crypto_init()`. |
| 143 | + |
| 144 | + |
| 145 | + |
| 146 | + |
| 147 | + |
| 148 | +.. function:: psa_decapsulate |
| 149 | + |
| 150 | + .. summary:: |
| 151 | + Uses a private key to decapsulate an encapsulation received from a counter party. |
| 152 | + |
| 153 | + .. param:: const psa_key_id_t * peer_key |
| 154 | + Public key of the peer. The peer key must be in the same format that `psa_import_key()` accepts for the public key type corresponding to the type of ``private_key``. That is, this function performs the equivalent of :code:`psa_import_key(..., peer_key, peer_key_length)`, with key attributes indicating the public key type corresponding to the type of ``private_key``. For example, for ECC keys, this means that peer_key is interpreted as a point on the curve that the private key is on. The standard formats for public keys are documented in the documentation of `psa_export_public_key()`. |
| 155 | + |
| 156 | + .. param:: size_t peer_key_length |
| 157 | + Size of the ``encapsulation`` buffer in bytes. |
| 158 | + |
| 159 | + .. param:: const psa_key_id_t * private_key |
| 160 | + Identifier of the key belonging to the person receiving the encapsulated message. |
| 161 | + It must be an asymmetric key pair. |
| 162 | + The private half of the key pair must permit the usage `PSA_KEY_USAGE_DECAPSULATE` |
| 163 | + |
| 164 | + .. param:: conts uint8_t * encapsulation |
| 165 | + Buffer containing the encapsulated key that was received from the counterparty. |
| 166 | + |
| 167 | + .. param:: size_t encapsulation_size |
| 168 | + Size of the ``encapsulation`` buffer in bytes. |
| 169 | + |
| 170 | + .. param:: psa_algorithm_t alg |
| 171 | + The encapsulation algorithm to use: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_ENCAPSULATION(alg)` is true. |
| 172 | + |
| 173 | + .. param:: const psa_key_attributes_t * attributes |
| 174 | + The attributes for the new key. |
| 175 | + This function uses the attributes as follows: |
| 176 | + |
| 177 | + * The key type is required. It cannot be an asymmetric public key. |
| 178 | + * The key size is required. It must be a valid size for the key type. |
| 179 | + * The key permitted-algorithm policy is required for keys that will be used for a cryptographic operation, see :secref:`permitted-algorithms`. |
| 180 | + * The key usage flags define what operations are permitted with the key, see :secref:`key-usage-flags`. |
| 181 | + * The key lifetime and identifier are required for a persistent key. |
| 182 | + |
| 183 | + .. note:: |
| 184 | + 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. |
| 185 | + |
| 186 | + .. param:: psa_key_id_t * output_key |
| 187 | + On success, an identifier for the newly created key. `PSA_KEY_ID_NULL` on failure. |
| 188 | + |
| 189 | + .. return:: psa_status_t |
| 190 | + .. retval:: PSA_SUCCESS |
| 191 | + Success. |
| 192 | + |
| 193 | + .. retval:: PSA_ERROR_NOT_SUPPORTED |
| 194 | + The following conditions can result in this error: |
| 195 | + |
| 196 | + * ``alg`` is not supported or is not an encapsulation algorithm. |
| 197 | + |
| 198 | + .. retval:: PSA_ERROR_INVALID_ARGUMENT |
| 199 | + The following conditions can result in this error: |
| 200 | + |
| 201 | + * ``alg`` is not supported or is not an encapsulation algorithm. |
| 202 | + |
| 203 | + .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY |
| 204 | + .. retval:: PSA_ERROR_COMMUNICATION_FAILURE |
| 205 | + .. retval:: PSA_ERROR_CORRUPTION_DETECTED |
| 206 | + .. retval:: PSA_ERROR_BAD_STATE |
| 207 | + The library requires initializing by a call to `psa_crypto_init()`. |
| 208 | + |
| 209 | + |
| 210 | +Support macros |
| 211 | +-------------- |
| 212 | + |
| 213 | +.. macro:: PSA_ALG_ENCAPSULATION_GET_BASE |
| 214 | + :definition: /* specification-defined value */ |
| 215 | +
|
| 216 | + .. summary:: |
| 217 | + Get the raw key encapsulation algorithm from a full encapsulation algorithm. |
| 218 | + |
| 219 | + .. param:: alg |
| 220 | + A key encapsulation algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_ENCAPSULATION(alg)` is true. |
| 221 | + |
| 222 | + .. return:: |
| 223 | + The underlying raw key encapsulation algorithm if ``alg`` is a key encapsulation algorithm. |
| 224 | + |
| 225 | + Unspecified if ``alg`` is not a key encapsulation algorithm or if it is not supported by the implementation. |
| 226 | + |
| 227 | + See also `PSA_ALG_ENCAPSULATION()` and `PSA_ALG_ENCAPSULATION_GET_KDF()`. |
| 228 | + |
| 229 | +.. macro:: PSA_ALG_ENCAPSULATION_GET_KDF |
| 230 | + :definition: /* specification-defined value */ |
| 231 | +
|
| 232 | + .. summary:: |
| 233 | + Get the key derivation algorithm used in a full encapsulation algorithm. |
| 234 | + |
| 235 | + .. param:: alg |
| 236 | + A encapsulation algorithm: a value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_ENCAPSULATION(alg)` is true. |
| 237 | + |
| 238 | + .. return:: |
| 239 | + The underlying key derivation algorithm if ``alg`` is a encapsulation algorithm. |
| 240 | + |
| 241 | + Unspecified if ``alg`` is not a encapsulation algorithm or if it is not supported by the implementation. |
| 242 | + |
| 243 | + See also `PSA_ALG_ENCAPSULATION()` and `PSA_ALG_ENCAPSULATION_GET_BASE()`. |
| 244 | + |
| 245 | +.. macro:: PSA_ALG_IS_RAW_ENCAPSULATION |
| 246 | + :definition: /* specification-defined value */ |
| 247 | +
|
| 248 | + .. summary:: |
| 249 | + Whether the specified algorithm is a raw encapsulation algorithm. |
| 250 | + |
| 251 | + .. param:: alg |
| 252 | + An algorithm identifier: a value of type `psa_algorithm_t`. |
| 253 | + |
| 254 | + .. return:: |
| 255 | + ``1`` if ``alg`` is a raw encapsulation algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. |
| 256 | + |
| 257 | + A raw encapsulation algorithm is one that does not specify a key derivation function. Usually, raw encapsulation algorithms are constructed directly with a ``PSA_ALG_xxx`` macro while non-raw encapsulation algorithms are constructed with `PSA_ALG_ENCAPSULATION()`. |
| 258 | + |
| 259 | + The raw encapsulation algorithm can be extracted from a full encapsulation algorithm identifier using `PSA_ALG_ENCAPSULATION_GET_BASE()`. |
| 260 | + |
| 261 | +.. macro:: PSA_ALG_IS_ENCAPSULATION |
| 262 | + :definition: /* specification-defined value */ |
| 263 | +
|
| 264 | + .. summary:: |
| 265 | + Whether the specified algorithm is a full encapsulation algorithm. |
| 266 | + |
| 267 | + .. param:: alg |
| 268 | + An algorithm identifier: a value of type `psa_algorithm_t`. |
| 269 | + |
| 270 | + .. return:: |
| 271 | + ``1`` if ``alg`` is a full encapsulation algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier. |
| 272 | + |
| 273 | + A full encapsulation algorithm is one that specifies a key derivation function as well as an encapsulation function. Usually, encapsulation algorithms are constructed with `PSA_ALG_ENCAPSULATION()` while non-raw encapsulation algorithms are constructed directly with a ``PSA_ALG_xxx`` macro. |
| 274 | + |
| 275 | + The raw encapsulation algorithm can be extracted from a full encapsulation algorithm identifier using `PSA_ALG_ENCAPSULATION_GET_BASE()`. |
| 276 | + |
| 277 | + |
| 278 | +.. macro:: PSA_ALG_IS_ECIES |
| 279 | + :definition: /* specification-defined value */ |
| 280 | +
|
| 281 | + .. summary:: |
| 282 | + Whether the specified algorithm is an Elliptic Curve Integrated Encryption Scheme algorithm. |
| 283 | + |
| 284 | + .. param:: alg |
| 285 | + An algorithm identifier: a value of type `psa_algorithm_t`. |
| 286 | + |
| 287 | + .. return:: |
| 288 | + ``1`` if ``alg`` is an Elliptic Curve Integrated Encryption Scheme algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported key agreement algorithm identifier. |
| 289 | + |
| 290 | + This includes the raw Elliptic Curve Integrated Encryption Scheme algorithm as well as Elliptic Curve Integrated Encryption Scheme followed by any supporter key derivation algorithm. |
| 291 | + |
| 292 | +.. macro:: PSA_ENCAPSULATION_OUTPUT_SIZE |
| 293 | + :definition: /* implementation-defined value */ |
| 294 | +
|
| 295 | + .. summary:: |
| 296 | + Sufficient output buffer size for `psa_encapsulate()`. |
| 297 | + |
| 298 | + .. param:: key_type |
| 299 | + A supported key type. |
| 300 | + .. param:: key_bits |
| 301 | + The size of the key in bits. |
| 302 | + |
| 303 | + .. return:: |
| 304 | + A sufficient output buffer size for the specified key type and size. An implementation can return either ``0`` or a correct size for a key type and size that it recognizes, but does not support. If the parameters are not valid, the return value is unspecified. |
| 305 | + |
| 306 | + If the size of the output buffer is at least this large, it is guaranteed that `psa_encapsulate()` will not fail due to an insufficient buffer size. The actual size of the output might be smaller in any given call. |
| 307 | + |
| 308 | + See also `PSA_ENCAPSULATION_OUTPUT_MAX_SIZE`. |
| 309 | + |
| 310 | +.. macro:: PSA_ENCAPSULATION_OUTPUT_MAX_SIZE |
| 311 | + :definition: /* implementation-defined value */ |
| 312 | +
|
| 313 | + .. summary:: |
| 314 | + Sufficient output buffer size for `psa_encapsulate()`, for any of the supported key types and encapsulation algorithms. |
| 315 | + |
| 316 | + If the size of the output buffer is at least this large, it is guaranteed that `psa_encapsulate()` will not fail due to an insufficient buffer size. |
| 317 | + |
| 318 | + See also `PSA_ENCAPSULATION_OUTPUT_SIZE()`. |
| 319 | + |
| 320 | + |
| 321 | + |
| 322 | + |
0 commit comments