pub unsafe extern "C" fn psa_key_derivation_output_key(
    attributes: *const psa_key_attributes_t,
    operation: *mut psa_key_derivation_operation_t,
    key: *mut mbedtls_svc_key_id_t
) -> psa_status_t
Expand description

Derive a key from an ongoing key derivation operation.

This function calculates output bytes from a key derivation algorithm and uses those bytes to generate a key deterministically. The key’s location, usage policy, type and size are taken from \p attributes.

If you view the key derivation’s output as a stream of bytes, this function destructively reads as many bytes as required from the stream. The operation’s capacity decreases by the number of bytes read.

If this function returns an error status other than #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 and on the key size (denoted \c bits below):

  • 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 (\c bits / 8) bytes from the operation. The following key types defined in this specification follow this scheme:

    • #PSA_KEY_TYPE_AES;
    • #PSA_KEY_TYPE_ARIA;
    • #PSA_KEY_TYPE_CAMELLIA;
    • #PSA_KEY_TYPE_DERIVE;
    • #PSA_KEY_TYPE_HMAC;
    • #PSA_KEY_TYPE_PASSWORD_HASH.
  • For ECC keys on a Montgomery elliptic curve (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a Montgomery curve), 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 7748 §5.
    • Curve448 (#PSA_ECC_FAMILY_MONTGOMERY, 448 bits): draw a 56-byte string and process it as specified in RFC 7748 §5.
  • For key types for which the key is represented by a single sequence of \c bits bits with constraints as to which bit sequences are acceptable, this function draws a byte string of length (\c bits / 8) bytes rounded up to the nearest whole number of bytes. If the resulting byte string is acceptable, it becomes the key, otherwise the drawn bytes are discarded. This process is repeated until an acceptable byte string is drawn. The byte string drawn from the operation is interpreted as specified for the output produced by psa_export_key(). The following key types defined in this specification follow this scheme:

    • #PSA_KEY_TYPE_DES. Force-set the parity bits, but discard forbidden weak keys. For 2-key and 3-key triple-DES, the three keys are generated successively (for example, for 3-key triple-DES, 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 (#PSA_KEY_TYPE_DH_KEY_PAIR(\c group) where \c group designates any Diffie-Hellman group) and ECC keys on a Weierstrass elliptic curve (#PSA_KEY_TYPE_ECC_KEY_PAIR(\c curve) where \c curve designates a Weierstrass curve). For these key types, interpret the byte string as integer in big-endian order. Discard it if it is not in the range [0, N - 2] where N is the boundary of the private key domain (the prime p for Diffie-Hellman, the subprime q for DSA, or the order of the curve’s base point for ECC). Add 1 to the resulting integer and use this as the private key x. This method allows compliance to NIST standards, specifically the methods titled “key-pair generation by testing candidates” in NIST SP 800-56A §5.6.1.1.4 for Diffie-Hellman, in FIPS 186-4 §B.1.2 for DSA, and in NIST SP 800-56A §5.6.1.2.2 or FIPS 186-4 §B.4.2 for elliptic curve keys.
  • For other key types, including #PSA_KEY_TYPE_RSA_KEY_PAIR, the way in which the operation output is consumed is implementation-defined.

In all cases, the data that is read is discarded from the operation. The operation’s capacity is decreased by the number of bytes read.

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 may include additional restrictions on the derived key based on the attributes and strength of the secret key.

\param[in] attributes The attributes for the new key. If the key type to be created is #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in the policy must be the same as in the current operation. \param[in,out] operation The key derivation operation object to read from. \param[out] key On success, an identifier for the newly created key. For persistent keys, this is the key identifier defined in \p attributes. \c 0 on failure.

\retval #PSA_SUCCESS Success. If the key is persistent, the key material and the key’s metadata have been saved to persistent storage. \retval #PSA_ERROR_ALREADY_EXISTS This is an attempt to create a persistent key, and there is already a persistent key with the given identifier. \retval #PSA_ERROR_INSUFFICIENT_DATA There was not enough data to create the desired key. Note that in this case, no output is written to the output buffer. The operation’s capacity is set to 0, thus subsequent calls to this function will not succeed, even with a smaller output buffer. \retval #PSA_ERROR_NOT_SUPPORTED The key type or key size is not supported, either by the implementation in general or in this particular location. \retval #PSA_ERROR_INVALID_ARGUMENT The provided key attributes are not valid for the operation. \retval #PSA_ERROR_NOT_PERMITTED The #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a key; or one of the inputs was a key whose policy didn’t allow #PSA_KEY_USAGE_DERIVE. \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription \retval #PSA_ERROR_DATA_INVALID \emptydescription \retval #PSA_ERROR_DATA_CORRUPT \emptydescription \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription \retval #PSA_ERROR_BAD_STATE The operation state is not valid (it must be active and completed all required input steps), or the library has not been previously initialized by psa_crypto_init(). It is implementation-dependent whether a failure to initialize results in this error code.