![]() |
|
|||
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 */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |