blob: 9e074c9cf6f259cb637227a102587ae548d20fc9 [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é-Gonnard8489f172015-08-07 17:47:39 +020023 * We implement EC-JPAKE as defined in Chapter 7.4 of the Thread v1.0
24 * Specification. References below are to this document.
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/*
40 * Write a point plus its length to a buffer
41 */
42static int ecjpake_write_len_point( unsigned char **p,
43 const unsigned char *end,
44 const mbedtls_ecp_group *grp,
45 const mbedtls_ecp_point *P )
46{
47 int ret;
48 size_t len;
49
50 /* Need at least 4 for length plus 1 for point */
51 if( end < *p || end - *p < 5 )
52 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
53
54 ret = mbedtls_ecp_point_write_binary( grp, P, MBEDTLS_ECP_PF_UNCOMPRESSED,
55 &len, *p + 4, end - ( *p + 4 ) );
56 if( ret != 0 )
57 return( ret );
58
59 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
60 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
61 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
62 (*p)[3] = (unsigned char)( ( len ) & 0xFF );
63
64 *p += 4 + len;
65
66 return( 0 );
67}
68
69/*
70 * Size of the temporary buffer for ecjpake_hash:
71 * 3 EC points plus their length, plus ID (6 bytes)
72 */
73#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 6 )
74
75/*
76 * Compute hash for ZKP (7.4.2.2.2.1)
77 */
78static int ecjpake_hash( const mbedtls_md_info_t *md_info,
79 const mbedtls_ecp_group *grp,
80 const mbedtls_ecp_point *G,
81 const mbedtls_ecp_point *V,
82 const mbedtls_ecp_point *X,
83 const char *id,
84 mbedtls_mpi *h )
85{
86 int ret;
87 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
88 unsigned char *p = buf;
89 const unsigned char *end = buf + sizeof( buf );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +020090 const size_t id_len = strlen( id );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020091 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
92
93 /* Write things to temporary buffer */
94 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, G ) );
95 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, V ) );
96 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, X ) );
97
98 if( end < p || (size_t)( end - p ) < id_len )
99 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
100
101 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
102 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
103 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
104 *p++ = (unsigned char)( ( id_len ) & 0xFF );
105
106 memcpy( p, id, id_len );
107 p += id_len;
108
109 /* Compute hash */
110 mbedtls_md( md_info, buf, p - buf, hash );
111
112 /* Turn it into an integer mod n */
113 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
114 mbedtls_md_get_size( md_info ) ) );
115 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
116
117cleanup:
118 return( ret );
119}
120
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200121/*
122 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
123 */
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200124static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200125 const mbedtls_ecp_group *grp,
126 const mbedtls_ecp_point *G,
127 const mbedtls_mpi *x,
128 const mbedtls_ecp_point *X,
129 const char *id,
130 unsigned char **p,
131 const unsigned char *end,
132 int (*f_rng)(void *, unsigned char *, size_t),
133 void *p_rng )
134{
135 int ret;
136 mbedtls_ecp_point V;
137 mbedtls_mpi v;
138 mbedtls_mpi h; /* later recycled to hold r */
139 size_t len;
140
141 if( end < *p )
142 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
143
144 mbedtls_ecp_point_init( &V );
145 mbedtls_mpi_init( &v );
146 mbedtls_mpi_init( &h );
147
148 /* Compute signature */
Manuel Pégourié-Gonnardc6181952015-08-11 14:33:51 +0200149 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
150 G, &v, &V, f_rng, p_rng ) );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200151 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, G, &V, X, id, &h ) );
152 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
153 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
154 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
155
156 /* Write it out */
157 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
158 MBEDTLS_ECP_PF_UNCOMPRESSED, &len, *p, end - *p ) );
159 *p += len;
160
161 len = mbedtls_mpi_size( &h ); /* actually r */
162 if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200163 {
164 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
165 goto cleanup;
166 }
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200167
168 *(*p)++ = (unsigned char)( len & 0xFF );
169 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
170 *p += len;
171
172cleanup:
173 mbedtls_ecp_point_free( &V );
174 mbedtls_mpi_free( &v );
175 mbedtls_mpi_free( &h );
176
177 return( ret );
178}
179
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200180/*
181 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
182 */
183static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
184 const mbedtls_ecp_group *grp,
185 const mbedtls_ecp_point *G,
186 const mbedtls_ecp_point *X,
187 const char *id,
188 unsigned char **p,
189 const unsigned char *end )
190{
191 int ret;
192 mbedtls_ecp_point V, VV;
193 mbedtls_mpi r, h;
194 size_t r_len;
195
196 mbedtls_ecp_point_init( &V );
197 mbedtls_ecp_point_init( &VV );
198 mbedtls_mpi_init( &r );
199 mbedtls_mpi_init( &h );
200
201 /*
202 * struct {
203 * ECPoint V;
204 * opaque r<1..2^8-1>;
205 * } ECSchnorrZKP;
206 */
207 if( end < *p )
208 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
209
210 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V,
211 (const unsigned char **) p, end - *p ) );
212
213 if( end < *p || (size_t)( end - *p ) < 1 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200214 {
215 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
216 goto cleanup;
217 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200218
219 r_len = *(*p)++;
220 if( end < *p || (size_t)( end - *p ) < r_len )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200221 {
222 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
223 goto cleanup;
224 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200225
226 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
227 *p += r_len;
228
229 /*
230 * Verification
231 */
232 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, G, &V, X, id, &h ) );
233 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
234 &VV, &h, X, &r, G ) );
235
236 if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200237 {
238 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
239 goto cleanup;
240 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200241
242cleanup:
243 mbedtls_ecp_point_free( &V );
244 mbedtls_ecp_point_free( &VV );
245 mbedtls_mpi_free( &r );
246 mbedtls_mpi_free( &h );
247
248 return( ret );
249}
250
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200251/*
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200252 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
253 * Output: verified public key X
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200254 */
255static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
256 const mbedtls_ecp_group *grp,
257 const mbedtls_ecp_point *G,
258 mbedtls_ecp_point *X,
259 const char *id,
260 unsigned char **p,
261 const unsigned char *end )
262{
263 int ret;
264
265 if( end < *p )
266 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
267
268 /*
269 * struct {
270 * ECPoint X;
271 * ECSchnorrZKP zkp;
272 * } ECJPAKEKeyKP;
273 */
274 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X,
275 (const unsigned char **) p, end - *p ) );
276 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, G, X, id, p, end ) );
277
278cleanup:
279 return( ret );
280}
281
282/*
283 * Generate an ECJPAKEKeyKP
284 * Output: the serialized structure, plus private/public key pair
285 */
286static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
287 const mbedtls_ecp_group *grp,
288 const mbedtls_ecp_point *G,
289 mbedtls_mpi *x,
290 mbedtls_ecp_point *X,
291 const char *id,
292 unsigned char **p,
293 const unsigned char *end,
294 int (*f_rng)(void *, unsigned char *, size_t),
295 void *p_rng )
296{
297 int ret;
298 size_t len;
299
300 if( end < *p )
301 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
302
303 /* Generate key (7.4.2.3.1) and write it out */
304 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
305 f_rng, p_rng ) );
306 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
307 MBEDTLS_ECP_PF_UNCOMPRESSED, &len, *p, end - *p ) );
308 *p += len;
309
310 /* Generate and write proof */
311 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, G, x, X, id,
312 p, end, f_rng, p_rng ) );
313
314cleanup:
315 return( ret );
316}
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200317
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200318/*
319 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
320 * Ouputs: verified peer public keys Xa, Xb
321 */
322static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
323 const mbedtls_ecp_group *grp,
324 const mbedtls_ecp_point *G,
325 mbedtls_ecp_point *Xa,
326 mbedtls_ecp_point *Xb,
327 const char *id,
328 const unsigned char *buf,
329 size_t len )
330{
331 int ret;
332 unsigned char *p = (unsigned char *) buf;
333 const unsigned char *end = buf + len;
334
335 /*
336 * struct {
337 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
338 * } ECJPAKEKeyKPPairList;
339 */
340 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, G, Xa, id, &p, end ) );
341 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, G, Xb, id, &p, end ) );
342
343 if( p != end )
344 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
345
346cleanup:
347 return( ret );
348}
349
350/*
351 * Generate a ECJPAKEKeyKPPairList
352 * Outputs: the serialized structure, plus two private/public key pairs
353 */
354static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
355 const mbedtls_ecp_group *grp,
356 const mbedtls_ecp_point *G,
357 mbedtls_mpi *xa,
358 mbedtls_ecp_point *Xa,
359 mbedtls_mpi *xb,
360 mbedtls_ecp_point *Xb,
361 const char *id,
362 unsigned char *buf,
363 size_t len,
364 size_t *olen,
365 int (*f_rng)(void *, unsigned char *, size_t),
366 void *p_rng )
367{
368 int ret;
369 unsigned char *p = buf;
370 const unsigned char *end = buf + len;
371
372 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, G, xa, Xa, id,
373 &p, end, f_rng, p_rng ) );
374 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, G, xb, Xb, id,
375 &p, end, f_rng, p_rng ) );
376
377 *olen = p - buf;
378
379cleanup:
380 return( ret );
381}
382
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200383#if defined(MBEDTLS_SELF_TEST)
384
385#if defined(MBEDTLS_PLATFORM_C)
386#include "mbedtls/platform.h"
387#else
388#include <stdio.h>
389#define mbedtls_printf printf
390#endif
391
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200392#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
393 !defined(MBEDTLS_SHA256_C)
394int mbedtls_ecjpake_self_test( int verbose )
395{
396 (void) verbose;
397 return( 0 );
398}
399#else
400
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200401static const unsigned char ecjpake_test_kkpp[] = {
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200402 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
403 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
404 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
405 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
406 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
407 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
408 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
409 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
410 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
411 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
412 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
413 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
414 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200415 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
416 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
417 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
418 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
419 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
420 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
421 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
422 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
423 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
424 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
425 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
426 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
427 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
428 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
429 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200430};
431
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200432/* For tests we don't need a secure RNG;
433 * use the LGC from Numerical Recipes for simplicity */
434static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
435{
436 static uint32_t x = 42;
437 (void) p;
438
439 while( len > 0 )
440 {
441 size_t use_len = len > 4 ? 4 : len;
442 x = 1664525 * x + 1013904223;
443 memcpy( out, &x, use_len );
444 out += use_len;
445 len -= use_len;
446 }
447
448 return( 0 );
449}
450
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200451#define TEST_ASSERT( x ) \
452 do { \
453 if( x ) \
454 ret = 0; \
455 else \
456 { \
457 ret = 1; \
458 goto cleanup; \
459 } \
460 } while( 0 )
461
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200462/*
463 * Checkup routine
464 */
465int mbedtls_ecjpake_self_test( int verbose )
466{
467 int ret;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200468 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200469 mbedtls_ecp_point Xa, Xb;
470 mbedtls_mpi xa, xb;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200471 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200472 unsigned char buf[1000];
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200473 size_t len;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200474
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200475 mbedtls_ecp_group_init( &grp );
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200476 mbedtls_ecp_point_init( &Xa );
477 mbedtls_ecp_point_init( &Xb );
478 mbedtls_mpi_init( &xa );
479 mbedtls_mpi_init( &xb );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200480
481 /* Common to all tests */
482 md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
483 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP256R1 ) );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200484
485 if( verbose != 0 )
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200486 mbedtls_printf( " ECJPAKE test #1 (kkpp read): " );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200487
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200488 TEST_ASSERT( ecjpake_kkpp_read( md_info, &grp, &grp.G,
489 &Xa, &Xb, "client",
490 ecjpake_test_kkpp,
491 sizeof( ecjpake_test_kkpp ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200492
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200493 /* Corrupt message */
494 memcpy( buf, ecjpake_test_kkpp, sizeof( ecjpake_test_kkpp ) );
495 buf[sizeof( ecjpake_test_kkpp ) - 1]--;
496 TEST_ASSERT( ecjpake_kkpp_read( md_info, &grp, &grp.G,
497 &Xa, &Xb, "client",
498 buf, sizeof( ecjpake_test_kkpp ) )
499 == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200500
501 if( verbose != 0 )
502 mbedtls_printf( "passed\n" );
503
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200504 if( verbose != 0 )
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200505 mbedtls_printf( " ECJPAKE test #2 (kkpp write/read): " );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200506
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200507 TEST_ASSERT( ecjpake_kkpp_write( md_info, &grp, &grp.G,
508 &xa, &Xa, &xb, &Xb, "client",
509 buf, sizeof( buf ), &len,
510 ecjpake_lgc, NULL ) == 0 );
511
512 TEST_ASSERT( ecjpake_kkpp_read( md_info, &grp, &grp.G,
513 &Xa, &Xb, "client",
514 buf, len ) == 0 );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200515
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200516 if( verbose != 0 )
517 mbedtls_printf( "passed\n" );
518
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200519cleanup:
520 mbedtls_ecp_group_free( &grp );
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200521 mbedtls_ecp_point_free( &Xa );
522 mbedtls_ecp_point_free( &Xb );
523 mbedtls_mpi_free( &xa );
524 mbedtls_mpi_free( &xb );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200525
526 if( ret != 0 )
527 {
528 if( verbose != 0 )
529 mbedtls_printf( "failed\n" );
530
531 ret = 1;
532 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200533
534 if( verbose != 0 )
535 mbedtls_printf( "\n" );
536
537 return( ret );
538}
539
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200540#undef TEST_ASSERT
541
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200542#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
543
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200544#endif /* MBEDTLS_SELF_TEST */
545
546#endif /* MBEDTLS_ECJPAKE_C */