10.13 Password-authenticated key exchange (PAKE)¶
PAKE protocols provide an interactive method for two or more parties to establish cryptographic keys based on knowledge of a low entropy secret, such as a password.
These can provide strong security for communication from a weak password, because the password is not directly communicated as part of the key exchange.
This chapter is divided into the following sections:
Common API for PAKE — the common interface elements, including the PAKE operation.
The J-PAKE protocol — the J-PAKE protocol, and the associated interface elements.
The SPAKE2+ protocol — the SPAKE2+ protocols, and the associated interface elements.
The WPA3-SAE protocol — the WPA3-SAE protocol, and the associated interface elements.
10.13.1 Common API for PAKE¶
This section defines all of the common interfaces used to carry out a PAKE protocol:
10.13.2 PAKE primitives¶
A PAKE algorithm specifies a sequence of interactions between the participants. Many PAKE algorithms are designed to allow different cryptographic primitives to be used for the key establishment operation, so long as all the participants are using the same underlying cryptography.
The cryptographic primitive for a PAKE operation is specified using a psa_pake_primitive_t value, which can be constructed using the PSA_PAKE_PRIMITIVE() macro, or can be provided as a numerical constant value.
A PAKE primitive is required when constructing a PAKE cipher-suite object, psa_pake_cipher_suite_t, which fully specifies the PAKE operation to be carried out.
psa_pake_primitive_t (typedef)¶
Encoding of the primitive associated with the PAKE.
Added in version 1.1.
typedef uint32_t psa_pake_primitive_t;
PAKE primitive values are constructed using PSA_PAKE_PRIMITIVE().
Figure 2 shows how the components of the primitive are encoded into a psa_pake_primitive_t value.
Figure 2 PAKE primitive encoding¶
The components of a PAKE primitive value can be extracted using the PSA_PAKE_PRIMITIVE_GET_TYPE(), PSA_PAKE_PRIMITIVE_GET_FAMILY(), and PSA_PAKE_PRIMITIVE_GET_BITS().
These can be used to set key attributes for keys used in PAKE algorithms.
SPAKE2+ registration provides an example of this usage.
psa_pake_primitive_type_t (typedef)¶
Encoding of the type of the PAKE’s primitive.
Added in version 1.1.
typedef uint8_t psa_pake_primitive_type_t;
The range of PAKE primitive type values is divided as follows:
0x00Reserved as an invalid primitive type.
0x01 - 0x7fSpecification-defined primitive type. Primitive types defined by this standard always have bit 7 clear. Unallocated primitive type values in this range are reserved for future use.
0x80 - 0xffImplementation-defined primitive type. Implementations that define additional primitive types must use an encoding with bit 7 set.
For specification-defined primitive types, see PSA_PAKE_PRIMITIVE_TYPE_ECC and PSA_PAKE_PRIMITIVE_TYPE_DH.
PSA_PAKE_PRIMITIVE_TYPE_ECC (macro)¶
The PAKE primitive type indicating the use of elliptic curves.
Added in version 1.1.
#define PSA_PAKE_PRIMITIVE_TYPE_ECC ((psa_pake_primitive_type_t)0x01)
The values of the family and bits components of the PAKE primitive identify a specific elliptic curve, using the same mapping that is used for ECC keys.
See the definition of psa_ecc_family_t.
Here family and bits refer to the values used to construct the PAKE primitive using PSA_PAKE_PRIMITIVE().
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 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 Key format within the definition of
PSA_KEY_TYPE_ECC_KEY_PAIR().
PSA_PAKE_PRIMITIVE_TYPE_DH (macro)¶
The PAKE primitive type indicating the use of a finite field Diffie-Hellman group.
Added in version 1.1.
#define PSA_PAKE_PRIMITIVE_TYPE_DH ((psa_pake_primitive_type_t)0x02)
The values of the family and bits components of the PAKE primitive identify a specific finite field Diffie-Hellman group, using the same mapping that is used for finite field Diffie-Hellman keys.
See the definition of psa_dh_family_t.
Here family and bits refer to the values used to construct the PAKE primitive using PSA_PAKE_PRIMITIVE().
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 finite field Diffie-Hellman group. 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 finite field Diffie-Hellman group. See Key format within the definition of
PSA_KEY_TYPE_DH_PUBLIC_KEY().
psa_pake_family_t (typedef)¶
Encoding of the family of the primitive associated with the PAKE.
Added in version 1.1.
typedef uint8_t psa_pake_family_t;
For more information on the family values, see PSA_PAKE_PRIMITIVE_TYPE_ECC and PSA_PAKE_PRIMITIVE_TYPE_DH.
PSA_PAKE_PRIMITIVE (macro)¶
Construct a PAKE primitive from type, family and bit-size.
Added in version 1.1.
#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \ /* specification-defined value */
Parameters
pake_typeThe type of the primitive: a value of type
psa_pake_primitive_type_t.pake_familyThe family of the primitive. The type and interpretation of this parameter depends on
pake_type. For more information, seePSA_PAKE_PRIMITIVE_TYPE_ECCandPSA_PAKE_PRIMITIVE_TYPE_DH.pake_bitsThe bit-size of the primitive: a value of type
size_t. The interpretation of this parameter depends onpake_typeandfamily. For more information, seePSA_PAKE_PRIMITIVE_TYPE_ECCandPSA_PAKE_PRIMITIVE_TYPE_DH.
Returns: psa_pake_primitive_t
The constructed primitive value.
Return 0 if the requested primitive can’t be encoded as psa_pake_primitive_t.
Description
A PAKE primitive value is used to specify a PAKE operation, as part of a PAKE cipher suite.
PSA_PAKE_PRIMITIVE_GET_TYPE (macro)¶
Extract the PAKE primitive type from a PAKE primitive.
Added in version 1.2.
#define PSA_PAKE_PRIMITIVE_GET_TYPE(pake_primitive) \ /* specification-defined value */
Parameters
pake_primitiveA PAKE primitive: a value of type
psa_pake_primitive_t.
Returns: psa_pake_primitive_type_t
The PAKE primitive type, if pake_primitive is a supported PAKE primitive.
Unspecified if pake_primitive is not a supported PAKE primitive.
PSA_PAKE_PRIMITIVE_GET_FAMILY (macro)¶
Extract the family from a PAKE primitive.
Added in version 1.2.
#define PSA_PAKE_PRIMITIVE_GET_FAMILY(pake_primitive) \ /* specification-defined value */
Parameters
pake_primitiveA PAKE primitive: a value of type
psa_pake_primitive_t.
Returns: psa_pake_family_t
The PAKE primitive family, if pake_primitive is a supported PAKE primitive.
Unspecified if pake_primitive is not a supported PAKE primitive.
Description
For more information on the family values, see PSA_PAKE_PRIMITIVE_TYPE_ECC and PSA_PAKE_PRIMITIVE_TYPE_DH.
PSA_PAKE_PRIMITIVE_GET_BITS (macro)¶
Extract the bit-size from a PAKE primitive.
Added in version 1.2.
#define PSA_PAKE_PRIMITIVE_GET_BITS(pake_primitive) \ /* specification-defined value */
Parameters
pake_primitiveA PAKE primitive: a value of type
psa_pake_primitive_t.
Returns: size_t
The PAKE primitive bit-size, if pake_primitive is a supported PAKE primitive.
Unspecified if pake_primitive is not a supported PAKE primitive.
Description
For more information on the bit-size values, see PSA_PAKE_PRIMITIVE_TYPE_ECC and PSA_PAKE_PRIMITIVE_TYPE_DH.
10.13.3 PAKE cipher suites¶
Most PAKE algorithms have parameters that must be specified by the application. These parameters include the following:
The cryptographic primitive used for key establishment, specified using a PAKE primitive.
A cryptographic hash algorithm.
Whether the application requires the shared secret before, or after, it is confirmed.
The hash algorithm is encoded into the PAKE algorithm identifier. The psa_pake_cipher_suite_t object is used to fully specify a PAKE operation, combining the PAKE protocol with all of the above parameters.
A PAKE cipher suite is required when setting up a PAKE operation in psa_pake_setup().
psa_pake_cipher_suite_t (typedef)¶
The type of an object describing a PAKE cipher suite.
Added in version 1.1.
typedef /* implementation-defined type */ psa_pake_cipher_suite_t;
This is the object that represents the cipher suite used for a PAKE algorithm. The PAKE cipher suite specifies the PAKE algorithm, and the options selected for that algorithm. The cipher suite includes the following attributes:
The PAKE algorithm itself.
The hash algorithm, encoded within the PAKE algorithm.
The PAKE primitive, which identifies the prime order group used for the key exchange operation. See PAKE primitives.
Whether to confirm the shared secret.
This is an implementation-defined type. Applications that make assumptions about the content of this object will result in implementation-specific behavior, and are non-portable.
Before calling any function on a PAKE cipher suite object, the application must initialize it by any of the following means:
Set the object to all-bits-zero, for example:
psa_pake_cipher_suite_t cipher_suite; memset(&cipher_suite, 0, sizeof(cipher_suite));
Initialize the object to logical zero values by declaring the object as static or global without an explicit initializer, for example:
static psa_pake_cipher_suite_t cipher_suite;
Initialize the object to the initializer
PSA_PAKE_CIPHER_SUITE_INIT, for example:psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT;
Assign the result of the function
psa_pake_cipher_suite_init()to the object, for example:psa_pake_cipher_suite_t cipher_suite; cipher_suite = psa_pake_cipher_suite_init();
Following initialization, the cipher-suite object contains the following values:
Attribute |
Value |
|---|---|
algorithm |
|
primitive |
|
key confirmation |
|
Valid algorithm, primitive, and key confirmation values must be set when using a PAKE cipher suite.
Implementation note
Implementations are recommended to define the cipher-suite object as a simple data structure, with fields corresponding to the individual cipher suite attributes.
In such an implementation, each function psa_pake_cs_set_xxx() sets a field and the corresponding function psa_pake_cs_get_xxx() retrieves the value of the field.
An implementation can report attribute values that are equivalent to the original one, but have a different encoding. For example, an implementation can use a more compact representation for attributes where many bit-patterns are invalid or not supported, and store all values that it does not support as a special marker value. In such an implementation, after setting an invalid value, the corresponding get function returns an invalid value which might not be the one that was originally stored.
PSA_PAKE_CIPHER_SUITE_INIT (macro)¶
This macro returns a suitable initializer for a PAKE cipher suite object of type psa_pake_cipher_suite_t.
Added in version 1.1.
#define PSA_PAKE_CIPHER_SUITE_INIT /* implementation-defined value */
psa_pake_cipher_suite_init (function)¶
Return an initial value for a PAKE cipher suite object.
Added in version 1.1.
psa_pake_cipher_suite_t psa_pake_cipher_suite_init(void);
Returns: psa_pake_cipher_suite_t
psa_pake_cs_get_algorithm (function)¶
Retrieve the PAKE algorithm from a PAKE cipher suite.
Added in version 1.1.
psa_algorithm_t psa_pake_cs_get_algorithm(const psa_pake_cipher_suite_t* cipher_suite);
Parameters
cipher_suiteThe cipher suite object to query.
Returns: psa_algorithm_t
The PAKE algorithm stored in the cipher suite object.
Description
Implementation note
This is a simple accessor function that is not required to validate its inputs.
It can be efficiently implemented as a static inline function or a function-like macro.
psa_pake_cs_set_algorithm (function)¶
Declare the PAKE algorithm for the cipher suite.
Added in version 1.1.
void psa_pake_cs_set_algorithm(psa_pake_cipher_suite_t* cipher_suite, psa_algorithm_t alg);
Parameters
cipher_suiteThe cipher suite object to write to.
algThe PAKE algorithm to write: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_PAKE(alg)is true.
Returns: void
Description
This function overwrites any PAKE algorithm previously set in cipher_suite.
Implementation note
This is a simple accessor function that is not required to validate its inputs.
It can be efficiently implemented as a static inline function or a function-like macro.
psa_pake_cs_get_primitive (function)¶
Retrieve the primitive from a PAKE cipher suite.
Added in version 1.1.
psa_pake_primitive_t psa_pake_cs_get_primitive(const psa_pake_cipher_suite_t* cipher_suite);
Parameters
cipher_suiteThe cipher suite object to query.
Returns: psa_pake_primitive_t
The primitive stored in the cipher suite object.
Description
Implementation note
This is a simple accessor function that is not required to validate its inputs.
It can be efficiently implemented as a static inline function or a function-like macro.
psa_pake_cs_set_primitive (function)¶
Declare the primitive for a PAKE cipher suite.
Added in version 1.1.
void psa_pake_cs_set_primitive(psa_pake_cipher_suite_t* cipher_suite, psa_pake_primitive_t primitive);
Parameters
cipher_suiteThe cipher suite object to write to.
primitiveThe PAKE primitive to write: a value of type
psa_pake_primitive_t. If this is0, the primitive type incipher_suitebecomes unspecified.
Returns: void
Description
This function overwrites any primitive previously set in cipher_suite.
Implementation note
This is a simple accessor function that is not required to validate its inputs.
It can be efficiently implemented as a static inline function or a function-like macro.
PSA_PAKE_CONFIRMED_KEY (macro)¶
A key confirmation value that indicates an confirmed key in a PAKE cipher suite.
Added in version 1.2.
#define PSA_PAKE_CONFIRMED_KEY 0
This key confirmation value will result in the PAKE algorithm exchanging data to verify that the shared key is identical for both parties. This is the default key confirmation value in an initialized PAKE cipher suite object.
Some algorithms do not include confirmation of the shared key.
PSA_PAKE_UNCONFIRMED_KEY (macro)¶
A key confirmation value that indicates an unconfirmed key in a PAKE cipher suite.
Added in version 1.2.
#define PSA_PAKE_UNCONFIRMED_KEY 1
This key confirmation value will result in the PAKE algorithm terminating prior to confirming that the resulting shared key is identical for both parties.
Some algorithms do not support returning an unconfirmed shared key.
Warning
When the shared key is not confirmed as part of the PAKE operation, the application is responsible for mitigating risks that arise from the possible mismatch in the output keys.
psa_pake_cs_get_key_confirmation (function)¶
Retrieve the key confirmation from a PAKE cipher suite.
Added in version 1.2.
uint32_t psa_pake_cs_get_key_confirmation(const psa_pake_cipher_suite_t* cipher_suite);
Parameters
cipher_suiteThe cipher suite object to query.
Returns: uint32_t
A key confirmation value: either PSA_PAKE_CONFIRMED_KEY or PSA_PAKE_UNCONFIRMED_KEY.
Description
Implementation note
This is a simple accessor function that is not required to validate its inputs.
It can be efficiently implemented as a static inline function or a function-like macro.
psa_pake_cs_set_key_confirmation (function)¶
Declare the key confirmation from a PAKE cipher suite.
Added in version 1.2.
void psa_pake_cs_set_key_confirmation(psa_pake_cipher_suite_t* cipher_suite, uint32_t key_confirmation);
Parameters
cipher_suiteThe cipher suite object to write to.
key_confirmationThe key confirmation value to write: either
PSA_PAKE_CONFIRMED_KEYorPSA_PAKE_UNCONFIRMED_KEY.
Returns: void
Description
This function overwrites any key confirmation previously set in cipher_suite.
The documentation of individual PAKE algorithms specifies which key confirmation values are valid for the algorithm.
Implementation note
This is a simple accessor function that is not required to validate its inputs.
It can be efficiently implemented as a static inline function or a function-like macro.
10.13.4 PAKE roles¶
Some PAKE algorithms need to know which role each participant is taking in the algorithm. For example:
Augmented PAKE algorithms typically have a client and a server participant.
Some symmetric PAKE algorithms assign an order to the two participants.
psa_pake_role_t (typedef)¶
Encoding of the application role in a PAKE algorithm.
Added in version 1.1.
typedef uint8_t psa_pake_role_t;
This type is used to encode the application’s role in the algorithm being executed. For more information see the documentation of individual PAKE role constants.
PSA_PAKE_ROLE_NONE (macro)¶
A value to indicate no role in a PAKE algorithm.
Added in version 1.1.
#define PSA_PAKE_ROLE_NONE ((psa_pake_role_t)0x00)
This value can be used in a call to psa_pake_set_role() for symmetric PAKE algorithms which do not assign roles.
PSA_PAKE_ROLE_FIRST (macro)¶
The first peer in a balanced PAKE.
Added in version 1.1.
#define PSA_PAKE_ROLE_FIRST ((psa_pake_role_t)0x01)
Although balanced PAKE algorithms are symmetric, some of them need the peers to be ordered for the transcript calculations.
If the algorithm does not need a specific ordering, then either do not call psa_pake_set_role(), or use PSA_PAKE_ROLE_NONE as the role parameter.
PSA_PAKE_ROLE_SECOND (macro)¶
The second peer in a balanced PAKE.
Added in version 1.1.
#define PSA_PAKE_ROLE_SECOND ((psa_pake_role_t)0x02)
Although balanced PAKE algorithms are symmetric, some of them need the peers to be ordered for the transcript calculations.
If the algorithm does not need a specific ordering, then either do not call psa_pake_set_role(), or use PSA_PAKE_ROLE_NONE as the role parameter.
PSA_PAKE_ROLE_CLIENT (macro)¶
The client in an augmented PAKE.
Added in version 1.1.
#define PSA_PAKE_ROLE_CLIENT ((psa_pake_role_t)0x11)
Augmented PAKE algorithms need to differentiate between client and server.
PSA_PAKE_ROLE_SERVER (macro)¶
The server in an augmented PAKE.
Added in version 1.1.
#define PSA_PAKE_ROLE_SERVER ((psa_pake_role_t)0x12)
Augmented PAKE algorithms need to differentiate between client and server.
10.13.5 PAKE step types¶
psa_pake_step_t (typedef)¶
Encoding of input and output steps for a PAKE algorithm.
Added in version 1.1.
typedef uint8_t psa_pake_step_t;
Some PAKE algorithms need to exchange more data than a single key share. This type encodes additional input and output steps for such algorithms.
PSA_PAKE_STEP_KEY_SHARE (macro)¶
A key share being sent to or received from a PAKE participant.
Added in version 1.1.
#define PSA_PAKE_STEP_KEY_SHARE ((psa_pake_step_t)0x01)
The format for both input and output using this step is the same as the format for public keys on the group specified by the PAKE operation’s primitive.
The public-key formats are defined in the documentation for psa_export_public_key().
For information regarding how the group is determined, consult the documentation PSA_PAKE_PRIMITIVE().
PSA_PAKE_STEP_ZK_PUBLIC (macro)¶
A Schnorr NIZKP public key being sent to or received from a PAKE participant.
Added in version 1.1.
#define PSA_PAKE_STEP_ZK_PUBLIC ((psa_pake_step_t)0x02)
This is the ephemeral public key in the Schnorr Non-Interactive Zero-Knowledge Proof, this is the value denoted by V in [RFC8235].
The format for both input and output at this step is the same as that for public keys on the group specified by the PAKE operation’s primitive.
For more information on the format, consult the documentation of psa_export_public_key().
For information regarding how the group is determined, consult the documentation PSA_PAKE_PRIMITIVE().
PSA_PAKE_STEP_ZK_PROOF (macro)¶
A Schnorr NIZKP proof being sent to or received from a PAKE participant.
Added in version 1.1.
#define PSA_PAKE_STEP_ZK_PROOF ((psa_pake_step_t)0x03)
This is the proof in the Schnorr Non-Interactive Zero-Knowledge Proof, this is the value denoted by r in [RFC8235].
Both for input and output, the value at this step is an integer less than the order of the group specified by the PAKE operation’s primitive. The format depends on the group as well:
For Montgomery curves, the encoding is little endian.
For other elliptic curves, and for finite field Diffie-Hellman groups, the encoding is big endian. See [SEC1] §2.3.8.
In both cases leading zeroes are permitted as long as the length in bytes does not exceed the byte length of the group order.
For information regarding how the group is determined, consult the documentation PSA_PAKE_PRIMITIVE().
PSA_PAKE_STEP_CONFIRM (macro)¶
A key confirmation value being sent to or received from a PAKE participant.
Added in version 1.2.
#define PSA_PAKE_STEP_CONFIRM ((psa_pake_step_t)0x04)
This value is used during the key confirmation phase of a PAKE protocol. The use of this step, and format of the value depends on the algorithm and cipher suite:
For a SPAKE2+ algorithm, the format for both input and output at this step is the same as the output of the MAC algorithm specified in the cipher suite. See SPAKE2+ operation.
For a WPA3-SAE algorithm, the format for both input and output at this step is a 2-byte little-endian send-confirm counter, followed by the confirm value, which is the output from the hash algorithm specified in the cipher suite. See WPA3-SAE operation.
PSA_PAKE_STEP_SALT (macro)¶
A salt value used for deriving shared secrets within a PAKE operation.
Added in version 1.4.
#define PSA_PAKE_STEP_SALT ((psa_pake_step_t)0x05)
This input can be used during the key exchange phase of a PAKE protocol. The use of this step, and format of the value depends on the algorithm and cipher suite:
For a WPA3-SAE algorithm, a salt value must be provided as defined in [IEEE-802.11] §12.4.5.4. See WPA3-SAE operation.
PSA_PAKE_STEP_COMMIT (macro)¶
A commitment value being sent to or received from a PAKE participant.
Added in version 1.4.
#define PSA_PAKE_STEP_COMMIT ((psa_pake_step_t)0x06)
This input and output is used during the key exchange phase of a PAKE protocol. The use of this step, and format of the value depends on the algorithm and cipher suite:
For a WPA3-SAE algorithm, the format for input and output at this step is a concatenation of the commit-scalar and COMMIT-ELEMENT values, as defined in [IEEE-802.11] §12.4.7.3.
See WPA3-SAE operation.
Note
These values are adjacent in the WPA3-SAE Authentication frame defined in [IEEE-802.11] §9.3.3.11. The concatenated value can be output directly to, or input directly from, the frame buffer.
PSA_PAKE_STEP_CONFIRM_COUNT (macro)¶
A counter used as part of key confirmation.
Added in version 1.4.
#define PSA_PAKE_STEP_CONFIRM_COUNT ((psa_pake_step_t)0x07)
This value is input during the key confirmation phase of a PAKE protocol. It enables multiple confirmation attempts to result in distinct confirmation values. The use of this step, and format of the value depends on the algorithm and cipher suite:
For a WPA3-SAE algorithm, the format for input at this step is the 2-byte little-endian send-confirm counter. See WPA3-SAE operation.
PSA_PAKE_STEP_KEY_ID (macro)¶
A key identifier value from a PAKE operation.
Added in version 1.4.
#define PSA_PAKE_STEP_KEY_ID ((psa_pake_step_t)0x08)
This value can be output from a PAKE operation following key confirmation. The use of this step, and format of the value depends on the algorithm and cipher suite:
For a WPA3-SAE algorithm, the format of the output at this step is the 16-byte PMKID. See WPA3-SAE operation.
10.13.6 Multi-part PAKE operations¶
psa_pake_operation_t (typedef)¶
The type of the state object for PAKE operations.
Added in version 1.1.
typedef /* implementation-defined type */ psa_pake_operation_t;
Before calling any function on a PAKE operation object, the application must initialize it by any of the following means:
Set the object to all-bits-zero, for example:
psa_pake_operation_t operation; memset(&operation, 0, sizeof(operation));
Initialize the object to logical zero values by declaring the object as static or global without an explicit initializer, for example:
static psa_pake_operation_t operation;
Initialize the object to the initializer
PSA_PAKE_OPERATION_INIT, for example:psa_pake_operation_t operation = PSA_PAKE_OPERATION_INIT;
Assign the result of the function
psa_pake_operation_init()to the object, for example:psa_pake_operation_t operation; operation = psa_pake_operation_init();
This is an implementation-defined type. Applications that make assumptions about the content of this object will result in implementation-specific behavior, and are non-portable.
PSA_PAKE_OPERATION_INIT (macro)¶
This macro returns a suitable initializer for a PAKE operation object of type psa_pake_operation_t.
Added in version 1.1.
#define PSA_PAKE_OPERATION_INIT /* implementation-defined value */
psa_pake_operation_init (function)¶
Return an initial value for a PAKE operation object.
Added in version 1.1.
psa_pake_operation_t psa_pake_operation_init(void);
Returns: psa_pake_operation_t
psa_pake_setup (function)¶
Setup a password-authenticated key exchange.
Added in version 1.1.
Changed in version 1.2: Added key to the operation setup.
psa_status_t psa_pake_setup(psa_pake_operation_t * operation, psa_key_id_t password_key, const psa_pake_cipher_suite_t * cipher_suite);
Parameters
operationThe operation object to set up. It must have been initialized as per the documentation for
psa_pake_operation_tand not yet in use.password_keyIdentifier of the key holding the password or a value derived from the password. It must remain valid until the operation terminates.
The valid key types depend on the PAKE algorithm, and participant role. Refer to the documentation of individual PAKE algorithms for more information.
The key must permit the usage
PSA_KEY_USAGE_DERIVE.cipher_suiteThe cipher suite to use. A PAKE cipher suite fully characterizes a PAKE algorithm, including the PAKE algorithm.
The cipher suite must be compatible with the key type of
password_key.
Returns: psa_status_t
PSA_SUCCESSSuccess. The operation is now active.
PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be inactive.
The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_INVALID_HANDLEpassword_keyis not a valid key identifier.PSA_ERROR_NOT_PERMITTEDpassword_keydoes not have thePSA_KEY_USAGE_DERIVEflag, or it does not permit the algorithm incipher_suite.PSA_ERROR_INVALID_ARGUMENTThe following conditions can result in this error:
The algorithm in
cipher_suiteis not a PAKE algorithm, or encodes an invalid hash algorithm.The PAKE primitive in
cipher_suiteis not compatible with the PAKE algorithm.The key confirmation value in
cipher_suiteis not compatible with the PAKE algorithm and primitive.The key type or key size of
password_keyis not compatible withcipher_suite.
PSA_ERROR_NOT_SUPPORTEDThe following conditions can result in this error:
The algorithm in
cipher_suiteis not a supported PAKE algorithm, or encodes an unsupported hash algorithm.The PAKE primitive in
cipher_suiteis not supported or not compatible with the PAKE algorithm.The key confirmation value in
cipher_suiteis not supported, or not compatible, with the PAKE algorithm and primitive.The key type or key size of
password_keyis not supported withcipher suite.
PSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTEDPSA_ERROR_STORAGE_FAILUREPSA_ERROR_DATA_CORRUPTPSA_ERROR_DATA_INVALID
Description
The sequence of operations to set up a password-authenticated key exchange operation is as follows:
Allocate a PAKE operation object which will be passed to all the functions listed here.
Initialize the operation object with one of the methods described in the documentation for
psa_pake_operation_t. For example, usingPSA_PAKE_OPERATION_INIT.Call
psa_pake_setup()to specify the cipher suite and provide the password or password-derived key.Call
psa_pake_set_xxx()functions on the operation to complete the setup. The exact sequence ofpsa_pake_set_xxx()functions that needs to be called depends on the algorithm in use.
A typical sequence of calls to perform a password-authenticated key exchange:
Call
psa_pake_output(operation,PSA_PAKE_STEP_KEY_SHARE, ...)to get the key share that needs to be sent to the peer.Call
psa_pake_input(operation,PSA_PAKE_STEP_KEY_SHARE, ...)to provide the key share that was received from the peer.Depending on the algorithm additional calls to
psa_pake_output()andpsa_pake_input()might be necessary.Call
psa_pake_get_shared_key()to access the shared secret.
Refer to the documentation of individual PAKE algorithms for details on the required set up and operation for each algorithm, and for constraints on the format and content of valid passwords.
After a successful call to psa_pake_setup(), the operation is active, and the application must eventually terminate the operation.
The following events terminate an operation:
A successful call to
psa_pake_get_shared_key().A call to
psa_pake_abort().
If psa_pake_setup() returns an error, the operation object is unchanged.
If a subsequent function call with an active operation returns an error, the operation enters an error state.
To abandon an active operation, or reset an operation in an error state, call psa_pake_abort().
psa_pake_set_role (function)¶
Set the application role for a password-authenticated key exchange.
Added in version 1.1.
psa_status_t psa_pake_set_role(psa_pake_operation_t * operation, psa_pake_role_t role);
Parameters
operationActive PAKE operation.
roleA value of type
psa_pake_role_tindicating the application role in the PAKE algorithm. See PAKE roles.
Returns: psa_status_t
PSA_SUCCESSSuccess.
PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be active, and
psa_pake_set_role(),psa_pake_input(), andpsa_pake_output()must not have been called yet.The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_INVALID_ARGUMENTThe following conditions can result in this error:
roleis not a valid PAKE role in the operation’s algorithm.roleis not compatible with the operation’s key type.
PSA_ERROR_NOT_SUPPORTEDThe following conditions can result in this error:
roleis not a valid PAKE role, or is not supported for the operation’s algorithm.roleis not supported with the operation’s key type.
PSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTED
Description
Not all PAKE algorithms need to differentiate the communicating participants. For PAKE algorithms that do not require a role to be specified, the application can do either of the following:
Not call
psa_pake_set_role()on the PAKE operation.Call
psa_pake_set_role()with thePSA_PAKE_ROLE_NONErole.
Refer to the documentation of individual PAKE algorithms for more information.
psa_pake_set_user (function)¶
Set the user ID for a password-authenticated key exchange.
Added in version 1.1.
psa_status_t psa_pake_set_user(psa_pake_operation_t * operation, const uint8_t * user_id, size_t user_id_len);
Parameters
operationActive PAKE operation.
user_idThe user ID to authenticate with.
user_id_lenSize of the
user_idbuffer in bytes.
Returns: psa_status_t
PSA_SUCCESSSuccess.
PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be active, and
psa_pake_set_user(),psa_pake_input(), andpsa_pake_output()must not have been called yet.The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_INVALID_ARGUMENTuser_idis not valid for the operation’s algorithm and cipher suite.PSA_ERROR_NOT_SUPPORTEDThe value of
user_idis not supported by the implementation.PSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTED
Description
Call this function to set the user ID.
For PAKE algorithms that associate a user identifier with both participants in the session, also call psa_pake_set_peer() with the peer ID.
For PAKE algorithms that associate a single user identifier with the session, call psa_pake_set_user() only.
Refer to the documentation of individual PAKE algorithms for more information.
psa_pake_set_peer (function)¶
Set the peer ID for a password-authenticated key exchange.
Added in version 1.1.
psa_status_t psa_pake_set_peer(psa_pake_operation_t * operation, const uint8_t * peer_id, size_t peer_id_len);
Parameters
operationActive PAKE operation.
peer_idThe peer’s ID to authenticate.
peer_id_lenSize of the
peer_idbuffer in bytes.
Returns: psa_status_t
PSA_SUCCESSSuccess.
PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be active, and
psa_pake_set_peer(),psa_pake_input(), andpsa_pake_output()must not have been called yet.Calling
psa_pake_set_peer()is invalid with the operation’s algorithm.The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_INVALID_ARGUMENTpeer_idis not valid for the operation’s algorithm and cipher suite.PSA_ERROR_NOT_SUPPORTEDThe value of
peer_idis not supported by the implementation.PSA_ERROR_NOT_SUPPORTEDPSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTED
Description
Call this function in addition to psa_pake_set_user() for PAKE algorithms that associate a user identifier with both participants in the session.
For PAKE algorithms that associate a single user identifier with the session, call psa_pake_set_user() only.
Refer to the documentation of individual PAKE algorithms for more information.
psa_pake_set_context (function)¶
Set the context data for a password-authenticated key exchange.
Added in version 1.2.
psa_status_t psa_pake_set_context(psa_pake_operation_t * operation, const uint8_t * context, size_t context_len);
Parameters
operationActive PAKE operation.
contextThe peer’s ID to authenticate.
context_lenSize of the
contextbuffer in bytes.
Returns: psa_status_t
PSA_SUCCESSSuccess.
PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be active, and
psa_pake_set_context(),psa_pake_input(), andpsa_pake_output()must not have been called yet.Calling
psa_pake_set_context()is invalid with the operation’s algorithm.The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_INVALID_ARGUMENTcontextis not valid for the operation’s algorithm and cipher suite.PSA_ERROR_NOT_SUPPORTEDThe value of
contextis not supported by the implementation.PSA_ERROR_NOT_SUPPORTEDPSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTED
Description
Call this function for PAKE algorithms that accept additional context data as part of the protocol setup.
Refer to the documentation of individual PAKE algorithms for more information.
psa_pake_output (function)¶
Get output for a step of a password-authenticated key exchange.
Added in version 1.1.
psa_status_t psa_pake_output(psa_pake_operation_t * operation, psa_pake_step_t step, uint8_t * output, size_t output_size, size_t * output_length);
Parameters
operationActive PAKE operation.
stepThe step of the algorithm for which the output is requested.
outputBuffer where the output is to be written. The format of the output depends on the
step, see PAKE step types.output_sizeSize of the
outputbuffer in bytes. This must be appropriate for the cipher suite and output step:A sufficient output size is
PSA_PAKE_OUTPUT_SIZE(alg,primitive,step)wherealgandprimitiveare the PAKE algorithm and primitive in the operation’s cipher suite, andstepis the output step.PSA_PAKE_OUTPUT_MAX_SIZEevaluates to the maximum output size of any supported PAKE algorithm, primitive and step.
output_lengthOn success, the number of bytes of the returned output.
Returns: psa_status_t
PSA_SUCCESSSuccess. The first
(*output_length)bytes ofoutputcontain the output.PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be active and fully set up, and this call must conform to the algorithm’s requirements for ordering of input and output steps.
The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_BUFFER_TOO_SMALLThe size of the
outputbuffer is too small.PSA_PAKE_OUTPUT_SIZE()orPSA_PAKE_OUTPUT_MAX_SIZEcan be used to determine a sufficient buffer size.PSA_ERROR_INVALID_ARGUMENTstepis not compatible with the operation’s algorithm.PSA_ERROR_NOT_SUPPORTEDstepis not supported with the operation’s algorithm.PSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTEDPSA_ERROR_STORAGE_FAILUREPSA_ERROR_DATA_CORRUPTPSA_ERROR_DATA_INVALID
Description
Depending on the algorithm being executed, you might need to call this function several times or you might not need to call this at all.
The exact sequence of calls to perform a password-authenticated key exchange depends on the algorithm in use. Refer to the documentation of individual PAKE algorithms for more information.
If this function returns an error status, the operation enters an error state and must be aborted by calling psa_pake_abort().
psa_pake_input (function)¶
Provide input for a step of a password-authenticated key exchange.
Added in version 1.1.
psa_status_t psa_pake_input(psa_pake_operation_t * operation, psa_pake_step_t step, const uint8_t * input, size_t input_length);
Parameters
operationActive PAKE operation.
stepThe step for which the input is provided.
inputBuffer containing the input. The format of the input depends on the
step, see PAKE step types.input_lengthSize of the
inputbuffer in bytes.
Returns: psa_status_t
PSA_SUCCESSSuccess.
PSA_ERROR_BAD_STATEThe following conditions can result in this error:
The operation state is not valid: it must be active and fully set up, and this call must conform to the algorithm’s requirements for ordering of input and output steps.
The library requires initializing by a call to
psa_crypto_init().
PSA_ERROR_INVALID_SIGNATUREThe verification fails for a
PSA_PAKE_STEP_ZK_PROOForPSA_PAKE_STEP_CONFIRMinput step.PSA_ERROR_INVALID_ARGUMENTThe following conditions can result in this error:
stepis not compatible with the operation’s algorithm.The input is not valid for the operation’s algorithm, cipher suite or
step.
PSA_ERROR_NOT_SUPPORTEDThe following conditions can result in this error:
stepis not supported with the operation’s algorithm.The input is not supported for the operation’s algorithm, cipher suite or
step.
PSA_ERROR_INSUFFICIENT_MEMORYPSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTEDPSA_ERROR_STORAGE_FAILUREPSA_ERROR_DATA_CORRUPTPSA_ERROR_DATA_INVALID
Description
Depending on the algorithm being executed, you might need to call this function several times or you might not need to call this at all.
The exact sequence of calls to perform a password-authenticated key exchange depends on the algorithm in use. Refer to the documentation of individual PAKE algorithms for more information.
PSA_PAKE_INPUT_SIZE() or PSA_PAKE_INPUT_MAX_SIZE can be used to allocate buffers of sufficient size to transfer inputs that are received from the peer into the operation.
If this function returns an error status, the operation enters an error state and must be aborted by calling psa_pake_abort().
psa_pake_abort (function)¶
Abort a PAKE operation.
Added in version 1.1.
psa_status_t psa_pake_abort(psa_pake_operation_t * operation);
Parameters
operationInitialized PAKE operation.
Returns: psa_status_t
PSA_SUCCESSSuccess. The operation object can now be discarded or reused.
PSA_ERROR_BAD_STATEThe library requires initializing by a call to
psa_crypto_init().PSA_ERROR_COMMUNICATION_FAILUREPSA_ERROR_CORRUPTION_DETECTED
Description
Aborting an operation frees all associated resources except for the operation object itself.
Once aborted, the operation object can be reused for another operation by calling psa_pake_setup() again.
This function can be called any time after the operation object has been initialized as described in psa_pake_operation_t.
In particular, calling psa_pake_abort() after the operation has been terminated by a call to psa_pake_abort() or psa_pake_get_shared_key() is safe and has no effect.
10.13.7 PAKE support macros¶
PSA_PAKE_OUTPUT_SIZE (macro)¶
Sufficient output buffer size for psa_pake_output(), in bytes.
Added in version 1.1.
#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ /* implementation-defined value */
Parameters
algA PAKE algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_PAKE(alg)is true.primitiveA primitive of type
psa_pake_primitive_tthat is compatible with algorithmalg.output_stepA value of type
psa_pake_step_tthat is valid for the algorithmalg.
Returns
A sufficient output buffer size for the specified PAKE algorithm, primitive, and output step.
An implementation can return either 0 or a correct size for a PAKE algorithm, primitive, and output step that it recognizes, but does not support.
If the parameters are not valid, the return value is unspecified.
Description
If the size of the output buffer is at least this large, it is guaranteed that psa_pake_output() will not fail due to an insufficient buffer size.
The actual size of the output might be smaller in any given call.
See also PSA_PAKE_OUTPUT_MAX_SIZE
PSA_PAKE_OUTPUT_MAX_SIZE (macro)¶
Sufficient output buffer size for psa_pake_output() for any of the supported PAKE algorithms, primitives and output steps.
Added in version 1.1.
#define PSA_PAKE_OUTPUT_MAX_SIZE /* implementation-defined value */
If the size of the output buffer is at least this large, it is guaranteed that psa_pake_output() will not fail due to an insufficient buffer size.
See also PSA_PAKE_OUTPUT_SIZE().
PSA_PAKE_INPUT_SIZE (macro)¶
Sufficient buffer size for inputs to psa_pake_input().
Added in version 1.1.
#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ /* implementation-defined value */
Parameters
algA PAKE algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_PAKE(alg)is true.primitiveA primitive of type
psa_pake_primitive_tthat is compatible with algorithmalg.input_stepA value of type
psa_pake_step_tthat is valid for the algorithmalg.
Returns
A sufficient buffer size for the specified PAKE algorithm, primitive, and input step.
An implementation can return either 0 or a correct size for a PAKE algorithm, primitive, and output step that it recognizes, but does not support.
If the parameters are not valid, the return value is unspecified.
Description
The value returned by this macro is guaranteed to be large enough for any valid input to psa_pake_input() in an operation with the specified parameters.
This macro can be useful when transferring inputs from the peer into the PAKE operation.
See also PSA_PAKE_INPUT_MAX_SIZE
PSA_PAKE_INPUT_MAX_SIZE (macro)¶
Sufficient buffer size for inputs to psa_pake_input() for any of the supported PAKE algorithms, primitives and input steps.
Added in version 1.1.
#define PSA_PAKE_INPUT_MAX_SIZE /* implementation-defined value */
This macro can be useful when transferring inputs from the peer into the PAKE operation.
See also PSA_PAKE_INPUT_SIZE().
10.13.8 The J-PAKE protocol¶
J-PAKE is the password-authenticated key exchange by juggling protocol, defined by J-PAKE: Password-Authenticated Key Exchange by Juggling [RFC8236]. This protocol uses the Schnorr Non-Interactive Zero-Knowledge Proof (NIZKP), as defined by Schnorr Non-interactive Zero-Knowledge Proof [RFC8235].
J-PAKE is a balanced PAKE, without key confirmation.
J-PAKE cipher suites¶
When setting up a PAKE cipher suite to use the J-PAKE protocol:
Use the
PSA_ALG_JPAKE()algorithm, parameterized by the required hash algorithm.Use a PAKE primitive for the required elliptic curve, or finite field group.
J-PAKE does not confirm the shared secret key that results from the key exchange.
For example, the following code creates a cipher suite to select J-PAKE using P-256 with the SHA-256 hash function:
psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_JPAKE(PSA_ALG_SHA_256)); psa_pake_cs_set_primitive(&cipher_suite, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256)); psa_pake_cs_set_key_confirmation(&cipher_suite, PSA_PAKE_UNCONFIRMED_KEY);
More information on selecting a specific elliptic curve or finite field Diffie-Hellman group is provided with the PSA_PAKE_PRIMITIVE_TYPE_ECC and PSA_PAKE_PRIMITIVE_TYPE_DH constants.
J-PAKE password processing¶
The PAKE operation for J-PAKE expects a key of type type PSA_KEY_TYPE_PASSWORD or PSA_KEY_TYPE_PASSWORD_HASH`.
The same key value must be provided to the PAKE operation in both participants.
The key can be the password text itself, in an agreed character encoding, or some value derived from the password, as required by a higher level protocol. For low-entropy passwords, it is recommended that a key-stretching derivation algorithm, such as PBKDF2, is used, and the resulting password hash is used as the key input to the PAKE operation.
J-PAKE operation¶
The J-PAKE operation follows the protocol shown in Figure 3.
Figure 3 The J-PAKE protocol¶
Setup¶
J-PAKE does not assign roles to the participants, so it is not necessary to call psa_pake_set_role().
J-PAKE requires both an application and a peer identity.
If the peer identity provided to psa_pake_set_peer() does not match the data received from the peer, then the call to psa_pake_input() for the PSA_PAKE_STEP_ZK_PROOF step will fail with PSA_ERROR_INVALID_SIGNATURE.
J-PAKE does not use a context.
A call to psa_pake_set_context() for a J-PAKE operation will fail with PSA_ERROR_BAD_STATE.
The following steps demonstrate the application code for ‘User’ in Figure 3. The code flow for the ‘Peer’ is the same as for ‘User’, as J-PAKE is a balanced PAKE.
To prepare a J-PAKE operation, initialize and set up a
psa_pake_operation_tobject by calling the following functions:psa_pake_operation_t jpake = PSA_PAKE_OPERATION_INIT; psa_pake_setup(&jpake, pake_key, &cipher_suite); psa_pake_set_user(&jpake, ...); psa_pake_set_peer(&jpake, ...);
See J-PAKE cipher suites and J-PAKE password processing for details on the requirements for the cipher suite and key.
The key material is used as an array of bytes, which is converted to an integer as described in SEC 1: Elliptic Curve Cryptography [SEC1] §2.3.8, before reducing it modulo \(q\). Here, \(q\) is the order of the group defined by the cipher-suite primitive.
psa_pake_setup()will return an error if the result of the conversion and reduction is0.
Key exchange¶
After setup, the key exchange flow for J-PAKE is as follows:
Round one.
The application can either extract the round one output values first, and then provide the round one inputs that are received from the Peer; or provide the peer inputs first, and then extract the outputs.
To get the first round data that needs to be sent to the peer, make the following calls to
psa_pake_output(), in the order shown:// Get g1 psa_pake_output(&jpake, PSA_PAKE_STEP_KEY_SHARE, ...); // Get V1, the ZKP public key for x1 psa_pake_output(&jpake, PSA_PAKE_STEP_ZK_PUBLIC, ...); // Get r1, the ZKP proof for x1 psa_pake_output(&jpake, PSA_PAKE_STEP_ZK_PROOF, ...); // Get g2 psa_pake_output(&jpake, PSA_PAKE_STEP_KEY_SHARE, ...); // Get V2, the ZKP public key for x2 psa_pake_output(&jpake, PSA_PAKE_STEP_ZK_PUBLIC, ...); // Get r2, the ZKP proof for x2 psa_pake_output(&jpake, PSA_PAKE_STEP_ZK_PROOF, ...);
To provide the first round data received from the peer to the operation, make the following calls to
psa_pake_input(), in the order shown:// Set g3 psa_pake_input(&jpake, PSA_PAKE_STEP_KEY_SHARE, ...); // Set V3, the ZKP public key for x3 psa_pake_input(&jpake, PSA_PAKE_STEP_ZK_PUBLIC, ...); // Set r3, the ZKP proof for x3 psa_pake_input(&jpake, PSA_PAKE_STEP_ZK_PROOF, ...); // Set g4 psa_pake_input(&jpake, PSA_PAKE_STEP_KEY_SHARE, ...); // Set V4, the ZKP public key for x4 psa_pake_input(&jpake, PSA_PAKE_STEP_ZK_PUBLIC, ...); // Set r4, the ZKP proof for x4 psa_pake_input(&jpake, PSA_PAKE_STEP_ZK_PROOF, ...);
Round two.
The application can either extract the round two output values first, and then provide the round two inputs that are received from the Peer; or provide the peer inputs first, and then extract the outputs.
To get the second round data that needs to be sent to the peer, make the following calls to
psa_pake_output(), in the order shown:// Get A psa_pake_output(&jpake, PSA_PAKE_STEP_KEY_SHARE, ...); // Get V5, the ZKP public key for x2*s psa_pake_output(&jpake, PSA_PAKE_STEP_ZK_PUBLIC, ...); // Get r5, the ZKP proof for x2*s psa_pake_output(&jpake, PSA_PAKE_STEP_ZK_PROOF, ...);
To provide the second round data received from the peer to the operation, make the following calls to
psa_pake_input(), in the order shown:// Set B psa_pake_input(&jpake, PSA_PAKE_STEP_KEY_SHARE, ...); // Set V6, the ZKP public key for x4*s psa_pake_input(&jpake, PSA_PAKE_STEP_ZK_PUBLIC, ...); // Set r6, the ZKP proof for x4*s psa_pake_input(&jpake, PSA_PAKE_STEP_ZK_PROOF, ...);
10.13.9 J-PAKE algorithms¶
PSA_ALG_JPAKE (macro)¶
Macro to build the Password-authenticated key exchange by juggling (J-PAKE) algorithm.
Added in version 1.1.
Changed in version 1.2: Parameterize J-PAKE algorithm by hash.
#define PSA_ALG_JPAKE(hash_alg) /* specification-defined value */
Parameters
hash_algA hash algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_HASH(hash_alg)is true.
Returns
A J-PAKE algorithm, parameterized by a specific hash.
Unspecified if hash_alg is not a supported hash algorithm.
Description
This is J-PAKE as defined by [RFC8236], instantiated with the following parameters:
The primitive group can be either an elliptic curve or defined over a finite field.
The Schnorr NIZKP, using the same group as the J-PAKE algorithm.
The cryptographic hash function,
hash_alg.
J-PAKE does not confirm the shared secret key that results from the key exchange.
The shared secret that is produced by J-PAKE is not suitable for use as an encryption key. It must be used as an input to a key-derivation operation to produce additional cryptographic keys.
See The J-PAKE protocol for the J-PAKE protocol flow and how to implement it with the Crypto API.
Compatible key types
PSA_ALG_IS_JPAKE (macro)¶
Whether the specified algorithm is a J-PAKE algorithm.
Added in version 1.2.
#define PSA_ALG_IS_JPAKE(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a J-PAKE algorithm, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
J-PAKE algorithms are constructed using PSA_ALG_JPAKE(hash_alg).
10.13.10 The SPAKE2+ protocol¶
SPAKE2+ is the augmented password-authenticated key exchange protocol, defined by SPAKE2+, an Augmented Password-Authenticated Key Exchange (PAKE) Protocol [RFC9383]. SPAKE2+ includes confirmation of the shared secret key that results from the key exchange.
SPAKE2+ is required by Matter Specification, Version 1.2 [MATTER], as MATTER_PAKE. [MATTER] uses an earlier draft of the SPAKE2+ protocol, SPAKE2+, an Augmented PAKE (Draft 02) [SPAKE2P-2].
Although the operation of the PAKE is similar for both of these variants, they have different key schedules for the derivation of the shared secret.
SPAKE2+ cipher suites¶
SPAKE2+ is instantiated with the following parameters:
An elliptic curve group.
A cryptographic hash function.
A key-derivation function.
A keyed MAC function.
Valid combinations of these parameters are defined in the table of cipher suites in [RFC9383] §4.
When setting up a PAKE cipher suite to use the SPAKE2+ protocol defined in [RFC9383]:
For cipher-suites that use HMAC for key confirmation, use the
PSA_ALG_SPAKE2P_HMAC()algorithm, parameterized by the required hash algorithm.For cipher-suites that use CMAC-AES-128 for key confirmation, use the
PSA_ALG_SPAKE2P_CMAC()algorithm, parameterized by the required hash algorithm.Use a PAKE primitive for the required elliptic curve.
For example, the following code creates a cipher suite to select SPAKE2+ using edwards25519 with the SHA-256 hash function:
psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_SPAKE2P_HMAC(PSA_ALG_SHA_256)); psa_pake_cs_set_primitive(&cipher_suite, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_TWISTED_EDWARDS, 255));
When setting up a PAKE cipher suite to use the SPAKE2+ protocol used by [MATTER]:
Use the
PSA_ALG_SPAKE2P_MATTERalgorithm.Use the
PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC,PSA_ECC_FAMILY_SECP_R1, 256)PAKE primitive.
The following code creates a cipher suite to select the [MATTER] variant of SPAKE2+:
psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_SPAKE2P_MATTER); psa_pake_cs_set_primitive(&cipher_suite, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256));
SPAKE2+ registration¶
The SPAKE2+ protocol has distinct roles for the two participants:
The Prover takes the role of client. It uses the protocol to prove that it knows the secret password, and produce a shared secret.
The Verifier takes the role of server. It uses the protocol to verify the client’s proof, and produce a shared secret.
The registration phase of SPAKE2+ provides the initial password processing, described in [RFC9383] §3.2. The result of registration is two pairs of values — \((w0, w1)\) and \((w0, L)\) — that need to be provided during the authentication phase to the Prover and Verifier, respectively. The design of SPAKE2+ ensures that knowledge of \((w0, L)\) does not enable an attacker to determine the password, or to compute \(w1\).
In the Crypto API, the registration output values are managed as an asymmetric key pair:
The Prover values, \((w0, w1)\), are stored in a key of type
PSA_KEY_TYPE_SPAKE2P_KEY_PAIR().The Verifier values, \((w0, L)\), are stored in a key of type
PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(), or derived from the matchingPSA_KEY_TYPE_SPAKE2P_KEY_PAIR().
The SPAKE2+ key types are parameterized by the same elliptic curve as the SPAKE2+ cipher suite.
The key pair is derived from the initial SPAKE2+ password prior to starting the PAKE operation.
It is recommended to use a key-stretching derivation algorithm, for example PBKDF2.
This process can take place immediately before the PAKE operation, or derived at some earlier point and stored by the participant.
Alternatively, the Verifier can be provisioned with the PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY() for the protocol, by the Prover, or some other agent.
Figure 4 illustrates some example SPAKE2+ key-derivation flows.
The resulting SPAKE2+ key pair must be protected at least as well as the password. The public key, exported from the key pair, does not need to be kept confidential. It is recommended that the Verifier stores only the public key, because disclosure of the public key does not enable an attacker to impersonate the Prover.
Figure 4 Examples of SPAKE2+ key-derivation procedures¶
The following steps demonstrate the derivation of a SPAKE2+ key pair using PBKDF2-HMAC-SHA256, for use with a SPAKE2+ cipher suite, cipher_suite. See SPAKE2+ cipher suites for an example of how to construct the cipher suite object.
Allocate and initialize a key-derivation object:
psa_key_derivation_operation_t pbkdf = PSA_KEY_DERIVATION_OPERATION_INIT;
Setup the key derivation from the SPAKE2+ password,
password_key, and parameterspbkdf2_params:psa_key_derivation_setup(&pbkdf, PSA_ALG_PBKDF2_HMAC(PSA_ALG_SHA_256)); psa_key_derivation_input_key(&pbkdf, PSA_KEY_DERIVATION_INPUT_PASSWORD, password_key); psa_key_derivation_input_integer(&pbkdf, PSA_KEY_DERIVATION_INPUT_COST, pbkdf2_params.cost); psa_key_derivation_input_bytes(&pbkdf, PSA_KEY_DERIVATION_INPUT_SALT, &pbkdf2_params.salt, pbkdf2_params.salt_len);
Allocate and initialize a key attributes object:
psa_key_attributes_t att = PSA_KEY_ATTRIBUTES_INIT;
Set the key type, size, and policy from the
cipher_suiteobject:const psa_pake_primitive_t primitive = psa_pake_cs_get_primitive(&cipher_suite); psa_set_key_type(&att, PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(PSA_PAKE_PRIMITIVE_GET_FAMILY(primitive))); psa_set_key_bits(&att, PSA_PAKE_PRIMITIVE_GET_BITS(primitive)); psa_set_key_usage_flags(&att, PSA_KEY_USAGE_DERIVE); psa_set_key_algorithm(&att, psa_pake_cs_get_algorithm(&cipher_suite));
Derive the key:
psa_key_id_t spake2p_key; psa_key_derivation_output_key(&att, &pbkdf, &spake2p_key); psa_key_derivation_abort(&pbkdf);
See SPAKE2+ keys for details of the key types, key-pair derivation, and public-key format.
SPAKE2+ operation¶
The SPAKE2+ operation follows the protocol shown in Figure 5.
Figure 5 The SPAKE2+ authentication and key confirmation protocol¶
Setup¶
In SPAKE2+, the Prover uses the PSA_PAKE_ROLE_CLIENT role, and the Verifier uses the PSA_PAKE_ROLE_SERVER role.
The key passed to the Prover must be a SPAKE2+ key pair, which is derived as recommended in SPAKE2+ registration.
The key passed to the Verifier can either be a SPAKE2+ key pair, or a SPAKE2+ public key.
A SPAKE2+ public key is imported from data that is output by calling psa_export_public_key() on a SPAKE2+ key pair.
Both participants in SPAKE2+ have an optional identity. If no identity value is provided, then a zero-length string is used for that identity in the protocol. If the participants do not supply the same identity values to the protocol, the computed secrets will be different, and key confirmation will fail.
Participants in SPAKE2+ can optionally provide a context:
If
psa_pake_set_context()is called, then the context and its encoded length are included in the SPAKE2+ transcript computation. This includes the case of a zero-length context.If
psa_pake_set_context()is not called, then the context and its encoded length are omitted entirely from the SPAKE2+ transcript computation. See [RFC9383] §3.3.
If the participants do not supply the same context value to the protocol, the computed secrets will be different, and key confirmation will fail.
The following steps demonstrate the application code for both Prover and Verifier in Figure 5.
- Prover
To prepare a SPAKE2+ operation for the Prover, initialize and set up a
psa_pake_operation_tobject by calling the following functions:psa_pake_operation_t spake2p_p = PSA_PAKE_OPERATION_INIT; psa_pake_setup(&spake2p_p, pake_key_p, &cipher_suite); psa_pake_set_role(&spake2p_p, PSA_PAKE_ROLE_CLIENT);
The key
pake_key_pis a SPAKE2+ key pair,PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(). See SPAKE2+ cipher suites for details on constructing a suitable cipher suite.- Prover
Provide any additional, optional, parameters:
psa_pake_set_user(&spake2p_p, ...); // Prover identity psa_pake_set_peer(&spake2p_p, ...); // Verifier identity psa_pake_set_context(&spake2p_p, ...); // Optional context
- Verifier
To prepare a SPAKE2+ operation for the Verifier, initialize and set up a
psa_pake_operation_tobject by calling the following functions:psa_pake_operation_t spake2p_v = PSA_PAKE_OPERATION_INIT; psa_pake_setup(&spake2p_v, pake_key_v, &cipher_suite); psa_pake_set_role(&spake2p_v, PSA_PAKE_ROLE_SERVER);
The key
pake_key_vis a SPAKE2+ key pair,PSA_KEY_TYPE_SPAKE2P_KEY_PAIR(), or public key,PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY(). See SPAKE2+ cipher suites for details on constructing a suitable cipher suite.- Verifier
Provide any additional, optional, parameters:
psa_pake_set_user(&spake2p_v, ...); // Verifier identity psa_pake_set_peer(&spake2p_v, ...); // Prover identity psa_pake_set_context(&spake2p_v, ...); // Optional context
Key exchange and confirmation¶
After setup, the key exchange and confirmation flow for SPAKE2+ is as follows.
Note
The sequence of calls for the Prover, and the sequence for the Verifier, must be in exactly this order.
- Prover
To get the key share to send to the Verifier, call:
// Get shareP psa_pake_output(&spake2p_p, PSA_PAKE_STEP_KEY_SHARE, ...);
- Verifier
To provide and validate the key share received from the Prover, call:
// Set shareP psa_pake_input(&spake2p_v, PSA_PAKE_STEP_KEY_SHARE, ...);
- Verifier
To get the Verifier key share and confirmation value to send to the Prover, call:
// Get shareV psa_pake_output(&spake2p_v, PSA_PAKE_STEP_KEY_SHARE, ...); // Get confirmV psa_pake_output(&spake2p_v, PSA_PAKE_STEP_CONFIRM, ...);
- Prover
To provide and validate the key share and verify the confirmation value received from the Verifier, call:
// Set shareV psa_pake_input(&spake2p_p, PSA_PAKE_STEP_KEY_SHARE, ...); // Set confirmV psa_pake_input(&spake2p_p, PSA_PAKE_STEP_KEY_CONFIRM, ...);
- Prover
To get the Prover key confirmation value to send to the Verifier, call:
// Get confirmP psa_pake_output(&spake2p_p, PSA_PAKE_STEP_CONFIRM, ...);
- Verifier
To verify the confirmation value received from the Prover, call:
// Set confirmP psa_pake_input(&spake2p_v, PSA_PAKE_STEP_CONFIRM, ...);
Extract shared secret¶
- Prover
To use the shared secret, extract it as a key-derivation key. For example, to extract a derivation key for HKDF-SHA-256:
// Set up the key attributes psa_key_attributes_t att = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_type(&att, PSA_KEY_TYPE_DERIVE); psa_set_key_usage_flags(&att, PSA_KEY_USAGE_DERIVE); psa_set_key_algorithm(&att, PSA_ALG_HKDF(PSA_ALG_SHA_256)); // Get K_shared psa_key_id_t shared_key; psa_pake_get_shared_key(&spake2p_p, &att, &shared_key);
- Verifier
To use the shared secret, extract it as a key-derivation key. The same key attributes can be used as the Prover:
// Get K_shared psa_key_id_t shared_key; psa_pake_get_shared_key(&spake2p_v, &att, &shared_key);
The shared secret that is produced by SPAKE2+ is pseudorandom. Although it can be used directly as an encryption key, it is recommended to use the shared secret as an input to a key-derivation operation to produce additional cryptographic keys.
For more information about the format of the values which are passed for each step, see PAKE step types.
If the validation of a key share fails, then the corresponding call to psa_pake_input() for the PSA_PAKE_STEP_KEY_SHARE step will return PSA_ERROR_INVALID_ARGUMENT.
If the verification of a key confirmation value fails, then the corresponding call to psa_pake_input() for the PSA_PAKE_STEP_CONFIRM step will return PSA_ERROR_INVALID_SIGNATURE.
10.13.11 SPAKE2+ algorithms¶
PSA_ALG_SPAKE2P_HMAC (macro)¶
Macro to build the SPAKE2+ algorithm, using HMAC-based key confirmation.
Added in version 1.2.
#define PSA_ALG_SPAKE2P_HMAC(hash_alg) /* specification-defined value */
Parameters
hash_algA hash algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_HASH(hash_alg)is true.
Returns
A SPAKE2+ algorithm, using HMAC for key confirmation, parameterized by a specific hash.
Unspecified if hash_alg is not a supported hash algorithm.
Description
This is SPAKE2+, as defined by SPAKE2+, an Augmented Password-Authenticated Key Exchange (PAKE) Protocol [RFC9383], for cipher suites that use HMAC for key confirmation. SPAKE2+ cipher suites are specified in [RFC9383] §4. See SPAKE2+ cipher suites.
The shared secret that is produced by SPAKE2+ is pseudorandom. Although it can be used directly as an encryption key, it is recommended to use the shared secret as an input to a key-derivation operation to produce additional cryptographic keys.
See The SPAKE2+ protocol for the SPAKE2+ protocol flow and how to implement it with the Crypto API.
Compatible key types
PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY (verification only)PSA_ALG_SPAKE2P_CMAC (macro)¶
Macro to build the SPAKE2+ algorithm, using CMAC-based key confirmation.
Added in version 1.2.
#define PSA_ALG_SPAKE2P_CMAC(hash_alg) /* specification-defined value */
Parameters
hash_algA hash algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_HASH(hash_alg)is true.
Returns
A SPAKE2+ algorithm, using CMAC for key confirmation, parameterized by a specific hash.
Unspecified if hash_alg is not a supported hash algorithm.
Description
This is SPAKE2+, as defined by SPAKE2+, an Augmented Password-Authenticated Key Exchange (PAKE) Protocol [RFC9383], for cipher suites that use CMAC-AES-128 for key confirmation.
SPAKE2+ cipher suites are specified in [RFC9383] §4.
The cipher suite’s hash algorithm is used as input to PSA_ALG_SPAKE2P_CMAC().
The shared secret that is produced by SPAKE2+ is pseudorandom. Although it can be used directly as an encryption key, it is recommended to use the shared secret as an input to a key-derivation operation to produce additional cryptographic keys.
See The SPAKE2+ protocol for the SPAKE2+ protocol flow and how to implement it with the Crypto API.
Compatible key types
PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY (verification only)PSA_ALG_SPAKE2P_MATTER (macro)¶
The SPAKE2+ algorithm, as used by the Matter v1 specification.
Added in version 1.2.
#define PSA_ALG_SPAKE2P_MATTER ((psa_algorithm_t)0x0A000609)
This is the PAKE algorithm specified as MATTER_PAKE in Matter Specification, Version 1.2 [MATTER]. This is based on draft-02 of the SPAKE2+ protocol, SPAKE2+, an Augmented PAKE (Draft 02) [SPAKE2P-2]. [MATTER] specifies a single SPAKE2+ cipher suite, P256-SHA256-HKDF-HMAC-SHA256.
The shared secret that is produced by this operation must be processed as directed by the [MATTER] specification.
This algorithm uses the same SPAKE2+ key types, key derivation, protocol flow, and the API usage described in The SPAKE2+ protocol. However, the following aspects are different:
The key schedule is different. This affects the computation of the shared secret and key confirmation values.
The protocol inputs and outputs have been renamed between draft-02 and the final RFC, as follows:
RFC 9383
Draft-02
shareP
pA
shareV
pB
confirmP
cA
confirmV
cB
K_shared
Ke
Compatible key types
PSA_KEY_TYPE_SPAKE2P_PUBLIC_KEY (verification only)PSA_ALG_IS_SPAKE2P (macro)¶
Whether the specified algorithm is a SPAKE2+ algorithm.
Added in version 1.2.
#define PSA_ALG_IS_SPAKE2P(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a SPAKE2+ algorithm, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
SPAKE2+ algorithms are constructed using PSA_ALG_SPAKE2P_HMAC(hash_alg), PSA_ALG_SPAKE2P_CMAC(hash_alg), or PSA_ALG_SPAKE2P_MATTER.
PSA_ALG_IS_SPAKE2P_HMAC (macro)¶
Whether the specified algorithm is a SPAKE2+ algorithm that uses a HMAC-based key confirmation.
Added in version 1.2.
#define PSA_ALG_IS_SPAKE2P_HMAC(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a SPAKE2+ algorithm that uses a HMAC-based key confirmation, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
SPAKE2+ algorithms, using HMAC-based key confirmation, are constructed using PSA_ALG_SPAKE2P_HMAC(hash_alg).
PSA_ALG_IS_SPAKE2P_CMAC (macro)¶
Whether the specified algorithm is a SPAKE2+ algorithm that uses a CMAC-based key confirmation.
Added in version 1.2.
#define PSA_ALG_IS_SPAKE2P_CMAC(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a SPAKE2+ algorithm that uses a CMAC-based key confirmation, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
SPAKE2+ algorithms, using CMAC-based key confirmation, are constructed using PSA_ALG_SPAKE2P_CMAC(hash_alg).
10.13.12 The WPA3-SAE protocol¶
WPA3-SAE is a balanced, password-authenticated key exchange protocol, defined by IEEE 802.11-2024: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications [IEEE-802.11]. It is used as the authentication and key exchange protocol for WLAN access points and mesh networks. WPA3-SAE includes confirmation of the shared secret key that results from the key exchange.
WPA3-SAE cipher suites¶
WPA3-SAE is instantiated with the following parameters:
An elliptic curve group or a finite field cyclic group.
A cryptographic hash function.
[IEEE-802.11] describes three variants of the WPA3-SAE algorithm. These differ in the method used to generate a password element (PWE) from the password, and in the size of the key confirmation key (SAE-KCK) and pairwise master key (PMK).
Table 16 summarizes the properties of the different algorithm variants.
Algorithm variant |
PWE method |
Hash algorithm |
SAE-KCK size |
PMK size |
|---|---|---|---|---|
Looping |
Looping |
SHA-256 |
256 |
256 |
Hash-to-element |
Hash-to-element |
SHA-256 SHA-384 SHA-512 |
256 384 512 |
256 256 256 |
Group-dependent-hash |
Hash-to-element |
SHA-256 SHA-384 SHA-512 |
256 384 512 |
256 384 512 |
When setting up a PAKE cipher suite to use the WPA3-SAE protocol:
For the looping variant, use the
PSA_ALG_WPA3_SAE_FIXED(PSA_ALG_SHA_256)algorithm.For the hash-to-element variant, use the
PSA_ALG_WPA3_SAE_FIXED(hash_alg)algorithm, wherehash_algis the required hash algorithm.For the group-dependent-hash variant, use the
PSA_ALG_WPA3_SAE_GDH(hash_alg)algorithm, wherehash_algis the required hash algorithm.Use a PAKE primitive for the required elliptic curve or finite field group.
Valid elliptic curves and finite field groups for WPA3-SAE are defined in [IEEE-802.11] §12.4.4.1. For the hash-to-element and group-dependent-hash variants, the required hash algorithm is determined from the size of the prime for the cyclic group. See Table 12-1 in [IEEE-802.11] §12.4.2.
If the hash algorithm in the cipher suite is not compatible with the WPA3-SAE algorithm and PAKE primitive, the call to psa_pake_setup() will fail with PSA_ERROR_INVALID_ARGUMENT.
For example, the following code creates a PAKE cipher suite for WPA3-SAE using hash-to-element over the secp256r1 elliptic curve (IANA group 19):
psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; psa_pake_cs_set_algorithm(&cipher_suite, PSA_ALG_WPA3_SAE_FIXED(PSA_ALG_SHA_256)); psa_pake_cs_set_primitive(&cipher_suite, PSA_PAKE_PRIMITIVE(PSA_PAKE_PRIMITIVE_TYPE_ECC, PSA_ECC_FAMILY_SECP_R1, 256));
WPA3-SAE password processing¶
WPA3-SAE defines the following two methods for deriving the password element PWE from the password:
Looping method |
Repeatedly sample candidate element values using a hash computed from the password, until a valid element is found. This derivation occurs as part of the authentication flow. |
Hash-to-element method |
Derive a password token element PT from the password, using the hash-to-curve procedure for elliptic curve groups, and a direct method for finite field groups. This derivation can be carried out when the network SSID and password is provisioned to the device, and PT is stored as part of the configuration. During authentication, PWE is derived from PT. |
The hash-to-element method is recommended, as it is less vulnerable to timing-based attacks, and reduces the authentication time.
Figure 6 illustrates the password processing required prior to the WPA3-SAE authentication flow.
Figure 6 WPA3-SAE password processing¶
For both methods, the password must be imported as a key of type PSA_KEY_TYPE_PASSWORD.
The password must be encoded as defined in [IEEE-802.11] §12.4.3.
Note
[IEEE-802.11] specifies that the same password is used for any configured WPA3-SAE cipher suites, and with any configured PWE-derivation methods.
The wildcard key policy PSA_ALG_WPA3_SAE_ANY permits a password key to be used for any valid derivation method, and with any valid WPA3-SAE cipher suite.
Looping method
Provide the password key directly to the WPA3-SAE PAKE operation in the call to psa_pake_setup().
Hash-to-element method
To use the hash-to-element method:
A WPA3-SAE password token is derived from the WPA3-SAE password, using a key-derivation operation with the
PSA_ALG_WPA3_SAE_H2E()algorithm. ThePSA_ALG_WPA3_SAE_H2E()algorithm is parameterized by the hash used in the required WPA3-SAE cipher suite.The password token is output from the key-derivation operation as a key of type
PSA_KEY_TYPE_WPA3_SAE_ECC()orPSA_KEY_TYPE_WPA3_SAE_DH(). The key type is parameterized by the elliptic curve or finite field Diffie-Hellman group used in the required WPA3-SAE cipher suite.The password token key must be protected at least as well as the password.
Pass the password token key to the WPA3-SAE PAKE operation in the call to
psa_pake_setup().
Note
The wildcard key policy PSA_ALG_WPA3_SAE_ANY permits a password token key to be used with both the PSA_ALG_WPA3_SAE_FIXED() and PSA_ALG_WPA3_SAE_GDH() PAKE algorithms.
The following steps demonstrate the derivation of a password token for use with the group-dependent-hash variant of WPA3-SAE. The selected cipher suite in the example is IANA Group 20: ECC using secp384r1, hash function SHA-384.
Allocate and initialize a key-derivation object:
psa_key_derivation_operation_t h2e_kdf = PSA_KEY_DERIVATION_OPERATION_INIT;
Setup the key derivation from the WPA3-SAE password,
password_key, with network SSIDssid:psa_key_derivation_setup(&h2e_kdf, PSA_ALG_WPA3_SAE_H2E(PSA_ALG_SHA_384)); psa_key_derivation_input_bytes(&h2e_kdf, PSA_KEY_DERIVATION_INPUT_SALT, ssid, ssid_len); psa_key_derivation_input_key(&h2e_kdf, PSA_KEY_DERIVATION_INPUT_PASSWORD, password_key);
Allocate and initialize a key attributes object:
psa_key_attributes_t pt_att = PSA_KEY_ATTRIBUTES_INIT;
Set the key type, size, and policy:
psa_set_key_type(&pt_att, PSA_KEY_TYPE_WPA3_SAE_ECC(PSA_ECC_FAMILY_SECP_R1)); psa_set_key_bits(&pt_att, 384); psa_set_key_usage_flags(&pt_att, PSA_KEY_USAGE_DERIVE); psa_set_key_algorithm(&pt_att, PSA_ALG_WPA3_SAE_GDH(PSA_ALG_SHA_384));
Derive the password token key:
psa_key_id_t pt_key; psa_key_derivation_output_key(&pt_att, &h2e_kdf, &pt_key); psa_key_derivation_abort(&h2e_kdf);
See WPA3-SAE password tokens for details of the key types and key derivation.
WPA3-SAE operation¶
The WPA3-SAE authentication operation follows the protocol shown in Figure 7.
Figure 7 The WPA3-SAE authentication and key confirmation protocol¶
The variable names commit-scalar, COMMIT-ELEMENT, peer-commit-scalar, and so on, are taken from the description of WPA3-SAE in [IEEE-802.11] §12.4.5.
Setup¶
The type of keys used to set up a PAKE multi-part operation for WPA3-SAE depends on the variant of WPA3-SAE that is required:
For the Looping variant, use a
PSA_KEY_TYPE_PASSWORDkey containing the secret password.For the Hash-to-element and Group-dependent-hash variants, use a
PSA_KEY_TYPE_WPA3_SAE_ECCorPSA_KEY_TYPE_WPA3_SAE_DHkey that is derived from the secret password, as described in WPA3-SAE password processing.
WPA-SAE does not assign roles to the participants, so it is not necessary to call psa_pake_set_role().
WPA-SAE requires the MAC addresses of both participants, which are provided to the PAKE multi-part operation as the user and peer identities.
WPA-SAE does not use a context.
A call to psa_pake_set_context() for a WPA-SAE operation will fail with PSA_ERROR_BAD_STATE.
The following steps demonstrate the application code for STA-A in Figure 7. The flow for STA-B is the same as for STA-A, as WPA3-SAE is a balanced PAKE.
To prepare a WPA3-SAE operation, initialize and set up a
psa_pake_operation_tobject by calling the following functions:psa_pake_operation_t wpa3_sae = PSA_PAKE_OPERATION_INIT; psa_pake_setup(&wpa3_sae, pt_key, &cipher_suite); psa_pake_set_user(&wpa3_sae, &sta_a_mac, mac_length); psa_pake_set_peer(&wpa3_sae, &sta_b_mac, mac_length);
See WPA3-SAE cipher suites and WPA3-SAE password processing for details on the requirements for the cipher suite and key.
Commit¶
Exchange commitment values to establish shared secret and confirmation keys.
The application can either extract the commitment values first, and then provide the commitment values that are received from the peer; or provide the peer inputs first, and then extract the outputs.
To get the commitment values to send to STA-B, call:
// Get commit-scalar || COMMIT-ELEMENT psa_pake_output(&wpa3_sae, PSA_PAKE_STEP_COMMIT, ...);
To provide and validate the commitment values from STA-B, call:
// Set peer-commit-scalar || PEER-COMMIT-ELEMENT psa_pake_input(&wpa3_sae, PSA_PAKE_STEP_COMMIT, ...);
Provide the salt used for shared secret derivation, as described in [IEEE-802.11] §12.4.5.4. For Hash-to-element and Group-dependent-hash variants, this is the list of rejected groups.
// Set salt psa_pake_input(&wpa3_sae, PSA_PAKE_STEP_SALT, ...);
Confirm¶
Exchange and verify confirmation values.
WPA3-SAE can make multiple attempts to confirm key establishment, to mitigate frame losses that can occur. To prevent replay of confirmation messages, each attempt generates a distinct confirmation value by including a confirmation counter value.
The application can either extract a confirmation value first, and then provide a confirmation value received from the peer; or provide the peer input first, and then extract the output.
To get a confirmation value to send to STA-B, the confirmation counter value \(send{-}confirm\) must be updated before extracting the combined send-confirm || confirm value, as follows:
// Set send-confirm counter psa_pake_input(&wpa3_sae, PSA_PAKE_STEP_SEND_CONFIRM, ...); // Get combined send-confirm || confirm value psa_pake_output(&wpa3_sae, PSA_PAKE_STEP_CONFIRM, ...);
To verify a confirmation value received from the peer, call:
// Set combined peer-send-confirm || peer-confirm value psa_pake_input(&wpa3_sae, PSA_PAKE_STEP_CONFIRM, ...);
Note
The application is permitted to request new confirmation values, or verify additional peer confirmation values, even after a peer confirmation value has been successfully verified.
Extract shared secret¶
Optionally, to extract the identity of the shared secret key, PMKID, call:
// Get PMKID psa_pake_output(&wpa3_sae, PSA_PAKE_STEP_KEY_ID, ...);
To use the shared secret, extract it as a key-derivation key. For example, to extract a derivation key for HKDF-SHA-256:
// Set up the key attributes psa_key_attributes_t att = PSA_KEY_ATTRIBUTES_INIT; psa_set_key_type(&att, PSA_KEY_TYPE_DERIVE); psa_set_key_usage_flags(&att, PSA_KEY_USAGE_DERIVE); psa_set_key_algorithm(&att, PSA_ALG_HKDF(PSA_ALG_SHA_256)); // Get K_shared psa_key_id_t shared_key; psa_pake_get_shared_key(&spake2p_p, &att, &shared_key);
The shared secret that is produced by WPA3-SAE is pseudorandom. Although it can be used directly as an encryption key, it is recommended to use the shared secret as an input to a key-derivation operation to produce additional cryptographic keys.
For more information about the format of the values which are passed for each step, see PAKE step types.
If the validation of a commitment value fails, then the corresponding call to psa_pake_input() for the PSA_PAKE_STEP_COMMIT step will return PSA_ERROR_INVALID_ARGUMENT.
If the verification of a confirmation value fails, then the corresponding call to psa_pake_input() for the PSA_PAKE_STEP_CONFIRM step will return PSA_ERROR_INVALID_SIGNATURE.
10.13.13 WPA3-SAE algorithms¶
PSA_ALG_WPA3_SAE_FIXED (macro)¶
Macro to build the WPA3-SAE algorithm, with fixed-sized PMK output key.
Added in version 1.4.
#define PSA_ALG_WPA3_SAE_FIXED(hash_alg) /* specification-defined value */
Parameters
hash_algA hash algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_HASH(hash_alg)is true.
Returns
A WPA3-SAE algorithm, for the Looping or Hash-to-element variants, parameterized by a specific hash.
Unspecified if hash_alg is not a supported hash algorithm.
Description
This is WPA3-SAE, as defined by IEEE 802.11-2024: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications [IEEE-802.11] §12.4, using the Looping or Hash-to-element password element derivation procedure, with fixed-sized PMK output key.
The hash algorithm specified must match one of the supported WPA3-SAE cipher suites. See WPA3-SAE cipher suites.
The shared secret that is produced by WPA3-SAE is pseudorandom. Although it can be used directly as an encryption key, it is recommended to use the shared secret as an input to a key-derivation operation to produce additional cryptographic keys.
See The WPA3-SAE protocol for the WPA3-SAE protocol flow and how to implement it with the Crypto API.
Compatible key types
PSA_ALG_WPA3_SAE_GDH (macro)¶
Macro to build the WPA3-SAE algorithm, with group-dependent size of the PMK output key.
Added in version 1.4.
#define PSA_ALG_WPA3_SAE_GDH(hash_alg) /* specification-defined value */
Parameters
hash_algA hash algorithm: a value of type
psa_algorithm_tsuch thatPSA_ALG_IS_HASH(hash_alg)is true.
Returns
A WPA3-SAE algorithm, for the group-dependent-hash variant, parameterized by a specific hash.
Unspecified if hash_alg is not a supported hash algorithm.
Description
This is WPA3-SAE, as defined by IEEE 802.11-2024: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications [IEEE-802.11] §12.4, using the hash-to-element password element derivation procedure, with group-dependent size for the PMK output key.
The hash algorithm specified must match one of the supported WPA3-SAE cipher suites. See WPA3-SAE cipher suites.
The shared secret that is produced by WPA3-SAE is pseudorandom. Although it can be used directly as an encryption key, it is recommended to use the shared secret as an input to a key-derivation operation to produce additional cryptographic keys.
See The WPA3-SAE protocol for the WPA3-SAE protocol flow and how to implement it with the Crypto API.
Compatible key types
PSA_ALG_IS_WPA3_SAE (macro)¶
Whether the specified algorithm is a WPA3-SAE algorithm.
Added in version 1.4.
#define PSA_ALG_IS_WPA3_SAE(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a WPA3-SAE algorithm, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
WPA3-SAE algorithms are constructed using PSA_ALG_WPA3_SAE_FIXED(hash_alg) or PSA_ALG_WPA3_SAE_GDH(hash_alg).
PSA_ALG_IS_WPA3_SAE_FIXED (macro)¶
Whether the specified algorithm is a WPA3-SAE algorithm with a fixed-sized output key.
Added in version 1.4.
#define PSA_ALG_IS_WPA3_SAE_FIXED(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a WPA3-SAE algorithm with a fixed-sized output key, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
WPA3-SAE algorithms with a fixed-sized output key, are constructed using PSA_ALG_WPA3_SAE_FIXED(hash_alg).
PSA_ALG_IS_WPA3_SAE_GDH (macro)¶
Whether the specified algorithm is a WPA3-SAE algorithm with a group-dependent size for the output key.
Added in version 1.4.
#define PSA_ALG_IS_WPA3_SAE_GDH(alg) /* specification-defined value */
Parameters
algAn algorithm identifier: a value of type
psa_algorithm_t.
Returns
1 if alg is a WPA3-SAE algorithm with a group-dependent size for the output key, 0 otherwise.
This macro can return either 0 or 1 if alg is not a supported PAKE algorithm identifier.
Description
WPA3-SAE algorithms with a group-dependent size for the output key, are constructed using PSA_ALG_WPA3_SAE_GDH(hash_alg).
PSA_ALG_WPA3_SAE_ANY (macro)¶
A wildcard algorithm for WPA3-SAE password keys and password token keys.
Added in version 1.4.
#define PSA_ALG_WPA3_SAE_ANY ((psa_algorithm_t)0x0a0088ff)
If a password key (key type PSA_KEY_TYPE_PASSWORD) specifies PSA_ALG_WPA3_SAE_ANY as its permitted algorithm, then the key can be used for any WPA3-SAE cipher suite with the PSA_ALG_WPA3_SAE_H2E key-derivation algorithm, and with the PSA_ALG_WPA3_SAE_FIXED PAKE algorithm.
If a WPA3-SAE password token key specifies PSA_ALG_WPA3_SAE_ANY as its permitted algorithm, then the key can be used with both the PSA_ALG_WPA3_SAE_FIXED() and PSA_ALG_WPA3_SAE_GDH() PAKE algorithms.