blob: 0535a570fffd0ed4253b10696c10ef9320402ec0 [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,
143 const mbedtls_ecp_point *P )
144{
145 int ret;
146 size_t len;
147
148 /* Need at least 4 for length plus 1 for point */
149 if( end < *p || end - *p < 5 )
150 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
151
152 ret = mbedtls_ecp_point_write_binary( grp, P, MBEDTLS_ECP_PF_UNCOMPRESSED,
153 &len, *p + 4, end - ( *p + 4 ) );
154 if( ret != 0 )
155 return( ret );
156
157 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
158 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
159 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
160 (*p)[3] = (unsigned char)( ( len ) & 0xFF );
161
162 *p += 4 + len;
163
164 return( 0 );
165}
166
167/*
168 * Size of the temporary buffer for ecjpake_hash:
169 * 3 EC points plus their length, plus ID (6 bytes)
170 */
171#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 6 )
172
173/*
174 * Compute hash for ZKP (7.4.2.2.2.1)
175 */
176static int ecjpake_hash( const mbedtls_md_info_t *md_info,
177 const mbedtls_ecp_group *grp,
178 const mbedtls_ecp_point *G,
179 const mbedtls_ecp_point *V,
180 const mbedtls_ecp_point *X,
181 const char *id,
182 mbedtls_mpi *h )
183{
184 int ret;
185 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
186 unsigned char *p = buf;
187 const unsigned char *end = buf + sizeof( buf );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200188 const size_t id_len = strlen( id );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200189 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
190
191 /* Write things to temporary buffer */
192 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, G ) );
193 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, V ) );
194 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, X ) );
195
196 if( end < p || (size_t)( end - p ) < id_len )
197 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
198
199 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
200 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
201 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
202 *p++ = (unsigned char)( ( id_len ) & 0xFF );
203
204 memcpy( p, id, id_len );
205 p += id_len;
206
207 /* Compute hash */
208 mbedtls_md( md_info, buf, p - buf, hash );
209
210 /* Turn it into an integer mod n */
211 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
212 mbedtls_md_get_size( md_info ) ) );
213 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
214
215cleanup:
216 return( ret );
217}
218
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200219/*
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200220 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
221 */
222static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
223 const mbedtls_ecp_group *grp,
224 const mbedtls_ecp_point *G,
225 const mbedtls_ecp_point *X,
226 const char *id,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200227 const unsigned char **p,
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200228 const unsigned char *end )
229{
230 int ret;
231 mbedtls_ecp_point V, VV;
232 mbedtls_mpi r, h;
233 size_t r_len;
234
235 mbedtls_ecp_point_init( &V );
236 mbedtls_ecp_point_init( &VV );
237 mbedtls_mpi_init( &r );
238 mbedtls_mpi_init( &h );
239
240 /*
241 * struct {
242 * ECPoint V;
243 * opaque r<1..2^8-1>;
244 * } ECSchnorrZKP;
245 */
246 if( end < *p )
247 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
248
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200249 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200250
251 if( end < *p || (size_t)( end - *p ) < 1 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200252 {
253 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
254 goto cleanup;
255 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200256
257 r_len = *(*p)++;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200258
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200259 if( end < *p || (size_t)( end - *p ) < r_len )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200260 {
261 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
262 goto cleanup;
263 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200264
265 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
266 *p += r_len;
267
268 /*
269 * Verification
270 */
271 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, G, &V, X, id, &h ) );
272 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
273 &VV, &h, X, &r, G ) );
274
275 if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200276 {
277 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
278 goto cleanup;
279 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200280
281cleanup:
282 mbedtls_ecp_point_free( &V );
283 mbedtls_ecp_point_free( &VV );
284 mbedtls_mpi_free( &r );
285 mbedtls_mpi_free( &h );
286
287 return( ret );
288}
289
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200290/*
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200291 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
292 */
293static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
294 const mbedtls_ecp_group *grp,
295 const mbedtls_ecp_point *G,
296 const mbedtls_mpi *x,
297 const mbedtls_ecp_point *X,
298 const char *id,
299 unsigned char **p,
300 const unsigned char *end,
301 int (*f_rng)(void *, unsigned char *, size_t),
302 void *p_rng )
303{
304 int ret;
305 mbedtls_ecp_point V;
306 mbedtls_mpi v;
307 mbedtls_mpi h; /* later recycled to hold r */
308 size_t len;
309
310 if( end < *p )
311 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
312
313 mbedtls_ecp_point_init( &V );
314 mbedtls_mpi_init( &v );
315 mbedtls_mpi_init( &h );
316
317 /* Compute signature */
318 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
319 G, &v, &V, f_rng, p_rng ) );
320 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, G, &V, X, id, &h ) );
321 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
322 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
323 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
324
325 /* Write it out */
326 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
327 MBEDTLS_ECP_PF_UNCOMPRESSED, &len, *p, end - *p ) );
328 *p += len;
329
330 len = mbedtls_mpi_size( &h ); /* actually r */
331 if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
332 {
333 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
334 goto cleanup;
335 }
336
337 *(*p)++ = (unsigned char)( len & 0xFF );
338 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
339 *p += len;
340
341cleanup:
342 mbedtls_ecp_point_free( &V );
343 mbedtls_mpi_free( &v );
344 mbedtls_mpi_free( &h );
345
346 return( ret );
347}
348
349/*
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200350 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
351 * Output: verified public key X
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200352 */
353static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
354 const mbedtls_ecp_group *grp,
355 const mbedtls_ecp_point *G,
356 mbedtls_ecp_point *X,
357 const char *id,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200358 const unsigned char **p,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200359 const unsigned char *end )
360{
361 int ret;
362
363 if( end < *p )
364 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
365
366 /*
367 * struct {
368 * ECPoint X;
369 * ECSchnorrZKP zkp;
370 * } ECJPAKEKeyKP;
371 */
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200372 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
Manuel Pégourié-Gonnard30590952015-08-17 10:37:40 +0200373 if( mbedtls_ecp_is_zero( X ) )
374 {
375 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
376 goto cleanup;
377 }
378
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200379 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, G, X, id, p, end ) );
380
381cleanup:
382 return( ret );
383}
384
385/*
386 * Generate an ECJPAKEKeyKP
387 * Output: the serialized structure, plus private/public key pair
388 */
389static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
390 const mbedtls_ecp_group *grp,
391 const mbedtls_ecp_point *G,
392 mbedtls_mpi *x,
393 mbedtls_ecp_point *X,
394 const char *id,
395 unsigned char **p,
396 const unsigned char *end,
397 int (*f_rng)(void *, unsigned char *, size_t),
398 void *p_rng )
399{
400 int ret;
401 size_t len;
402
403 if( end < *p )
404 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
405
406 /* Generate key (7.4.2.3.1) and write it out */
407 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
408 f_rng, p_rng ) );
409 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
410 MBEDTLS_ECP_PF_UNCOMPRESSED, &len, *p, end - *p ) );
411 *p += len;
412
413 /* Generate and write proof */
414 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, G, x, X, id,
415 p, end, f_rng, p_rng ) );
416
417cleanup:
418 return( ret );
419}
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200420
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200421/*
422 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
423 * Ouputs: verified peer public keys Xa, Xb
424 */
425static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
426 const mbedtls_ecp_group *grp,
427 const mbedtls_ecp_point *G,
428 mbedtls_ecp_point *Xa,
429 mbedtls_ecp_point *Xb,
430 const char *id,
431 const unsigned char *buf,
432 size_t len )
433{
434 int ret;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200435 const unsigned char *p = buf;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200436 const unsigned char *end = buf + len;
437
438 /*
439 * struct {
440 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
441 * } ECJPAKEKeyKPPairList;
442 */
443 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, G, Xa, id, &p, end ) );
444 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, G, Xb, id, &p, end ) );
445
446 if( p != end )
447 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
448
449cleanup:
450 return( ret );
451}
452
453/*
454 * Generate a ECJPAKEKeyKPPairList
455 * Outputs: the serialized structure, plus two private/public key pairs
456 */
457static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
458 const mbedtls_ecp_group *grp,
459 const mbedtls_ecp_point *G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200460 mbedtls_mpi *xm1,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200461 mbedtls_ecp_point *Xa,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200462 mbedtls_mpi *xm2,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200463 mbedtls_ecp_point *Xb,
464 const char *id,
465 unsigned char *buf,
466 size_t len,
467 size_t *olen,
468 int (*f_rng)(void *, unsigned char *, size_t),
469 void *p_rng )
470{
471 int ret;
472 unsigned char *p = buf;
473 const unsigned char *end = buf + len;
474
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200475 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, G, xm1, Xa, id,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200476 &p, end, f_rng, p_rng ) );
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200477 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, G, xm2, Xb, id,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200478 &p, end, f_rng, p_rng ) );
479
480 *olen = p - buf;
481
482cleanup:
483 return( ret );
484}
485
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200486/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200487 * Read and process the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200488 */
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200489int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
490 const unsigned char *buf,
491 size_t len )
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200492{
493 return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, &ctx->grp.G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200494 &ctx->Xp1, &ctx->Xp2, ID_PEER,
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200495 buf, len ) );
496}
497
498/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200499 * Generate and write the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200500 */
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200501int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200502 unsigned char *buf, size_t len, size_t *olen,
503 int (*f_rng)(void *, unsigned char *, size_t),
504 void *p_rng )
505{
506 return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, &ctx->grp.G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200507 &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200508 ID_MINE, buf, len, olen, f_rng, p_rng ) );
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200509}
510
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200511/*
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200512 * Compute the sum of three points R = A + B + C
513 */
514static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
515 const mbedtls_ecp_point *A,
516 const mbedtls_ecp_point *B,
517 const mbedtls_ecp_point *C )
518{
519 int ret;
520 mbedtls_mpi one;
521
522 mbedtls_mpi_init( &one );
523
524 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
525 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
526 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
527
528cleanup:
529 mbedtls_mpi_free( &one );
530
531 return( ret );
532}
533
534/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200535 * 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 +0200536 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200537int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200538 const unsigned char *buf,
539 size_t len )
540{
541 int ret;
542 const unsigned char *p = buf;
543 const unsigned char *end = buf + len;
544 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200545 mbedtls_ecp_point G; /* C: GB, S: GA */
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200546
547 mbedtls_ecp_group_init( &grp );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200548 mbedtls_ecp_point_init( &G );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200549
550 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200551 * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
552 * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
553 * Unified: G = Xm1 + Xm2 + Xp1
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200554 * We need that before parsing in order to check Xp as we read it
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200555 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200556 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200557 &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200558
559 /*
560 * struct {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200561 * ECParameters curve_params; // only client reading server msg
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200562 * ECJPAKEKeyKP ecjpake_key_kp;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200563 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200564 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200565 if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200566 {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200567 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200568 if( grp.id != ctx->grp.id )
569 {
570 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
571 goto cleanup;
572 }
573 }
574
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200575 MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200576 &G, &ctx->Xp, ID_PEER, &p, end ) );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200577
578 if( p != end )
579 {
580 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
581 goto cleanup;
582 }
583
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200584cleanup:
585 mbedtls_ecp_group_free( &grp );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200586 mbedtls_ecp_point_free( &G );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200587
588 return( ret );
589}
590
591/*
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200592 * Compute R = +/- X * S mod N, taking care not to leak S
593 */
594static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
595 const mbedtls_mpi *X,
596 const mbedtls_mpi *S,
597 const mbedtls_mpi *N,
598 int (*f_rng)(void *, unsigned char *, size_t),
599 void *p_rng )
600{
601 int ret;
602 mbedtls_mpi b; /* Blinding value, then s + N * blinding */
603
604 mbedtls_mpi_init( &b );
605
606 /* b = s + rnd-128-bit * N */
607 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
608 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
609 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
610
611 /* R = sign * X * b mod N */
612 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
613 R->s *= sign;
614 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
615
616cleanup:
617 mbedtls_mpi_free( &b );
618
619 return( ret );
620}
621
622/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200623 * 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 +0200624 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200625int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200626 unsigned char *buf, size_t len, size_t *olen,
627 int (*f_rng)(void *, unsigned char *, size_t),
628 void *p_rng )
629{
630 int ret;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200631 mbedtls_ecp_point G; /* C: GA, S: GB */
632 mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
633 mbedtls_mpi xm; /* C: xc, S: xs */
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200634 unsigned char *p = buf;
635 const unsigned char *end = buf + len;
636 size_t ec_len;
637
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200638 mbedtls_ecp_point_init( &G );
639 mbedtls_ecp_point_init( &Xm );
640 mbedtls_mpi_init( &xm );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200641
642 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200643 * 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 +0200644 *
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200645 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
646 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
647 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200648 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200649 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200650 &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200651 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
652 &ctx->grp.N, f_rng, p_rng ) );
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200653 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200654
655 /*
656 * Now write things out
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200657 *
658 * struct {
659 * ECParameters curve_params; // only server writing its message
660 * ECJPAKEKeyKP ecjpake_key_kp;
661 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200662 */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200663 if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
664 {
665 if( end < p )
666 {
667 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
668 goto cleanup;
669 }
670 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
671 p, end - p ) );
672 p += ec_len;
673 }
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200674
675 if( end < p )
676 {
677 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
678 goto cleanup;
679 }
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200680 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200681 MBEDTLS_ECP_PF_UNCOMPRESSED, &ec_len, p, end - p ) );
682 p += ec_len;
683
684 MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200685 &G, &xm, &Xm, ID_MINE,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200686 &p, end, f_rng, p_rng ) );
687
688 *olen = p - buf;
689
690cleanup:
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200691 mbedtls_ecp_point_free( &G );
692 mbedtls_ecp_point_free( &Xm );
693 mbedtls_mpi_free( &xm );
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200694
695 return( ret );
696}
697
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200698/*
699 * Derive PMS (7.4.2.7 / 7.4.2.8)
700 */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200701int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200702 unsigned char *buf, size_t len, size_t *olen,
703 int (*f_rng)(void *, unsigned char *, size_t),
704 void *p_rng )
705{
706 int ret;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200707 mbedtls_ecp_point K;
708 mbedtls_mpi m_xm2_s, one;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200709 unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
710 size_t x_bytes;
711
712 *olen = mbedtls_md_get_size( ctx->md_info );
713 if( len < *olen )
714 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
715
716 mbedtls_ecp_point_init( &K );
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200717 mbedtls_mpi_init( &m_xm2_s );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200718 mbedtls_mpi_init( &one );
719
720 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200721
722 /*
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200723 * Client: K = ( Xs - X4 * x2 * s ) * x2
724 * Server: K = ( Xc - X2 * x4 * s ) * x4
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200725 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200726 */
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200727 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
728 &ctx->grp.N, f_rng, p_rng ) );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200729 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
730 &one, &ctx->Xp,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200731 &m_xm2_s, &ctx->Xp2 ) );
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200732 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200733 f_rng, p_rng ) );
734
735 /* PMS = SHA-256( K.X ) */
736 x_bytes = ( ctx->grp.pbits + 7 ) / 8;
737 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
738 MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
739
740cleanup:
741 mbedtls_ecp_point_free( &K );
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200742 mbedtls_mpi_free( &m_xm2_s );
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200743 mbedtls_mpi_free( &one );
744
745 return( ret );
746}
747
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200748#undef ID_MINE
749#undef ID_PEER
750
751
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200752#if defined(MBEDTLS_SELF_TEST)
753
754#if defined(MBEDTLS_PLATFORM_C)
755#include "mbedtls/platform.h"
756#else
757#include <stdio.h>
758#define mbedtls_printf printf
759#endif
760
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200761#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
762 !defined(MBEDTLS_SHA256_C)
763int mbedtls_ecjpake_self_test( int verbose )
764{
765 (void) verbose;
766 return( 0 );
767}
768#else
769
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200770static const unsigned char ecjpake_test_password[] = {
771 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
772 0x65, 0x73, 0x74
773};
774
775static const unsigned char ecjpake_test_x1[] = {
776 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
777 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
778 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
779};
780
781static const unsigned char ecjpake_test_x2[] = {
782 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
783 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
784 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
785};
786
787static const unsigned char ecjpake_test_x3[] = {
788 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
789 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
790 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
791};
792
793static const unsigned char ecjpake_test_x4[] = {
794 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
795 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
796 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
797};
798
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200799static const unsigned char ecjpake_test_cli_one[] = {
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200800 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
801 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
802 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
803 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
804 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
805 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
806 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
807 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
808 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
809 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
810 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
811 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
812 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200813 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
814 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
815 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
816 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
817 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
818 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
819 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
820 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
821 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
822 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
823 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
824 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
825 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
826 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
827 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200828};
829
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200830static const unsigned char ecjpake_test_srv_one[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200831 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
832 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
833 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
834 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
835 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
836 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
837 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
838 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
839 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
840 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
841 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
842 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
843 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
844 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
845 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
846 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
847 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
848 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
849 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
850 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
851 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
852 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
853 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
854 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
855 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
856 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
857 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
858 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
859};
860
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200861static const unsigned char ecjpake_test_srv_two[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200862 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
863 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
864 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
865 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
866 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
867 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
868 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
869 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
870 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
871 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
872 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
873 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
874 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
875 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
876};
877
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200878static const unsigned char ecjpake_test_cli_two[] = {
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200879 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
880 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
881 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
882 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
883 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
884 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
885 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
886 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
887 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
888 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
889 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
890 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
891 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
892 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
893};
894
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200895static const unsigned char ecjpake_test_pms[] = {
896 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
897 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
898 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
899};
900
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200901/* Load my private keys and generate the correponding public keys */
902static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
903 const unsigned char *xm1, size_t len1,
904 const unsigned char *xm2, size_t len2 )
905{
906 int ret;
907
908 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
909 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
910 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
911 &ctx->grp.G, NULL, NULL ) );
912 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
913 &ctx->grp.G, NULL, NULL ) );
914
915cleanup:
916 return( ret );
917}
918
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200919/* For tests we don't need a secure RNG;
920 * use the LGC from Numerical Recipes for simplicity */
921static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
922{
923 static uint32_t x = 42;
924 (void) p;
925
926 while( len > 0 )
927 {
928 size_t use_len = len > 4 ? 4 : len;
929 x = 1664525 * x + 1013904223;
930 memcpy( out, &x, use_len );
931 out += use_len;
932 len -= use_len;
933 }
934
935 return( 0 );
936}
937
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200938#define TEST_ASSERT( x ) \
939 do { \
940 if( x ) \
941 ret = 0; \
942 else \
943 { \
944 ret = 1; \
945 goto cleanup; \
946 } \
947 } while( 0 )
948
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200949/*
950 * Checkup routine
951 */
952int mbedtls_ecjpake_self_test( int verbose )
953{
954 int ret;
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200955 mbedtls_ecjpake_context cli;
956 mbedtls_ecjpake_context srv;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200957 unsigned char buf[512], pms[32];
958 size_t len, pmslen;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200959
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200960 mbedtls_ecjpake_init( &cli );
961 mbedtls_ecjpake_init( &srv );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200962
963 if( verbose != 0 )
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200964 mbedtls_printf( " ECJPAKE test #0 (setup): " );
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200965
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200966 TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200967 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
968 ecjpake_test_password,
969 sizeof( ecjpake_test_password ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200970
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200971 TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200972 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
973 ecjpake_test_password,
974 sizeof( ecjpake_test_password ) ) == 0 );
975
976 if( verbose != 0 )
977 mbedtls_printf( "passed\n" );
978
979 if( verbose != 0 )
980 mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
981
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200982 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200983 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
984
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200985 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200986
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200987 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200988 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
989
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200990 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200991
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200992 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200993 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
994
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200995 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200996
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +0200997 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200998 pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
999
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001000 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001001 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1002
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001003 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001004
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001005 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001006 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1007
1008 TEST_ASSERT( len == pmslen );
1009 TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
1010
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001011 if( verbose != 0 )
1012 mbedtls_printf( "passed\n" );
1013
1014 if( verbose != 0 )
1015 mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
1016
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001017 /* Simulate generation of round one */
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +02001018 MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
1019 ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001020 ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001021
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +02001022 MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
1023 ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001024 ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001025
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001026 /* Read round one */
1027 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
1028 ecjpake_test_cli_one,
1029 sizeof( ecjpake_test_cli_one ) ) == 0 );
1030
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +02001031 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001032 ecjpake_test_srv_one,
1033 sizeof( ecjpake_test_srv_one ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001034
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001035 /* Skip generation of round two, read round two */
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001036 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001037 ecjpake_test_srv_two,
1038 sizeof( ecjpake_test_srv_two ) ) == 0 );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +02001039
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +02001040 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001041 ecjpake_test_cli_two,
1042 sizeof( ecjpake_test_cli_two ) ) == 0 );
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +02001043
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001044 /* Server derives PMS */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001045 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001046 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1047
1048 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1049 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1050
1051 memset( buf, 0, len ); /* Avoid interferences with next step */
1052
1053 /* Client derives PMS */
Manuel Pégourié-Gonnardf7368c92015-08-14 14:33:05 +02001054 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001055 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1056
1057 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1058 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1059
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001060 if( verbose != 0 )
1061 mbedtls_printf( "passed\n" );
1062
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001063cleanup:
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001064 mbedtls_ecjpake_free( &cli );
1065 mbedtls_ecjpake_free( &srv );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001066
1067 if( ret != 0 )
1068 {
1069 if( verbose != 0 )
1070 mbedtls_printf( "failed\n" );
1071
1072 ret = 1;
1073 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001074
1075 if( verbose != 0 )
1076 mbedtls_printf( "\n" );
1077
1078 return( ret );
1079}
1080
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +02001081#undef TEST_ASSERT
1082
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001083#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
1084
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001085#endif /* MBEDTLS_SELF_TEST */
1086
1087#endif /* MBEDTLS_ECJPAKE_C */