2 * Elliptic curve J-PAKE
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This file is part of mbed TLS (https://tls.mbed.org)
23 * References in the code are to the Thread v1.0 Specification,
24 * available to members of the Thread Group http://threadgroup.org/
27 #if !defined(MBEDTLS_CONFIG_FILE)
28 #include "mbedtls/config.h"
30 #include MBEDTLS_CONFIG_FILE
33 #if defined(MBEDTLS_ECJPAKE_C)
35 #include "mbedtls/ecjpake.h"
40 * Convert a mbedtls_ecjpake_role to identifier string
42 static const char * const ecjpake_id
[] = {
47 #define ID_MINE ( ecjpake_id[ ctx->role ] )
48 #define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
53 void mbedtls_ecjpake_init( mbedtls_ecjpake_context
*ctx
)
59 mbedtls_ecp_group_init( &ctx
->grp
);
60 ctx
->point_format
= MBEDTLS_ECP_PF_UNCOMPRESSED
;
62 mbedtls_ecp_point_init( &ctx
->Xm1
);
63 mbedtls_ecp_point_init( &ctx
->Xm2
);
64 mbedtls_ecp_point_init( &ctx
->Xp1
);
65 mbedtls_ecp_point_init( &ctx
->Xp2
);
66 mbedtls_ecp_point_init( &ctx
->Xp
);
68 mbedtls_mpi_init( &ctx
->xm1
);
69 mbedtls_mpi_init( &ctx
->xm2
);
70 mbedtls_mpi_init( &ctx
->s
);
76 void mbedtls_ecjpake_free( mbedtls_ecjpake_context
*ctx
)
82 mbedtls_ecp_group_free( &ctx
->grp
);
84 mbedtls_ecp_point_free( &ctx
->Xm1
);
85 mbedtls_ecp_point_free( &ctx
->Xm2
);
86 mbedtls_ecp_point_free( &ctx
->Xp1
);
87 mbedtls_ecp_point_free( &ctx
->Xp2
);
88 mbedtls_ecp_point_free( &ctx
->Xp
);
90 mbedtls_mpi_free( &ctx
->xm1
);
91 mbedtls_mpi_free( &ctx
->xm2
);
92 mbedtls_mpi_free( &ctx
->s
);
98 int mbedtls_ecjpake_setup( mbedtls_ecjpake_context
*ctx
,
99 mbedtls_ecjpake_role role
,
100 mbedtls_md_type_t hash
,
101 mbedtls_ecp_group_id curve
,
102 const unsigned char *secret
,
109 if( ( ctx
->md_info
= mbedtls_md_info_from_type( hash
) ) == NULL
)
110 return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE
);
112 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx
->grp
, curve
) );
114 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx
->s
, secret
, len
) );
118 mbedtls_ecjpake_free( ctx
);
124 * Check if context is ready for use
126 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context
*ctx
)
128 if( ctx
->md_info
== NULL
||
129 ctx
->grp
.id
== MBEDTLS_ECP_DP_NONE
||
132 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
139 * Write a point plus its length to a buffer
141 static int ecjpake_write_len_point( unsigned char **p
,
142 const unsigned char *end
,
143 const mbedtls_ecp_group
*grp
,
145 const mbedtls_ecp_point
*P
)
150 /* Need at least 4 for length plus 1 for point */
151 if( end
< *p
|| end
- *p
< 5 )
152 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
);
154 ret
= mbedtls_ecp_point_write_binary( grp
, P
, pf
,
155 &len
, *p
+ 4, end
- ( *p
+ 4 ) );
159 (*p
)[0] = (unsigned char)( ( len
>> 24 ) & 0xFF );
160 (*p
)[1] = (unsigned char)( ( len
>> 16 ) & 0xFF );
161 (*p
)[2] = (unsigned char)( ( len
>> 8 ) & 0xFF );
162 (*p
)[3] = (unsigned char)( ( len
) & 0xFF );
170 * Size of the temporary buffer for ecjpake_hash:
171 * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
173 #define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
176 * Compute hash for ZKP (7.4.2.2.2.1)
178 static int ecjpake_hash( const mbedtls_md_info_t
*md_info
,
179 const mbedtls_ecp_group
*grp
,
181 const mbedtls_ecp_point
*G
,
182 const mbedtls_ecp_point
*V
,
183 const mbedtls_ecp_point
*X
,
188 unsigned char buf
[ECJPAKE_HASH_BUF_LEN
];
189 unsigned char *p
= buf
;
190 const unsigned char *end
= buf
+ sizeof( buf
);
191 const size_t id_len
= strlen( id
);
192 unsigned char hash
[MBEDTLS_MD_MAX_SIZE
];
194 /* Write things to temporary buffer */
195 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p
, end
, grp
, pf
, G
) );
196 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p
, end
, grp
, pf
, V
) );
197 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p
, end
, grp
, pf
, X
) );
200 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
);
202 *p
++ = (unsigned char)( ( id_len
>> 24 ) & 0xFF );
203 *p
++ = (unsigned char)( ( id_len
>> 16 ) & 0xFF );
204 *p
++ = (unsigned char)( ( id_len
>> 8 ) & 0xFF );
205 *p
++ = (unsigned char)( ( id_len
) & 0xFF );
207 if( end
< p
|| (size_t)( end
- p
) < id_len
)
208 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
);
210 memcpy( p
, id
, id_len
);
214 mbedtls_md( md_info
, buf
, p
- buf
, hash
);
216 /* Turn it into an integer mod n */
217 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h
, hash
,
218 mbedtls_md_get_size( md_info
) ) );
219 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h
, h
, &grp
->N
) );
226 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
228 static int ecjpake_zkp_read( const mbedtls_md_info_t
*md_info
,
229 const mbedtls_ecp_group
*grp
,
231 const mbedtls_ecp_point
*G
,
232 const mbedtls_ecp_point
*X
,
234 const unsigned char **p
,
235 const unsigned char *end
)
238 mbedtls_ecp_point V
, VV
;
242 mbedtls_ecp_point_init( &V
);
243 mbedtls_ecp_point_init( &VV
);
244 mbedtls_mpi_init( &r
);
245 mbedtls_mpi_init( &h
);
250 * opaque r<1..2^8-1>;
254 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
256 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp
, &V
, p
, end
- *p
) );
258 if( end
< *p
|| (size_t)( end
- *p
) < 1 )
260 ret
= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
266 if( end
< *p
|| (size_t)( end
- *p
) < r_len
)
268 ret
= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
272 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r
, *p
, r_len
) );
278 MBEDTLS_MPI_CHK( ecjpake_hash( md_info
, grp
, pf
, G
, &V
, X
, id
, &h
) );
279 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group
*) grp
,
280 &VV
, &h
, X
, &r
, G
) );
282 if( mbedtls_ecp_point_cmp( &VV
, &V
) != 0 )
284 ret
= MBEDTLS_ERR_ECP_VERIFY_FAILED
;
289 mbedtls_ecp_point_free( &V
);
290 mbedtls_ecp_point_free( &VV
);
291 mbedtls_mpi_free( &r
);
292 mbedtls_mpi_free( &h
);
298 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
300 static int ecjpake_zkp_write( const mbedtls_md_info_t
*md_info
,
301 const mbedtls_ecp_group
*grp
,
303 const mbedtls_ecp_point
*G
,
304 const mbedtls_mpi
*x
,
305 const mbedtls_ecp_point
*X
,
308 const unsigned char *end
,
309 int (*f_rng
)(void *, unsigned char *, size_t),
315 mbedtls_mpi h
; /* later recycled to hold r */
319 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
);
321 mbedtls_ecp_point_init( &V
);
322 mbedtls_mpi_init( &v
);
323 mbedtls_mpi_init( &h
);
325 /* Compute signature */
326 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group
*) grp
,
327 G
, &v
, &V
, f_rng
, p_rng
) );
328 MBEDTLS_MPI_CHK( ecjpake_hash( md_info
, grp
, pf
, G
, &V
, X
, id
, &h
) );
329 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h
, &h
, x
) ); /* x*h */
330 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h
, &v
, &h
) ); /* v - x*h */
331 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h
, &h
, &grp
->N
) ); /* r */
334 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp
, &V
,
335 pf
, &len
, *p
, end
- *p
) );
338 len
= mbedtls_mpi_size( &h
); /* actually r */
339 if( end
< *p
|| (size_t)( end
- *p
) < 1 + len
|| len
> 255 )
341 ret
= MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
;
345 *(*p
)++ = (unsigned char)( len
& 0xFF );
346 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h
, *p
, len
) ); /* r */
350 mbedtls_ecp_point_free( &V
);
351 mbedtls_mpi_free( &v
);
352 mbedtls_mpi_free( &h
);
358 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
359 * Output: verified public key X
361 static int ecjpake_kkp_read( const mbedtls_md_info_t
*md_info
,
362 const mbedtls_ecp_group
*grp
,
364 const mbedtls_ecp_point
*G
,
365 mbedtls_ecp_point
*X
,
367 const unsigned char **p
,
368 const unsigned char *end
)
373 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA
);
381 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp
, X
, p
, end
- *p
) );
382 if( mbedtls_ecp_is_zero( X
) )
384 ret
= MBEDTLS_ERR_ECP_INVALID_KEY
;
388 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info
, grp
, pf
, G
, X
, id
, p
, end
) );
395 * Generate an ECJPAKEKeyKP
396 * Output: the serialized structure, plus private/public key pair
398 static int ecjpake_kkp_write( const mbedtls_md_info_t
*md_info
,
399 const mbedtls_ecp_group
*grp
,
401 const mbedtls_ecp_point
*G
,
403 mbedtls_ecp_point
*X
,
406 const unsigned char *end
,
407 int (*f_rng
)(void *, unsigned char *, size_t),
414 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
);
416 /* Generate key (7.4.2.3.1) and write it out */
417 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group
*) grp
, G
, x
, X
,
419 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp
, X
,
420 pf
, &len
, *p
, end
- *p
) );
423 /* Generate and write proof */
424 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info
, grp
, pf
, G
, x
, X
, id
,
425 p
, end
, f_rng
, p_rng
) );
432 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
433 * Ouputs: verified peer public keys Xa, Xb
435 static int ecjpake_kkpp_read( const mbedtls_md_info_t
*md_info
,
436 const mbedtls_ecp_group
*grp
,
438 const mbedtls_ecp_point
*G
,
439 mbedtls_ecp_point
*Xa
,
440 mbedtls_ecp_point
*Xb
,
442 const unsigned char *buf
,
446 const unsigned char *p
= buf
;
447 const unsigned char *end
= buf
+ len
;
451 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
452 * } ECJPAKEKeyKPPairList;
454 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info
, grp
, pf
, G
, Xa
, id
, &p
, end
) );
455 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info
, grp
, pf
, G
, Xb
, id
, &p
, end
) );
458 ret
= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
465 * Generate a ECJPAKEKeyKPPairList
466 * Outputs: the serialized structure, plus two private/public key pairs
468 static int ecjpake_kkpp_write( const mbedtls_md_info_t
*md_info
,
469 const mbedtls_ecp_group
*grp
,
471 const mbedtls_ecp_point
*G
,
473 mbedtls_ecp_point
*Xa
,
475 mbedtls_ecp_point
*Xb
,
480 int (*f_rng
)(void *, unsigned char *, size_t),
484 unsigned char *p
= buf
;
485 const unsigned char *end
= buf
+ len
;
487 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info
, grp
, pf
, G
, xm1
, Xa
, id
,
488 &p
, end
, f_rng
, p_rng
) );
489 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info
, grp
, pf
, G
, xm2
, Xb
, id
,
490 &p
, end
, f_rng
, p_rng
) );
499 * Read and process the first round message
501 int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context
*ctx
,
502 const unsigned char *buf
,
505 return( ecjpake_kkpp_read( ctx
->md_info
, &ctx
->grp
, ctx
->point_format
,
507 &ctx
->Xp1
, &ctx
->Xp2
, ID_PEER
,
512 * Generate and write the first round message
514 int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context
*ctx
,
515 unsigned char *buf
, size_t len
, size_t *olen
,
516 int (*f_rng
)(void *, unsigned char *, size_t),
519 return( ecjpake_kkpp_write( ctx
->md_info
, &ctx
->grp
, ctx
->point_format
,
521 &ctx
->xm1
, &ctx
->Xm1
, &ctx
->xm2
, &ctx
->Xm2
,
522 ID_MINE
, buf
, len
, olen
, f_rng
, p_rng
) );
526 * Compute the sum of three points R = A + B + C
528 static int ecjpake_ecp_add3( mbedtls_ecp_group
*grp
, mbedtls_ecp_point
*R
,
529 const mbedtls_ecp_point
*A
,
530 const mbedtls_ecp_point
*B
,
531 const mbedtls_ecp_point
*C
)
536 mbedtls_mpi_init( &one
);
538 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one
, 1 ) );
539 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp
, R
, &one
, A
, &one
, B
) );
540 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp
, R
, &one
, R
, &one
, C
) );
543 mbedtls_mpi_free( &one
);
549 * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
551 int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context
*ctx
,
552 const unsigned char *buf
,
556 const unsigned char *p
= buf
;
557 const unsigned char *end
= buf
+ len
;
558 mbedtls_ecp_group grp
;
559 mbedtls_ecp_point G
; /* C: GB, S: GA */
561 mbedtls_ecp_group_init( &grp
);
562 mbedtls_ecp_point_init( &G
);
565 * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
566 * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
567 * Unified: G = Xm1 + Xm2 + Xp1
568 * We need that before parsing in order to check Xp as we read it
570 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx
->grp
, &G
,
571 &ctx
->Xm1
, &ctx
->Xm2
, &ctx
->Xp1
) );
575 * ECParameters curve_params; // only client reading server msg
576 * ECJPAKEKeyKP ecjpake_key_kp;
577 * } Client/ServerECJPAKEParams;
579 if( ctx
->role
== MBEDTLS_ECJPAKE_CLIENT
)
581 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp
, &p
, len
) );
582 if( grp
.id
!= ctx
->grp
.id
)
584 ret
= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
;
589 MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx
->md_info
, &ctx
->grp
,
591 &G
, &ctx
->Xp
, ID_PEER
, &p
, end
) );
595 ret
= MBEDTLS_ERR_ECP_BAD_INPUT_DATA
;
600 mbedtls_ecp_group_free( &grp
);
601 mbedtls_ecp_point_free( &G
);
607 * Compute R = +/- X * S mod N, taking care not to leak S
609 static int ecjpake_mul_secret( mbedtls_mpi
*R
, int sign
,
610 const mbedtls_mpi
*X
,
611 const mbedtls_mpi
*S
,
612 const mbedtls_mpi
*N
,
613 int (*f_rng
)(void *, unsigned char *, size_t),
617 mbedtls_mpi b
; /* Blinding value, then s + N * blinding */
619 mbedtls_mpi_init( &b
);
621 /* b = s + rnd-128-bit * N */
622 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b
, 16, f_rng
, p_rng
) );
623 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b
, &b
, N
) );
624 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b
, &b
, S
) );
626 /* R = sign * X * b mod N */
627 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R
, X
, &b
) );
629 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R
, R
, N
) );
632 mbedtls_mpi_free( &b
);
638 * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
640 int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context
*ctx
,
641 unsigned char *buf
, size_t len
, size_t *olen
,
642 int (*f_rng
)(void *, unsigned char *, size_t),
646 mbedtls_ecp_point G
; /* C: GA, S: GB */
647 mbedtls_ecp_point Xm
; /* C: Xc, S: Xs */
648 mbedtls_mpi xm
; /* C: xc, S: xs */
649 unsigned char *p
= buf
;
650 const unsigned char *end
= buf
+ len
;
653 mbedtls_ecp_point_init( &G
);
654 mbedtls_ecp_point_init( &Xm
);
655 mbedtls_mpi_init( &xm
);
658 * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
660 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
661 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
662 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
664 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx
->grp
, &G
,
665 &ctx
->Xp1
, &ctx
->Xp2
, &ctx
->Xm1
) );
666 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm
, 1, &ctx
->xm2
, &ctx
->s
,
667 &ctx
->grp
.N
, f_rng
, p_rng
) );
668 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx
->grp
, &Xm
, &xm
, &G
, f_rng
, p_rng
) );
671 * Now write things out
674 * ECParameters curve_params; // only server writing its message
675 * ECJPAKEKeyKP ecjpake_key_kp;
676 * } Client/ServerECJPAKEParams;
678 if( ctx
->role
== MBEDTLS_ECJPAKE_SERVER
)
682 ret
= MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
;
685 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx
->grp
, &ec_len
,
692 ret
= MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
;
695 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx
->grp
, &Xm
,
696 ctx
->point_format
, &ec_len
, p
, end
- p
) );
699 MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx
->md_info
, &ctx
->grp
,
701 &G
, &xm
, &Xm
, ID_MINE
,
702 &p
, end
, f_rng
, p_rng
) );
707 mbedtls_ecp_point_free( &G
);
708 mbedtls_ecp_point_free( &Xm
);
709 mbedtls_mpi_free( &xm
);
715 * Derive PMS (7.4.2.7 / 7.4.2.8)
717 int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context
*ctx
,
718 unsigned char *buf
, size_t len
, size_t *olen
,
719 int (*f_rng
)(void *, unsigned char *, size_t),
724 mbedtls_mpi m_xm2_s
, one
;
725 unsigned char kx
[MBEDTLS_ECP_MAX_BYTES
];
728 *olen
= mbedtls_md_get_size( ctx
->md_info
);
730 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL
);
732 mbedtls_ecp_point_init( &K
);
733 mbedtls_mpi_init( &m_xm2_s
);
734 mbedtls_mpi_init( &one
);
736 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one
, 1 ) );
739 * Client: K = ( Xs - X4 * x2 * s ) * x2
740 * Server: K = ( Xc - X2 * x4 * s ) * x4
741 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
743 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s
, -1, &ctx
->xm2
, &ctx
->s
,
744 &ctx
->grp
.N
, f_rng
, p_rng
) );
745 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx
->grp
, &K
,
747 &m_xm2_s
, &ctx
->Xp2
) );
748 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx
->grp
, &K
, &ctx
->xm2
, &K
,
751 /* PMS = SHA-256( K.X ) */
752 x_bytes
= ( ctx
->grp
.pbits
+ 7 ) / 8;
753 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K
.X
, kx
, x_bytes
) );
754 MBEDTLS_MPI_CHK( mbedtls_md( ctx
->md_info
, kx
, x_bytes
, buf
) );
757 mbedtls_ecp_point_free( &K
);
758 mbedtls_mpi_free( &m_xm2_s
);
759 mbedtls_mpi_free( &one
);
768 #if defined(MBEDTLS_SELF_TEST)
770 #if defined(MBEDTLS_PLATFORM_C)
771 #include "mbedtls/platform.h"
774 #define mbedtls_printf printf
777 #if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
778 !defined(MBEDTLS_SHA256_C)
779 int mbedtls_ecjpake_self_test( int verbose
)
786 static const unsigned char ecjpake_test_password
[] = {
787 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
791 static const unsigned char ecjpake_test_x1
[] = {
792 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
793 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
794 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
797 static const unsigned char ecjpake_test_x2
[] = {
798 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
799 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
800 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
803 static const unsigned char ecjpake_test_x3
[] = {
804 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
805 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
806 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
809 static const unsigned char ecjpake_test_x4
[] = {
810 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
811 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
812 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
815 static const unsigned char ecjpake_test_cli_one
[] = {
816 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
817 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
818 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
819 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
820 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
821 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
822 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
823 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
824 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
825 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
826 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
827 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
828 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
829 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
830 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
831 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
832 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
833 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
834 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
835 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
836 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
837 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
838 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
839 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
840 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
841 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
842 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
843 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
846 static const unsigned char ecjpake_test_srv_one
[] = {
847 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
848 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
849 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
850 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
851 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
852 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
853 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
854 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
855 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
856 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
857 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
858 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
859 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
860 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
861 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
862 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
863 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
864 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
865 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
866 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
867 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
868 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
869 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
870 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
871 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
872 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
873 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
874 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
877 static const unsigned char ecjpake_test_srv_two
[] = {
878 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
879 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
880 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
881 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
882 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
883 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
884 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
885 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
886 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
887 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
888 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
889 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
890 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
891 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
894 static const unsigned char ecjpake_test_cli_two
[] = {
895 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
896 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
897 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
898 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
899 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
900 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
901 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
902 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
903 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
904 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
905 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
906 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
907 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
908 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
911 static const unsigned char ecjpake_test_pms
[] = {
912 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
913 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
914 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
917 /* Load my private keys and generate the correponding public keys */
918 static int ecjpake_test_load( mbedtls_ecjpake_context
*ctx
,
919 const unsigned char *xm1
, size_t len1
,
920 const unsigned char *xm2
, size_t len2
)
924 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx
->xm1
, xm1
, len1
) );
925 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx
->xm2
, xm2
, len2
) );
926 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx
->grp
, &ctx
->Xm1
, &ctx
->xm1
,
927 &ctx
->grp
.G
, NULL
, NULL
) );
928 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx
->grp
, &ctx
->Xm2
, &ctx
->xm2
,
929 &ctx
->grp
.G
, NULL
, NULL
) );
935 /* For tests we don't need a secure RNG;
936 * use the LGC from Numerical Recipes for simplicity */
937 static int ecjpake_lgc( void *p
, unsigned char *out
, size_t len
)
939 static uint32_t x
= 42;
944 size_t use_len
= len
> 4 ? 4 : len
;
945 x
= 1664525 * x
+ 1013904223;
946 memcpy( out
, &x
, use_len
);
954 #define TEST_ASSERT( x ) \
968 int mbedtls_ecjpake_self_test( int verbose
)
971 mbedtls_ecjpake_context cli
;
972 mbedtls_ecjpake_context srv
;
973 unsigned char buf
[512], pms
[32];
976 mbedtls_ecjpake_init( &cli
);
977 mbedtls_ecjpake_init( &srv
);
980 mbedtls_printf( " ECJPAKE test #0 (setup): " );
982 TEST_ASSERT( mbedtls_ecjpake_setup( &cli
, MBEDTLS_ECJPAKE_CLIENT
,
983 MBEDTLS_MD_SHA256
, MBEDTLS_ECP_DP_SECP256R1
,
984 ecjpake_test_password
,
985 sizeof( ecjpake_test_password
) ) == 0 );
987 TEST_ASSERT( mbedtls_ecjpake_setup( &srv
, MBEDTLS_ECJPAKE_SERVER
,
988 MBEDTLS_MD_SHA256
, MBEDTLS_ECP_DP_SECP256R1
,
989 ecjpake_test_password
,
990 sizeof( ecjpake_test_password
) ) == 0 );
993 mbedtls_printf( "passed\n" );
996 mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
998 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli
,
999 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1001 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv
, buf
, len
) == 0 );
1003 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv
,
1004 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1006 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli
, buf
, len
) == 0 );
1008 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv
,
1009 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1011 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli
, buf
, len
) == 0 );
1013 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli
,
1014 pms
, sizeof( pms
), &pmslen
, ecjpake_lgc
, NULL
) == 0 );
1016 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli
,
1017 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1019 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv
, buf
, len
) == 0 );
1021 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv
,
1022 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1024 TEST_ASSERT( len
== pmslen
);
1025 TEST_ASSERT( memcmp( buf
, pms
, len
) == 0 );
1028 mbedtls_printf( "passed\n" );
1031 mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
1033 /* Simulate generation of round one */
1034 MBEDTLS_MPI_CHK( ecjpake_test_load( &cli
,
1035 ecjpake_test_x1
, sizeof( ecjpake_test_x1
),
1036 ecjpake_test_x2
, sizeof( ecjpake_test_x2
) ) );
1038 MBEDTLS_MPI_CHK( ecjpake_test_load( &srv
,
1039 ecjpake_test_x3
, sizeof( ecjpake_test_x3
),
1040 ecjpake_test_x4
, sizeof( ecjpake_test_x4
) ) );
1042 /* Read round one */
1043 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv
,
1044 ecjpake_test_cli_one
,
1045 sizeof( ecjpake_test_cli_one
) ) == 0 );
1047 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli
,
1048 ecjpake_test_srv_one
,
1049 sizeof( ecjpake_test_srv_one
) ) == 0 );
1051 /* Skip generation of round two, read round two */
1052 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli
,
1053 ecjpake_test_srv_two
,
1054 sizeof( ecjpake_test_srv_two
) ) == 0 );
1056 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv
,
1057 ecjpake_test_cli_two
,
1058 sizeof( ecjpake_test_cli_two
) ) == 0 );
1060 /* Server derives PMS */
1061 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv
,
1062 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1064 TEST_ASSERT( len
== sizeof( ecjpake_test_pms
) );
1065 TEST_ASSERT( memcmp( buf
, ecjpake_test_pms
, len
) == 0 );
1067 memset( buf
, 0, len
); /* Avoid interferences with next step */
1069 /* Client derives PMS */
1070 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli
,
1071 buf
, sizeof( buf
), &len
, ecjpake_lgc
, NULL
) == 0 );
1073 TEST_ASSERT( len
== sizeof( ecjpake_test_pms
) );
1074 TEST_ASSERT( memcmp( buf
, ecjpake_test_pms
, len
) == 0 );
1077 mbedtls_printf( "passed\n" );
1080 mbedtls_ecjpake_free( &cli
);
1081 mbedtls_ecjpake_free( &srv
);
1086 mbedtls_printf( "failed\n" );
1092 mbedtls_printf( "\n" );
1099 #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
1101 #endif /* MBEDTLS_SELF_TEST */
1103 #endif /* MBEDTLS_ECJPAKE_C */