1
#pragma clang diagnostic ignored "-Wunknown-warning-option"
2
#pragma clang diagnostic ignored "-Wimplicit-int-conversion"
3
#pragma clang diagnostic ignored "-Wsign-conversion"
5
#pragma GCC diagnostic ignored "-Wconversion"
7
#pragma clang diagnostic ignored "-Wimplicit-int-conversion"
8
#pragma clang diagnostic ignored "-Wsign-conversion"
10
#pragma GCC diagnostic ignored "-Wconversion"
12
#pragma clang diagnostic ignored "-Wimplicit-int-conversion"
13
#pragma clang diagnostic ignored "-Wsign-conversion"
15
* Elliptic curve J-PAKE
17
* Copyright The Mbed TLS Contributors
18
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
20
* This file is provided under the Apache License 2.0, or the
21
* GNU General Public License v2.0 or later.
26
* Licensed under the Apache License, Version 2.0 (the "License"); you may
27
* not use this file except in compliance with the License.
28
* You may obtain a copy of the License at
30
* http://www.apache.org/licenses/LICENSE-2.0
32
* Unless required by applicable law or agreed to in writing, software
33
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
34
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35
* See the License for the specific language governing permissions and
36
* limitations under the License.
41
* GNU General Public License v2.0 or later:
43
* This program is free software; you can redistribute it and/or modify
44
* it under the terms of the GNU General Public License as published by
45
* the Free Software Foundation; either version 2 of the License, or
46
* (at your option) any later version.
48
* This program is distributed in the hope that it will be useful,
49
* but WITHOUT ANY WARRANTY; without even the implied warranty of
50
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51
* GNU General Public License for more details.
53
* You should have received a copy of the GNU General Public License along
54
* with this program; if not, write to the Free Software Foundation, Inc.,
55
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
61
* References in the code are to the Thread v1.0 Specification,
62
* available to members of the Thread Group http://threadgroup.org/
65
#if !defined(MBEDTLS_CONFIG_FILE)
66
#include "mbedtls/config.h"
68
#include MBEDTLS_CONFIG_FILE
71
#if defined(MBEDTLS_ECJPAKE_C)
73
#include "mbedtls/ecjpake.h"
74
#include "mbedtls/platform_util.h"
78
#if !defined(MBEDTLS_ECJPAKE_ALT)
80
/* Parameter validation macros based on platform_util.h */
81
#define ECJPAKE_VALIDATE_RET( cond ) \
82
MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
83
#define ECJPAKE_VALIDATE( cond ) \
84
MBEDTLS_INTERNAL_VALIDATE( cond )
87
* Convert a mbedtls_ecjpake_role to identifier string
89
static const char * const ecjpake_id[] = {
94
#define ID_MINE ( ecjpake_id[ ctx->role ] )
95
#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
100
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
102
ECJPAKE_VALIDATE( ctx != NULL );
105
mbedtls_ecp_group_init( &ctx->grp );
106
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
108
mbedtls_ecp_point_init( &ctx->Xm1 );
109
mbedtls_ecp_point_init( &ctx->Xm2 );
110
mbedtls_ecp_point_init( &ctx->Xp1 );
111
mbedtls_ecp_point_init( &ctx->Xp2 );
112
mbedtls_ecp_point_init( &ctx->Xp );
114
mbedtls_mpi_init( &ctx->xm1 );
115
mbedtls_mpi_init( &ctx->xm2 );
116
mbedtls_mpi_init( &ctx->s );
122
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
128
mbedtls_ecp_group_free( &ctx->grp );
130
mbedtls_ecp_point_free( &ctx->Xm1 );
131
mbedtls_ecp_point_free( &ctx->Xm2 );
132
mbedtls_ecp_point_free( &ctx->Xp1 );
133
mbedtls_ecp_point_free( &ctx->Xp2 );
134
mbedtls_ecp_point_free( &ctx->Xp );
136
mbedtls_mpi_free( &ctx->xm1 );
137
mbedtls_mpi_free( &ctx->xm2 );
138
mbedtls_mpi_free( &ctx->s );
144
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
145
mbedtls_ecjpake_role role,
146
mbedtls_md_type_t hash,
147
mbedtls_ecp_group_id curve,
148
const unsigned char *secret,
153
ECJPAKE_VALIDATE_RET( ctx != NULL );
154
ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
155
role == MBEDTLS_ECJPAKE_SERVER );
156
ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 );
160
if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
161
return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
163
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
165
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
169
mbedtls_ecjpake_free( ctx );
175
* Check if context is ready for use
177
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
179
ECJPAKE_VALIDATE_RET( ctx != NULL );
181
if( ctx->md_info == NULL ||
182
ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
185
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
192
* Write a point plus its length to a buffer
194
static int ecjpake_write_len_point( unsigned char **p,
195
const unsigned char *end,
196
const mbedtls_ecp_group *grp,
198
const mbedtls_ecp_point *P )
203
/* Need at least 4 for length plus 1 for point */
204
if( end < *p || end - *p < 5 )
205
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
207
ret = mbedtls_ecp_point_write_binary( grp, P, pf,
208
&len, *p + 4, end - ( *p + 4 ) );
212
(*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
213
(*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
214
(*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
215
(*p)[3] = (unsigned char)( ( len ) & 0xFF );
223
* Size of the temporary buffer for ecjpake_hash:
224
* 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
226
#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
229
* Compute hash for ZKP (7.4.2.2.2.1)
231
static int ecjpake_hash( const mbedtls_md_info_t *md_info,
232
const mbedtls_ecp_group *grp,
234
const mbedtls_ecp_point *G,
235
const mbedtls_ecp_point *V,
236
const mbedtls_ecp_point *X,
241
unsigned char buf[ECJPAKE_HASH_BUF_LEN];
242
unsigned char *p = buf;
243
const unsigned char *end = buf + sizeof( buf );
244
const size_t id_len = strlen( id );
245
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
247
/* Write things to temporary buffer */
248
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
249
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
250
MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
253
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
255
*p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
256
*p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
257
*p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
258
*p++ = (unsigned char)( ( id_len ) & 0xFF );
260
if( end < p || (size_t)( end - p ) < id_len )
261
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
263
memcpy( p, id, id_len );
267
MBEDTLS_MPI_CHK( mbedtls_md( md_info, buf, p - buf, hash ) );
269
/* Turn it into an integer mod n */
270
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
271
mbedtls_md_get_size( md_info ) ) );
272
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
279
* Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
281
static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
282
const mbedtls_ecp_group *grp,
284
const mbedtls_ecp_point *G,
285
const mbedtls_ecp_point *X,
287
const unsigned char **p,
288
const unsigned char *end )
291
mbedtls_ecp_point V, VV;
295
mbedtls_ecp_point_init( &V );
296
mbedtls_ecp_point_init( &VV );
297
mbedtls_mpi_init( &r );
298
mbedtls_mpi_init( &h );
303
* opaque r<1..2^8-1>;
307
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
309
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
311
if( end < *p || (size_t)( end - *p ) < 1 )
313
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
319
if( end < *p || (size_t)( end - *p ) < r_len )
321
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
325
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
331
MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
332
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
333
&VV, &h, X, &r, G ) );
335
if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
337
ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
342
mbedtls_ecp_point_free( &V );
343
mbedtls_ecp_point_free( &VV );
344
mbedtls_mpi_free( &r );
345
mbedtls_mpi_free( &h );
351
* Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
353
static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
354
const mbedtls_ecp_group *grp,
356
const mbedtls_ecp_point *G,
357
const mbedtls_mpi *x,
358
const mbedtls_ecp_point *X,
361
const unsigned char *end,
362
int (*f_rng)(void *, unsigned char *, size_t),
368
mbedtls_mpi h; /* later recycled to hold r */
372
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
374
mbedtls_ecp_point_init( &V );
375
mbedtls_mpi_init( &v );
376
mbedtls_mpi_init( &h );
378
/* Compute signature */
379
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
380
G, &v, &V, f_rng, p_rng ) );
381
MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
382
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
383
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
384
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
387
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
388
pf, &len, *p, end - *p ) );
391
len = mbedtls_mpi_size( &h ); /* actually r */
392
if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
394
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
398
*(*p)++ = (unsigned char)( len & 0xFF );
399
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
403
mbedtls_ecp_point_free( &V );
404
mbedtls_mpi_free( &v );
405
mbedtls_mpi_free( &h );
411
* Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
412
* Output: verified public key X
414
static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
415
const mbedtls_ecp_group *grp,
417
const mbedtls_ecp_point *G,
418
mbedtls_ecp_point *X,
420
const unsigned char **p,
421
const unsigned char *end )
426
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
434
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
435
if( mbedtls_ecp_is_zero( X ) )
437
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
441
MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
448
* Generate an ECJPAKEKeyKP
449
* Output: the serialized structure, plus private/public key pair
451
static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
452
const mbedtls_ecp_group *grp,
454
const mbedtls_ecp_point *G,
456
mbedtls_ecp_point *X,
459
const unsigned char *end,
460
int (*f_rng)(void *, unsigned char *, size_t),
467
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
469
/* Generate key (7.4.2.3.1) and write it out */
470
MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
472
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
473
pf, &len, *p, end - *p ) );
476
/* Generate and write proof */
477
MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
478
p, end, f_rng, p_rng ) );
485
* Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
486
* Ouputs: verified peer public keys Xa, Xb
488
static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
489
const mbedtls_ecp_group *grp,
491
const mbedtls_ecp_point *G,
492
mbedtls_ecp_point *Xa,
493
mbedtls_ecp_point *Xb,
495
const unsigned char *buf,
499
const unsigned char *p = buf;
500
const unsigned char *end = buf + len;
504
* ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
505
* } ECJPAKEKeyKPPairList;
507
MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
508
MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
511
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
518
* Generate a ECJPAKEKeyKPPairList
519
* Outputs: the serialized structure, plus two private/public key pairs
521
static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
522
const mbedtls_ecp_group *grp,
524
const mbedtls_ecp_point *G,
526
mbedtls_ecp_point *Xa,
528
mbedtls_ecp_point *Xb,
533
int (*f_rng)(void *, unsigned char *, size_t),
537
unsigned char *p = buf;
538
const unsigned char *end = buf + len;
540
MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
541
&p, end, f_rng, p_rng ) );
542
MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
543
&p, end, f_rng, p_rng ) );
552
* Read and process the first round message
554
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
555
const unsigned char *buf,
558
ECJPAKE_VALIDATE_RET( ctx != NULL );
559
ECJPAKE_VALIDATE_RET( buf != NULL );
561
return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
563
&ctx->Xp1, &ctx->Xp2, ID_PEER,
568
* Generate and write the first round message
570
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
571
unsigned char *buf, size_t len, size_t *olen,
572
int (*f_rng)(void *, unsigned char *, size_t),
575
ECJPAKE_VALIDATE_RET( ctx != NULL );
576
ECJPAKE_VALIDATE_RET( buf != NULL );
577
ECJPAKE_VALIDATE_RET( olen != NULL );
578
ECJPAKE_VALIDATE_RET( f_rng != NULL );
580
return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
582
&ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
583
ID_MINE, buf, len, olen, f_rng, p_rng ) );
587
* Compute the sum of three points R = A + B + C
589
static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
590
const mbedtls_ecp_point *A,
591
const mbedtls_ecp_point *B,
592
const mbedtls_ecp_point *C )
597
mbedtls_mpi_init( &one );
599
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
600
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
601
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
604
mbedtls_mpi_free( &one );
610
* Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
612
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
613
const unsigned char *buf,
617
const unsigned char *p = buf;
618
const unsigned char *end = buf + len;
619
mbedtls_ecp_group grp;
620
mbedtls_ecp_point G; /* C: GB, S: GA */
622
ECJPAKE_VALIDATE_RET( ctx != NULL );
623
ECJPAKE_VALIDATE_RET( buf != NULL );
625
mbedtls_ecp_group_init( &grp );
626
mbedtls_ecp_point_init( &G );
629
* Server: GA = X3 + X4 + X1 (7.4.2.6.1)
630
* Client: GB = X1 + X2 + X3 (7.4.2.5.1)
631
* Unified: G = Xm1 + Xm2 + Xp1
632
* We need that before parsing in order to check Xp as we read it
634
MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
635
&ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
639
* ECParameters curve_params; // only client reading server msg
640
* ECJPAKEKeyKP ecjpake_key_kp;
641
* } Client/ServerECJPAKEParams;
643
if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
645
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
646
if( grp.id != ctx->grp.id )
648
ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
653
MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
655
&G, &ctx->Xp, ID_PEER, &p, end ) );
659
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
664
mbedtls_ecp_group_free( &grp );
665
mbedtls_ecp_point_free( &G );
671
* Compute R = +/- X * S mod N, taking care not to leak S
673
static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
674
const mbedtls_mpi *X,
675
const mbedtls_mpi *S,
676
const mbedtls_mpi *N,
677
int (*f_rng)(void *, unsigned char *, size_t),
681
mbedtls_mpi b; /* Blinding value, then s + N * blinding */
683
mbedtls_mpi_init( &b );
685
/* b = s + rnd-128-bit * N */
686
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
687
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
688
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
690
/* R = sign * X * b mod N */
691
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
693
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
696
mbedtls_mpi_free( &b );
702
* Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
704
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
705
unsigned char *buf, size_t len, size_t *olen,
706
int (*f_rng)(void *, unsigned char *, size_t),
710
mbedtls_ecp_point G; /* C: GA, S: GB */
711
mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
712
mbedtls_mpi xm; /* C: xc, S: xs */
713
unsigned char *p = buf;
714
const unsigned char *end = buf + len;
717
ECJPAKE_VALIDATE_RET( ctx != NULL );
718
ECJPAKE_VALIDATE_RET( buf != NULL );
719
ECJPAKE_VALIDATE_RET( olen != NULL );
720
ECJPAKE_VALIDATE_RET( f_rng != NULL );
722
mbedtls_ecp_point_init( &G );
723
mbedtls_ecp_point_init( &Xm );
724
mbedtls_mpi_init( &xm );
727
* First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
729
* Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
730
* Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
731
* Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
733
MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
734
&ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
735
MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
736
&ctx->grp.N, f_rng, p_rng ) );
737
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
740
* Now write things out
743
* ECParameters curve_params; // only server writing its message
744
* ECJPAKEKeyKP ecjpake_key_kp;
745
* } Client/ServerECJPAKEParams;
747
if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
751
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
754
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
761
ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
764
MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
765
ctx->point_format, &ec_len, p, end - p ) );
768
MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
770
&G, &xm, &Xm, ID_MINE,
771
&p, end, f_rng, p_rng ) );
776
mbedtls_ecp_point_free( &G );
777
mbedtls_ecp_point_free( &Xm );
778
mbedtls_mpi_free( &xm );
784
* Derive PMS (7.4.2.7 / 7.4.2.8)
786
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
787
unsigned char *buf, size_t len, size_t *olen,
788
int (*f_rng)(void *, unsigned char *, size_t),
793
mbedtls_mpi m_xm2_s, one;
794
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
797
ECJPAKE_VALIDATE_RET( ctx != NULL );
798
ECJPAKE_VALIDATE_RET( buf != NULL );
799
ECJPAKE_VALIDATE_RET( olen != NULL );
800
ECJPAKE_VALIDATE_RET( f_rng != NULL );
802
*olen = mbedtls_md_get_size( ctx->md_info );
804
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
806
mbedtls_ecp_point_init( &K );
807
mbedtls_mpi_init( &m_xm2_s );
808
mbedtls_mpi_init( &one );
810
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
813
* Client: K = ( Xs - X4 * x2 * s ) * x2
814
* Server: K = ( Xc - X2 * x4 * s ) * x4
815
* Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
817
MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
818
&ctx->grp.N, f_rng, p_rng ) );
819
MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
821
&m_xm2_s, &ctx->Xp2 ) );
822
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
825
/* PMS = SHA-256( K.X ) */
826
x_bytes = ( ctx->grp.pbits + 7 ) / 8;
827
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
828
MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
831
mbedtls_ecp_point_free( &K );
832
mbedtls_mpi_free( &m_xm2_s );
833
mbedtls_mpi_free( &one );
841
#endif /* ! MBEDTLS_ECJPAKE_ALT */
843
#if defined(MBEDTLS_SELF_TEST)
845
#if defined(MBEDTLS_PLATFORM_C)
846
#include "mbedtls/platform.h"
849
#define mbedtls_printf printf
852
#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
853
!defined(MBEDTLS_SHA256_C)
854
int mbedtls_ecjpake_self_test( int verbose )
861
static const unsigned char ecjpake_test_password[] = {
862
0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
866
#if !defined(MBEDTLS_ECJPAKE_ALT)
868
static const unsigned char ecjpake_test_x1[] = {
869
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
870
0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
871
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
874
static const unsigned char ecjpake_test_x2[] = {
875
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
876
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
877
0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
880
static const unsigned char ecjpake_test_x3[] = {
881
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
882
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
883
0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
886
static const unsigned char ecjpake_test_x4[] = {
887
0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
888
0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
889
0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
892
static const unsigned char ecjpake_test_cli_one[] = {
893
0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
894
0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
895
0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
896
0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
897
0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
898
0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
899
0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
900
0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
901
0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
902
0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
903
0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
904
0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
905
0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
906
0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
907
0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
908
0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
909
0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
910
0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
911
0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
912
0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
913
0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
914
0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
915
0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
916
0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
917
0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
918
0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
919
0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
920
0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
923
static const unsigned char ecjpake_test_srv_one[] = {
924
0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
925
0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
926
0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
927
0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
928
0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
929
0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
930
0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
931
0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
932
0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
933
0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
934
0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
935
0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
936
0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
937
0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
938
0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
939
0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
940
0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
941
0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
942
0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
943
0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
944
0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
945
0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
946
0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
947
0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
948
0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
949
0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
950
0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
951
0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
954
static const unsigned char ecjpake_test_srv_two[] = {
955
0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
956
0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
957
0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
958
0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
959
0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
960
0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
961
0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
962
0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
963
0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
964
0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
965
0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
966
0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
967
0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
968
0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
971
static const unsigned char ecjpake_test_cli_two[] = {
972
0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
973
0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
974
0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
975
0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
976
0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
977
0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
978
0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
979
0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
980
0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
981
0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
982
0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
983
0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
984
0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
985
0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
988
static const unsigned char ecjpake_test_pms[] = {
989
0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
990
0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
991
0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
994
/* Load my private keys and generate the corresponding public keys */
995
static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
996
const unsigned char *xm1, size_t len1,
997
const unsigned char *xm2, size_t len2 )
1001
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
1002
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
1003
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
1004
&ctx->grp.G, NULL, NULL ) );
1005
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
1006
&ctx->grp.G, NULL, NULL ) );
1012
#endif /* ! MBEDTLS_ECJPAKE_ALT */
1014
/* For tests we don't need a secure RNG;
1015
* use the LGC from Numerical Recipes for simplicity */
1016
static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
1018
static uint32_t x = 42;
1023
size_t use_len = len > 4 ? 4 : len;
1024
x = 1664525 * x + 1013904223;
1025
memcpy( out, &x, use_len );
1033
#define TEST_ASSERT( x ) \
1047
int mbedtls_ecjpake_self_test( int verbose )
1050
mbedtls_ecjpake_context cli;
1051
mbedtls_ecjpake_context srv;
1052
unsigned char buf[512], pms[32];
1055
mbedtls_ecjpake_init( &cli );
1056
mbedtls_ecjpake_init( &srv );
1059
mbedtls_printf( " ECJPAKE test #0 (setup): " );
1061
TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
1062
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
1063
ecjpake_test_password,
1064
sizeof( ecjpake_test_password ) ) == 0 );
1066
TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
1067
MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
1068
ecjpake_test_password,
1069
sizeof( ecjpake_test_password ) ) == 0 );
1072
mbedtls_printf( "passed\n" );
1075
mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
1077
TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
1078
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1080
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
1082
TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
1083
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1085
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
1087
TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
1088
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1090
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
1092
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
1093
pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
1095
TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
1096
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1098
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
1100
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
1101
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1103
TEST_ASSERT( len == pmslen );
1104
TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
1107
mbedtls_printf( "passed\n" );
1109
#if !defined(MBEDTLS_ECJPAKE_ALT)
1110
/* 'reference handshake' tests can only be run against implementations
1111
* for which we have 100% control over how the random ephemeral keys
1112
* are generated. This is only the case for the internal mbed TLS
1113
* implementation, so these tests are skipped in case the internal
1114
* implementation is swapped out for an alternative one. */
1116
mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
1118
/* Simulate generation of round one */
1119
MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
1120
ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
1121
ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
1123
MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
1124
ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
1125
ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
1127
/* Read round one */
1128
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
1129
ecjpake_test_cli_one,
1130
sizeof( ecjpake_test_cli_one ) ) == 0 );
1132
TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
1133
ecjpake_test_srv_one,
1134
sizeof( ecjpake_test_srv_one ) ) == 0 );
1136
/* Skip generation of round two, read round two */
1137
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
1138
ecjpake_test_srv_two,
1139
sizeof( ecjpake_test_srv_two ) ) == 0 );
1141
TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
1142
ecjpake_test_cli_two,
1143
sizeof( ecjpake_test_cli_two ) ) == 0 );
1145
/* Server derives PMS */
1146
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
1147
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1149
TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1150
TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1152
memset( buf, 0, len ); /* Avoid interferences with next step */
1154
/* Client derives PMS */
1155
TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
1156
buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
1158
TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
1159
TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
1162
mbedtls_printf( "passed\n" );
1163
#endif /* ! MBEDTLS_ECJPAKE_ALT */
1166
mbedtls_ecjpake_free( &cli );
1167
mbedtls_ecjpake_free( &srv );
1172
mbedtls_printf( "failed\n" );
1178
mbedtls_printf( "\n" );
1185
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
1187
#endif /* MBEDTLS_SELF_TEST */
1189
#endif /* MBEDTLS_ECJPAKE_C */