Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-27 09:37:31

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 "mbedtls/build_info.h"
0031 
0032 #include "mbedtls/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 #if !defined(MBEDTLS_ECJPAKE_ALT)
0049 /**
0050  * EC J-PAKE context structure.
0051  *
0052  * J-PAKE is a symmetric protocol, except for the identifiers used in
0053  * Zero-Knowledge Proofs, and the serialization of the second message
0054  * (KeyExchange) as defined by the Thread spec.
0055  *
0056  * In order to benefit from this symmetry, we choose a different naming
0057  * convention from the Thread v1.0 spec. Correspondence is indicated in the
0058  * description as a pair C: client name, S: server name
0059  */
0060 typedef struct mbedtls_ecjpake_context {
0061     mbedtls_md_type_t MBEDTLS_PRIVATE(md_type);          /**< Hash to use                    */
0062     mbedtls_ecp_group MBEDTLS_PRIVATE(grp);              /**< Elliptic curve                 */
0063     mbedtls_ecjpake_role MBEDTLS_PRIVATE(role);          /**< Are we client or server?       */
0064     int MBEDTLS_PRIVATE(point_format);                   /**< Format for point export        */
0065 
0066     mbedtls_ecp_point MBEDTLS_PRIVATE(Xm1);              /**< My public key 1   C: X1, S: X3 */
0067     mbedtls_ecp_point MBEDTLS_PRIVATE(Xm2);              /**< My public key 2   C: X2, S: X4 */
0068     mbedtls_ecp_point MBEDTLS_PRIVATE(Xp1);              /**< Peer public key 1 C: X3, S: X1 */
0069     mbedtls_ecp_point MBEDTLS_PRIVATE(Xp2);              /**< Peer public key 2 C: X4, S: X2 */
0070     mbedtls_ecp_point MBEDTLS_PRIVATE(Xp);               /**< Peer public key   C: Xs, S: Xc */
0071 
0072     mbedtls_mpi MBEDTLS_PRIVATE(xm1);                    /**< My private key 1  C: x1, S: x3 */
0073     mbedtls_mpi MBEDTLS_PRIVATE(xm2);                    /**< My private key 2  C: x2, S: x4 */
0074 
0075     mbedtls_mpi MBEDTLS_PRIVATE(s);                      /**< Pre-shared secret (passphrase) */
0076 } mbedtls_ecjpake_context;
0077 
0078 #else  /* MBEDTLS_ECJPAKE_ALT */
0079 #include "ecjpake_alt.h"
0080 #endif /* MBEDTLS_ECJPAKE_ALT */
0081 
0082 /**
0083  * \brief           Initialize an ECJPAKE context.
0084  *
0085  * \param ctx       The ECJPAKE context to initialize.
0086  *                  This must not be \c NULL.
0087  */
0088 void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx);
0089 
0090 /**
0091  * \brief           Set up an ECJPAKE context for use.
0092  *
0093  * \note            Currently the only values for hash/curve allowed by the
0094  *                  standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
0095  *
0096  * \param ctx       The ECJPAKE context to set up. This must be initialized.
0097  * \param role      The role of the caller. This must be either
0098  *                  #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
0099  * \param hash      The identifier of the hash function to use,
0100  *                  for example #MBEDTLS_MD_SHA256.
0101  * \param curve     The identifier of the elliptic curve to use,
0102  *                  for example #MBEDTLS_ECP_DP_SECP256R1.
0103  * \param secret    The pre-shared secret (passphrase). This must be
0104  *                  a readable not empty buffer of length \p len Bytes. It need
0105  *                  only be valid for the duration of this call.
0106  * \param len       The length of the pre-shared secret \p secret.
0107  *
0108  * \return          \c 0 if successful.
0109  * \return          A negative error code on failure.
0110  */
0111 int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx,
0112                           mbedtls_ecjpake_role role,
0113                           mbedtls_md_type_t hash,
0114                           mbedtls_ecp_group_id curve,
0115                           const unsigned char *secret,
0116                           size_t len);
0117 
0118 /**
0119  * \brief               Set the point format for future reads and writes.
0120  *
0121  * \param ctx           The ECJPAKE context to configure.
0122  * \param point_format  The point format to use:
0123  *                      #MBEDTLS_ECP_PF_UNCOMPRESSED (default)
0124  *                      or #MBEDTLS_ECP_PF_COMPRESSED.
0125  *
0126  * \return              \c 0 if successful.
0127  * \return              #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p point_format
0128  *                      is invalid.
0129  */
0130 int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx,
0131                                      int point_format);
0132 
0133 /**
0134  * \brief           Check if an ECJPAKE context is ready for use.
0135  *
0136  * \param ctx       The ECJPAKE context to check. This must be
0137  *                  initialized.
0138  *
0139  * \return          \c 0 if the context is ready for use.
0140  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
0141  */
0142 int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx);
0143 
0144 /**
0145  * \brief           Generate and write the first round message
0146  *                  (TLS: contents of the Client/ServerHello extension,
0147  *                  excluding extension type and length bytes).
0148  *
0149  * \param ctx       The ECJPAKE context to use. This must be
0150  *                  initialized and set up.
0151  * \param buf       The buffer to write the contents to. This must be a
0152  *                  writable buffer of length \p len Bytes.
0153  * \param len       The length of \p buf in Bytes.
0154  * \param olen      The address at which to store the total number
0155  *                  of Bytes written to \p buf. This must not be \c NULL.
0156  * \param f_rng     The RNG function to use. This must not be \c NULL.
0157  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0158  *                  may be \c NULL if \p f_rng doesn't use a context.
0159  *
0160  * \return          \c 0 if successful.
0161  * \return          A negative error code on failure.
0162  */
0163 int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
0164                                     unsigned char *buf, size_t len, size_t *olen,
0165                                     int (*f_rng)(void *, unsigned char *, size_t),
0166                                     void *p_rng);
0167 
0168 /**
0169  * \brief           Read and process the first round message
0170  *                  (TLS: contents of the Client/ServerHello extension,
0171  *                  excluding extension type and length bytes).
0172  *
0173  * \param ctx       The ECJPAKE context to use. This must be initialized
0174  *                  and set up.
0175  * \param buf       The buffer holding the first round message. This must
0176  *                  be a readable buffer of length \p len Bytes.
0177  * \param len       The length in Bytes of \p buf.
0178  *
0179  * \return          \c 0 if successful.
0180  * \return          A negative error code on failure.
0181  */
0182 int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx,
0183                                    const unsigned char *buf,
0184                                    size_t len);
0185 
0186 /**
0187  * \brief           Generate and write the second round message
0188  *                  (TLS: contents of the Client/ServerKeyExchange).
0189  *
0190  * \param ctx       The ECJPAKE context to use. This must be initialized,
0191  *                  set up, and already have performed round one.
0192  * \param buf       The buffer to write the round two contents to.
0193  *                  This must be a writable buffer of length \p len Bytes.
0194  * \param len       The size of \p buf in Bytes.
0195  * \param olen      The address at which to store the total number of Bytes
0196  *                  written to \p buf. This must not be \c NULL.
0197  * \param f_rng     The RNG function to use. This must not be \c NULL.
0198  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0199  *                  may be \c NULL if \p f_rng doesn't use a context.
0200  *
0201  * \return          \c 0 if successful.
0202  * \return          A negative error code on failure.
0203  */
0204 int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
0205                                     unsigned char *buf, size_t len, size_t *olen,
0206                                     int (*f_rng)(void *, unsigned char *, size_t),
0207                                     void *p_rng);
0208 
0209 /**
0210  * \brief           Read and process the second round message
0211  *                  (TLS: contents of the Client/ServerKeyExchange).
0212  *
0213  * \param ctx       The ECJPAKE context to use. This must be initialized
0214  *                  and set up and already have performed round one.
0215  * \param buf       The buffer holding the second round message. This must
0216  *                  be a readable buffer of length \p len Bytes.
0217  * \param len       The length in Bytes of \p buf.
0218  *
0219  * \return          \c 0 if successful.
0220  * \return          A negative error code on failure.
0221  */
0222 int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx,
0223                                    const unsigned char *buf,
0224                                    size_t len);
0225 
0226 /**
0227  * \brief           Derive the shared secret
0228  *                  (TLS: Pre-Master Secret).
0229  *
0230  * \param ctx       The ECJPAKE context to use. This must be initialized,
0231  *                  set up and have performed both round one and two.
0232  * \param buf       The buffer to write the derived secret to. This must
0233  *                  be a writable buffer of length \p len Bytes.
0234  * \param len       The length of \p buf in Bytes.
0235  * \param olen      The address at which to store the total number of Bytes
0236  *                  written to \p buf. This must not be \c NULL.
0237  * \param f_rng     The RNG function to use. This must not be \c NULL.
0238  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0239  *                  may be \c NULL if \p f_rng doesn't use a context.
0240  *
0241  * \return          \c 0 if successful.
0242  * \return          A negative error code on failure.
0243  */
0244 int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
0245                                   unsigned char *buf, size_t len, size_t *olen,
0246                                   int (*f_rng)(void *, unsigned char *, size_t),
0247                                   void *p_rng);
0248 
0249 /**
0250  * \brief           Write the shared key material to be passed to a Key
0251  *                  Derivation Function as described in RFC8236.
0252  *
0253  * \param ctx       The ECJPAKE context to use. This must be initialized,
0254  *                  set up and have performed both round one and two.
0255  * \param buf       The buffer to write the derived secret to. This must
0256  *                  be a writable buffer of length \p len Bytes.
0257  * \param len       The length of \p buf in Bytes.
0258  * \param olen      The address at which to store the total number of bytes
0259  *                  written to \p buf. This must not be \c NULL.
0260  * \param f_rng     The RNG function to use. This must not be \c NULL.
0261  * \param p_rng     The RNG parameter to be passed to \p f_rng. This
0262  *                  may be \c NULL if \p f_rng doesn't use a context.
0263  *
0264  * \return          \c 0 if successful.
0265  * \return          A negative error code on failure.
0266  */
0267 int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx,
0268                                      unsigned char *buf, size_t len, size_t *olen,
0269                                      int (*f_rng)(void *, unsigned char *, size_t),
0270                                      void *p_rng);
0271 
0272 /**
0273  * \brief           This clears an ECJPAKE context and frees any
0274  *                  embedded data structure.
0275  *
0276  * \param ctx       The ECJPAKE context to free. This may be \c NULL,
0277  *                  in which case this function does nothing. If it is not
0278  *                  \c NULL, it must point to an initialized ECJPAKE context.
0279  */
0280 void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx);
0281 
0282 #if defined(MBEDTLS_SELF_TEST)
0283 
0284 /**
0285  * \brief          Checkup routine
0286  *
0287  * \return         0 if successful, or 1 if a test failed
0288  */
0289 int mbedtls_ecjpake_self_test(int verbose);
0290 
0291 #endif /* MBEDTLS_SELF_TEST */
0292 
0293 #ifdef __cplusplus
0294 }
0295 #endif
0296 
0297 
0298 #endif /* ecjpake.h */