1 /** 2 * \file ecjpake.h 3 * 4 * \brief Elliptic curve J-PAKE 5 */ 6 /* 7 * Copyright The Mbed TLS Contributors 8 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 9 */ 10 #ifndef MBEDTLS_ECJPAKE_H 11 #define MBEDTLS_ECJPAKE_H 12 #include "mbedtls/private_access.h" 13 14 /* 15 * J-PAKE is a password-authenticated key exchange that allows deriving a 16 * strong shared secret from a (potentially low entropy) pre-shared 17 * passphrase, with forward secrecy and mutual authentication. 18 * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling 19 * 20 * This file implements the Elliptic Curve variant of J-PAKE, 21 * as defined in Chapter 7.4 of the Thread v1.0 Specification, 22 * available to members of the Thread Group http://threadgroup.org/ 23 * 24 * As the J-PAKE algorithm is inherently symmetric, so is our API. 25 * Each party needs to send its first round message, in any order, to the 26 * other party, then each sends its second round message, in any order. 27 * The payloads are serialized in a way suitable for use in TLS, but could 28 * also be use outside TLS. 29 */ 30 #include "mbedtls/build_info.h" 31 32 #include "mbedtls/ecp.h" 33 #include "mbedtls/md.h" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * Roles in the EC J-PAKE exchange 41 */ 42 typedef enum { 43 MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */ 44 MBEDTLS_ECJPAKE_SERVER, /**< Server */ 45 MBEDTLS_ECJPAKE_NONE, /**< Undefined */ 46 } mbedtls_ecjpake_role; 47 48 #if !defined(MBEDTLS_ECJPAKE_ALT) 49 /** 50 * EC J-PAKE context structure. 51 * 52 * J-PAKE is a symmetric protocol, except for the identifiers used in 53 * Zero-Knowledge Proofs, and the serialization of the second message 54 * (KeyExchange) as defined by the Thread spec. 55 * 56 * In order to benefit from this symmetry, we choose a different naming 57 * convention from the Thread v1.0 spec. Correspondence is indicated in the 58 * description as a pair C: client name, S: server name 59 */ 60 typedef struct mbedtls_ecjpake_context { 61 mbedtls_md_type_t MBEDTLS_PRIVATE(md_type); /**< Hash to use */ 62 mbedtls_ecp_group MBEDTLS_PRIVATE(grp); /**< Elliptic curve */ 63 mbedtls_ecjpake_role MBEDTLS_PRIVATE(role); /**< Are we client or server? */ 64 int MBEDTLS_PRIVATE(point_format); /**< Format for point export */ 65 66 mbedtls_ecp_point MBEDTLS_PRIVATE(Xm1); /**< My public key 1 C: X1, S: X3 */ 67 mbedtls_ecp_point MBEDTLS_PRIVATE(Xm2); /**< My public key 2 C: X2, S: X4 */ 68 mbedtls_ecp_point MBEDTLS_PRIVATE(Xp1); /**< Peer public key 1 C: X3, S: X1 */ 69 mbedtls_ecp_point MBEDTLS_PRIVATE(Xp2); /**< Peer public key 2 C: X4, S: X2 */ 70 mbedtls_ecp_point MBEDTLS_PRIVATE(Xp); /**< Peer public key C: Xs, S: Xc */ 71 72 mbedtls_mpi MBEDTLS_PRIVATE(xm1); /**< My private key 1 C: x1, S: x3 */ 73 mbedtls_mpi MBEDTLS_PRIVATE(xm2); /**< My private key 2 C: x2, S: x4 */ 74 75 mbedtls_mpi MBEDTLS_PRIVATE(s); /**< Pre-shared secret (passphrase) */ 76 } mbedtls_ecjpake_context; 77 78 #else /* MBEDTLS_ECJPAKE_ALT */ 79 #include "ecjpake_alt.h" 80 #endif /* MBEDTLS_ECJPAKE_ALT */ 81 82 /** 83 * \brief Initialize an ECJPAKE context. 84 * 85 * \param ctx The ECJPAKE context to initialize. 86 * This must not be \c NULL. 87 */ 88 void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx); 89 90 /** 91 * \brief Set up an ECJPAKE context for use. 92 * 93 * \note Currently the only values for hash/curve allowed by the 94 * standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1. 95 * 96 * \param ctx The ECJPAKE context to set up. This must be initialized. 97 * \param role The role of the caller. This must be either 98 * #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER. 99 * \param hash The identifier of the hash function to use, 100 * for example #MBEDTLS_MD_SHA256. 101 * \param curve The identifier of the elliptic curve to use, 102 * for example #MBEDTLS_ECP_DP_SECP256R1. 103 * \param secret The pre-shared secret (passphrase). This must be 104 * a readable not empty buffer of length \p len Bytes. It need 105 * only be valid for the duration of this call. 106 * \param len The length of the pre-shared secret \p secret. 107 * 108 * \return \c 0 if successful. 109 * \return A negative error code on failure. 110 */ 111 int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx, 112 mbedtls_ecjpake_role role, 113 mbedtls_md_type_t hash, 114 mbedtls_ecp_group_id curve, 115 const unsigned char *secret, 116 size_t len); 117 118 /** 119 * \brief Set the point format for future reads and writes. 120 * 121 * \param ctx The ECJPAKE context to configure. 122 * \param point_format The point format to use: 123 * #MBEDTLS_ECP_PF_UNCOMPRESSED (default) 124 * or #MBEDTLS_ECP_PF_COMPRESSED. 125 * 126 * \return \c 0 if successful. 127 * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p point_format 128 * is invalid. 129 */ 130 int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx, 131 int point_format); 132 133 /** 134 * \brief Check if an ECJPAKE context is ready for use. 135 * 136 * \param ctx The ECJPAKE context to check. This must be 137 * initialized. 138 * 139 * \return \c 0 if the context is ready for use. 140 * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise. 141 */ 142 int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx); 143 144 /** 145 * \brief Generate and write the first round message 146 * (TLS: contents of the Client/ServerHello extension, 147 * excluding extension type and length bytes). 148 * 149 * \param ctx The ECJPAKE context to use. This must be 150 * initialized and set up. 151 * \param buf The buffer to write the contents to. This must be a 152 * writable buffer of length \p len Bytes. 153 * \param len The length of \p buf in Bytes. 154 * \param olen The address at which to store the total number 155 * of Bytes written to \p buf. This must not be \c NULL. 156 * \param f_rng The RNG function to use. This must not be \c NULL. 157 * \param p_rng The RNG parameter to be passed to \p f_rng. This 158 * may be \c NULL if \p f_rng doesn't use a context. 159 * 160 * \return \c 0 if successful. 161 * \return A negative error code on failure. 162 */ 163 int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx, 164 unsigned char *buf, size_t len, size_t *olen, 165 int (*f_rng)(void *, unsigned char *, size_t), 166 void *p_rng); 167 168 /** 169 * \brief Read and process the first round message 170 * (TLS: contents of the Client/ServerHello extension, 171 * excluding extension type and length bytes). 172 * 173 * \param ctx The ECJPAKE context to use. This must be initialized 174 * and set up. 175 * \param buf The buffer holding the first round message. This must 176 * be a readable buffer of length \p len Bytes. 177 * \param len The length in Bytes of \p buf. 178 * 179 * \return \c 0 if successful. 180 * \return A negative error code on failure. 181 */ 182 int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx, 183 const unsigned char *buf, 184 size_t len); 185 186 /** 187 * \brief Generate and write the second round message 188 * (TLS: contents of the Client/ServerKeyExchange). 189 * 190 * \param ctx The ECJPAKE context to use. This must be initialized, 191 * set up, and already have performed round one. 192 * \param buf The buffer to write the round two contents to. 193 * This must be a writable buffer of length \p len Bytes. 194 * \param len The size of \p buf in Bytes. 195 * \param olen The address at which to store the total number of Bytes 196 * written to \p buf. This must not be \c NULL. 197 * \param f_rng The RNG function to use. This must not be \c NULL. 198 * \param p_rng The RNG parameter to be passed to \p f_rng. This 199 * may be \c NULL if \p f_rng doesn't use a context. 200 * 201 * \return \c 0 if successful. 202 * \return A negative error code on failure. 203 */ 204 int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx, 205 unsigned char *buf, size_t len, size_t *olen, 206 int (*f_rng)(void *, unsigned char *, size_t), 207 void *p_rng); 208 209 /** 210 * \brief Read and process the second round message 211 * (TLS: contents of the Client/ServerKeyExchange). 212 * 213 * \param ctx The ECJPAKE context to use. This must be initialized 214 * and set up and already have performed round one. 215 * \param buf The buffer holding the second round message. This must 216 * be a readable buffer of length \p len Bytes. 217 * \param len The length in Bytes of \p buf. 218 * 219 * \return \c 0 if successful. 220 * \return A negative error code on failure. 221 */ 222 int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx, 223 const unsigned char *buf, 224 size_t len); 225 226 /** 227 * \brief Derive the shared secret 228 * (TLS: Pre-Master Secret). 229 * 230 * \param ctx The ECJPAKE context to use. This must be initialized, 231 * set up and have performed both round one and two. 232 * \param buf The buffer to write the derived secret to. This must 233 * be a writable buffer of length \p len Bytes. 234 * \param len The length of \p buf in Bytes. 235 * \param olen The address at which to store the total number of Bytes 236 * written to \p buf. This must not be \c NULL. 237 * \param f_rng The RNG function to use. This must not be \c NULL. 238 * \param p_rng The RNG parameter to be passed to \p f_rng. This 239 * may be \c NULL if \p f_rng doesn't use a context. 240 * 241 * \return \c 0 if successful. 242 * \return A negative error code on failure. 243 */ 244 int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx, 245 unsigned char *buf, size_t len, size_t *olen, 246 int (*f_rng)(void *, unsigned char *, size_t), 247 void *p_rng); 248 249 /** 250 * \brief Write the shared key material to be passed to a Key 251 * Derivation Function as described in RFC8236. 252 * 253 * \param ctx The ECJPAKE context to use. This must be initialized, 254 * set up and have performed both round one and two. 255 * \param buf The buffer to write the derived secret to. This must 256 * be a writable buffer of length \p len Bytes. 257 * \param len The length of \p buf in Bytes. 258 * \param olen The address at which to store the total number of bytes 259 * written to \p buf. This must not be \c NULL. 260 * \param f_rng The RNG function to use. This must not be \c NULL. 261 * \param p_rng The RNG parameter to be passed to \p f_rng. This 262 * may be \c NULL if \p f_rng doesn't use a context. 263 * 264 * \return \c 0 if successful. 265 * \return A negative error code on failure. 266 */ 267 int mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx, 268 unsigned char *buf, size_t len, size_t *olen, 269 int (*f_rng)(void *, unsigned char *, size_t), 270 void *p_rng); 271 272 /** 273 * \brief This clears an ECJPAKE context and frees any 274 * embedded data structure. 275 * 276 * \param ctx The ECJPAKE context to free. This may be \c NULL, 277 * in which case this function does nothing. If it is not 278 * \c NULL, it must point to an initialized ECJPAKE context. 279 */ 280 void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx); 281 282 #if defined(MBEDTLS_SELF_TEST) 283 284 /** 285 * \brief Checkup routine 286 * 287 * \return 0 if successful, or 1 if a test failed 288 */ 289 int mbedtls_ecjpake_self_test(int verbose); 290 291 #endif /* MBEDTLS_SELF_TEST */ 292 293 #ifdef __cplusplus 294 } 295 #endif 296 297 298 #endif /* ecjpake.h */ 299