blob: 1a9844249c70eb62b8ea2e9840f716c2d30fc75c [file] [log] [blame]
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001/**
2 * \file ecjpake.h
3 *
4 * \brief Elliptic curve J-PAKE
Darryl Greena40a1012018-01-05 15:33:17 +00005 */
6/*
Bence Szépkúti1e148272020-08-07 13:07:28 +02007 * Copyright The Mbed TLS Contributors
Dave Rodgman7ff79652023-11-03 12:04:52 +00008 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02009 */
10#ifndef MBEDTLS_ECJPAKE_H
11#define MBEDTLS_ECJPAKE_H
12
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020013/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +020014 * J-PAKE is a password-authenticated key exchange that allows deriving a
15 * strong shared secret from a (potentially low entropy) pre-shared
16 * passphrase, with forward secrecy and mutual authentication.
17 * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
18 *
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +020019 * This file implements the Elliptic Curve variant of J-PAKE,
20 * as defined in Chapter 7.4 of the Thread v1.0 Specification,
21 * available to members of the Thread Group http://threadgroup.org/
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +020022 *
23 * As the J-PAKE algorithm is inherently symmetric, so is our API.
24 * Each party needs to send its first round message, in any order, to the
25 * other party, then each sends its second round message, in any order.
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +020026 * The payloads are serialized in a way suitable for use in TLS, but could
27 * also be use outside TLS.
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020028 */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050029#if !defined(MBEDTLS_CONFIG_FILE)
Jaeden Ameroc49fbbf2019-07-04 20:01:14 +010030#include "mbedtls/config.h"
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050031#else
32#include MBEDTLS_CONFIG_FILE
33#endif
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020034
Jaeden Ameroc49fbbf2019-07-04 20:01:14 +010035#include "mbedtls/ecp.h"
36#include "mbedtls/md.h"
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020037
38#ifdef __cplusplus
39extern "C" {
40#endif
41
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020042/**
43 * Roles in the EC J-PAKE exchange
44 */
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +020045typedef enum {
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020046 MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
47 MBEDTLS_ECJPAKE_SERVER, /**< Server */
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +020048} mbedtls_ecjpake_role;
49
Ron Eldor4e6d55d2018-02-07 16:36:15 +020050#if !defined(MBEDTLS_ECJPAKE_ALT)
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020051/**
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020052 * EC J-PAKE context structure.
53 *
54 * J-PAKE is a symmetric protocol, except for the identifiers used in
55 * Zero-Knowledge Proofs, and the serialization of the second message
56 * (KeyExchange) as defined by the Thread spec.
57 *
58 * In order to benefit from this symmetry, we choose a different naming
Shaun Case0e7791f2021-12-20 21:14:10 -080059 * convention from the Thread v1.0 spec. Correspondence is indicated in the
Simon Butcher5b331b92016-01-03 16:14:14 +000060 * description as a pair C: client name, S: server name
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020061 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010062typedef struct mbedtls_ecjpake_context {
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020063 const mbedtls_md_info_t *md_info; /**< Hash to use */
64 mbedtls_ecp_group grp; /**< Elliptic curve */
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +020065 mbedtls_ecjpake_role role; /**< Are we client or server? */
Robert Cragie7cdad772015-10-02 13:31:41 +010066 int point_format; /**< Format for point export */
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020067
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020068 mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */
69 mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */
70 mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */
71 mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */
72 mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020073
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020074 mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */
75 mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +020076
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020077 mbedtls_mpi s; /**< Pre-shared secret (passphrase) */
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020078} mbedtls_ecjpake_context;
79
Ron Eldor4e6d55d2018-02-07 16:36:15 +020080#else /* MBEDTLS_ECJPAKE_ALT */
81#include "ecjpake_alt.h"
82#endif /* MBEDTLS_ECJPAKE_ALT */
83
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +020084/**
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050085 * \brief Initialize an ECJPAKE context.
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020086 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050087 * \param ctx The ECJPAKE context to initialize.
88 * This must not be \c NULL.
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020089 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010090void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020091
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +020092/**
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050093 * \brief Set up an ECJPAKE context for use.
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020094 *
95 * \note Currently the only values for hash/curve allowed by the
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050096 * standard are #MBEDTLS_MD_SHA256/#MBEDTLS_ECP_DP_SECP256R1.
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020097 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050098 * \param ctx The ECJPAKE context to set up. This must be initialized.
99 * \param role The role of the caller. This must be either
100 * #MBEDTLS_ECJPAKE_CLIENT or #MBEDTLS_ECJPAKE_SERVER.
101 * \param hash The identifier of the hash function to use,
102 * for example #MBEDTLS_MD_SHA256.
103 * \param curve The identifier of the elliptic curve to use,
104 * for example #MBEDTLS_ECP_DP_SECP256R1.
105 * \param secret The pre-shared secret (passphrase). This must be
106 * a readable buffer of length \p len Bytes. It need
107 * only be valid for the duration of this call.
108 * \param len The length of the pre-shared secret \p secret.
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200109 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500110 * \return \c 0 if successful.
111 * \return A negative error code on failure.
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200112 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100113int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx,
114 mbedtls_ecjpake_role role,
115 mbedtls_md_type_t hash,
116 mbedtls_ecp_group_id curve,
117 const unsigned char *secret,
118 size_t len);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200119
Andres Amaya Garciaaf610a02016-12-14 10:13:43 +0000120/**
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500121 * \brief Check if an ECJPAKE context is ready for use.
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200122 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500123 * \param ctx The ECJPAKE context to check. This must be
124 * initialized.
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200125 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500126 * \return \c 0 if the context is ready for use.
127 * \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise.
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200128 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx);
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200130
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200131/**
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200132 * \brief Generate and write the first round message
133 * (TLS: contents of the Client/ServerHello extension,
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500134 * excluding extension type and length bytes).
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200135 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500136 * \param ctx The ECJPAKE context to use. This must be
137 * initialized and set up.
138 * \param buf The buffer to write the contents to. This must be a
139 * writable buffer of length \p len Bytes.
140 * \param len The length of \p buf in Bytes.
141 * \param olen The address at which to store the total number
142 * of Bytes written to \p buf. This must not be \c NULL.
143 * \param f_rng The RNG function to use. This must not be \c NULL.
144 * \param p_rng The RNG parameter to be passed to \p f_rng. This
145 * may be \c NULL if \p f_rng doesn't use a context.
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200146 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500147 * \return \c 0 if successful.
148 * \return A negative error code on failure.
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200149 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100150int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
151 unsigned char *buf, size_t len, size_t *olen,
152 int (*f_rng)(void *, unsigned char *, size_t),
153 void *p_rng);
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200154
155/**
156 * \brief Read and process the first round message
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200157 * (TLS: contents of the Client/ServerHello extension,
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500158 * excluding extension type and length bytes).
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200159 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500160 * \param ctx The ECJPAKE context to use. This must be initialized
161 * and set up.
162 * \param buf The buffer holding the first round message. This must
163 * be a readable buffer of length \p len Bytes.
164 * \param len The length in Bytes of \p buf.
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200165 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500166 * \return \c 0 if successful.
167 * \return A negative error code on failure.
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200168 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100169int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx,
170 const unsigned char *buf,
171 size_t len);
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200172
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200173/**
174 * \brief Generate and write the second round message
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500175 * (TLS: contents of the Client/ServerKeyExchange).
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200176 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500177 * \param ctx The ECJPAKE context to use. This must be initialized,
178 * set up, and already have performed round one.
179 * \param buf The buffer to write the round two contents to.
180 * This must be a writable buffer of length \p len Bytes.
181 * \param len The size of \p buf in Bytes.
182 * \param olen The address at which to store the total number of Bytes
183 * written to \p buf. This must not be \c NULL.
184 * \param f_rng The RNG function to use. This must not be \c NULL.
185 * \param p_rng The RNG parameter to be passed to \p f_rng. This
186 * may be \c NULL if \p f_rng doesn't use a context.
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200187 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500188 * \return \c 0 if successful.
189 * \return A negative error code on failure.
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200190 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100191int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
192 unsigned char *buf, size_t len, size_t *olen,
193 int (*f_rng)(void *, unsigned char *, size_t),
194 void *p_rng);
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200195
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200196/**
197 * \brief Read and process the second round message
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500198 * (TLS: contents of the Client/ServerKeyExchange).
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200199 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500200 * \param ctx The ECJPAKE context to use. This must be initialized
201 * and set up and already have performed round one.
202 * \param buf The buffer holding the second round message. This must
203 * be a readable buffer of length \p len Bytes.
204 * \param len The length in Bytes of \p buf.
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200205 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500206 * \return \c 0 if successful.
207 * \return A negative error code on failure.
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200208 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx,
210 const unsigned char *buf,
211 size_t len);
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200212
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200213/**
214 * \brief Derive the shared secret
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500215 * (TLS: Pre-Master Secret).
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200216 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500217 * \param ctx The ECJPAKE context to use. This must be initialized,
218 * set up and have performed both round one and two.
219 * \param buf The buffer to write the derived secret to. This must
220 * be a writable buffer of length \p len Bytes.
221 * \param len The length of \p buf in Bytes.
222 * \param olen The address at which to store the total number of Bytes
223 * written to \p buf. This must not be \c NULL.
224 * \param f_rng The RNG function to use. This must not be \c NULL.
225 * \param p_rng The RNG parameter to be passed to \p f_rng. This
226 * may be \c NULL if \p f_rng doesn't use a context.
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200227 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500228 * \return \c 0 if successful.
229 * \return A negative error code on failure.
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200230 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100231int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
232 unsigned char *buf, size_t len, size_t *olen,
233 int (*f_rng)(void *, unsigned char *, size_t),
234 void *p_rng);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200235
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200236/**
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500237 * \brief This clears an ECJPAKE context and frees any
238 * embedded data structure.
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200239 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500240 * \param ctx The ECJPAKE context to free. This may be \c NULL,
241 * in which case this function does nothing. If it is not
242 * \c NULL, it must point to an initialized ECJPAKE context.
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200243 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100244void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx);
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200245
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200246#if defined(MBEDTLS_SELF_TEST)
Hanno Becker616d1ca2018-01-24 10:25:05 +0000247
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200248/**
249 * \brief Checkup routine
250 *
251 * \return 0 if successful, or 1 if a test failed
252 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100253int mbedtls_ecjpake_self_test(int verbose);
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200254
Ron Eldor4e6d55d2018-02-07 16:36:15 +0200255#endif /* MBEDTLS_SELF_TEST */
256
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200257#ifdef __cplusplus
258}
259#endif
260
Hanno Becker616d1ca2018-01-24 10:25:05 +0000261
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200262#endif /* ecjpake.h */