blob: 6a724521506b7a9d57c4e65f16ceed231ff77c98 [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
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020023 * References in the code are to the Thread v1.0 Specification,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +020024 * available to members of the Thread Group http://threadgroup.org/
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020025 */
26
27#if !defined(MBEDTLS_CONFIG_FILE)
28#include "mbedtls/config.h"
29#else
30#include MBEDTLS_CONFIG_FILE
31#endif
32
33#if defined(MBEDTLS_ECJPAKE_C)
34
35#include "mbedtls/ecjpake.h"
36
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020037#include <string.h>
38
39/*
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +020040 * Convert a mbedtls_ecjpake_role to identifier string
41 */
42static const char * const ecjpake_id[] = {
43 "client",
44 "server"
45};
46
47#define ID_MINE ( ecjpake_id[ ctx->role ] )
48#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
49
50/*
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020051 * Initialize context
52 */
53void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
54{
55 if( ctx == NULL )
56 return;
57
58 ctx->md_info = NULL;
59 mbedtls_ecp_group_init( &ctx->grp );
60
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020061 mbedtls_ecp_point_init( &ctx->Xm1 );
62 mbedtls_ecp_point_init( &ctx->Xm2 );
63 mbedtls_ecp_point_init( &ctx->Xp1 );
64 mbedtls_ecp_point_init( &ctx->Xp2 );
65 mbedtls_ecp_point_init( &ctx->Xp );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020066
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020067 mbedtls_mpi_init( &ctx->xm1 );
68 mbedtls_mpi_init( &ctx->xm2 );
69 mbedtls_mpi_init( &ctx->s );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020070}
71
72/*
73 * Free context
74 */
75void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
76{
77 if( ctx == NULL )
78 return;
79
80 ctx->md_info = NULL;
81 mbedtls_ecp_group_free( &ctx->grp );
82
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020083 mbedtls_ecp_point_free( &ctx->Xm1 );
84 mbedtls_ecp_point_free( &ctx->Xm2 );
85 mbedtls_ecp_point_free( &ctx->Xp1 );
86 mbedtls_ecp_point_free( &ctx->Xp2 );
87 mbedtls_ecp_point_free( &ctx->Xp );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020088
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +020089 mbedtls_mpi_free( &ctx->xm1 );
90 mbedtls_mpi_free( &ctx->xm2 );
91 mbedtls_mpi_free( &ctx->s );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020092}
93
94/*
95 * Setup context
96 */
97int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +020098 mbedtls_ecjpake_role role,
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020099 mbedtls_md_type_t hash,
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200100 mbedtls_ecp_group_id curve,
101 const unsigned char *secret,
102 size_t len )
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200103{
104 int ret;
105
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200106 ctx->role = role;
107
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200108 if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
109 return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
110
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200111 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200112
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200113 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200114
115cleanup:
116 if( ret != 0 )
117 mbedtls_ecjpake_free( ctx );
118
119 return( ret );
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200120}
121
122/*
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200123 * Check if context is ready for use
124 */
125int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
126{
127 if( ctx->md_info == NULL ||
128 ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
129 ctx->s.p == NULL )
130 {
131 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
132 }
133
134 return( 0 );
135}
136
137/*
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200138 * Write a point plus its length to a buffer
139 */
140static int ecjpake_write_len_point( unsigned char **p,
141 const unsigned char *end,
142 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100143 const int pf,
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200144 const mbedtls_ecp_point *P )
145{
146 int ret;
147 size_t len;
148
149 /* Need at least 4 for length plus 1 for point */
150 if( end < *p || end - *p < 5 )
151 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
152
Robert Cragie7cdad772015-10-02 13:31:41 +0100153 ret = mbedtls_ecp_point_write_binary( grp, P, pf,
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200154 &len, *p + 4, end - ( *p + 4 ) );
155 if( ret != 0 )
156 return( ret );
157
158 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
159 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
160 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
161 (*p)[3] = (unsigned char)( ( len ) & 0xFF );
162
163 *p += 4 + len;
164
165 return( 0 );
166}
167
168/*
169 * Size of the temporary buffer for ecjpake_hash:
170 * 3 EC points plus their length, plus ID (6 bytes)
171 */
172#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 6 )
173
174/*
175 * Compute hash for ZKP (7.4.2.2.2.1)
176 */
177static int ecjpake_hash( const mbedtls_md_info_t *md_info,
178 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100179 const int pf,
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200180 const mbedtls_ecp_point *G,
181 const mbedtls_ecp_point *V,
182 const mbedtls_ecp_point *X,
183 const char *id,
184 mbedtls_mpi *h )
185{
186 int ret;
187 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
188 unsigned char *p = buf;
189 const unsigned char *end = buf + sizeof( buf );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200190 const size_t id_len = strlen( id );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200191 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
192
193 /* Write things to temporary buffer */
Robert Cragie7cdad772015-10-02 13:31:41 +0100194 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
195 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
196 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200197
198 if( end < p || (size_t)( end - p ) < id_len )
199 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
200
201 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
202 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
203 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
204 *p++ = (unsigned char)( ( id_len ) & 0xFF );
205
206 memcpy( p, id, id_len );
207 p += id_len;
208
209 /* Compute hash */
210 mbedtls_md( md_info, buf, p - buf, hash );
211
212 /* Turn it into an integer mod n */
213 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
214 mbedtls_md_get_size( md_info ) ) );
215 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
216
217cleanup:
218 return( ret );
219}
220
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200221/*
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200222 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
223 */
224static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
225 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100226 const int pf,
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200227 const mbedtls_ecp_point *G,
228 const mbedtls_ecp_point *X,
229 const char *id,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200230 const unsigned char **p,
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200231 const unsigned char *end )
232{
233 int ret;
234 mbedtls_ecp_point V, VV;
235 mbedtls_mpi r, h;
236 size_t r_len;
237
238 mbedtls_ecp_point_init( &V );
239 mbedtls_ecp_point_init( &VV );
240 mbedtls_mpi_init( &r );
241 mbedtls_mpi_init( &h );
242
243 /*
244 * struct {
245 * ECPoint V;
246 * opaque r<1..2^8-1>;
247 * } ECSchnorrZKP;
248 */
249 if( end < *p )
250 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
251
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200252 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200253
254 if( end < *p || (size_t)( end - *p ) < 1 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200255 {
256 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
257 goto cleanup;
258 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200259
260 r_len = *(*p)++;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200261
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200262 if( end < *p || (size_t)( end - *p ) < r_len )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200263 {
264 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
265 goto cleanup;
266 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200267
268 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
269 *p += r_len;
270
271 /*
272 * Verification
273 */
Robert Cragie7cdad772015-10-02 13:31:41 +0100274 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200275 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
276 &VV, &h, X, &r, G ) );
277
278 if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200279 {
280 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
281 goto cleanup;
282 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200283
284cleanup:
285 mbedtls_ecp_point_free( &V );
286 mbedtls_ecp_point_free( &VV );
287 mbedtls_mpi_free( &r );
288 mbedtls_mpi_free( &h );
289
290 return( ret );
291}
292
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200293/*
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200294 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
295 */
296static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
297 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100298 const int pf,
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200299 const mbedtls_ecp_point *G,
300 const mbedtls_mpi *x,
301 const mbedtls_ecp_point *X,
302 const char *id,
303 unsigned char **p,
304 const unsigned char *end,
305 int (*f_rng)(void *, unsigned char *, size_t),
306 void *p_rng )
307{
308 int ret;
309 mbedtls_ecp_point V;
310 mbedtls_mpi v;
311 mbedtls_mpi h; /* later recycled to hold r */
312 size_t len;
313
314 if( end < *p )
315 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
316
317 mbedtls_ecp_point_init( &V );
318 mbedtls_mpi_init( &v );
319 mbedtls_mpi_init( &h );
320
321 /* Compute signature */
322 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
323 G, &v, &V, f_rng, p_rng ) );
Robert Cragie7cdad772015-10-02 13:31:41 +0100324 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200325 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
326 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
327 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
328
329 /* Write it out */
330 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
Robert Cragie7cdad772015-10-02 13:31:41 +0100331 pf, &len, *p, end - *p ) );
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200332 *p += len;
333
334 len = mbedtls_mpi_size( &h ); /* actually r */
335 if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
336 {
337 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
338 goto cleanup;
339 }
340
341 *(*p)++ = (unsigned char)( len & 0xFF );
342 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
343 *p += len;
344
345cleanup:
346 mbedtls_ecp_point_free( &V );
347 mbedtls_mpi_free( &v );
348 mbedtls_mpi_free( &h );
349
350 return( ret );
351}
352
353/*
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200354 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
355 * Output: verified public key X
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200356 */
357static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
358 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100359 const int pf,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200360 const mbedtls_ecp_point *G,
361 mbedtls_ecp_point *X,
362 const char *id,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200363 const unsigned char **p,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200364 const unsigned char *end )
365{
366 int ret;
367
368 if( end < *p )
369 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
370
371 /*
372 * struct {
373 * ECPoint X;
374 * ECSchnorrZKP zkp;
375 * } ECJPAKEKeyKP;
376 */
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200377 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
Manuel Pégourié-Gonnard30590952015-08-17 10:37:40 +0200378 if( mbedtls_ecp_is_zero( X ) )
379 {
380 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
381 goto cleanup;
382 }
383
Robert Cragie7cdad772015-10-02 13:31:41 +0100384 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200385
386cleanup:
387 return( ret );
388}
389
390/*
391 * Generate an ECJPAKEKeyKP
392 * Output: the serialized structure, plus private/public key pair
393 */
394static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
395 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100396 const int pf,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200397 const mbedtls_ecp_point *G,
398 mbedtls_mpi *x,
399 mbedtls_ecp_point *X,
400 const char *id,
401 unsigned char **p,
402 const unsigned char *end,
403 int (*f_rng)(void *, unsigned char *, size_t),
404 void *p_rng )
405{
406 int ret;
407 size_t len;
408
409 if( end < *p )
410 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
411
412 /* Generate key (7.4.2.3.1) and write it out */
413 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
414 f_rng, p_rng ) );
415 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
Robert Cragie7cdad772015-10-02 13:31:41 +0100416 pf, &len, *p, end - *p ) );
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200417 *p += len;
418
419 /* Generate and write proof */
Robert Cragie7cdad772015-10-02 13:31:41 +0100420 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200421 p, end, f_rng, p_rng ) );
422
423cleanup:
424 return( ret );
425}
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200426
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200427/*
428 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
429 * Ouputs: verified peer public keys Xa, Xb
430 */
431static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
432 const mbedtls_ecp_group *grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100433 const int pf,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200434 const mbedtls_ecp_point *G,
435 mbedtls_ecp_point *Xa,
436 mbedtls_ecp_point *Xb,
437 const char *id,
438 const unsigned char *buf,
439 size_t len )
440{
441 int ret;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200442 const unsigned char *p = buf;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200443 const unsigned char *end = buf + len;
444
445 /*
446 * struct {
447 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
448 * } ECJPAKEKeyKPPairList;
449 */
Robert Cragie7cdad772015-10-02 13:31:41 +0100450 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
451 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200452
453 if( p != end )
454 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
455
456cleanup:
457 return( ret );
458}
459
460/*
461 * Generate a ECJPAKEKeyKPPairList
462 * Outputs: the serialized structure, plus two private/public key pairs
463 */
464static int ecjpake_kkpp_write( 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,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200468 mbedtls_mpi *xm1,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200469 mbedtls_ecp_point *Xa,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200470 mbedtls_mpi *xm2,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200471 mbedtls_ecp_point *Xb,
472 const char *id,
473 unsigned char *buf,
474 size_t len,
475 size_t *olen,
476 int (*f_rng)(void *, unsigned char *, size_t),
477 void *p_rng )
478{
479 int ret;
480 unsigned char *p = buf;
481 const unsigned char *end = buf + len;
482
Robert Cragie7cdad772015-10-02 13:31:41 +0100483 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200484 &p, end, f_rng, p_rng ) );
Robert Cragie7cdad772015-10-02 13:31:41 +0100485 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200486 &p, end, f_rng, p_rng ) );
487
488 *olen = p - buf;
489
490cleanup:
491 return( ret );
492}
493
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200494/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200495 * Read and process the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200496 */
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200497int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
498 const unsigned char *buf,
499 size_t len )
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200500{
Robert Cragie7cdad772015-10-02 13:31:41 +0100501 return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
502 &ctx->grp.G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200503 &ctx->Xp1, &ctx->Xp2, ID_PEER,
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200504 buf, len ) );
505}
506
507/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200508 * Generate and write the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200509 */
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200510int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200511 unsigned char *buf, size_t len, size_t *olen,
512 int (*f_rng)(void *, unsigned char *, size_t),
513 void *p_rng )
514{
Robert Cragie7cdad772015-10-02 13:31:41 +0100515 return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
516 &ctx->grp.G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200517 &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200518 ID_MINE, buf, len, olen, f_rng, p_rng ) );
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200519}
520
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200521/*
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200522 * Compute the sum of three points R = A + B + C
523 */
524static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
525 const mbedtls_ecp_point *A,
526 const mbedtls_ecp_point *B,
527 const mbedtls_ecp_point *C )
528{
529 int ret;
530 mbedtls_mpi one;
531
532 mbedtls_mpi_init( &one );
533
534 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
535 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
536 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
537
538cleanup:
539 mbedtls_mpi_free( &one );
540
541 return( ret );
542}
543
544/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200545 * 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 +0200546 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200547int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200548 const unsigned char *buf,
549 size_t len )
550{
551 int ret;
552 const unsigned char *p = buf;
553 const unsigned char *end = buf + len;
554 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200555 mbedtls_ecp_point G; /* C: GB, S: GA */
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200556
557 mbedtls_ecp_group_init( &grp );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200558 mbedtls_ecp_point_init( &G );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200559
560 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200561 * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
562 * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
563 * Unified: G = Xm1 + Xm2 + Xp1
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200564 * We need that before parsing in order to check Xp as we read it
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200565 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200566 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200567 &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200568
569 /*
570 * struct {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200571 * ECParameters curve_params; // only client reading server msg
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200572 * ECJPAKEKeyKP ecjpake_key_kp;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200573 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200574 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200575 if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200576 {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200577 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200578 if( grp.id != ctx->grp.id )
579 {
580 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
581 goto cleanup;
582 }
583 }
584
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200585 MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100586 ctx->point_format,
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200587 &G, &ctx->Xp, ID_PEER, &p, end ) );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200588
589 if( p != end )
590 {
591 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
592 goto cleanup;
593 }
594
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200595cleanup:
596 mbedtls_ecp_group_free( &grp );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200597 mbedtls_ecp_point_free( &G );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200598
599 return( ret );
600}
601
602/*
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200603 * Compute R = +/- X * S mod N, taking care not to leak S
604 */
605static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
606 const mbedtls_mpi *X,
607 const mbedtls_mpi *S,
608 const mbedtls_mpi *N,
609 int (*f_rng)(void *, unsigned char *, size_t),
610 void *p_rng )
611{
612 int ret;
613 mbedtls_mpi b; /* Blinding value, then s + N * blinding */
614
615 mbedtls_mpi_init( &b );
616
617 /* b = s + rnd-128-bit * N */
618 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
619 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
620 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
621
622 /* R = sign * X * b mod N */
623 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
624 R->s *= sign;
625 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
626
627cleanup:
628 mbedtls_mpi_free( &b );
629
630 return( ret );
631}
632
633/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200634 * 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 +0200635 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200636int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200637 unsigned char *buf, size_t len, size_t *olen,
638 int (*f_rng)(void *, unsigned char *, size_t),
639 void *p_rng )
640{
641 int ret;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200642 mbedtls_ecp_point G; /* C: GA, S: GB */
643 mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
644 mbedtls_mpi xm; /* C: xc, S: xs */
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200645 unsigned char *p = buf;
646 const unsigned char *end = buf + len;
647 size_t ec_len;
648
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200649 mbedtls_ecp_point_init( &G );
650 mbedtls_ecp_point_init( &Xm );
651 mbedtls_mpi_init( &xm );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200652
653 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200654 * 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 +0200655 *
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200656 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
657 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
658 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200659 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200660 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200661 &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200662 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
663 &ctx->grp.N, f_rng, p_rng ) );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200664 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200665
666 /*
667 * Now write things out
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200668 *
669 * struct {
670 * ECParameters curve_params; // only server writing its message
671 * ECJPAKEKeyKP ecjpake_key_kp;
672 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200673 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200674 if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
675 {
676 if( end < p )
677 {
678 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
679 goto cleanup;
680 }
681 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
682 p, end - p ) );
683 p += ec_len;
684 }
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200685
686 if( end < p )
687 {
688 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
689 goto cleanup;
690 }
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200691 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
Robert Cragie7cdad772015-10-02 13:31:41 +0100692 ctx->point_format, &ec_len, p, end - p ) );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200693 p += ec_len;
694
695 MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
Robert Cragie7cdad772015-10-02 13:31:41 +0100696 ctx->point_format,
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200697 &G, &xm, &Xm, ID_MINE,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200698 &p, end, f_rng, p_rng ) );
699
700 *olen = p - buf;
701
702cleanup:
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200703 mbedtls_ecp_point_free( &G );
704 mbedtls_ecp_point_free( &Xm );
705 mbedtls_mpi_free( &xm );
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200706
707 return( ret );
708}
709
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200710/*
711 * Derive PMS (7.4.2.7 / 7.4.2.8)
712 */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200713int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200714 unsigned char *buf, size_t len, size_t *olen,
715 int (*f_rng)(void *, unsigned char *, size_t),
716 void *p_rng )
717{
718 int ret;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200719 mbedtls_ecp_point K;
720 mbedtls_mpi m_xm2_s, one;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200721 unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
722 size_t x_bytes;
723
724 *olen = mbedtls_md_get_size( ctx->md_info );
725 if( len < *olen )
726 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
727
728 mbedtls_ecp_point_init( &K );
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200729 mbedtls_mpi_init( &m_xm2_s );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200730 mbedtls_mpi_init( &one );
731
732 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200733
734 /*
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200735 * Client: K = ( Xs - X4 * x2 * s ) * x2
736 * Server: K = ( Xc - X2 * x4 * s ) * x4
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200737 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200738 */
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200739 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
740 &ctx->grp.N, f_rng, p_rng ) );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200741 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
742 &one, &ctx->Xp,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200743 &m_xm2_s, &ctx->Xp2 ) );
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200744 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200745 f_rng, p_rng ) );
746
747 /* PMS = SHA-256( K.X ) */
748 x_bytes = ( ctx->grp.pbits + 7 ) / 8;
749 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
750 MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
751
752cleanup:
753 mbedtls_ecp_point_free( &K );
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200754 mbedtls_mpi_free( &m_xm2_s );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200755 mbedtls_mpi_free( &one );
756
757 return( ret );
758}
759
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200760#undef ID_MINE
761#undef ID_PEER
762
763
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200764#if defined(MBEDTLS_SELF_TEST)
765
766#if defined(MBEDTLS_PLATFORM_C)
767#include "mbedtls/platform.h"
768#else
769#include <stdio.h>
770#define mbedtls_printf printf
771#endif
772
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200773#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
774 !defined(MBEDTLS_SHA256_C)
775int mbedtls_ecjpake_self_test( int verbose )
776{
777 (void) verbose;
778 return( 0 );
779}
780#else
781
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200782static const unsigned char ecjpake_test_password[] = {
783 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
784 0x65, 0x73, 0x74
785};
786
787static const unsigned char ecjpake_test_x1[] = {
788 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
789 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
790 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
791};
792
793static const unsigned char ecjpake_test_x2[] = {
794 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
795 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
796 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
797};
798
799static const unsigned char ecjpake_test_x3[] = {
800 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
801 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
802 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
803};
804
805static const unsigned char ecjpake_test_x4[] = {
806 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
807 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
808 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
809};
810
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200811static const unsigned char ecjpake_test_cli_one[] = {
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200812 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
813 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
814 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
815 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
816 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
817 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
818 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
819 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
820 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
821 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
822 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
823 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
824 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200825 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
826 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
827 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
828 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
829 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
830 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
831 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
832 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
833 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
834 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
835 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
836 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
837 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
838 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
839 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200840};
841
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200842static const unsigned char ecjpake_test_srv_one[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200843 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
844 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
845 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
846 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
847 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
848 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
849 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
850 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
851 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
852 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
853 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
854 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
855 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
856 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
857 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
858 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
859 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
860 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
861 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
862 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
863 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
864 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
865 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
866 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
867 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
868 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
869 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
870 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
871};
872
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200873static const unsigned char ecjpake_test_srv_two[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200874 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
875 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
876 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
877 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
878 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
879 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
880 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
881 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
882 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
883 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
884 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
885 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
886 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
887 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
888};
889
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200890static const unsigned char ecjpake_test_cli_two[] = {
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200891 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
892 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
893 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
894 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
895 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
896 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
897 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
898 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
899 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
900 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
901 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
902 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
903 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
904 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
905};
906
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200907static const unsigned char ecjpake_test_pms[] = {
908 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
909 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
910 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
911};
912
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200913/* Load my private keys and generate the correponding public keys */
914static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
915 const unsigned char *xm1, size_t len1,
916 const unsigned char *xm2, size_t len2 )
917{
918 int ret;
919
920 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
921 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
922 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
923 &ctx->grp.G, NULL, NULL ) );
924 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
925 &ctx->grp.G, NULL, NULL ) );
926
927cleanup:
928 return( ret );
929}
930
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200931/* For tests we don't need a secure RNG;
932 * use the LGC from Numerical Recipes for simplicity */
933static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
934{
935 static uint32_t x = 42;
936 (void) p;
937
938 while( len > 0 )
939 {
940 size_t use_len = len > 4 ? 4 : len;
941 x = 1664525 * x + 1013904223;
942 memcpy( out, &x, use_len );
943 out += use_len;
944 len -= use_len;
945 }
946
947 return( 0 );
948}
949
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200950#define TEST_ASSERT( x ) \
951 do { \
952 if( x ) \
953 ret = 0; \
954 else \
955 { \
956 ret = 1; \
957 goto cleanup; \
958 } \
959 } while( 0 )
960
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200961/*
962 * Checkup routine
963 */
964int mbedtls_ecjpake_self_test( int verbose )
965{
966 int ret;
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200967 mbedtls_ecjpake_context cli;
968 mbedtls_ecjpake_context srv;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200969 unsigned char buf[512], pms[32];
970 size_t len, pmslen;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200971
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200972 mbedtls_ecjpake_init( &cli );
973 mbedtls_ecjpake_init( &srv );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200974
975 if( verbose != 0 )
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200976 mbedtls_printf( " ECJPAKE test #0 (setup): " );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200977
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200978 TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200979 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
980 ecjpake_test_password,
981 sizeof( ecjpake_test_password ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200982
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200983 TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200984 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
985 ecjpake_test_password,
986 sizeof( ecjpake_test_password ) ) == 0 );
987
988 if( verbose != 0 )
989 mbedtls_printf( "passed\n" );
990
991 if( verbose != 0 )
992 mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
993
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200994 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200995 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
996
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200997 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200998
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200999 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001000 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1001
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001002 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001003
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001004 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +02001005 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1006
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001007 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +02001008
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001009 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001010 pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
1011
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001012 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001013 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1014
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001015 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001016
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001017 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001018 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1019
1020 TEST_ASSERT( len == pmslen );
1021 TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
1022
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001023 if( verbose != 0 )
1024 mbedtls_printf( "passed\n" );
1025
1026 if( verbose != 0 )
1027 mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
1028
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001029 /* Simulate generation of round one */
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +02001030 MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
1031 ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001032 ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001033
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +02001034 MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
1035 ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001036 ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001037
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001038 /* Read round one */
1039 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
1040 ecjpake_test_cli_one,
1041 sizeof( ecjpake_test_cli_one ) ) == 0 );
1042
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001043 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001044 ecjpake_test_srv_one,
1045 sizeof( ecjpake_test_srv_one ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001046
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001047 /* Skip generation of round two, read round two */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001048 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001049 ecjpake_test_srv_two,
1050 sizeof( ecjpake_test_srv_two ) ) == 0 );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +02001051
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001052 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001053 ecjpake_test_cli_two,
1054 sizeof( ecjpake_test_cli_two ) ) == 0 );
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +02001055
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001056 /* Server derives PMS */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001057 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001058 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1059
1060 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1061 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1062
1063 memset( buf, 0, len ); /* Avoid interferences with next step */
1064
1065 /* Client derives PMS */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001066 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001067 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1068
1069 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1070 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1071
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001072 if( verbose != 0 )
1073 mbedtls_printf( "passed\n" );
1074
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001075cleanup:
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001076 mbedtls_ecjpake_free( &cli );
1077 mbedtls_ecjpake_free( &srv );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001078
1079 if( ret != 0 )
1080 {
1081 if( verbose != 0 )
1082 mbedtls_printf( "failed\n" );
1083
1084 ret = 1;
1085 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001086
1087 if( verbose != 0 )
1088 mbedtls_printf( "\n" );
1089
1090 return( ret );
1091}
1092
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +02001093#undef TEST_ASSERT
1094
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001095#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
1096
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001097#endif /* MBEDTLS_SELF_TEST */
1098
1099#endif /* MBEDTLS_ECJPAKE_C */