Gilles Peskine | 6c723a2 | 2020-04-17 16:57:52 +0200 | [diff] [blame^] | 1 | .. _functionality-overview: |
| 2 | |
| 3 | Functionality overview |
| 4 | ---------------------- |
| 5 | |
| 6 | This section provides a high-level overview of the functionality provided by the |
| 7 | interface defined in this specification. Refer to the `API definition |
| 8 | <api-reference>` for a detailed description. |
| 9 | |
| 10 | `future` describes features that might be included in future versions of this |
| 11 | specification. |
| 12 | |
| 13 | Due to the modularity of the interface, almost every part of the library is |
| 14 | optional. The only mandatory function is `psa_crypto_init()`. |
| 15 | |
| 16 | Library management |
| 17 | ~~~~~~~~~~~~~~~~~~ |
| 18 | |
| 19 | Applications must call `psa_crypto_init()` to initialize the library before |
| 20 | using any other function. |
| 21 | |
| 22 | Key management |
| 23 | ~~~~~~~~~~~~~~ |
| 24 | |
| 25 | Applications always access keys indirectly via an identifier, and can perform |
| 26 | operations using a key without accessing the key material. This allows keys to |
| 27 | be *non-extractable*, where an application can use a key but is not permitted to |
| 28 | obtain the key material. Non-extractable keys are bound to the device, can be |
| 29 | rate-limited and can have their usage restricted by policies. |
| 30 | |
| 31 | Each key has a set of attributes that describe the key and the policy for using |
| 32 | the key. A `psa_key_attributes_t` object contains all of the attributes, which |
| 33 | is used when creating a key and when querying key attributes. |
| 34 | |
| 35 | Each key has a *lifetime* that determines when the key material is destroyed. |
| 36 | There are two types of lifetimes: `volatile <volatile-keys>` and |
| 37 | `persistent <persistent-keys>`. |
| 38 | |
| 39 | .. _volatile-keys: |
| 40 | |
| 41 | Volatile keys |
| 42 | ^^^^^^^^^^^^^ |
| 43 | |
| 44 | A *volatile* key exists until it explicitly destroyed with `psa_destroy_key()` |
| 45 | or until the application terminates, which conceptually destroys all of its |
| 46 | volatile keys. |
| 47 | |
| 48 | Conceptually, a volatile key is stored in RAM. Volatile keys have the |
| 49 | lifetime `PSA_KEY_LIFETIME_VOLATILE`. |
| 50 | |
| 51 | To create a volatile key: |
| 52 | |
| 53 | 1. Populate a `psa_key_attributes_t` object with the required type, size, policy |
| 54 | and other key attributes. |
| 55 | 2. Create the key with `psa_import_key()`, `psa_generate_key()`, |
| 56 | `psa_key_derivation_output_key()` or `psa_copy_key()`. If successful, these |
| 57 | functions output a transient `key identifier <key-ids>`. |
| 58 | |
| 59 | To destroy a volatile key, call `psa_destroy_key()` with the key identifier. |
| 60 | |
| 61 | .. _persistent-keys: |
| 62 | |
| 63 | Persistent keys |
| 64 | ^^^^^^^^^^^^^^^ |
| 65 | |
| 66 | A *persistent* key exists until it explicitly destroyed with `psa_destroy_key()` |
| 67 | or until it is wiped by the reset or destruction of the device. |
| 68 | |
| 69 | Each persistent key has a permanent key identifier, which acts as a name for the key. |
| 70 | Within an application, the key identifier corresponds to a single key. The |
| 71 | application specifies the key identifier when the key is created and when |
| 72 | using the key. |
| 73 | |
| 74 | Persistent keys can be stored in different storage areas; this is indicated |
| 75 | through different lifetime values. This specification defines a single lifetime |
| 76 | value `PSA_KEY_LIFETIME_PERSISTENT` which corresponds to a default storage |
| 77 | area. Implementations can define alternative lifetime values corresponding to |
| 78 | different storage areas with different retention policies, or to secure elements |
| 79 | with different security characteristics. |
| 80 | |
| 81 | To create a persistent key: |
| 82 | |
| 83 | 1. Populate a `psa_key_attributes_t` object with the key’s type, size, policy |
| 84 | and other attributes. |
| 85 | 2. In the attributes object, set the desired lifetime and persistent identifier |
| 86 | for the key. |
| 87 | 3. Create the key with one of the *key creation functions*: |
| 88 | |
| 89 | * `psa_import_key()` |
| 90 | * `psa_generate_key()` |
| 91 | * `psa_key_derivation_output_key()` |
| 92 | * `psa_copy_key()` |
| 93 | |
| 94 | If successful, these functions output the `key identifier <key-ids>` |
| 95 | that was specified by the application in step 2. |
| 96 | |
| 97 | To access an existing persistent key: use the key identifier in any API that |
| 98 | requires a key. |
| 99 | |
| 100 | To remove cached copies of key material for persistent keys created with the |
| 101 | `PSA_KEY_USAGE_CACHE` policy: call `psa_purge_key()` with the key identifier. |
| 102 | |
| 103 | To destroy a persistent key: call `psa_destroy_key()` with the key identifier. |
| 104 | Destroying a persistent key permanently removes it from memory and storage. |
| 105 | |
| 106 | The key lifetime and identifier are set when the key is created and cannot be |
| 107 | changed without destroying the key first. If the original key permits copying, |
| 108 | then the application can specify a different lifetime for the copy of the key. |
| 109 | |
| 110 | .. _key-ids: |
| 111 | |
| 112 | Key identifiers |
| 113 | ^^^^^^^^^^^^^^^ |
| 114 | |
| 115 | Key identifiers are integral values that act as permanent names for persistent |
| 116 | keys, or as transient references to volatile keys. Key identifiers use the |
| 117 | `psa_key_id_t` type, and the range of identifier values is divided as follows: |
| 118 | |
| 119 | :code:`PSA_KEY_ID_NULL = 0` |
| 120 | Reserved as an invalid key identifier. |
| 121 | :code:`PSA_KEY_ID_USER_MIN - PSA_KEY_ID_USER_MAX` |
| 122 | Applications can freely choose persistent key identifiers in this range. |
| 123 | :code:`PSA_KEY_ID_VENDOR_MIN - PSA_KEY_ID_VENDOR_MAX` |
| 124 | Implementations can define additional persistent key identifiers in this |
| 125 | range, and must allocate any volatile key identifiers from this range. |
| 126 | |
| 127 | Key identifiers outside these ranges are reserved for future use. |
| 128 | |
| 129 | Key identifiers are output from a successful call to one of |
| 130 | the key creation functions. For persistent keys, this is the same identifier |
| 131 | as the one specified in the key attributes used to create the key. |
| 132 | The key identifier remains valid until it is invalidated by passing it to |
| 133 | `psa_destroy_key()`. A volatile key identifier must not be used after it has been |
| 134 | invalidated. |
| 135 | |
| 136 | Valid key identifiers must have distinct values within the same application. If |
| 137 | the implementation provides `caller isolation <isolation>`, then key |
| 138 | identifiers are local to each application. That is, the same key identifier in two |
| 139 | applications corresponds to two different keys. |
| 140 | |
| 141 | If an invalid key identifier is provided as a parameter in any function, the |
| 142 | function will return `PSA_ERROR_INVALID_HANDLE`; except for the special case of |
| 143 | calling :code:`psa_destroy_key(PSA_KEY_ID_NULL)`, which has no effect and always |
| 144 | returns `PSA_SUCCESS`. |
| 145 | |
| 146 | There must be a matching call to `psa_destroy_key()` for each successful call |
| 147 | to a create a volatile key. |
| 148 | |
| 149 | A call to `psa_destroy_key()` destroys the key material, and will cause any active |
| 150 | operations that are using the key to fail. Therefore an application must not |
| 151 | destroy a key while an operation using that key is in progress, unless the |
| 152 | application is prepared to handle a failure of the operation. |
| 153 | |
| 154 | Recommendations of minimum standards for key management |
| 155 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 156 | |
| 157 | Most implementations provide the following functions: |
| 158 | |
| 159 | * `psa_import_key()`. The exceptions are implementations that only give access |
| 160 | to a key or keys that are provisioned by proprietary means, and do not allow |
| 161 | the main application to use its own cryptographic material. |
| 162 | |
| 163 | * `psa_get_key_attributes()` and the ``psa_get_key_xxx()`` accessor functions. |
| 164 | They are easy to implement, and it is difficult to write applications and to |
| 165 | diagnose issues without being able to check the metadata. |
| 166 | |
| 167 | * `psa_export_public_key()`. This function is usually provided if the |
| 168 | implementation supports any asymmetric algorithm, since public-key |
| 169 | cryptography often requires the delivery of a public key that is associated |
| 170 | with a protected private key. |
| 171 | |
| 172 | * `psa_export_key()`. However, highly constrained implementations that are |
| 173 | designed to work only with short-term keys, or only with long-term |
| 174 | non-extractable keys, do not need to provide this function. |
| 175 | |
| 176 | Usage policies |
| 177 | ~~~~~~~~~~~~~~ |
| 178 | |
| 179 | All keys have an associated policy that regulates which operations are permitted |
| 180 | on the key. Each key policy is a set of usage flags and a specific algorithm |
| 181 | that is permitted with the key. The policy is part of the key attributes that |
| 182 | are managed by a `psa_key_attributes_t` object. |
| 183 | |
| 184 | The usage flags are encoded in a bitmask, which has the type |
| 185 | `psa_key_usage_t`. Four kinds of usage flag can be specified: |
| 186 | |
| 187 | * The extractable flag `PSA_KEY_USAGE_EXPORT` determines whether the key |
| 188 | material can be extracted. |
| 189 | * The copyable flag `PSA_KEY_USAGE_COPY` determines whether the key material |
| 190 | can be copied into a new key, which can have a different lifetime or a more |
| 191 | restrictive policy. |
| 192 | * The cacheable flag `PSA_KEY_USAGE_CACHE` determines whether the |
| 193 | implementation is permitted to retain non-essential copies of the |
| 194 | key material in RAM. This policy only applies to persistent keys. See also |
| 195 | :title:`key-material`. |
| 196 | * The other usage flags, for example, `PSA_KEY_USAGE_ENCRYPT` and `PSA_KEY_USAGE_SIGN_MESSAGE`, |
| 197 | determine whether the corresponding operation is permitted on the key. |
| 198 | |
| 199 | In addition to the usage bitmask, a policy specifies which algorithm is |
| 200 | permitted with the key. This specification only defines policies that restrict |
| 201 | keys to a single algorithm, which is consistent with both common practice and |
| 202 | security good practice. |
| 203 | |
| 204 | A highly constrained implementation might not be able to support all the policies |
| 205 | that can be expressed through this interface. If an implementation cannot create |
| 206 | a key with the required policy, it must return an appropriate error code when |
| 207 | the key is created. |
| 208 | |
| 209 | Symmetric cryptography |
| 210 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 211 | |
| 212 | This specification defines interfaces for the following types of symmetric |
| 213 | cryptographic operation: |
| 214 | |
| 215 | * Message digests, commonly known as hash functions. |
| 216 | * Message authentication codes (MAC). |
| 217 | * Symmetric ciphers. |
| 218 | * Authenticated encryption with associated data (AEAD). |
| 219 | |
| 220 | For each type of symmetric cryptographic operation, the API includes: |
| 221 | |
| 222 | * A pair of *single-part* functions. For example, compute and verify, or |
| 223 | encrypt and decrypt. |
| 224 | * A series of functions that permit *multi-part operations*. |
| 225 | |
| 226 | Single-part Functions |
| 227 | ^^^^^^^^^^^^^^^^^^^^^ |
| 228 | |
| 229 | Single-part functions are APIs that implement the cryptographic operation in a |
| 230 | single function call. This is the easiest API to use when all of the inputs and |
| 231 | outputs fit into the application memory. |
| 232 | |
| 233 | Some use cases involve messages that are too large to be assembled in memory, or |
| 234 | require non-default configuration of the algorithm. These use cases require the |
| 235 | use of a :title:`multi-part operation <multi-part-operations>`. |
| 236 | |
| 237 | .. _multi-part-operations: |
| 238 | |
| 239 | Multi-part operations |
| 240 | ^^^^^^^^^^^^^^^^^^^^^ |
| 241 | |
| 242 | Multi-part operations are APIs which split a single cryptographic operation into |
| 243 | a sequence of separate steps. This enables fine control over the configuration |
| 244 | of the cryptographic operation, and allows the message data to be processed in |
| 245 | fragments instead of all at once. For example, the following situations require |
| 246 | the use of a multi-part operation: |
| 247 | |
| 248 | - Processing messages that cannot be assembled in memory. |
| 249 | - Using a deterministic IV for unauthenticated encryption. |
| 250 | - Providing the IV separately for unauthenticated encryption or decryption. |
| 251 | - Separating the AEAD authentication tag from the cipher text. |
| 252 | |
| 253 | Each multi-part operation defines a specific object type to maintain the state |
| 254 | of the operation. These types are implementation-defined. All multi-part |
| 255 | operations follow the same pattern of use: |
| 256 | |
| 257 | 1. **Allocate:** Allocate memory for an operation object of the appropriate |
| 258 | type. The application can use any allocation strategy: stack, heap, static, etc. |
| 259 | |
| 260 | 2. **Initialize:** Initialize or assign the operation object by one of the |
| 261 | following methods: |
| 262 | |
| 263 | - Set it to logical zero. This is automatic for static and global |
| 264 | variables. Explicit initialization must use the associated |
| 265 | ``PSA_xxx_INIT`` macro as the type is implementation-defined. |
| 266 | - Set it to all-bits zero. This is automatic if the object was |
| 267 | allocated with ``calloc()``. |
| 268 | - Assign the value of the associated macro ``PSA_xxx_INIT``. |
| 269 | - Assign the result of calling the associated function |
| 270 | ``psa_xxx_init()``. |
| 271 | |
| 272 | The resulting object is now *inactive*. |
| 273 | |
| 274 | It is an error to initialize an operation object that is in *active* or |
| 275 | *error* states. This can leak memory or other resources. |
| 276 | |
| 277 | 3. **Setup:** Start a new multi-part operation on an *inactive* operation |
| 278 | object. Each operation object will define one or more setup functions to |
| 279 | start a specific operation. |
| 280 | |
| 281 | On success, a setup function will put an operation object into an *active* |
| 282 | state. On failure, the operation object will remain *inactive*. |
| 283 | |
| 284 | 4. **Update:** Update an *active* operation object. The update function can |
| 285 | provide additional parameters, supply data for processing or generate |
| 286 | outputs. |
| 287 | |
| 288 | On success, the operation object remains *active*. On failure, the |
| 289 | operation object will enter an *error* state. |
| 290 | |
| 291 | 5. **Finish:** To end the operation, call the applicable finishing function. |
| 292 | This will take any final inputs, produce any final outputs, and then |
| 293 | release any resources associated with the operation. |
| 294 | |
| 295 | On success, the operation object returns to the *inactive* state. On |
| 296 | failure, the operation object will enter an *error* state. |
| 297 | |
| 298 | An operation can be aborted at any stage during its use by calling the |
| 299 | associated ``psa_xxx_abort()`` function. This will release any resources |
| 300 | associated with the operation and return the operation object to the *inactive* |
| 301 | state. |
| 302 | |
| 303 | Any error that occurs to an operation while it is in an *active* state will |
| 304 | result in the operation entering an *error* state. The application must call the |
| 305 | associated ``psa_xxx_abort()`` function to release the operation resources and |
| 306 | return the object to the *inactive* state. |
| 307 | |
| 308 | Once an operation object is returned to the *inactive* state, it can be reused |
| 309 | by calling one of the applicable setup functions again. |
| 310 | |
| 311 | If a multi-part operation object is not initialized before use, the behavior is |
| 312 | undefined. |
| 313 | |
| 314 | If a multi-part operation function determines that the operation object is not in |
| 315 | any valid state, it can return `PSA_ERROR_CORRUPTION_DETECTED`. |
| 316 | |
| 317 | If a multi-part operation function is called with an operation object in the |
| 318 | wrong state, the function will return `PSA_ERROR_BAD_STATE` and the operation |
| 319 | object will enter the *error* state. |
| 320 | |
| 321 | It is safe to move a multi-part operation object to a different memory location, |
| 322 | for example, using a bitwise copy, and then to use the object in the new |
| 323 | location. For example, an application can allocate an operation object on the |
| 324 | stack and return it, or the operation object can be allocated within memory |
| 325 | managed by a garbage collector. However, this does not permit the following |
| 326 | behaviors: |
| 327 | |
| 328 | - Moving the object while a function is being called on the object. This is |
| 329 | not safe. See also `concurrency`. |
| 330 | - Working with both the original and the copied operation objects. This |
| 331 | requires cloning the operation, which is only available for hash operations |
| 332 | using `psa_hash_clone()`. |
| 333 | |
| 334 | Each type of multi-part operation can have multiple *active* states. |
| 335 | Documentation for the specific operation describes the configuration and update |
| 336 | functions, and any requirements about their usage and ordering. |
| 337 | |
| 338 | Message digests (Hashes) |
| 339 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 340 | |
| 341 | The single-part hash functions are: |
| 342 | |
| 343 | - `psa_hash_compute()` to calculate the hash of a message. |
| 344 | - `psa_hash_compare()` to compare the hash of a message with a reference value. |
| 345 | |
| 346 | The `psa_hash_operation_t` `multi-part operation <multi-part-operations>` |
| 347 | allows messages to be processed in fragments: |
| 348 | |
| 349 | 1. Initialize the `psa_hash_operation_t` object to zero, or by assigning the |
| 350 | value of the associated macro `PSA_HASH_OPERATION_INIT`. |
| 351 | 2. Call `psa_hash_setup()` to specify the required hash algorithm, call |
| 352 | `psa_hash_clone()` to duplicate the state of *active* `psa_hash_operation_t` |
| 353 | object, or call `psa_hash_resume()` to restart a hash operation with the |
| 354 | output from a previously suspended hash operation. |
| 355 | 3. Call the `psa_hash_update()` function on successive chunks of the message. |
| 356 | 4. At the end of the message, call the required finishing function: |
| 357 | |
| 358 | - To suspend the hash operation and extract a hash suspend state, |
| 359 | call `psa_hash_suspend()`. The output state can subsequently be used |
| 360 | to resume the hash operation. |
| 361 | - To calculate the digest of a message, call `psa_hash_finish()`. |
| 362 | - To verify the digest of a message against a reference value, call |
| 363 | `psa_hash_verify()`. |
| 364 | |
| 365 | To abort the operation or recover from an error, call `psa_hash_abort()`. |
| 366 | |
| 367 | Message authentication codes (MACs) |
| 368 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 369 | |
| 370 | The single-part MAC functions are: |
| 371 | |
| 372 | - `psa_mac_compute()` to calculate the MAC of a message. |
| 373 | - `psa_mac_verify()` to compare the MAC of a message with a reference value. |
| 374 | |
| 375 | The `psa_mac_operation_t` `multi-part operation <multi-part-operations>` |
| 376 | allows messages to be processed in fragments: |
| 377 | |
| 378 | 1. Initialize the `psa_mac_operation_t` object to zero, or by assigning the |
| 379 | value of the associated macro `PSA_MAC_OPERATION_INIT`. |
| 380 | 2. Call `psa_mac_sign_setup()` or `psa_mac_verify_setup()` to specify the |
| 381 | algorithm and key. |
| 382 | 3. Call the `psa_mac_update()` function on successive chunks of the message. |
| 383 | 4. At the end of the message, call the required finishing function: |
| 384 | |
| 385 | - To calculate the MAC of the message, call `psa_mac_sign_finish()`. |
| 386 | - To verify the MAC of the message against a reference value, call |
| 387 | `psa_mac_verify_finish()`. |
| 388 | |
| 389 | To abort the operation or recover from an error, call `psa_mac_abort()`. |
| 390 | |
| 391 | Encryption and decryption |
| 392 | ^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 393 | |
| 394 | .. note:: |
| 395 | |
| 396 | The unauthenticated cipher API is provided to implement legacy protocols and |
| 397 | for use cases where the data integrity and authenticity is guaranteed by |
| 398 | non-cryptographic means. It is recommended that newer protocols use |
| 399 | :title:`func-aead`. |
| 400 | |
| 401 | The single-part functions for encrypting or decrypting a message using an |
| 402 | unauthenticated symmetric cipher are: |
| 403 | |
| 404 | - `psa_cipher_encrypt()` to encrypt a message using an unauthenticated symmetric |
| 405 | cipher. The encryption function generates a random IV. Use the multi-part API |
| 406 | to provide a deterministic IV: this is not secure in general, but |
| 407 | can be secure in some conditions that depend on the algorithm. |
| 408 | - `psa_cipher_decrypt()` to decrypt a message using an unauthenticated symmetric |
| 409 | cipher. |
| 410 | |
| 411 | The `psa_cipher_operation_t` `multi-part operation <multi-part-operations>` |
| 412 | permits alternative initialization parameters and allows messages to be |
| 413 | processed in fragments: |
| 414 | |
| 415 | 1. Initialize the `psa_cipher_operation_t` object to zero, or by assigning the |
| 416 | value of the associated macro `PSA_CIPHER_OPERATION_INIT`. |
| 417 | 2. Call `psa_cipher_encrypt_setup()` or `psa_cipher_decrypt_setup()` to specify the |
| 418 | algorithm and key. |
| 419 | 3. Provide additional parameters: |
| 420 | |
| 421 | - When encrypting data, generate or set an initialization vector (IV), |
| 422 | nonce, or similar initial value such as an initial counter value. To |
| 423 | generate a random IV, which is recommended in most protocols, call |
| 424 | `psa_cipher_generate_iv()`. To set the IV, call `psa_cipher_set_iv()`. |
| 425 | - When decrypting, set the IV or nonce. To set the IV, call |
| 426 | `psa_cipher_set_iv()`. |
| 427 | 4. Call the `psa_cipher_update()` function on successive chunks of the message. |
| 428 | 5. Call `psa_cipher_finish()` to complete the operation and return any final |
| 429 | output. |
| 430 | |
| 431 | To abort the operation or recover from an error, call `psa_cipher_abort()`. |
| 432 | |
| 433 | .. _func-aead: |
| 434 | |
| 435 | Authenticated encryption (AEAD) |
| 436 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 437 | |
| 438 | The single-part AEAD functions are: |
| 439 | |
| 440 | - `psa_aead_encrypt()` to encrypt a message using an authenticated symmetric |
| 441 | cipher. |
| 442 | - `psa_aead_decrypt()` to decrypt a message using an authenticated symmetric |
| 443 | cipher. |
| 444 | |
| 445 | These functions follow the interface recommended by :RFC:`5116`. |
| 446 | |
| 447 | The encryption function requires a nonce to be provided. To generate a random |
| 448 | nonce, either call `psa_generate_random()` or use the AEAD multi-part API. |
| 449 | |
| 450 | The `psa_aead_operation_t` `multi-part operation <multi-part-operations>` |
| 451 | permits alternative initialization parameters and allows messages to be |
| 452 | processed in fragments: |
| 453 | |
| 454 | 1. Initialize the `psa_aead_operation_t` object to zero, or by assigning the |
| 455 | value of the associated macro `PSA_AEAD_OPERATION_INIT`. |
| 456 | 2. Call `psa_aead_encrypt_setup()` or `psa_aead_decrypt_setup()` to specify the |
| 457 | algorithm and key. |
| 458 | 3. Provide additional parameters: |
| 459 | |
| 460 | - If the algorithm requires it, call `psa_aead_set_lengths()` to specify the |
| 461 | length of the non-encrypted and encrypted inputs to the operation. |
| 462 | - When encrypting, call either `psa_aead_generate_nonce()` or |
| 463 | `psa_aead_set_nonce()` to generate or set the nonce. |
| 464 | - When decrypting, call `psa_aead_set_nonce()` to set the nonce. |
| 465 | 4. Call `psa_aead_update_ad()` zero or more times with fragments of the |
| 466 | non-encrypted additional data. |
| 467 | 5. Call `psa_aead_update()` zero or more times with fragments of the plaintext |
| 468 | or ciphertext to encrypt or decrypt. |
| 469 | 6. At the end of the message, call the required finishing function: |
| 470 | |
| 471 | - To complete an encryption operation, call `psa_aead_finish()` to compute |
| 472 | and return authentication tag. |
| 473 | - To complete a decryption operation, call `psa_aead_verify()` to |
| 474 | compute the authentication tag and verify it against a reference value. |
| 475 | |
| 476 | To abort the operation or recover from an error, call `psa_aead_abort()`. |
| 477 | |
| 478 | Having a multi-part interface to authenticated encryption raises specific issues. |
| 479 | |
| 480 | Multi-part authenticated decryption produces partial results that are not |
| 481 | authenticated. Applications must not use or expose partial results of |
| 482 | authenticated decryption until `psa_aead_verify()` has returned a success |
| 483 | status and must destroy all partial results without revealing them if |
| 484 | `psa_aead_verify()` returns a failure status. Revealing partial results, either directly or indirectly through the application’s behavior, can compromise the |
| 485 | confidentiality of all inputs that are encrypted with the same key. |
| 486 | |
| 487 | For encryption, some common algorithms cannot be processed in a streaming |
| 488 | fashion. For SIV mode, the whole plaintext must be known before the encryption |
| 489 | can start; the multi-part AEAD API is not meant to be usable with SIV mode. For |
| 490 | CCM mode, the length of the plaintext must be known before the encryption can |
| 491 | start; the application can call the function `psa_aead_set_lengths()` to provide |
| 492 | these lengths before providing input. |
| 493 | |
| 494 | .. _key-derivation: |
| 495 | |
| 496 | Key derivation |
| 497 | ^^^^^^^^^^^^^^ |
| 498 | |
| 499 | A key derivation encodes a deterministic method to generate a finite stream of |
| 500 | bytes. This data stream is computed by the cryptoprocessor and extracted in |
| 501 | chunks. If two key derivation operations are constructed with the same |
| 502 | parameters, then they produce the same output. |
| 503 | |
| 504 | A key derivation consists of two phases: |
| 505 | |
| 506 | 1. Input collection. This is sometimes known as *extraction*: the operation |
| 507 | “extracts” information from the inputs to generate a pseudorandom |
| 508 | intermediate secret value. |
| 509 | 2. Output generation. This is sometimes known as *expansion*: the operation |
| 510 | “expands” the intermediate secret value to the desired output length. |
| 511 | |
| 512 | The specification defines a `multi-part operation <multi-part-operations>` |
| 513 | API for key derivation that allows for multiple key and non-key outputs to be |
| 514 | extracted from a single derivation operation object. |
| 515 | |
| 516 | In an implementation with `isolation <isolation>`, the intermediate |
| 517 | state of the key derivation is not visible to the caller, and if an output of |
| 518 | the derivation is a non-exportable key, then this key cannot be recovered |
| 519 | outside the isolation boundary. |
| 520 | |
| 521 | Applications use the `psa_key_derivation_operation_t` type to create key |
| 522 | derivation operations. The operation object is used as follows: |
| 523 | |
| 524 | 1. Initialize a `psa_key_derivation_operation_t` object to zero or to |
| 525 | `PSA_KEY_DERIVATION_OPERATION_INIT`. |
| 526 | 2. Call `psa_key_derivation_setup()` to select a key derivation algorithm. |
| 527 | 3. Call the functions `psa_key_derivation_input_bytes()` and |
| 528 | `psa_key_derivation_input_key()`, or `psa_key_derivation_key_agreement()` to |
| 529 | provide the inputs to the key derivation algorithm. Many key derivation |
| 530 | algorithms take multiple inputs; the ``step`` parameter to these functions |
| 531 | indicates which input is being provided. The documentation for each key |
| 532 | derivation algorithm describes the expected inputs for that algorithm and |
| 533 | in what order to pass them. |
| 534 | 4. Optionally, call `psa_key_derivation_set_capacity()` to set a limit on the |
| 535 | amount of data that can be output from the key derivation operation. |
| 536 | 5. Call `psa_key_derivation_output_key()` to create a derived key, or |
| 537 | `psa_key_derivation_output_bytes()` to export the derived data. These |
| 538 | functions can be called multiple times to read successive output from the key |
| 539 | derivation, until the stream is exhausted when its capacity has been reached. |
| 540 | 6. Key derivation does not finish in the same way as other multi-part |
| 541 | operations. Call `psa_key_derivation_abort()` to release the key derivation |
| 542 | operation memory when the object is no longer required. |
| 543 | |
| 544 | To recover from an error, call `psa_key_derivation_abort()` to release the key |
| 545 | derivation operation memory. |
| 546 | |
| 547 | A key derivation operation cannot be rewound. Once a part of the stream has been |
| 548 | output, it cannot be output again. This ensures that the same part of the output |
| 549 | will not be used for different purposes. |
| 550 | |
| 551 | Example of the symmetric cryptography API |
| 552 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 553 | |
| 554 | Here is an example of a use case where a master key is used to generate both a |
| 555 | message encryption key and an IV for the encryption, and the derived key and IV |
| 556 | are then used to encrypt a message. |
| 557 | |
| 558 | 1. Derive the message encryption material from the master key. |
| 559 | |
| 560 | 1. Initialize a `psa_key_derivation_operation_t` object to zero or to |
| 561 | `PSA_KEY_DERIVATION_OPERATION_INIT`. |
| 562 | 2. Call `psa_key_derivation_setup()` with `PSA_ALG_HKDF` as the algorithm. |
| 563 | 3. Call `psa_key_derivation_input_key()` with the step |
| 564 | `PSA_KEY_DERIVATION_INPUT_SECRET` and the master key. |
| 565 | 4. Call `psa_key_derivation_input_bytes()` with the step |
| 566 | `PSA_KEY_DERIVATION_INPUT_INFO` and a public value that uniquely |
| 567 | identifies the message. |
| 568 | 5. Populate a `psa_key_attributes_t` object with the derived message |
| 569 | encryption key’s attributes. |
| 570 | 6. Call `psa_key_derivation_output_key()` to create the derived message key. |
| 571 | 7. Call `psa_key_derivation_output_bytes()` to generate the derived IV. |
| 572 | 8. Call `psa_key_derivation_abort()` to release the key derivation operation |
| 573 | memory. |
| 574 | |
| 575 | 2. Encrypt the message with the derived material. |
| 576 | |
| 577 | 1. Initialize a `psa_cipher_operation_t` object to zero or to |
| 578 | `PSA_CIPHER_OPERATION_INIT`. |
| 579 | 2. Call `psa_cipher_encrypt_setup()` with the derived message encryption key. |
| 580 | 3. Call `psa_cipher_set_iv()` using the derived IV retrieved above. |
| 581 | 4. Call `psa_cipher_update()` one or more times to encrypt the message. |
| 582 | 5. Call `psa_cipher_finish()` at the end of the message. |
| 583 | |
| 584 | 3. Call `psa_destroy_key()` to clear the generated key. |
| 585 | |
| 586 | Asymmetric cryptography |
| 587 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 588 | |
| 589 | This specification defines functions for asymmetric cryptography, including |
| 590 | asymmetric encryption, asymmetric signature, and two-way key agreement. |
| 591 | |
| 592 | Asymmetric encryption |
| 593 | ^^^^^^^^^^^^^^^^^^^^^ |
| 594 | |
| 595 | Asymmetric encryption is provided through the functions |
| 596 | `psa_asymmetric_encrypt()` and `psa_asymmetric_decrypt()`. |
| 597 | |
| 598 | Hash-and-sign |
| 599 | ^^^^^^^^^^^^^ |
| 600 | |
| 601 | The signature and verification functions `psa_sign_message()` and |
| 602 | `psa_verify_message()` take a message as one of their inputs and perform a |
| 603 | hash-and-sign algorithm. |
| 604 | |
| 605 | The functions `psa_sign_hash()` and `psa_verify_hash()` take a message hash as |
| 606 | one of their inputs. This is useful for signing pre-computed hashes, or for |
| 607 | implementing hash-and-sign using a :ref:`multi-part hash operation <hash-mp>` |
| 608 | before signing the resulting hash. To determine which |
| 609 | hash algorithm to use, call the macro `PSA_ALG_GET_HASH()` on the |
| 610 | corresponding signature algorithm. |
| 611 | |
| 612 | Some hash-and-sign algorithms add padding to the message hash before completing |
| 613 | the signing operation. The format of the padding that is used depends on the |
| 614 | algorithm used to construct the signature. |
| 615 | |
| 616 | Key agreement |
| 617 | ^^^^^^^^^^^^^ |
| 618 | |
| 619 | This specification defines two functions for a Diffie-Hellman-style key |
| 620 | agreement where each party combines its own private key with the peer’s public |
| 621 | key. |
| 622 | |
| 623 | The recommended approach is to use a `key derivation |
| 624 | operation <key-derivation>` with the `psa_key_derivation_key_agreement()` |
| 625 | input function, which calculates a shared secret for the key derivation |
| 626 | function. |
| 627 | |
| 628 | Where an application needs direct access to the shared secret, it can call |
| 629 | `psa_raw_key_agreement()` instead. Note that in general the shared secret is not |
| 630 | directly suitable for use as a key because it is biased. |
| 631 | |
| 632 | Randomness and key generation |
| 633 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 634 | |
| 635 | We strongly recommended that implementations include a random generator, |
| 636 | consisting of a cryptographically secure pseudo-random generator (CSPRNG), which |
| 637 | is adequately seeded with a cryptographic-quality hardware entropy source, |
| 638 | commonly referred to as a true random number generator (TRNG). Constrained |
| 639 | implementations can omit the random generation functionality if they do not |
| 640 | implement any algorithm that requires randomness internally, and they do not |
| 641 | provide a key generation functionality. For example, a special-purpose component |
| 642 | for signature verification can omit this. |
| 643 | |
| 644 | It is recommended that applications use `psa_generate_key()`, |
| 645 | `psa_cipher_generate_iv()` or `psa_aead_generate_nonce()` to generate |
| 646 | suitably-formatted random data, as applicable. In addition, the API includes a |
| 647 | function `psa_generate_random()` to generate and extract arbitrary random data. |