2. Password-authenticated key exchange (PAKE)¶
This is a proposed PAKE interface for PSA Certified Crypto API [PSA-CRYPT]. It is not part of the official Crypto API yet.
Note
The content of this specification is not part of the stable Crypto API and may change substantially from version to version.
2.1. Algorithm encoding¶
A new algorithm category is added for PAKE algorithms. The algorithm category table in [PSA-CRYPT] Appendix B is extended with the information in Table 4.
Algorithm category |
CAT |
Category details |
---|---|---|
PAKE |
|
2.1.1. PAKE algorithm encoding¶
The algorithm identifier for PAKE algorithms defined in this specification are encoded as shown in Figure 1.
The defined values for PAKE-TYPE are shown in Table 5.
PAKE algorithm |
PAKE-TYPE |
Algorithm identifier |
Algorithm value |
---|---|---|---|
J-PAKE |
|
|
2.2. Changes and additions to the Programming API¶
2.2.1. PAKE algorithms¶
PSA_ALG_IS_PAKE
(macro)¶
Whether the specified algorithm is a password-authenticated key exchange.
#define PSA_ALG_IS_PAKE(alg) /* specification-defined value */
Parameters
alg
An algorithm identifier: a value of type
psa_algorithm_t
.
Returns
1
if alg
is a password-authenticated key exchange (PAKE) algorithm, 0
otherwise.
This macro can return either 0
or 1
if alg
is not a supported algorithm identifier.
PSA_ALG_JPAKE
(macro)¶
The Password-authenticated key exchange by juggling (J-PAKE) algorithm.
#define PSA_ALG_JPAKE ((psa_algorithm_t)0x0a000100)
This is J-PAKE as defined by J-PAKE: Password-Authenticated Key Exchange by Juggling [RFC8236], instantiated with the following parameters:
The group can be either an elliptic curve or defined over a finite field.
Schnorr NIZK proof as defined by Schnorr Non-interactive Zero-Knowledge Proof [RFC8235], using the same group as the J-PAKE algorithm.
A cryptographic hash function.
To select these parameters and set up the cipher suite, initialize a psa_pake_cipher_suite_t
object, and call the following functions in any order:
psa_pake_cipher_suite_t cipher_suite = PSA_PAKE_CIPHER_SUITE_INIT; psa_pake_cs_set_algorithm(cipher_suite, PSA_ALG_JPAKE); psa_pake_cs_set_primitive(cipher_suite, PSA_PAKE_PRIMITIVE(type, family, bits)); psa_pake_cs_set_hash(cipher_suite, hash);
More information on selecting a specific Elliptic curve or Diffie-Hellman field is provided with the PSA_PAKE_PRIMITIVE_TYPE_ECC
and PSA_PAKE_PRIMITIVE_TYPE_DH
constants.
The J-PAKE operation follows the protocol shown in Figure 2.
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
.
The following steps demonstrate the application code for ‘User’ in Figure 2. The input and output steps must be carried out in exactly the same sequence as shown.
To prepare a J-Pake operation, initialize and set up a
psa_pake_operation_t
object by calling the following functions:psa_pake_operation_t jpake = PSA_PAKE_OPERATION_INIT; psa_pake_setup(&jpake, &cipher_suite); psa_pake_set_user(&jpake, ...); psa_pake_set_peer(&jpake, ...); psa_pake_set_password_key(&jpake, ...);
The password is provided as a key. This 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.
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_set_password_key()
will return an error if the result of the conversion and reduction is0
.
After setup, the key exchange flow for J-PAKE is as follows:
To get the first round data that needs to be sent to the peer, call:
// 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, call:
// 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, ...);
To get the second round data that needs to be sent to the peer, call:
// 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 call:
// 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, ...);
To use the shared secret, set up a key derivation operation and transfer the computed value:
// Set up the KDF psa_key_derivation_operation_t kdf = PSA_KEY_DERIVATION_OPERATION_INIT; psa_key_derivation_setup(&kdf, ...); psa_key_derivation_input_bytes(&kdf, PSA_KEY_DERIVATION_INPUT_CONTEXT, ...); psa_key_derivation_input_bytes(&kdf, PSA_KEY_DERIVATION_INPUT_LABEL, ...); // Get Ka=Kb=K psa_pake_get_implicit_key(&jpake, &kdf)
For more information about the format of the values which are passed for each step, see PAKE step types.
If the verification of a Zero-knowledge proof provided by the peer fails, then the corresponding call to psa_pake_input()
for the PSA_PAKE_STEP_ZK_PROOF
step will return PSA_ERROR_INVALID_SIGNATURE
.
Warning
At the end of this sequence there is a cryptographic guarantee that only a peer that used the same password is able to compute the same key. But there is no guarantee that the peer is the participant it claims to be, or that the peer used the same password during the exchange.
At this point, authentication is implicit — material encrypted or authenticated using the computed key can only be decrypted or verified by someone with the same key. The peer is not authenticated at this point, and no action should be taken by the application which assumes that the peer is authenticated, for example, by accessing restricted files.
To make the authentication explicit, there are various methods to confirm that both parties have the same key. See [RFC8236] §5 for two examples.
Compatible key types
PSA_KEY_TYPE_PASSWORD
PSA_KEY_TYPE_PASSWORD_HASH
2.2.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_type_t
(typedef)¶
Encoding of the type of the PAKE’s primitive.
typedef uint8_t psa_pake_primitive_type_t;
The range of PAKE primitive type values is divided as follows:
0
x00
Reserved as an invalid primitive type.
0
x01
– 0
x7f
Specification-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.
0
x80
– 0
xff
Implementation-defined primitive type. Implementations that define additional primitive types must use an encoding with bit 7 set.
For specification-defined primitive types, see the documentation of individual PSA_PAKE_PRIMITIVE_TYPE_XXX
constants.
PSA_PAKE_PRIMITIVE_TYPE_ECC
(macro)¶
The PAKE primitive type indicating the use of elliptic curves.
#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. For more information, consult the documentation of
psa_export_public_key
()
.The format for scalars is the same as that for private keys on the specific Elliptic curve. For more information, consult the documentation of
psa_export_key
()
.
PSA_PAKE_PRIMITIVE_TYPE_DH
(macro)¶
The PAKE primitive type indicating the use of Diffie-Hellman groups.
#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 Diffie-Hellman group, using the same mapping that is used for 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 Diffie-Hellman group. For more information, consult the documentation of
psa_export_public_key
()
.The format for scalars is the same as that for private keys in the specific Diffie-Hellman group. For more information, consult the documentation of
psa_export_key
()
.
psa_pake_family_t
(typedef)¶
Encoding of the family of the primitive associated with the PAKE.
typedef uint8_t psa_pake_family_t;
For more information see the documentation of individual PSA_PAKE_PRIMITIVE_TYPE_XXX
constants.
psa_pake_primitive_t
(typedef)¶
Encoding of the primitive associated with the PAKE.
typedef uint32_t psa_pake_primitive_t;
PAKE primitive values are constructed using PSA_PAKE_PRIMITIVE()
.
Rationale
An integral type is required for psa_pake_primitive_t
to enable values of this type to be compile-time-constants. This allows them to be used in case
statements, and used to calculate static buffer sizes with PSA_PAKE_OUTPUT_SIZE()
and PSA_PAKE_INPUT_SIZE()
.
PSA_PAKE_PRIMITIVE
(macro)¶
Construct a PAKE primitive from type, family and bit-size.
#define PSA_PAKE_PRIMITIVE(pake_type, pake_family, pake_bits) \ /* specification-defined value */
Parameters
pake_type
The type of the primitive: a value of type
psa_pake_primitive_type_t
.pake_family
The family of the primitive. The type and interpretation of this parameter depends on
pake_type
. For more information, consult the documentation of individualpsa_pake_primitive_type_t
constants.pake_bits
The bit-size of the primitive: a value of type
size_t
. The interpretation of this parameter depends onfamily
. For more information, consult the documentation of individualpsa_pake_primitive_type_t
constants.
Returns: psa_pake_primitive_t
The constructed primitive value.
Return 0
if the requested primitive can’t be encoded as psa_pake_primitive_t
.
2.2.3. PAKE cipher suites¶
A PAKE algorithm uses a specific cryptographic primitive for key establishment, specified using a PAKE primitive. PAKE algorithms also require a cryptographic hash algorithm, which is agreed between the participants.
The psa_pake_cipher_suite_t
object is used to fully specify a PAKE operation, combining the PAKE algorithm, the PAKE primitive, the hash or any other algorithm that parametrises the PAKE in question.
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.
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 PAKE primitive, which identifies the prime order group used for the key exchange operation. See PAKE primitives.
The hash algorithm to use in the operation.
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 implementations 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.
This is an implementation-defined type. Applications that make assumptions about the content of this object will result in 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();
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
.
#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.
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.
psa_algorithm_t psa_pake_cs_get_algorithm(const psa_pake_cipher_suite_t* cipher_suite);
Parameters
cipher_suite
The 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.
void psa_pake_cs_set_algorithm(psa_pake_cipher_suite_t* cipher_suite, psa_algorithm_t alg);
Parameters
cipher_suite
The cipher suite object to write to.
alg
The PAKE algorithm to write: a value of type
psa_algorithm_t
such 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.
psa_pake_primitive_t psa_pake_cs_get_primitive(const psa_pake_cipher_suite_t* cipher_suite);
Parameters
cipher_suite
The 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.
void psa_pake_cs_set_primitive(psa_pake_cipher_suite_t* cipher_suite, psa_pake_primitive_t primitive);
Parameters
cipher_suite
The cipher suite object to write to.
primitive
The PAKE primitive to write: a value of type
psa_pake_primitive_t
. If this is0
, the primitive type incipher_suite
becomes 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_cs_get_hash
(function)¶
Retrieve the hash algorithm from a PAKE cipher suite.
psa_pake_primitive_t psa_pake_cs_get_hash(const psa_pake_cipher_suite_t* cipher_suite);
Parameters
cipher_suite
The cipher suite object to query.
Returns: psa_pake_primitive_t
The hash algorithm stored in the cipher suite object.
The return value is PSA_ALG_NONE
if the PAKE is not parametrized by a hash algorithm, or if the hash algorithm is not set.
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_hash
(function)¶
Declare the hash algorithm for a PAKE cipher suite.
void psa_pake_cs_set_hash(psa_pake_cipher_suite_t* cipher_suite, psa_algorithm_t hash_alg);
Parameters
cipher_suite
The cipher suite object to write to.
hash_alg
The hash algorithm to write: a value of type
psa_algorithm_t
such thatPSA_ALG_IS_HASH
(
hash_alg
)
is true. If this isPSA_ALG_NONE
, the hash algorithm incipher_suite
becomes unspecified.
Returns: void
Description
This function overwrites any hash algorithm previously set in cipher_suite
.
The documentation of individual PAKE algorithms specifies which hash algorithms are compatible, or if no hash algorithm is required.
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.
2.2.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 need to assign an order to the participants.
psa_pake_role_t
(typedef)¶
Encoding of the application role in a PAKE algorithm.
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.
#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.
#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.
#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.
#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.
#define PSA_PAKE_ROLE_SERVER ((psa_pake_role_t)0x12)
Augmented PAKE algorithms need to differentiate between client and server.
2.2.5. PAKE step types¶
psa_pake_step_t
(typedef)¶
Encoding of input and output steps for a PAKE algorithm.
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)¶
The key share being sent to or received from the peer.
#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.
#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.
#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 Diffie-Hellman groups, the encoding is big endian. See [SEC1] §2.3.8.
In both cases leading zeroes are allowed 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()
.
2.2.6. Multi-part PAKE operations¶
psa_pake_operation_t
(typedef)¶
The type of the state object for PAKE operations.
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_cipher_suite_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 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
.
#define PSA_PAKE_OPERATION_INIT /* implementation-defined value */
psa_pake_operation_init
(function)¶
Return an initial value for a PAKE operation object.
psa_pake_operation_t psa_pake_operation_init(void);
Returns: psa_pake_operation_t
psa_pake_setup
(function)¶
Set the session information for a password-authenticated key exchange.
psa_status_t psa_pake_setup(psa_pake_operation_t *operation, const psa_pake_cipher_suite_t *cipher_suite);
Parameters
operation
The operation object to set up. It must have been initialized as per the documentation for
psa_pake_operation_t
and not yet in use.cipher_suite
The cipher suite to use. A PAKE cipher suite fully characterizes a PAKE algorithm, including the PAKE algorithm.
Returns: psa_status_t
PSA_SUCCESS
Success.
PSA_ERROR_BAD_STATE
The 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_ARGUMENT
The following conditions can result in this error:
The algorithm in
cipher_suite
is not a PAKE algorithm.The PAKE primitive in
cipher_suite
is not compatible with the PAKE algorithm.The hash algorithm in
cipher_suite
is invalid, or not compatible with the PAKE algorithm and primitive.
PSA_ERROR_NOT_SUPPORTED
The following conditions can result in this error:
The algorithm in
cipher_suite
is not a supported PAKE algorithm.The PAKE primitive in
cipher_suite
is not supported or not compatible with the PAKE algorithm.The hash algorithm in
cipher_suite
is not supported, or not compatible with the PAKE algorithm and primitive.
PSA_ERROR_COMMUNICATION_FAILURE
PSA_ERROR_CORRUPTION_DETECTED
Description
The sequence of operations to set up a password-authenticated key exchange operation is as follows:
Allocate an 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.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_implicit_key()
for accessing the shared secret.
Refer to the documentation of individual PAKE algorithms for details on the required set up and operation for each algorithm. See PAKE algorithms.
If an error occurs at any step after a call to psa_pake_setup()
, the operation will need to be reset by a call to psa_pake_abort()
.
The application may call psa_pake_abort()
at any time after the operation has been initialized.
After a successful call to psa_pake_setup()
, the application must eventually terminate the operation.
The following events terminate an operation:
A call to
psa_pake_abort()
.A successful call to
psa_pake_get_implicit_key()
.
psa_pake_set_password_key
(function)¶
Set the password for a password-authenticated key exchange using a key.
psa_status_t psa_pake_set_password_key(psa_pake_operation_t *operation, psa_key_id_t password);
Parameters
operation
Active PAKE operation.
password
Identifier of the key holding the password or a value derived from the password. It must remain valid until the operation terminates. It must be of type
PSA_KEY_TYPE_PASSWORD
orPSA_KEY_TYPE_PASSWORD_HASH
. It must allow the usagePSA_KEY_USAGE_DERIVE
.
Returns: psa_status_t
PSA_SUCCESS
Success.
PSA_ERROR_BAD_STATE
The following conditions can result in this error:
The operation state is not valid: it must be active, and
psa_pake_set_password_key()
,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_HANDLE
password
is not a valid key identifier.PSA_ERROR_NOT_PERMITTED
The key does not have the
PSA_KEY_USAGE_DERIVE
flag, or it does not permit the operation’s algorithm.PSA_ERROR_INVALID_ARGUMENT
The following conditions can result in this error:
The key type for
password
is notPSA_KEY_TYPE_PASSWORD
orPSA_KEY_TYPE_PASSWORD_HASH
.password
is not compatible with the operation’s cipher suite.
PSA_ERROR_NOT_SUPPORTED
The key type or key size of
password
is not supported with the operation’s cipher suite.PSA_ERROR_COMMUNICATION_FAILURE
PSA_ERROR_CORRUPTION_DETECTED
PSA_ERROR_STORAGE_FAILURE
PSA_ERROR_DATA_CORRUPT
PSA_ERROR_DATA_INVALID
Description
Refer to the documentation of individual PAKE algorithms for constraints on the format and content of valid passwords. See PAKE algorithms.
psa_pake_set_user
(function)¶
Set the user ID for a password-authenticated key exchange.
psa_status_t psa_pake_set_user(psa_pake_operation_t *operation, const uint8_t *user_id, size_t user_id_len);
Parameters
operation
Active PAKE operation.
user_id
The user ID to authenticate with.
user_id_len
Size of the
user_id
buffer in bytes.
Returns: psa_status_t
PSA_SUCCESS
Success.
PSA_ERROR_BAD_STATE
The 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_ARGUMENT
user_id
is not valid for the operation’s algorithm and cipher suite.PSA_ERROR_NOT_SUPPORTED
The value of
user_id
is not supported by the implementation.PSA_ERROR_INSUFFICIENT_MEMORY
PSA_ERROR_COMMUNICATION_FAILURE
PSA_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. See PAKE algorithms.
psa_pake_set_peer
(function)¶
Set the peer ID for a password-authenticated key exchange.
psa_status_t psa_pake_set_peer(psa_pake_operation_t *operation, const uint8_t *peer_id, size_t peer_id_len);
Parameters
operation
Active PAKE operation.
peer_id
The peer’s ID to authenticate.
peer_id_len
Size of the
peer_id
buffer in bytes.
Returns: psa_status_t
PSA_SUCCESS
Success.
PSA_ERROR_BAD_STATE
The 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_ARGUMENT
peer_id
is not valid for the operation’s algorithm and cipher suite.PSA_ERROR_NOT_SUPPORTED
The value of
peer_id
is not supported by the implementation.PSA_ERROR_NOT_SUPPORTED
PSA_ERROR_INSUFFICIENT_MEMORY
PSA_ERROR_COMMUNICATION_FAILURE
PSA_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. See PAKE algorithms.
psa_pake_set_role
(function)¶
Set the application role for a password-authenticated key exchange.
psa_status_t psa_pake_set_role(psa_pake_operation_t *operation, psa_pake_role_t role);
Parameters
operation
Active PAKE operation.
role
A value of type
psa_pake_role_t
indicating the application role in the PAKE algorithm. See PAKE roles.
Returns: psa_status_t
PSA_SUCCESS
Success.
PSA_ERROR_BAD_STATE
The 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_ARGUMENT
role
is not a valid PAKE role in the operation’s algorithm.PSA_ERROR_NOT_SUPPORTED
role
is not a valid PAKE role, or is not supported for the operation’s algorithm.PSA_ERROR_COMMUNICATION_FAILURE
PSA_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_NONE
role.
Refer to the documentation of individual PAKE algorithms for more information. See PAKE algorithms.
psa_pake_output
(function)¶
Get output for a step of a password-authenticated key exchange.
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
operation
Active PAKE operation.
step
The step of the algorithm for which the output is requested.
output
Buffer where the output is to be written. The format of the output depends on the
step
, see PAKE step types.output_size
Size of the
output
buffer 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
)
wherealg
andprimitive
are the PAKE algorithm and primitive in the operation’s cipher suite, andstep
is the output step.PSA_PAKE_OUTPUT_MAX_SIZE
evaluates to the maximum output size of any supported PAKE algorithm, primitive and step.
output_length
On success, the number of bytes of the returned output.
Returns: psa_status_t
PSA_SUCCESS
Success. The first
(*output_length)
bytes ofoutput
contain the output.PSA_ERROR_BAD_STATE
The 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_SMALL
The size of the
output
buffer is too small.PSA_PAKE_OUTPUT_SIZE()
orPSA_PAKE_OUTPUT_MAX_SIZE
can be used to determine a sufficient buffer size.PSA_ERROR_INVALID_ARGUMENT
step
is not compatible with the operation’s algorithm.PSA_ERROR_NOT_SUPPORTED
step
is not supported with the operation’s algorithm.PSA_ERROR_INSUFFICIENT_ENTROPY
PSA_ERROR_INSUFFICIENT_MEMORY
PSA_ERROR_COMMUNICATION_FAILURE
PSA_ERROR_CORRUPTION_DETECTED
PSA_ERROR_STORAGE_FAILURE
PSA_ERROR_DATA_CORRUPT
PSA_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. See PAKE algorithms.
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.
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
operation
Active PAKE operation.
step
The step for which the input is provided.
input
Buffer containing the input. The format of the input depends on the
step
, see PAKE step types.input_length
Size of the
input
buffer in bytes.
Returns: psa_status_t
PSA_SUCCESS
Success.
PSA_ERROR_BAD_STATE
The 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_SIGNATURE
The verification fails for a
PSA_PAKE_STEP_ZK_PROOF
input step.PSA_ERROR_INVALID_ARGUMENT
The following conditions can result in this error:
step
is not compatible with the operation’s algorithm.The input is not valid for the operation’s algorithm, cipher suite or
step
.
PSA_ERROR_NOT_SUPPORTED
The following conditions can result in this error:
step
is not supported with the operation’s algorithm.The input is not supported for the operation’s algorithm, cipher suite or
step
.
PSA_ERROR_INSUFFICIENT_MEMORY
PSA_ERROR_COMMUNICATION_FAILURE
PSA_ERROR_CORRUPTION_DETECTED
PSA_ERROR_STORAGE_FAILURE
PSA_ERROR_DATA_CORRUPT
PSA_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. See PAKE algorithms.
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_get_implicit_key
(function)¶
Pass the implicitly confirmed shared secret from a PAKE into a key derivation operation.
psa_status_t psa_pake_get_implicit_key(psa_pake_operation_t *operation, psa_key_derivation_operation_t *output);
Parameters
operation
Active PAKE operation.
output
A key derivation operation that is ready for an input step of type
PSA_KEY_DERIVATION_INPUT_SECRET
.
Returns: psa_status_t
PSA_SUCCESS
Success. Use the
output
key derivation operation to continue with derivation of keys or data.PSA_ERROR_BAD_STATE
The following conditions can result in this error:
The state of PAKE operation
operation
is not valid: it must be active, with all setup, input, and output steps complete.The state of key derivation operation
output
is not valid for thePSA_KEY_DERIVATION_INPUT_SECRET
step.The library requires initializing by a call to
psa_crypto_init
()
.
PSA_ERROR_INVALID_ARGUMENT
PSA_KEY_DERIVATION_INPUT_SECRET
is not compatible with the algorithm in theoutput
key derivation operation.PSA_ERROR_NOT_SUPPORTED
Input from a PAKE is not supported by the algorithm in the
output
key derivation operation.PSA_ERROR_INSUFFICIENT_MEMORY
PSA_ERROR_COMMUNICATION_FAILURE
PSA_ERROR_CORRUPTION_DETECTED
PSA_ERROR_STORAGE_FAILURE
PSA_ERROR_DATA_CORRUPT
PSA_ERROR_DATA_INVALID
Description
At this step in the PAKE operation there is a cryptographic guarantee that only an authenticated participant who used the same password is able to compute the key. But there is no guarantee that the peer is the participant it claims to be, and was able to compute the same key.
In this situation, the authentication is only implicit. Since the peer is not authenticated, no action should be taken that assumes that the peer is who it claims to be For example, do not access restricted files on the peer’s behalf until an explicit authentication has succeeded.
This function can be called after the key exchange phase of the operation has completed.
It injects the shared secret output of the PAKE into the provided key derivation operation.
The input step PSA_KEY_DERIVATION_INPUT_SECRET
is used to input the shared key material into the key derivation operation.
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. See PAKE algorithms.
When this function returns successfully, operation
becomes inactive.
If this function returns an error status, both the operation
and the key_derivation
operations enter an error state and must be aborted by calling psa_pake_abort()
and psa_key_derivation_abort
()
respectively.
psa_pake_abort
(function)¶
Abort a PAKE operation.
psa_status_t psa_pake_abort(psa_pake_operation_t * operation);
Parameters
operation
Initialized PAKE operation.
Returns: psa_status_t
PSA_SUCCESS
Success. The operation object can now be discarded or reused.
PSA_ERROR_BAD_STATE
The library requires initializing by a call to
psa_crypto_init
()
.PSA_ERROR_COMMUNICATION_FAILURE
PSA_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_implicit_key()
is safe and has no effect.
2.2.7. Support macros¶
PSA_PAKE_OUTPUT_SIZE
(macro)¶
Sufficient output buffer size for psa_pake_output()
, in bytes.
#define PSA_PAKE_OUTPUT_SIZE(alg, primitive, output_step) \ /* implementation-defined value */
Parameters
alg
A PAKE algorithm: a value of type
psa_algorithm_t
such thatPSA_ALG_IS_PAKE
(
alg
)
is true.primitive
A primitive of type
psa_pake_primitive_t
that is compatible with algorithmalg
.output_step
A value of type
psa_pake_step_t
that 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.
#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()
.
#define PSA_PAKE_INPUT_SIZE(alg, primitive, input_step) \ /* implementation-defined value */
Parameters
alg
A PAKE algorithm: a value of type
psa_algorithm_t
such thatPSA_ALG_IS_PAKE
(
alg
)
is true.primitive
A primitive of type
psa_pake_primitive_t
that is compatible with algorithmalg
.input_step
A value of type
psa_pake_step_t
that 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.
#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()
.