Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:50

0001 /**
0002  * \file ecjpake.h
0003  *
0004  * \brief Elliptic curve J-PAKE
0005  */
0006 /*
0007  *  Copyright The Mbed TLS Contributors
0008  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
0009  */
0010 #ifndef MBEDTLS_ECJPAKE_H
0011 #define MBEDTLS_ECJPAKE_H
0012 #include "mbedtls/private_access.h"
0013 
0014 /*
0015  * J-PAKE is a password-authenticated key exchange that allows deriving a
0016  * strong shared secret from a (potentially low entropy) pre-shared
0017  * passphrase, with forward secrecy and mutual authentication.
0018  * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
0019  *
0020  * This file implements the Elliptic Curve variant of J-PAKE,
0021  * as defined in Chapter 7.4 of the Thread v1.0 Specification,
0022  * available to members of the Thread Group http://threadgroup.org/
0023  *
0024  * As the J-PAKE algorithm is inherently symmetric, so is our API.
0025  * Each party needs to send its first round message, in any order, to the
0026  * other party, then each sends its second round message, in any order.
0027  * The payloads are serialized in a way suitable for use in TLS, but could
0028  * also be use outside TLS.
0029  */
0030 #include "tf-psa-crypto/build_info.h"
0031 
0032 #include "mbedtls/private/ecp.h"
0033 #include "mbedtls/md.h"
0034 
0035 #ifdef __cplusplus
0036 extern "C" {
0037 #endif
0038 
0039 /**
0040  * Roles in the EC J-PAKE exchange
0041  */
0042 typedef enum {
0043     MBEDTLS_ECJPAKE_CLIENT = 0,         /**< Client                         */
0044     MBEDTLS_ECJPAKE_SERVER,             /**< Server                         */
0045     MBEDTLS_ECJPAKE_NONE,               /**< Undefined                      */
0046 } mbedtls_ecjpake_role;
0047 
0048 /**
0049  * EC J-PAKE context structure.
0050  *
0051  * J-PAKE is a symmetric protocol, except for the identifiers used in
0052  * Zero-Knowledge Proofs, and the serialization of the second message
0053  * (KeyExchange) as defined by the Thread spec.
0054  *
0055  * In order to benefit from this symmetry, we choose a different naming
0056  * convention from the Thread v1.0 spec. Correspondence is indicated in the
0057  * description as a pair C: client name, S: server name
0058  */
0059 typedef struct mbedtls_ecjpake_context {
0060     mbedtls_md_type_t MBEDTLS_PRIVATE(md_type);          /**< Hash to use                    */
0061     mbedtls_ecp_group MBEDTLS_PRIVATE(grp);              /**< Elliptic curve                 */
0062     mbedtls_ecjpake_role MBEDTLS_PRIVATE(role);          /**< Are we client or server?       */
0063     int MBEDTLS_PRIVATE(point_format);                   /**< Format for point export        */
0064 
0065     mbedtls_ecp_point MBEDTLS_PRIVATE(Xm1);              /**< My public key 1   C: X1, S: X3 */
0066     mbedtls_ecp_point MBEDTLS_PRIVATE(Xm2);              /**< My public key 2   C: X2, S: X4 */
0067     mbedtls_ecp_point MBEDTLS_PRIVATE(Xp1);              /**< Peer public key 1 C: X3, S: X1 */
0068     mbedtls_ecp_point MBEDTLS_PRIVATE(Xp2);              /**< Peer public key 2 C: X4, S: X2 */
0069     mbedtls_ecp_point MBEDTLS_PRIVATE(Xp);               /**< Peer public key   C: Xs, S: Xc */
0070 
0071     mbedtls_mpi MBEDTLS_PRIVATE(xm1);                    /**< My private key 1  C: x1, S: x3 */
0072     mbedtls_mpi MBEDTLS_PRIVATE(xm2);                    /**< My private key 2  C: x2, S: x4 */
0073 
0074     mbedtls_mpi MBEDTLS_PRIVATE(s);                      /**< Pre-shared secret (passphrase) */
0075 } mbedtls_ecjpake_context;
0076 
0077 #if defined(MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS)
0078 /**
0079  * \brief           Initialize an ECJPAKE context.
0080  *
0081  * \param ctx       The ECJPAKE context to initialize.
0082  *                  This must not be \c NULL.
0083  */
0084 void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx);
0085 
0086 /**
0087  * \brief           Set up an ECJPAKE context for use.
0088  *
0089  * \note            Currently the only values for hash/curve allowed by the
0090  *                  standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
0091  *
0092  * \param ctx       The ECJPAKE context to set up. This must be initialized.
0093  * \param role      The role of the caller. This must be either
0094  *                  #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
0095  * \param hash      The identifier of the hash function to use,
0096  *                  for example #MBEDTLS_MD_SHA256.
0097  * \param curve     The identifier of the elliptic curve to use,
0098  *                  for example #MBEDTLS_ECP_DP_SECP256R1.
0099  * \param secret    The pre-shared secret (passphrase). This must be
0100  *                  a readable not empty buffer of length \p len Bytes. It need
0101  *                  only be valid for the duration of this call.
0102  * \param len       The length of the pre-shared secret \p secret.
0103  *
0104  * \return          \c 0 if successful.
0105  * \return          A negative error code on failure.
0106  */
0107 int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx,
0108                           mbedtls_ecjpake_role role,
0109                           mbedtls_md_type_t hash,
0110                           mbedtls_ecp_group_id curve,
0111                           const unsigned char *secret,
0112                           size_t len);
0113 
0114 /**
0115  * \brief               Set the point format for future reads and writes.
0116  *
0117  * \param ctx           The ECJPAKE context to configure.
0118  * \param point_format  The point format to use:
0119  *                      #MBEDTLS_ECP_PF_UNCOMPRESSED (default)
0120  *                      or #MBEDTLS_ECP_PF_COMPRESSED.
0121  *
0122  * \return              \c 0 if successful.
0123  * \return              #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p point_format
0124  *                      is invalid.
0125  */
0126 int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx,
0127                                      int point_format);
0128 
0129 /**
0130  * \brief           Check if an ECJPAKE context is ready for use.
0131  *
0132  * \param ctx       The ECJPAKE context to check. This must be
0133  *                  initialized.
0134  *
0135  * \return          \c 0 if the context is ready for use.
0136  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
0137  */
0138 int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx);
0139 
0140 /**
0141  * \brief           Generate and write the first round message
0142  *                  (TLS: contents of the Client/ServerHello extension,
0143  *                  excluding extension type and length bytes).
0144  *
0145  * \param ctx       The ECJPAKE context to use. This must be
0146  *                  initialized and set up.
0147  * \param buf       The buffer to write the contents to. This must be a
0148  *                  writable buffer of length \p len Bytes.
0149  * \param len       The length of \p buf in Bytes.
0150  * \param olen      The address at which to store the total number
0151  *                  of Bytes written to \p buf. This must not be \c NULL.
0152  * \param f_rng     The RNG function to use. This must not be \c NULL.
0153  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0154  *                  may be \c NULL if \p f_rng doesn't use a context.
0155  *
0156  * \return          \c 0 if successful.
0157  * \return          A negative error code on failure.
0158  */
0159 int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
0160                                     unsigned char *buf, size_t len, size_t *olen,
0161                                     int (*f_rng)(void *, unsigned char *, size_t),
0162                                     void *p_rng);
0163 
0164 /**
0165  * \brief           Read and process the first round message
0166  *                  (TLS: contents of the Client/ServerHello extension,
0167  *                  excluding extension type and length bytes).
0168  *
0169  * \param ctx       The ECJPAKE context to use. This must be initialized
0170  *                  and set up.
0171  * \param buf       The buffer holding the first round message. This must
0172  *                  be a readable buffer of length \p len Bytes.
0173  * \param len       The length in Bytes of \p buf.
0174  *
0175  * \return          \c 0 if successful.
0176  * \return          A negative error code on failure.
0177  */
0178 int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx,
0179                                    const unsigned char *buf,
0180                                    size_t len);
0181 
0182 /**
0183  * \brief           Generate and write the second round message
0184  *                  (TLS: contents of the Client/ServerKeyExchange).
0185  *
0186  * \param ctx       The ECJPAKE context to use. This must be initialized,
0187  *                  set up, and already have performed round one.
0188  * \param buf       The buffer to write the round two contents to.
0189  *                  This must be a writable buffer of length \p len Bytes.
0190  * \param len       The size of \p buf in Bytes.
0191  * \param olen      The address at which to store the total number of Bytes
0192  *                  written to \p buf. This must not be \c NULL.
0193  * \param f_rng     The RNG function to use. This must not be \c NULL.
0194  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0195  *                  may be \c NULL if \p f_rng doesn't use a context.
0196  *
0197  * \return          \c 0 if successful.
0198  * \return          A negative error code on failure.
0199  */
0200 int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
0201                                     unsigned char *buf, size_t len, size_t *olen,
0202                                     int (*f_rng)(void *, unsigned char *, size_t),
0203                                     void *p_rng);
0204 
0205 /**
0206  * \brief           Read and process the second round message
0207  *                  (TLS: contents of the Client/ServerKeyExchange).
0208  *
0209  * \param ctx       The ECJPAKE context to use. This must be initialized
0210  *                  and set up and already have performed round one.
0211  * \param buf       The buffer holding the second round message. This must
0212  *                  be a readable buffer of length \p len Bytes.
0213  * \param len       The length in Bytes of \p buf.
0214  *
0215  * \return          \c 0 if successful.
0216  * \return          A negative error code on failure.
0217  */
0218 int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx,
0219                                    const unsigned char *buf,
0220                                    size_t len);
0221 
0222 /**
0223  * \brief           Derive the shared secret
0224  *                  (TLS: Pre-Master Secret).
0225  *
0226  * \param ctx       The ECJPAKE context to use. This must be initialized,
0227  *                  set up and have performed both round one and two.
0228  * \param buf       The buffer to write the derived secret to. This must
0229  *                  be a writable buffer of length \p len Bytes.
0230  * \param len       The length of \p buf in Bytes.
0231  * \param olen      The address at which to store the total number of Bytes
0232  *                  written to \p buf. This must not be \c NULL.
0233  * \param f_rng     The RNG function to use. This must not be \c NULL.
0234  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0235  *                  may be \c NULL if \p f_rng doesn't use a context.
0236  *
0237  * \return          \c 0 if successful.
0238  * \return          A negative error code on failure.
0239  */
0240 int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
0241                                   unsigned char *buf, size_t len, size_t *olen,
0242                                   int (*f_rng)(void *, unsigned char *, size_t),
0243                                   void *p_rng);
0244 
0245 /**
0246  * \brief           Write the shared key material to be passed to a Key
0247  *                  Derivation Function as described in RFC8236.
0248  *
0249  * \param ctx       The ECJPAKE context to use. This must be initialized,
0250  *                  set up and have performed both round one and two.
0251  * \param buf       The buffer to write the derived secret to. This must
0252  *                  be a writable buffer of length \p len Bytes.
0253  * \param len       The length of \p buf in Bytes.
0254  * \param olen      The address at which to store the total number of bytes
0255  *                  written to \p buf. This must not be \c NULL.
0256  * \param f_rng     The RNG function to use. This must not be \c NULL.
0257  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0258  *                  may be \c NULL if \p f_rng doesn't use a context.
0259  *
0260  * \return          \c 0 if successful.
0261  * \return          A negative error code on failure.
0262  */
0263 int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx,
0264                                      unsigned char *buf, size_t len, size_t *olen,
0265                                      int (*f_rng)(void *, unsigned char *, size_t),
0266                                      void *p_rng);
0267 
0268 /**
0269  * \brief           This clears an ECJPAKE context and frees any
0270  *                  embedded data structure.
0271  *
0272  * \param ctx       The ECJPAKE context to free. This may be \c NULL,
0273  *                  in which case this function does nothing. If it is not
0274  *                  \c NULL, it must point to an initialized ECJPAKE context.
0275  */
0276 void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx);
0277 
0278 #if defined(MBEDTLS_SELF_TEST)
0279 
0280 /**
0281  * \brief          Checkup routine
0282  *
0283  * \return         0 if successful, or 1 if a test failed
0284  */
0285 int mbedtls_ecjpake_self_test(int verbose);
0286 
0287 #endif /* MBEDTLS_SELF_TEST */
0288 
0289 #endif /* MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS */
0290 
0291 #ifdef __cplusplus
0292 }
0293 #endif
0294 
0295 
0296 #endif /* ecjpake.h */