10.9. Key agreement
10.9.1. Key agreement algorithms
PSA_ALG_KEY_AGREEMENT
(macro)
Macro to build a combined algorithm that chains a key agreement with a key derivation.
#define PSA_ALG_KEY_AGREEMENT(ka_alg, kdf_alg) \ /* specificationdefined value */
Parameters

ka_alg
A key agreement algorithm (
PSA_ALG_XXX
value such thatPSA_ALG_IS_KEY_AGREEMENT
(
ka_alg
)
is true).
kdf_alg
A key derivation algorithm (
PSA_ALG_XXX
value such thatPSA_ALG_IS_KEY_DERIVATION
(
kdf_alg
)
is true).
Returns
The corresponding key agreement and derivation algorithm.
Unspecified if ka_alg
is not a supported key agreement algorithm or kdf_alg
is not a supported key derivation algorithm.
Description
A combined key agreement algorithm is used with a multipart key derivation operation, using a call to psa_key_derivation_key_agreement()
.
The component parts of a key agreement algorithm can be extracted using PSA_ALG_KEY_AGREEMENT_GET_BASE()
and PSA_ALG_KEY_AGREEMENT_GET_KDF()
.
PSA_ALG_FFDH
(macro)
The finitefield DiffieHellman (DH) key agreement algorithm.
#define PSA_ALG_FFDH ((psa_algorithm_t)0x09010000)
This algorithm can be used directly in a call to psa_raw_key_agreement()
, or combined with a key derivation operation using PSA_ALG_KEY_AGREEMENT()
for use with psa_key_derivation_key_agreement()
.
When used as part of a multipart key derivation operation, this implements a DiffieHellman key agreement scheme using a single DiffieHellman keypair for each participant. This includes the dhEphem, dhOneFlow, and dhStatic schemes. The input step PSA_KEY_DERIVATION_INPUT_SECRET
is used when providing the secret and peer keys to the operation.
The shared secret produced by this key agreement algorithm is g^{ab}
in bigendian format. It is ceiling(m / 8)
bytes long where m
is the size of the prime p
in bits.
This key agreement scheme is defined by NIST Special Publication 80056A: Recommendation for PairWise KeyEstablishment Schemes Using Discrete Logarithm Cryptography [SP80056A] §5.7.1.1 under the name FFC DH.
PSA_ALG_ECDH
(macro)
The elliptic curve DiffieHellman (ECDH) key agreement algorithm.
#define PSA_ALG_ECDH ((psa_algorithm_t)0x09020000)
This algorithm can be used directly in a call to psa_raw_key_agreement()
, or combined with a key derivation operation using PSA_ALG_KEY_AGREEMENT()
for use with psa_key_derivation_key_agreement()
.
When used as part of a multipart key derivation operation, this implements a DiffieHellman key agreement scheme using a single elliptic curve keypair for each participant. This includes the Ephemeral unified model, the Static unified model, and the Onepass DiffieHellman schemes. The input step PSA_KEY_DERIVATION_INPUT_SECRET
is used when providing the secret and peer keys to the operation.
The shared secret produced by key agreement is the xcoordinate of the shared secret point. It is always ceiling(m / 8)
bytes long where m
is the bit size associated with the curve, i.e. the bit size of the order of the curve’s coordinate field. When m
is not a multiple of 8, the byte containing the most significant bit of the shared secret is padded with zero bits. The byte order is either littleendian or bigendian depending on the curve type.
For Montgomery curves (curve family
PSA_ECC_FAMILY_MONTGOMERY
), the shared secret is the xcoordinate ofZ = d_A Q_B = d_B Q_A
in littleendian byte order.For Curve25519, this is the X25519 function defined in Curve25519: new DiffieHellman speed records [Curve25519]. The bit size
m
is 255.For Curve448, this is the X448 function defined in Ed448Goldilocks, a new elliptic curve [Curve448]. The bit size
m
is 448.
For Weierstrass curves (curve families
PSA_ECC_FAMILY_SECP_XX
,PSA_ECC_FAMILY_SECT_XX
,PSA_ECC_FAMILY_BRAINPOOL_P_R1
andPSA_ECC_FAMILY_FRP
) the shared secret is the xcoordinate ofZ = h d_A Q_B = h d_B Q_A
in bigendian byte order. This is the Elliptic Curve Cryptography Cofactor DiffieHellman primitive defined by SEC 1: Elliptic Curve Cryptography [SEC1] §3.3.2 as, and also as ECC CDH by NIST Special Publication 80056A: Recommendation for PairWise KeyEstablishment Schemes Using Discrete Logarithm Cryptography [SP80056A] §5.7.1.2.Over prime fields (curve families
PSA_ECC_FAMILY_SECP_XX
,PSA_ECC_FAMILY_BRAINPOOL_P_R1
andPSA_ECC_FAMILY_FRP
), the bit size ism = ceiling(log_2(p))
for the fieldF_p
.Over binary fields (curve families
PSA_ECC_FAMILY_SECT_XX
), the bit size ism
for the fieldF_{2^m}
.
Note
The cofactor DiffieHellman primitive is equivalent to the standard elliptic curve DiffieHellman calculation
Z = d_A Q_B = d_B Q_A
([SEC1] §3.3.1) for curves where the cofactorh
is1
. This is true for all curves in thePSA_ECC_FAMILY_SECP_XX
,PSA_ECC_FAMILY_BRAINPOOL_P_R1
, andPSA_ECC_FAMILY_FRP
families.
10.9.2. Standalone key agreement
psa_raw_key_agreement
(function)
Perform a key agreement and return the raw shared secret.
psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, psa_key_id_t private_key, const uint8_t * peer_key, size_t peer_key_length, uint8_t * output, size_t output_size, size_t * output_length);
Parameters

alg
The key agreement algorithm to compute (
PSA_ALG_XXX
value such thatPSA_ALG_IS_RAW_KEY_AGREEMENT
(
alg
)
is true).
private_key
Identifier of the private key to use. It must allow the usage
PSA_KEY_USAGE_DERIVE
.
peer_key
Public key of the peer. It must be in the same format that
psa_import_key()
accepts. The standard formats for public keys are documented in the documentation ofpsa_export_public_key()
.
peer_key_length
Size of
peer_key
in bytes.
output
Buffer where the raw shared secret is to be written.

output_size
Size of the
output
buffer in bytes. This must be appropriate for the keys:The required output size is
PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE
(
type
,
bits
)
wheretype
is the type ofprivate_key
andbits
is the bitsize of eitherprivate_key
or thepeer_key
.PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
evaluates to the maximum output size of any supported raw key agreement algorithm.

output_length
On success, the number of bytes that make up the returned output.
Returns: psa_status_t

PSA_SUCCESS
Success.

PSA_ERROR_INVALID_HANDLE

PSA_ERROR_NOT_PERMITTED
The key does not have the
PSA_KEY_USAGE_DERIVE
flag, or it does not permit the requested algorithm.
PSA_ERROR_INVALID_ARGUMENT
alg
is not a key agreement algorithm
PSA_ERROR_INVALID_ARGUMENT
private_key
is not compatible withalg
, orpeer_key
is not valid foralg
or not compatible withprivate_key
.
PSA_ERROR_BUFFER_TOO_SMALL
The size of the
output
buffer is too small.PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE()
orPSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
can be used to determine the required buffer size.
PSA_ERROR_NOT_SUPPORTED
alg
is not a supported key agreement algorithm.
PSA_ERROR_INSUFFICIENT_MEMORY

PSA_ERROR_COMMUNICATION_FAILURE

PSA_ERROR_HARDWARE_FAILURE

PSA_ERROR_CORRUPTION_DETECTED

PSA_ERROR_STORAGE_FAILURE

PSA_ERROR_DATA_CORRUPT

PSA_ERROR_DATA_INVALID

