PSA PAKE: Add J-PAKE to the interface
Signed-off-by: Janos Follath <janos.follath@arm.com>
This commit is contained in:
parent
8a09ca9d94
commit
9c6b147d98
5 changed files with 217 additions and 12 deletions
|
@ -4366,6 +4366,9 @@ psa_status_t psa_pake_get_key_share(psa_pake_operation_t *operation,
|
|||
* Depending on the protocol being executed, you might need to call this
|
||||
* function several times or you might not need to call this at all.
|
||||
*
|
||||
* Calling this function with PSA_PAKE_DATA_KEY_SHARE as \p type is equivalent
|
||||
* to calling psa_pake_get_key_share().
|
||||
*
|
||||
* The exact sequence of calls to perform a password-authenticated key
|
||||
* exchange depends on the protocol in use. Refer to the documentation of
|
||||
* individual PAKE algorithm types (`PSA_ALG_XXX` values of type
|
||||
|
@ -4443,6 +4446,9 @@ psa_status_t psa_pake_set_key_share(psa_pake_operation_t *operation,
|
|||
* Depending on the protocol being executed, you might need to call this
|
||||
* function several times or you might not need to call this at all.
|
||||
*
|
||||
* Calling this function with PSA_PAKE_DATA_KEY_SHARE as \p type is equivalent
|
||||
* to calling psa_pake_set_key_share().
|
||||
*
|
||||
* The exact sequence of calls to perform a password-authenticated key
|
||||
* exchange depends on the protocol in use. Refer to the documentation of
|
||||
* individual PAKE algorithm types (`PSA_ALG_XXX` values of type
|
||||
|
|
|
@ -387,8 +387,13 @@ typedef uint16_t psa_key_derivation_step_t;
|
|||
/** \brief Encoding of the side of PAKE */
|
||||
typedef uint16_t psa_pake_side_t;
|
||||
|
||||
/** \brief Encoding of the type of input/output for PAKE */
|
||||
typedef uint16_t psa_pake_data_t;
|
||||
/** Encoding of input and output indicators for PAKE.
|
||||
*
|
||||
* Some PAKE protocols need to exchange more data than just a single key share.
|
||||
* This type is for encoding additional input and output data for such
|
||||
* protocols.
|
||||
*/
|
||||
typedef uint8_t psa_pake_data_t;
|
||||
|
||||
/** Encoding of the type of the PAKE's primitive.
|
||||
*
|
||||
|
|
|
@ -731,6 +731,7 @@
|
|||
#define PSA_ALG_CATEGORY_ASYMMETRIC_ENCRYPTION ((psa_algorithm_t)0x07000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_DERIVATION ((psa_algorithm_t)0x08000000)
|
||||
#define PSA_ALG_CATEGORY_KEY_AGREEMENT ((psa_algorithm_t)0x09000000)
|
||||
#define PSA_ALG_CATEGORY_PAKE ((psa_algorithm_t)0x0a000000)
|
||||
|
||||
/** Whether an algorithm is vendor-defined.
|
||||
*
|
||||
|
@ -848,6 +849,18 @@
|
|||
(PSA_ALG_IS_KEY_DERIVATION(alg) && \
|
||||
(alg) & PSA_ALG_KEY_DERIVATION_STRETCHING_FLAG)
|
||||
|
||||
/** Whether the specified algorithm is a password-authenticated key exchange.
|
||||
*
|
||||
* \param alg An algorithm identifier (value of type #psa_algorithm_t).
|
||||
*
|
||||
* \return 1 if \p alg is a password-authenticated key exchange (PAKE)
|
||||
* algorithm, 0 otherwise.
|
||||
* This macro may return either 0 or 1 if \p alg is not a supported
|
||||
* algorithm identifier.
|
||||
*/
|
||||
#define PSA_ALG_IS_PAKE(alg) \
|
||||
(((alg) & PSA_ALG_CATEGORY_MASK) == PSA_ALG_CATEGORY_PAKE)
|
||||
|
||||
#define PSA_ALG_HASH_MASK ((psa_algorithm_t)0x000000ff)
|
||||
/** MD2 */
|
||||
#define PSA_ALG_MD2 ((psa_algorithm_t)0x02000001)
|
||||
|
@ -1953,6 +1966,58 @@
|
|||
#define PSA_ALG_GET_HASH(alg) \
|
||||
(((alg) & 0x000000ff) == 0 ? ((psa_algorithm_t)0) : 0x02000000 | ((alg) & 0x000000ff))
|
||||
|
||||
/** The Password-authenticated key exchange by juggling (J-PAKE) protocol.
|
||||
*
|
||||
* J-PAKE can be instantiated over finite fields or elliptic curves. This can
|
||||
* be achieved by passing either #PSA_PAKE_PRIMITIVE_TYPE_FIELD or
|
||||
* #PSA_PAKE_PRIMITIVE_TYPE_CURVE to #PSA_PAKE_PRIMITIVE respectively, when
|
||||
* creating the cipher suite.
|
||||
*
|
||||
* In theory the protocol works with any non-interactive zero-knowledge proof.
|
||||
* Implementations of the present specification use Schnorr NIZK and this does
|
||||
* not need to be configured in the cipher suites.
|
||||
*
|
||||
* J-PAKE can be used with any secure cryptographic hash function, the choice
|
||||
* of hash must be supplied to the psa_pake_cipher_suite() as the second
|
||||
* parameter (\p hash).
|
||||
*
|
||||
* All the remaining parameters passed to psa_pake_cipher_suite() when creating
|
||||
* the cipher suite must be 0.
|
||||
*
|
||||
* The key exchange flow for JPAKE is as follows:
|
||||
* -# To get the first round data that needs to be sent to the peer, call
|
||||
* psa_pake_get_key_share(operation, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_ZK_PUBLIC, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_ZK_PROOF, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_KEY_SHARE_2, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_ZK_PUBLIC_2, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_ZK_PROOF_2, ...);
|
||||
* -# To provide the first round data received from the peer to the operation,
|
||||
* call
|
||||
* psa_pake_set_key_share(operation, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_ZK_PUBLIC, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_ZK_PROOF, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_KEY_SHARE_2, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_ZK_PUBLIC_2, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_ZK_PROOF_2, ...);
|
||||
* -# To get the second round data that needs to be sent to the peer, call
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_KEY_SHARE_3, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_ZK_PUBLIC_3, ...);
|
||||
* psa_pake_output(operation, #PSA_PAKE_DATA_ZK_PROOF_3, ...);
|
||||
* -# To provide the second round data received from the peer to the operation,
|
||||
* call
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_KEY_SHARE_3, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_ZK_PUBLIC_3, ...);
|
||||
* psa_pake_input(operation, #PSA_PAKE_DATA_ZK_PROOF_3, ...);
|
||||
* -# Call psa_pake_get_implicit_key() for accessing the shared secret.
|
||||
*
|
||||
* For more information consult the documentation of the individual
|
||||
* PSA_PAKE_DATA_XXX constants.
|
||||
*
|
||||
* J-PAKE is standardised for example in RFC 8236 and in THREAD.
|
||||
*/
|
||||
#define PSA_ALG_PAKE_JPAKE ((psa_algorithm_t)0x0a000001)
|
||||
|
||||
/**@}*/
|
||||
|
||||
/** \defgroup key_lifetimes Key lifetimes
|
||||
|
@ -2415,21 +2480,39 @@ static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key )
|
|||
*/
|
||||
#define PSA_PAKE_SIDE_SERVER ((psa_pake_side_t)0x0102)
|
||||
|
||||
/** The pake uses finite fields.
|
||||
*
|
||||
* The corresponding family type is ::psa_dh_family_t. In determining a
|
||||
* specific curve in the family ::psa_pake_bits_t values are interpreted in the
|
||||
* exact same way as ::psa_key_bits_t would.
|
||||
*/
|
||||
#define PSA_PAKE_PRIMITIVE_TYPE_FIELD ((psa_pake_primitive_type_t)0x01)
|
||||
|
||||
/** The pake uses elliptic curves.
|
||||
/** The PAKE uses elliptic curves.
|
||||
*
|
||||
* The corresponding family type is ::psa_ecc_family_t. in determining a
|
||||
* specific curve in the family ::psa_pake_bits_t values are interpreted in the
|
||||
* exact same way as ::psa_key_bits_t would.
|
||||
*
|
||||
* Input and output during the operation can involve group elements and scalar
|
||||
* values:
|
||||
* -# The format for group elements is the same as for public keys on the
|
||||
* specific curve would be. For more information, consult the documentation of
|
||||
* psa_export_public_key().
|
||||
* -# The format for scalars is the same as for private keys on the specific
|
||||
* curve would be. For more information, consult the documentation of
|
||||
* psa_export_key().
|
||||
*/
|
||||
#define PSA_PAKE_PRIMITIVE_TYPE_CURVE ((psa_pake_primitive_type_t)0x02)
|
||||
#define PSA_PAKE_PRIMITIVE_TYPE_CURVE ((psa_pake_primitive_type_t)0x01)
|
||||
|
||||
/** The PAKE uses finite fields based Diffie-Hellman groups.
|
||||
*
|
||||
* The corresponding family type is ::psa_dh_family_t. In determining a
|
||||
* specific group in the family ::psa_pake_bits_t values are interpreted in the
|
||||
* exact same way as ::psa_key_bits_t would.
|
||||
*
|
||||
* Input and output during the operation can involve group elements and scalar
|
||||
* values:
|
||||
* -# The format for group elements is the same as for public keys on the
|
||||
* specific group would be. For more information, consult the documentation of
|
||||
* psa_export_public_key().
|
||||
* -# The format for scalars is the same as for private keys on the specific
|
||||
* group would be. For more information, consult the documentation of
|
||||
* psa_export_key().
|
||||
*/
|
||||
#define PSA_PAKE_PRIMITIVE_TYPE_FIELD_DH ((psa_pake_primitive_type_t)0x02)
|
||||
|
||||
/** Construct a PAKE primitive from type, family and bitsize.
|
||||
*
|
||||
|
@ -2451,5 +2534,87 @@ static inline int mbedtls_svc_key_id_is_null( mbedtls_svc_key_id_t key )
|
|||
#define PSA_PAKE_PRIMITIVE(type, family, bits) \
|
||||
((psa_pake_primitive_t) (((type) << 24 | (persistence) << 16) | (bits)))
|
||||
|
||||
|
||||
/** The key share being sent to or received from the peer.
|
||||
*
|
||||
* Unless the documentation of the PAKE algorithm says otherwise this is a
|
||||
* group element.
|
||||
*
|
||||
* For information regarding representation consult the documentation of
|
||||
* individual ::psa_pake_primitive_type_t constants.
|
||||
*
|
||||
* Some PAKE protocols need to exchange several key shares. If that is the
|
||||
* case, this value marks the first key share sent and the first key share
|
||||
* received. For values sent or received afterwards, use
|
||||
* #PSA_PAKE_DATA_KEY_SHARE_2 and #PSA_PAKE_DATA_KEY_SHARE_3.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_KEY_SHARE ((psa_pake_data_t)0x01)
|
||||
|
||||
|
||||
/** A Schnorr NIZKP public key.
|
||||
*
|
||||
* This is a group element.
|
||||
*
|
||||
* For information regarding representation consult the documentation of
|
||||
* individual ::psa_pake_primitive_type_t constants.
|
||||
*
|
||||
* Some PAKE protocols need to perform several zero-knowledge proofs. If that
|
||||
* is the case, this value marks the first public key sent and the first public
|
||||
* key received. For values sent or received afterwards, use
|
||||
* #PSA_PAKE_DATA_ZK_PUBLIC_2 and #PSA_PAKE_DATA_ZK_PUBLIC_3.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_ZK_PUBLIC ((psa_pake_data_t)0x02)
|
||||
|
||||
|
||||
/** A Schnorr NIZKP proof.
|
||||
*
|
||||
* This is a skalar value.
|
||||
*
|
||||
* For information regarding representation consult the documentation of
|
||||
* individual ::psa_pake_primitive_type_t constants.
|
||||
*
|
||||
* Some PAKE protocols need to perform several zero-knowledge proofs. If that
|
||||
* is the case, this value marks the first proof sent and the first proof
|
||||
* received. For values sent or received afterwards, use
|
||||
* #PSA_PAKE_DATA_ZK_PROOF_2 and #PSA_PAKE_DATA_ZK_PROOF_3.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_ZK_PROOF ((psa_pake_data_t)0x03)
|
||||
|
||||
/** Marks the second key share sent and received.
|
||||
*
|
||||
* See #PSA_PAKE_DATA_KEY_SHARE.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_KEY_SHARE_2 ((psa_pake_data_t)0x04)
|
||||
|
||||
/** Marks the second Schnorr NIZKP public key sent and received.
|
||||
*
|
||||
* See #PSA_PAKE_DATA_ZK_PUBLIC.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_ZK_PUBLIC_2 ((psa_pake_data_t)0x05)
|
||||
|
||||
/** Marks the second Schnorr NIZKP proof sent and received.
|
||||
*
|
||||
* See #PSA_PAKE_DATA_ZK_PROOF.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_ZK_PROOF_2 ((psa_pake_data_t)0x06)
|
||||
|
||||
/** Marks the third key share sent and received.
|
||||
*
|
||||
* See #PSA_PAKE_DATA_KEY_SHARE.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_KEY_SHARE_3 ((psa_pake_data_t)0x07)
|
||||
|
||||
/** Marks the third Schnorr NIZKP public key sent and received.
|
||||
*
|
||||
* See #PSA_PAKE_DATA_ZK_PUBLIC.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_ZK_PUBLIC_3 ((psa_pake_data_t)0x08)
|
||||
|
||||
/** Marks the third Schnorr NIZKP proof sent and received.
|
||||
*
|
||||
* See #PSA_PAKE_DATA_ZK_PROOF.
|
||||
*/
|
||||
#define PSA_PAKE_DATA_ZK_PROOF_3 ((psa_pake_data_t)0x09)
|
||||
|
||||
/**@}*/
|
||||
#endif /* PSA_CRYPTO_VALUES_H */
|
||||
|
|
|
@ -294,6 +294,9 @@ Key agreement: ECDH, HKDF using SHA-384
|
|||
depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_384
|
||||
key_agreement_algorithm:PSA_ALG_KEY_AGREEMENT( PSA_ALG_ECDH, PSA_ALG_HKDF( PSA_ALG_SHA_384 ) ):ALG_IS_ECDH:PSA_ALG_ECDH:PSA_ALG_HKDF( PSA_ALG_SHA_384 )
|
||||
|
||||
PAKE: J-PAKE
|
||||
pake_algorithm:PSA_ALG_PAKE_JPAKE
|
||||
|
||||
Key type: raw data
|
||||
key_type:PSA_KEY_TYPE_RAW_DATA:KEY_TYPE_IS_UNSTRUCTURED
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@ void mac_algorithm_core( psa_algorithm_t alg, int classification_flags,
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Length */
|
||||
|
@ -181,6 +182,7 @@ void aead_algorithm_core( psa_algorithm_t alg, int classification_flags,
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Tag length */
|
||||
|
@ -220,6 +222,7 @@ void hash_algorithm( int alg_arg, int length_arg )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, 0 );
|
||||
|
||||
/* Dependent algorithms */
|
||||
|
@ -362,6 +365,7 @@ void cipher_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -462,6 +466,7 @@ void asymmetric_signature_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -491,6 +496,7 @@ void asymmetric_encryption_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
}
|
||||
/* END_CASE */
|
||||
|
@ -511,6 +517,7 @@ void key_derivation_algorithm( int alg_arg, int classification_flags )
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Check combinations with key agreements */
|
||||
|
@ -540,6 +547,7 @@ void key_agreement_algorithm( int alg_arg, int classification_flags,
|
|||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_PAKE( alg ) );
|
||||
algorithm_classification( alg, classification_flags );
|
||||
|
||||
/* Shared secret derivation properties */
|
||||
|
@ -548,6 +556,24 @@ void key_agreement_algorithm( int alg_arg, int classification_flags,
|
|||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE */
|
||||
void pake_algorithm( int alg_arg )
|
||||
{
|
||||
psa_algorithm_t alg = alg_arg;
|
||||
|
||||
/* Algorithm classification */
|
||||
TEST_ASSERT( ! PSA_ALG_IS_HASH( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_MAC( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_CIPHER( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_AEAD( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_SIGN( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_ASYMMETRIC_ENCRYPTION( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) );
|
||||
TEST_ASSERT( ! PSA_ALG_IS_KEY_DERIVATION( alg ) );
|
||||
TEST_ASSERT( PSA_ALG_IS_PAKE( alg ) );
|
||||
}
|
||||
|
||||
/* END_CASE */
|
||||
/* BEGIN_CASE */
|
||||
void key_type( int type_arg, int classification_flags )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue