1 /**
2  * \file ecjpake.h
3  *
4  * \brief Elliptic curve J-PAKE
5  *
6  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
7  *  SPDX-License-Identifier: Apache-2.0
8  *
9  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
10  *  not use this file except in compliance with the License.
11  *  You may obtain a copy of the License at
12  *
13  *  http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *  Unless required by applicable law or agreed to in writing, software
16  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *  See the License for the specific language governing permissions and
19  *  limitations under the License.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 #ifndef MBEDTLS_ECJPAKE_H
24 #define MBEDTLS_ECJPAKE_H
25 
26 /*
27  * J-PAKE is a password-authenticated key exchange that allows deriving a
28  * strong shared secret from a (potentially low entropy) pre-shared
29  * passphrase, with forward secrecy and mutual authentication.
30  * https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
31  *
32  * This file implements the Elliptic Curve variant of J-PAKE,
33  * as defined in Chapter 7.4 of the Thread v1.0 Specification,
34  * available to members of the Thread Group http://threadgroup.org/
35  *
36  * As the J-PAKE algorithm is inherently symmetric, so is our API.
37  * Each party needs to send its first round message, in any order, to the
38  * other party, then each sends its second round message, in any order.
39  * The payloads are serialized in a way suitable for use in TLS, but could
40  * also be use outside TLS.
41  */
42 
43 #include "ecp.h"
44 #include "md.h"
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 /**
51  * Roles in the EC J-PAKE exchange
52  */
53 typedef enum {
54     MBEDTLS_ECJPAKE_CLIENT = 0,         /**< Client                         */
55     MBEDTLS_ECJPAKE_SERVER,             /**< Server                         */
56 } mbedtls_ecjpake_role;
57 
58 /**
59  * EC J-PAKE context structure.
60  *
61  * J-PAKE is a symmetric protocol, except for the identifiers used in
62  * Zero-Knowledge Proofs, and the serialization of the second message
63  * (KeyExchange) as defined by the Thread spec.
64  *
65  * In order to benefit from this symmetry, we choose a different naming
66  * convetion from the Thread v1.0 spec. Correspondance is indicated in the
67  * description as a pair C: client name, S: server name
68  */
69 typedef struct
70 {
71     const mbedtls_md_info_t *md_info;   /**< Hash to use                    */
72     mbedtls_ecp_group grp;              /**< Elliptic curve                 */
73     mbedtls_ecjpake_role role;          /**< Are we client or server?       */
74     int point_format;                   /**< Format for point export        */
75 
76     mbedtls_ecp_point Xm1;              /**< My public key 1   C: X1, S: X3 */
77     mbedtls_ecp_point Xm2;              /**< My public key 2   C: X2, S: X4 */
78     mbedtls_ecp_point Xp1;              /**< Peer public key 1 C: X3, S: X1 */
79     mbedtls_ecp_point Xp2;              /**< Peer public key 2 C: X4, S: X2 */
80     mbedtls_ecp_point Xp;               /**< Peer public key   C: Xs, S: Xc */
81 
82     mbedtls_mpi xm1;                    /**< My private key 1  C: x1, S: x3 */
83     mbedtls_mpi xm2;                    /**< My private key 2  C: x2, S: x4 */
84 
85     mbedtls_mpi s;                      /**< Pre-shared secret (passphrase) */
86 } mbedtls_ecjpake_context;
87 
88 /**
89  * \brief           Initialize a context
90  *                  (just makes it ready for setup() or free()).
91  *
92  * \param ctx       context to initialize
93  */
94 void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
95 
96 /**
97  * \brief           Set up a context for use
98  *
99  * \note            Currently the only values for hash/curve allowed by the
100  *                  standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
101  *
102  * \param ctx       context to set up
103  * \param role      Our role: client or server
104  * \param hash      hash function to use (MBEDTLS_MD_XXX)
105  * \param curve     elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
106  * \param secret    pre-shared secret (passphrase)
107  * \param len       length of the shared secret
108  *
109  * \return          0 if successfull,
110  *                  a negative error code otherwise
111  */
112 int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
113                            mbedtls_ecjpake_role role,
114                            mbedtls_md_type_t hash,
115                            mbedtls_ecp_group_id curve,
116                            const unsigned char *secret,
117                            size_t len );
118 
119 /*
120  * \brief           Check if a context is ready for use
121  *
122  * \param ctx       Context to check
123  *
124  * \return          0 if the context is ready for use,
125  *                  MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
126  */
127 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
128 
129 /**
130  * \brief           Generate and write the first round message
131  *                  (TLS: contents of the Client/ServerHello extension,
132  *                  excluding extension type and length bytes)
133  *
134  * \param ctx       Context to use
135  * \param buf       Buffer to write the contents to
136  * \param len       Buffer size
137  * \param olen      Will be updated with the number of bytes written
138  * \param f_rng     RNG function
139  * \param p_rng     RNG parameter
140  *
141  * \return          0 if successfull,
142  *                  a negative error code otherwise
143  */
144 int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
145                             unsigned char *buf, size_t len, size_t *olen,
146                             int (*f_rng)(void *, unsigned char *, size_t),
147                             void *p_rng );
148 
149 /**
150  * \brief           Read and process the first round message
151  *                  (TLS: contents of the Client/ServerHello extension,
152  *                  excluding extension type and length bytes)
153  *
154  * \param ctx       Context to use
155  * \param buf       Pointer to extension contents
156  * \param len       Extension length
157  *
158  * \return          0 if successfull,
159  *                  a negative error code otherwise
160  */
161 int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
162                                     const unsigned char *buf,
163                                     size_t len );
164 
165 /**
166  * \brief           Generate and write the second round message
167  *                  (TLS: contents of the Client/ServerKeyExchange)
168  *
169  * \param ctx       Context to use
170  * \param buf       Buffer to write the contents to
171  * \param len       Buffer size
172  * \param olen      Will be updated with the number of bytes written
173  * \param f_rng     RNG function
174  * \param p_rng     RNG parameter
175  *
176  * \return          0 if successfull,
177  *                  a negative error code otherwise
178  */
179 int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
180                             unsigned char *buf, size_t len, size_t *olen,
181                             int (*f_rng)(void *, unsigned char *, size_t),
182                             void *p_rng );
183 
184 /**
185  * \brief           Read and process the second round message
186  *                  (TLS: contents of the Client/ServerKeyExchange)
187  *
188  * \param ctx       Context to use
189  * \param buf       Pointer to the message
190  * \param len       Message length
191  *
192  * \return          0 if successfull,
193  *                  a negative error code otherwise
194  */
195 int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
196                                     const unsigned char *buf,
197                                     size_t len );
198 
199 /**
200  * \brief           Derive the shared secret
201  *                  (TLS: Pre-Master Secret)
202  *
203  * \param ctx       Context to use
204  * \param buf       Buffer to write the contents to
205  * \param len       Buffer size
206  * \param olen      Will be updated with the number of bytes written
207  * \param f_rng     RNG function
208  * \param p_rng     RNG parameter
209  *
210  * \return          0 if successfull,
211  *                  a negative error code otherwise
212  */
213 int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
214                             unsigned char *buf, size_t len, size_t *olen,
215                             int (*f_rng)(void *, unsigned char *, size_t),
216                             void *p_rng );
217 
218 /**
219  * \brief           Free a context's content
220  *
221  * \param ctx       context to free
222  */
223 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
224 
225 #if defined(MBEDTLS_SELF_TEST)
226 /**
227  * \brief          Checkup routine
228  *
229  * \return         0 if successful, or 1 if a test failed
230  */
231 int mbedtls_ecjpake_self_test( int verbose );
232 #endif
233 
234 #ifdef __cplusplus
235 }
236 #endif
237 
238 #endif /* ecjpake.h */
239