PSA_ERROR_BAD_STATE
The library has not been previously initialized by
psa_crypto_init()
. It is implementationdependent whether a failure to initialize results in this error code.
Description
Warning
The raw result of a key agreement algorithm such as finitefield DiffieHellman or elliptic curve DiffieHellman has biases, and is not suitable for use as key material. Instead it is recommended that the result is used as input to a key derivation algorithm. To chain a key agreement with a key derivation, use psa_key_derivation_key_agreement()
and other functions from the key derivation interface.
10.9.3. Combining key agreement and key derivation
psa_key_derivation_key_agreement
(function)
Perform a key agreement and use the shared secret as input to a key derivation.
psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t * operation, psa_key_derivation_step_t step, psa_key_id_t private_key, const uint8_t * peer_key, size_t peer_key_length);
Parameters

operation
The key derivation operation object to use. It must have been set up with
psa_key_derivation_setup()
with a key agreement and derivation algorithmalg
(PSA_ALG_XXX
value such thatPSA_ALG_IS_KEY_AGREEMENT
(
alg
)
is true andPSA_ALG_IS_RAW_KEY_AGREEMENT
(
alg
)
is false). The operation must be ready for an input of the type given bystep
.
step
Which step the input data is for.

private_key
Identifier of the private key to use. It must allow the usage
PSA_KEY_USAGE_DERIVE
.
peer_key
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 ofpsa_import_key
(...,
peer_key
,
peer_key_length
)
where with key attributes indicating the public key type corresponding to the type ofprivate_key
. For example, for EC 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 ofpsa_export_public_key()
.
peer_key_length
Size of
peer_key
in bytes.
Returns: psa_status_t

PSA_SUCCESS
Success.

PSA_ERROR_BAD_STATE
The operation state is not valid for this key agreement
step
.
PSA_ERROR_INVALID_HANDLE

PSA_ERROR_NOT_PERMITTED
The key does not have the
PSA_KEY_USAGE_DERIVE
flag, or it does not permit the requested algorithm.
PSA_ERROR_INVALID_ARGUMENT
private_key
is not compatible withalg
, orpeer_key
is not valid foralg
or not compatible withprivate_key
.
PSA_ERROR_NOT_SUPPORTED
alg
is not supported or is not a key derivation algorithm.
PSA_ERROR_INVALID_ARGUMENT
step
does not allow an input resulting from a key agreement.
PSA_ERROR_INSUFFICIENT_MEMORY

PSA_ERROR_COMMUNICATION_FAILURE

PSA_ERROR_HARDWARE_FAILURE

PSA_ERROR_CORRUPTION_DETECTED

PSA_ERROR_STORAGE_FAILURE

PSA_ERROR_DATA_CORRUPT

PSA_ERROR_DATA_INVALID

PSA_ERROR_BAD_STATE
The library has not been previously initialized by
psa_crypto_init()
. It is implementationdependent whether a failure to initialize results in this error code.
Description
A key agreement algorithm takes two inputs: a private key private_key
a public key peer_key
. The result of this function is passed as input to a key derivation. The output of this key derivation can be extracted by reading from the resulting operation to produce keys and other cryptographic material.
If this function returns an error status, the operation enters an error state and must be aborted by calling psa_key_derivation_abort()
.
10.9.4. Support macros
PSA_ALG_KEY_AGREEMENT_GET_BASE
(macro)
Get the raw key agreement algorithm from a full key agreement algorithm.
#define PSA_ALG_KEY_AGREEMENT_GET_BASE(alg) /* specificationdefined value */
Parameters

alg
A key agreement algorithm identifier (value of type
psa_algorithm_t
such thatPSA_ALG_IS_KEY_AGREEMENT
(
alg
)
is true).
Returns
The underlying raw key agreement algorithm if alg
is a key agreement algorithm.
Unspecified if alg
is not a key agreement algorithm or if it is not supported by the implementation.
Description
See also PSA_ALG_KEY_AGREEMENT()
and PSA_ALG_KEY_AGREEMENT_GET_KDF()
.
PSA_ALG_KEY_AGREEMENT_GET_KDF
(macro)
Get the key derivation algorithm used in a full key agreement algorithm.
#define PSA_ALG_KEY_AGREEMENT_GET_KDF(alg) /* specificationdefined value */
Parameters

