blob: 09bd1fbc4c86b6f762433cae364a94da67cbd08a [file] [log] [blame]
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001/*
2 * Elliptic curve J-PAKE
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Bence Szépkúti4e9f7122020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *
Bence Szépkúti4e9f7122020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020046 * This file is part of mbed TLS (https://tls.mbed.org)
47 */
48
49/*
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020050 * References in the code are to the Thread v1.0 Specification,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +020051 * available to members of the Thread Group http://threadgroup.org/
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020052 */
53
54#if !defined(MBEDTLS_CONFIG_FILE)
55#include "mbedtls/config.h"
56#else
57#include MBEDTLS_CONFIG_FILE
58#endif
59
60#if defined(MBEDTLS_ECJPAKE_C)
61
62#include "mbedtls/ecjpake.h"
63
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020064#include <string.h>
65
Hanno Becker616d1ca2018-01-24 10:25:05 +000066#if !defined(MBEDTLS_ECJPAKE_ALT)
67
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020068/*
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +020069 * Convert a mbedtls_ecjpake_role to identifier string
70 */
71static const char * const ecjpake_id[] = {
72 "client",
73 "server"
74};
75
76#define ID_MINE ( ecjpake_id[ ctx->role ] )
77#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
78
79/*
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020080 * Initialize context
81 */
82void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
83{
84 if( ctx == NULL )
85 return;
86
87 ctx->md_info = NULL;
88 mbedtls_ecp_group_init( &ctx->grp );
Manuel Pégourié-Gonnardb7da1942015-10-19 13:35:22 +020089 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020090
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020091 mbedtls_ecp_point_init( &ctx->Xm1 );
92 mbedtls_ecp_point_init( &ctx->Xm2 );
93 mbedtls_ecp_point_init( &ctx->Xp1 );
94 mbedtls_ecp_point_init( &ctx->Xp2 );
95 mbedtls_ecp_point_init( &ctx->Xp );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020096
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020097 mbedtls_mpi_init( &ctx->xm1 );
98 mbedtls_mpi_init( &ctx->xm2 );
99 mbedtls_mpi_init( &ctx->s );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200100}
101
102/*
103 * Free context
104 */
105void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
106{
107 if( ctx == NULL )
108 return;
109
110 ctx->md_info = NULL;
111 mbedtls_ecp_group_free( &ctx->grp );
112
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200113 mbedtls_ecp_point_free( &ctx->Xm1 );
114 mbedtls_ecp_point_free( &ctx->Xm2 );
115 mbedtls_ecp_point_free( &ctx->Xp1 );
116 mbedtls_ecp_point_free( &ctx->Xp2 );
117 mbedtls_ecp_point_free( &ctx->Xp );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200118
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200119 mbedtls_mpi_free( &ctx->xm1 );
120 mbedtls_mpi_free( &ctx->xm2 );
121 mbedtls_mpi_free( &ctx->s );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200122}
123
124/*
125 * Setup context
126 */
127int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200128 mbedtls_ecjpake_role role,
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200129 mbedtls_md_type_t hash,
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200130 mbedtls_ecp_group_id curve,
131 const unsigned char *secret,
132 size_t len )
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200133{
134 int ret;
135
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200136 ctx->role = role;
137
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200138 if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
139 return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
140
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200141 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200142
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200143 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200144
145cleanup:
146 if( ret != 0 )
147 mbedtls_ecjpake_free( ctx );
148
149 return( ret );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200150}
151
152/*
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200153 * Check if context is ready for use
154 */
155int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
156{
157 if( ctx->md_info == NULL ||
158 ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
159 ctx->s.p == NULL )
160 {
161 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
162 }
163
164 return( 0 );
165}
166
167/*
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200168 * Write a point plus its length to a buffer
169 */
170static int ecjpake_write_len_point( unsigned char **p,
171 const unsigned char *end,
172 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100173 const int pf,
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200174 const mbedtls_ecp_point *P )
175{
176 int ret;
177 size_t len;
178
179 /* Need at least 4 for length plus 1 for point */
180 if( end < *p || end - *p < 5 )
181 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
182
Robert Cragie7cdad772015-10-02 13:31:41 +0100183 ret = mbedtls_ecp_point_write_binary( grp, P, pf,
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200184 &len, *p + 4, end - ( *p + 4 ) );
185 if( ret != 0 )
186 return( ret );
187
188 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
189 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
190 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
191 (*p)[3] = (unsigned char)( ( len ) & 0xFF );
192
193 *p += 4 + len;
194
195 return( 0 );
196}
197
198/*
199 * Size of the temporary buffer for ecjpake_hash:
Manuel Pégourié-Gonnard4b20c0e2015-10-20 16:16:38 +0200200 * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200201 */
Manuel Pégourié-Gonnard4b20c0e2015-10-20 16:16:38 +0200202#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200203
204/*
205 * Compute hash for ZKP (7.4.2.2.2.1)
206 */
207static int ecjpake_hash( const mbedtls_md_info_t *md_info,
208 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100209 const int pf,
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200210 const mbedtls_ecp_point *G,
211 const mbedtls_ecp_point *V,
212 const mbedtls_ecp_point *X,
213 const char *id,
214 mbedtls_mpi *h )
215{
216 int ret;
217 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
218 unsigned char *p = buf;
219 const unsigned char *end = buf + sizeof( buf );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200220 const size_t id_len = strlen( id );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200221 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
222
223 /* Write things to temporary buffer */
Robert Cragie7cdad772015-10-02 13:31:41 +0100224 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
225 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
226 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200227
Manuel Pégourié-Gonnard4b20c0e2015-10-20 16:16:38 +0200228 if( end - p < 4 )
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200229 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
230
231 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
232 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
233 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
234 *p++ = (unsigned char)( ( id_len ) & 0xFF );
235
Manuel Pégourié-Gonnard4b20c0e2015-10-20 16:16:38 +0200236 if( end < p || (size_t)( end - p ) < id_len )
237 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
238
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200239 memcpy( p, id, id_len );
240 p += id_len;
241
242 /* Compute hash */
k-stachowiak202b1df2019-06-28 14:14:02 +0200243 MBEDTLS_MPI_CHK( mbedtls_md( md_info, buf, p - buf, hash ) );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200244
245 /* Turn it into an integer mod n */
246 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
247 mbedtls_md_get_size( md_info ) ) );
248 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
249
250cleanup:
251 return( ret );
252}
253
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200254/*
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200255 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
256 */
257static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
258 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100259 const int pf,
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200260 const mbedtls_ecp_point *G,
261 const mbedtls_ecp_point *X,
262 const char *id,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200263 const unsigned char **p,
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200264 const unsigned char *end )
265{
266 int ret;
267 mbedtls_ecp_point V, VV;
268 mbedtls_mpi r, h;
269 size_t r_len;
270
271 mbedtls_ecp_point_init( &V );
272 mbedtls_ecp_point_init( &VV );
273 mbedtls_mpi_init( &r );
274 mbedtls_mpi_init( &h );
275
276 /*
277 * struct {
278 * ECPoint V;
279 * opaque r<1..2^8-1>;
280 * } ECSchnorrZKP;
281 */
282 if( end < *p )
283 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
284
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200285 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200286
287 if( end < *p || (size_t)( end - *p ) < 1 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200288 {
289 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
290 goto cleanup;
291 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200292
293 r_len = *(*p)++;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200294
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200295 if( end < *p || (size_t)( end - *p ) < r_len )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200296 {
297 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
298 goto cleanup;
299 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200300
301 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
302 *p += r_len;
303
304 /*
305 * Verification
306 */
Robert Cragie7cdad772015-10-02 13:31:41 +0100307 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200308 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
309 &VV, &h, X, &r, G ) );
310
311 if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200312 {
313 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
314 goto cleanup;
315 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200316
317cleanup:
318 mbedtls_ecp_point_free( &V );
319 mbedtls_ecp_point_free( &VV );
320 mbedtls_mpi_free( &r );
321 mbedtls_mpi_free( &h );
322
323 return( ret );
324}
325
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200326/*
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200327 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
328 */
329static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
330 const mbedtls_ecp_group *grp,
Simon Butcherbb5e1c32018-06-08 11:14:43 +0100331 const int pf,
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200332 const mbedtls_ecp_point *G,
333 const mbedtls_mpi *x,
334 const mbedtls_ecp_point *X,
335 const char *id,
336 unsigned char **p,
337 const unsigned char *end,
338 int (*f_rng)(void *, unsigned char *, size_t),
339 void *p_rng )
340{
341 int ret;
342 mbedtls_ecp_point V;
343 mbedtls_mpi v;
344 mbedtls_mpi h; /* later recycled to hold r */
345 size_t len;
346
347 if( end < *p )
348 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
349
350 mbedtls_ecp_point_init( &V );
351 mbedtls_mpi_init( &v );
352 mbedtls_mpi_init( &h );
353
354 /* Compute signature */
355 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
356 G, &v, &V, f_rng, p_rng ) );
Robert Cragie7cdad772015-10-02 13:31:41 +0100357 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200358 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
359 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
360 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
361
362 /* Write it out */
363 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
Robert Cragie7cdad772015-10-02 13:31:41 +0100364 pf, &len, *p, end - *p ) );
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200365 *p += len;
366
367 len = mbedtls_mpi_size( &h ); /* actually r */
368 if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
369 {
370 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
371 goto cleanup;
372 }
373
374 *(*p)++ = (unsigned char)( len & 0xFF );
375 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
376 *p += len;
377
378cleanup:
379 mbedtls_ecp_point_free( &V );
380 mbedtls_mpi_free( &v );
381 mbedtls_mpi_free( &h );
382
383 return( ret );
384}
385
386/*
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200387 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
388 * Output: verified public key X
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200389 */
390static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
391 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100392 const int pf,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200393 const mbedtls_ecp_point *G,
394 mbedtls_ecp_point *X,
395 const char *id,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200396 const unsigned char **p,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200397 const unsigned char *end )
398{
399 int ret;
400
401 if( end < *p )
402 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
403
404 /*
405 * struct {
406 * ECPoint X;
407 * ECSchnorrZKP zkp;
408 * } ECJPAKEKeyKP;
409 */
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200410 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
Manuel Pégourié-Gonnard30590952015-08-17 10:37:40 +0200411 if( mbedtls_ecp_is_zero( X ) )
412 {
413 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
414 goto cleanup;
415 }
416
Robert Cragie7cdad772015-10-02 13:31:41 +0100417 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200418
419cleanup:
420 return( ret );
421}
422
423/*
424 * Generate an ECJPAKEKeyKP
425 * Output: the serialized structure, plus private/public key pair
426 */
427static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
428 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100429 const int pf,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200430 const mbedtls_ecp_point *G,
431 mbedtls_mpi *x,
432 mbedtls_ecp_point *X,
433 const char *id,
434 unsigned char **p,
435 const unsigned char *end,
436 int (*f_rng)(void *, unsigned char *, size_t),
437 void *p_rng )
438{
439 int ret;
440 size_t len;
441
442 if( end < *p )
443 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
444
445 /* Generate key (7.4.2.3.1) and write it out */
446 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
447 f_rng, p_rng ) );
448 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
Robert Cragie7cdad772015-10-02 13:31:41 +0100449 pf, &len, *p, end - *p ) );
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200450 *p += len;
451
452 /* Generate and write proof */
Robert Cragie7cdad772015-10-02 13:31:41 +0100453 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200454 p, end, f_rng, p_rng ) );
455
456cleanup:
457 return( ret );
458}
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200459
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200460/*
461 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
462 * Ouputs: verified peer public keys Xa, Xb
463 */
464static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
465 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100466 const int pf,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200467 const mbedtls_ecp_point *G,
468 mbedtls_ecp_point *Xa,
469 mbedtls_ecp_point *Xb,
470 const char *id,
471 const unsigned char *buf,
472 size_t len )
473{
474 int ret;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200475 const unsigned char *p = buf;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200476 const unsigned char *end = buf + len;
477
478 /*
479 * struct {
480 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
481 * } ECJPAKEKeyKPPairList;
482 */
Robert Cragie7cdad772015-10-02 13:31:41 +0100483 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
484 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200485
486 if( p != end )
487 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
488
489cleanup:
490 return( ret );
491}
492
493/*
494 * Generate a ECJPAKEKeyKPPairList
495 * Outputs: the serialized structure, plus two private/public key pairs
496 */
497static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
498 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100499 const int pf,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200500 const mbedtls_ecp_point *G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200501 mbedtls_mpi *xm1,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200502 mbedtls_ecp_point *Xa,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200503 mbedtls_mpi *xm2,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200504 mbedtls_ecp_point *Xb,
505 const char *id,
506 unsigned char *buf,
507 size_t len,
508 size_t *olen,
509 int (*f_rng)(void *, unsigned char *, size_t),
510 void *p_rng )
511{
512 int ret;
513 unsigned char *p = buf;
514 const unsigned char *end = buf + len;
515
Robert Cragie7cdad772015-10-02 13:31:41 +0100516 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200517 &p, end, f_rng, p_rng ) );
Robert Cragie7cdad772015-10-02 13:31:41 +0100518 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200519 &p, end, f_rng, p_rng ) );
520
521 *olen = p - buf;
522
523cleanup:
524 return( ret );
525}
526
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200527/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200528 * Read and process the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200529 */
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200530int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
531 const unsigned char *buf,
532 size_t len )
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200533{
Robert Cragie7cdad772015-10-02 13:31:41 +0100534 return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
535 &ctx->grp.G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200536 &ctx->Xp1, &ctx->Xp2, ID_PEER,
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200537 buf, len ) );
538}
539
540/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200541 * Generate and write the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200542 */
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200543int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200544 unsigned char *buf, size_t len, size_t *olen,
545 int (*f_rng)(void *, unsigned char *, size_t),
546 void *p_rng )
547{
Robert Cragie7cdad772015-10-02 13:31:41 +0100548 return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
549 &ctx->grp.G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200550 &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200551 ID_MINE, buf, len, olen, f_rng, p_rng ) );
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200552}
553
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200554/*
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200555 * Compute the sum of three points R = A + B + C
556 */
557static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
558 const mbedtls_ecp_point *A,
559 const mbedtls_ecp_point *B,
560 const mbedtls_ecp_point *C )
561{
562 int ret;
563 mbedtls_mpi one;
564
565 mbedtls_mpi_init( &one );
566
567 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
568 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
569 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
570
571cleanup:
572 mbedtls_mpi_free( &one );
573
574 return( ret );
575}
576
577/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200578 * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200579 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200580int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200581 const unsigned char *buf,
582 size_t len )
583{
584 int ret;
585 const unsigned char *p = buf;
586 const unsigned char *end = buf + len;
587 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200588 mbedtls_ecp_point G; /* C: GB, S: GA */
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200589
590 mbedtls_ecp_group_init( &grp );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200591 mbedtls_ecp_point_init( &G );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200592
593 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200594 * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
595 * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
596 * Unified: G = Xm1 + Xm2 + Xp1
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200597 * We need that before parsing in order to check Xp as we read it
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200598 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200599 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200600 &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200601
602 /*
603 * struct {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200604 * ECParameters curve_params; // only client reading server msg
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200605 * ECJPAKEKeyKP ecjpake_key_kp;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200606 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200607 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200608 if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200609 {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200610 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200611 if( grp.id != ctx->grp.id )
612 {
613 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
614 goto cleanup;
615 }
616 }
617
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200618 MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100619 ctx->point_format,
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200620 &G, &ctx->Xp, ID_PEER, &p, end ) );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200621
622 if( p != end )
623 {
624 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
625 goto cleanup;
626 }
627
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200628cleanup:
629 mbedtls_ecp_group_free( &grp );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200630 mbedtls_ecp_point_free( &G );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200631
632 return( ret );
633}
634
635/*
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200636 * Compute R = +/- X * S mod N, taking care not to leak S
637 */
638static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
639 const mbedtls_mpi *X,
640 const mbedtls_mpi *S,
641 const mbedtls_mpi *N,
642 int (*f_rng)(void *, unsigned char *, size_t),
643 void *p_rng )
644{
645 int ret;
646 mbedtls_mpi b; /* Blinding value, then s + N * blinding */
647
648 mbedtls_mpi_init( &b );
649
650 /* b = s + rnd-128-bit * N */
651 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
652 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
653 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
654
655 /* R = sign * X * b mod N */
656 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
657 R->s *= sign;
658 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
659
660cleanup:
661 mbedtls_mpi_free( &b );
662
663 return( ret );
664}
665
666/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200667 * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200668 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200669int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200670 unsigned char *buf, size_t len, size_t *olen,
671 int (*f_rng)(void *, unsigned char *, size_t),
672 void *p_rng )
673{
674 int ret;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200675 mbedtls_ecp_point G; /* C: GA, S: GB */
676 mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
677 mbedtls_mpi xm; /* C: xc, S: xs */
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200678 unsigned char *p = buf;
679 const unsigned char *end = buf + len;
680 size_t ec_len;
681
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200682 mbedtls_ecp_point_init( &G );
683 mbedtls_ecp_point_init( &Xm );
684 mbedtls_mpi_init( &xm );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200685
686 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200687 * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200688 *
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200689 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
690 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
691 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200692 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200693 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200694 &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200695 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
696 &ctx->grp.N, f_rng, p_rng ) );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200697 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200698
699 /*
700 * Now write things out
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200701 *
702 * struct {
703 * ECParameters curve_params; // only server writing its message
704 * ECJPAKEKeyKP ecjpake_key_kp;
705 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200706 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200707 if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
708 {
709 if( end < p )
710 {
711 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
712 goto cleanup;
713 }
714 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
715 p, end - p ) );
716 p += ec_len;
717 }
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200718
719 if( end < p )
720 {
721 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
722 goto cleanup;
723 }
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200724 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
Robert Cragie7cdad772015-10-02 13:31:41 +0100725 ctx->point_format, &ec_len, p, end - p ) );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200726 p += ec_len;
727
728 MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100729 ctx->point_format,
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200730 &G, &xm, &Xm, ID_MINE,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200731 &p, end, f_rng, p_rng ) );
732
733 *olen = p - buf;
734
735cleanup:
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200736 mbedtls_ecp_point_free( &G );
737 mbedtls_ecp_point_free( &Xm );
738 mbedtls_mpi_free( &xm );
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200739
740 return( ret );
741}
742
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200743/*
744 * Derive PMS (7.4.2.7 / 7.4.2.8)
745 */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200746int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200747 unsigned char *buf, size_t len, size_t *olen,
748 int (*f_rng)(void *, unsigned char *, size_t),
749 void *p_rng )
750{
751 int ret;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200752 mbedtls_ecp_point K;
753 mbedtls_mpi m_xm2_s, one;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200754 unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
755 size_t x_bytes;
756
757 *olen = mbedtls_md_get_size( ctx->md_info );
758 if( len < *olen )
759 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
760
761 mbedtls_ecp_point_init( &K );
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200762 mbedtls_mpi_init( &m_xm2_s );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200763 mbedtls_mpi_init( &one );
764
765 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200766
767 /*
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200768 * Client: K = ( Xs - X4 * x2 * s ) * x2
769 * Server: K = ( Xc - X2 * x4 * s ) * x4
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200770 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200771 */
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200772 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
773 &ctx->grp.N, f_rng, p_rng ) );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200774 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
775 &one, &ctx->Xp,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200776 &m_xm2_s, &ctx->Xp2 ) );
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200777 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200778 f_rng, p_rng ) );
779
780 /* PMS = SHA-256( K.X ) */
781 x_bytes = ( ctx->grp.pbits + 7 ) / 8;
782 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
783 MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
784
785cleanup:
786 mbedtls_ecp_point_free( &K );
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200787 mbedtls_mpi_free( &m_xm2_s );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200788 mbedtls_mpi_free( &one );
789
790 return( ret );
791}
792
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200793#undef ID_MINE
794#undef ID_PEER
795
Hanno Becker616d1ca2018-01-24 10:25:05 +0000796#endif /* ! MBEDTLS_ECJPAKE_ALT */
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200797
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200798#if defined(MBEDTLS_SELF_TEST)
799
800#if defined(MBEDTLS_PLATFORM_C)
801#include "mbedtls/platform.h"
802#else
803#include <stdio.h>
804#define mbedtls_printf printf
805#endif
806
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200807#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
808 !defined(MBEDTLS_SHA256_C)
809int mbedtls_ecjpake_self_test( int verbose )
810{
811 (void) verbose;
812 return( 0 );
813}
814#else
815
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200816static const unsigned char ecjpake_test_password[] = {
817 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
818 0x65, 0x73, 0x74
819};
820
821static const unsigned char ecjpake_test_x1[] = {
822 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
823 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
824 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
825};
826
827static const unsigned char ecjpake_test_x2[] = {
828 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
829 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
830 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
831};
832
833static const unsigned char ecjpake_test_x3[] = {
834 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
835 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
836 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
837};
838
839static const unsigned char ecjpake_test_x4[] = {
840 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
841 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
842 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
843};
844
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200845static const unsigned char ecjpake_test_cli_one[] = {
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200846 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
847 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
848 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
849 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
850 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
851 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
852 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
853 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
854 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
855 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
856 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
857 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
858 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200859 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
860 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
861 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
862 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
863 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
864 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
865 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
866 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
867 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
868 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
869 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
870 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
871 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
872 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
873 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200874};
875
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200876static const unsigned char ecjpake_test_srv_one[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200877 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
878 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
879 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
880 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
881 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
882 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
883 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
884 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
885 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
886 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
887 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
888 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
889 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
890 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
891 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
892 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
893 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
894 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
895 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
896 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
897 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
898 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
899 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
900 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
901 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
902 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
903 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
904 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
905};
906
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200907static const unsigned char ecjpake_test_srv_two[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200908 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
909 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
910 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
911 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
912 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
913 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
914 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
915 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
916 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
917 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
918 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
919 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
920 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
921 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
922};
923
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200924static const unsigned char ecjpake_test_cli_two[] = {
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200925 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
926 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
927 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
928 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
929 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
930 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
931 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
932 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
933 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
934 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
935 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
936 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
937 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
938 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
939};
940
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200941static const unsigned char ecjpake_test_pms[] = {
942 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
943 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
944 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
945};
946
Antonin Décimo8fd91562019-01-23 15:24:37 +0100947/* Load my private keys and generate the corresponding public keys */
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200948static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
949 const unsigned char *xm1, size_t len1,
950 const unsigned char *xm2, size_t len2 )
951{
952 int ret;
953
954 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
955 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
956 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
957 &ctx->grp.G, NULL, NULL ) );
958 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
959 &ctx->grp.G, NULL, NULL ) );
960
961cleanup:
962 return( ret );
963}
964
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200965/* For tests we don't need a secure RNG;
966 * use the LGC from Numerical Recipes for simplicity */
967static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
968{
969 static uint32_t x = 42;
970 (void) p;
971
972 while( len > 0 )
973 {
974 size_t use_len = len > 4 ? 4 : len;
975 x = 1664525 * x + 1013904223;
976 memcpy( out, &x, use_len );
977 out += use_len;
978 len -= use_len;
979 }
980
981 return( 0 );
982}
983
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200984#define TEST_ASSERT( x ) \
985 do { \
986 if( x ) \
987 ret = 0; \
988 else \
989 { \
990 ret = 1; \
991 goto cleanup; \
992 } \
993 } while( 0 )
994
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200995/*
996 * Checkup routine
997 */
998int mbedtls_ecjpake_self_test( int verbose )
999{
1000 int ret;
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001001 mbedtls_ecjpake_context cli;
1002 mbedtls_ecjpake_context srv;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001003 unsigned char buf[512], pms[32];
1004 size_t len, pmslen;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001005
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001006 mbedtls_ecjpake_init( &cli );
1007 mbedtls_ecjpake_init( &srv );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001008
1009 if( verbose != 0 )
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001010 mbedtls_printf( " ECJPAKE test #0 (setup): " );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +02001011
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +02001012 TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001013 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
1014 ecjpake_test_password,
1015 sizeof( ecjpake_test_password ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001016
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +02001017 TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001018 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
1019 ecjpake_test_password,
1020 sizeof( ecjpake_test_password ) ) == 0 );
1021
1022 if( verbose != 0 )
1023 mbedtls_printf( "passed\n" );
1024
1025 if( verbose != 0 )
1026 mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
1027
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001028 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001029 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1030
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001031 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001032
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001033 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001034 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1035
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001036 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001037
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001038 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +02001039 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1040
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001041 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +02001042
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001043 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001044 pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
1045
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001046 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001047 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1048
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001049 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001050
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001051 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001052 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1053
1054 TEST_ASSERT( len == pmslen );
1055 TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
1056
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001057 if( verbose != 0 )
1058 mbedtls_printf( "passed\n" );
1059
1060 if( verbose != 0 )
1061 mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
1062
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001063 /* Simulate generation of round one */
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +02001064 MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
1065 ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001066 ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001067
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +02001068 MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
1069 ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001070 ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001071
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001072 /* Read round one */
1073 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
1074 ecjpake_test_cli_one,
1075 sizeof( ecjpake_test_cli_one ) ) == 0 );
1076
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001077 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001078 ecjpake_test_srv_one,
1079 sizeof( ecjpake_test_srv_one ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001080
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001081 /* Skip generation of round two, read round two */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001082 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001083 ecjpake_test_srv_two,
1084 sizeof( ecjpake_test_srv_two ) ) == 0 );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +02001085
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001086 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001087 ecjpake_test_cli_two,
1088 sizeof( ecjpake_test_cli_two ) ) == 0 );
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +02001089
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001090 /* Server derives PMS */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001091 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001092 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1093
1094 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1095 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1096
1097 memset( buf, 0, len ); /* Avoid interferences with next step */
1098
1099 /* Client derives PMS */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001100 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001101 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1102
1103 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1104 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1105
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001106 if( verbose != 0 )
1107 mbedtls_printf( "passed\n" );
1108
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001109cleanup:
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001110 mbedtls_ecjpake_free( &cli );
1111 mbedtls_ecjpake_free( &srv );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001112
1113 if( ret != 0 )
1114 {
1115 if( verbose != 0 )
1116 mbedtls_printf( "failed\n" );
1117
1118 ret = 1;
1119 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001120
1121 if( verbose != 0 )
1122 mbedtls_printf( "\n" );
1123
1124 return( ret );
1125}
1126
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +02001127#undef TEST_ASSERT
1128
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001129#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
1130
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001131#endif /* MBEDTLS_SELF_TEST */
1132
1133#endif /* MBEDTLS_ECJPAKE_C */