alg
A key agreement algorithm identifier (value of type
psa_algorithm_t
such thatPSA_ALG_IS_KEY_AGREEMENT
(
alg
)
is true).
Returns
The underlying key derivation algorithm if alg
is a key agreement algorithm.
Unspecified if alg
is not a key agreement algorithm or if it is not supported by the implementation.
Description
See also PSA_ALG_KEY_AGREEMENT()
and PSA_ALG_KEY_AGREEMENT_GET_BASE()
.
PSA_ALG_IS_RAW_KEY_AGREEMENT
(macro)
Whether the specified algorithm is a raw key agreement algorithm.
#define PSA_ALG_IS_RAW_KEY_AGREEMENT(alg) /* specificationdefined value */
Parameters

alg
An algorithm identifier (value of type
psa_algorithm_t
).
Returns
1
if alg
is a raw key agreement algorithm, 0
otherwise. This macro can return either 0
or 1
if alg
is not a supported algorithm identifier.
Description
A raw key agreement algorithm is one that does not specify a key derivation function. Usually, raw key agreement algorithms are constructed directly with a PSA_ALG_xxx
macro while nonraw key agreement algorithms are constructed with PSA_ALG_KEY_AGREEMENT()
.
The raw key agreement algorithm can be extracted from a full key agreement algorithm identifier using PSA_ALG_KEY_AGREEMENT_GET_BASE()
.
PSA_ALG_IS_FFDH
(macro)
Whether the specified algorithm is a finite field DiffieHellman algorithm.
#define PSA_ALG_IS_FFDH(alg) /* specificationdefined value */
Parameters

alg
An algorithm identifier (value of type
psa_algorithm_t
).
Returns
1
if alg
is a finite field DiffieHellman algorithm, 0
otherwise. This macro can return either 0
or 1
if alg
is not a supported key agreement algorithm identifier.
Description
This includes the raw finite field DiffieHellman algorithm as well as finitefield DiffieHellman followed by any supporter key derivation algorithm.
PSA_ALG_IS_ECDH
(macro)
Whether the specified algorithm is an elliptic curve DiffieHellman algorithm.
#define PSA_ALG_IS_ECDH(alg) /* specificationdefined value */
Parameters

alg
An algorithm identifier (value of type
psa_algorithm_t
).
Returns
1
if alg
is an elliptic curve DiffieHellman algorithm, 0
otherwise. This macro can return either 0
or 1
if alg
is not a supported key agreement algorithm identifier.
Description
This includes the raw elliptic curve DiffieHellman algorithm as well as elliptic curve DiffieHellman followed by any supporter key derivation algorithm.
PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE
(macro)
Sufficient output buffer size for psa_raw_key_agreement()
.
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE(key_type, key_bits) \ /* implementationdefined value */
Parameters

key_type
A supported key type.

key_bits
The size of the key in bits.
Returns
If the parameters are valid and supported, return a buffer size in bytes that guarantees that psa_raw_key_agreement()
will not fail with PSA_ERROR_BUFFER_TOO_SMALL
. If the parameters are a valid combination that is not supported by the implementation, this macro must return either a sensible size or 0
. If the parameters are not valid, the return value is unspecified.
Description
This macro returns a compiletime constant if its arguments are compiletime constants.
Warning
This function might evaluate its arguments multiple times or zero times. Providing arguments that have side effects will result in implementationspecific behavior, and is nonportable.
See also PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
.
PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE
(macro)
Maximum size of the output from psa_raw_key_agreement()
.
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE \ /* implementationdefined value */
This macro must expand to a compiletime constant integer. It is recommended that this value is the maximum size of the output any raw key agreement algorithm supported by the implementation, in bytes. The value must not be smaller than this maximum.
See also PSA_RAW_KEY_AGREEMENT_OUTPUT_SIZE()
.