blob: f56142cc9d1730fbafb1c17e462a2c3e957afc05 [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,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200188 const unsigned char **p,
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200189 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
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200210 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200211
212 if( end < *p || (size_t)( end - *p ) < 1 )
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200213 {
214 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
215 goto cleanup;
216 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200217
218 r_len = *(*p)++;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200219
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200220 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,
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200260 const unsigned char **p,
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200261 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 */
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200274 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200275 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, G, X, id, p, end ) );
276
277cleanup:
278 return( ret );
279}
280
281/*
282 * Generate an ECJPAKEKeyKP
283 * Output: the serialized structure, plus private/public key pair
284 */
285static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
286 const mbedtls_ecp_group *grp,
287 const mbedtls_ecp_point *G,
288 mbedtls_mpi *x,
289 mbedtls_ecp_point *X,
290 const char *id,
291 unsigned char **p,
292 const unsigned char *end,
293 int (*f_rng)(void *, unsigned char *, size_t),
294 void *p_rng )
295{
296 int ret;
297 size_t len;
298
299 if( end < *p )
300 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
301
302 /* Generate key (7.4.2.3.1) and write it out */
303 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
304 f_rng, p_rng ) );
305 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
306 MBEDTLS_ECP_PF_UNCOMPRESSED, &len, *p, end - *p ) );
307 *p += len;
308
309 /* Generate and write proof */
310 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, G, x, X, id,
311 p, end, f_rng, p_rng ) );
312
313cleanup:
314 return( ret );
315}
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200316
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200317/*
318 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
319 * Ouputs: verified peer public keys Xa, Xb
320 */
321static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
322 const mbedtls_ecp_group *grp,
323 const mbedtls_ecp_point *G,
324 mbedtls_ecp_point *Xa,
325 mbedtls_ecp_point *Xb,
326 const char *id,
327 const unsigned char *buf,
328 size_t len )
329{
330 int ret;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200331 const unsigned char *p = buf;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200332 const unsigned char *end = buf + len;
333
334 /*
335 * struct {
336 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
337 * } ECJPAKEKeyKPPairList;
338 */
339 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, G, Xa, id, &p, end ) );
340 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, G, Xb, id, &p, end ) );
341
342 if( p != end )
343 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
344
345cleanup:
346 return( ret );
347}
348
349/*
350 * Generate a ECJPAKEKeyKPPairList
351 * Outputs: the serialized structure, plus two private/public key pairs
352 */
353static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
354 const mbedtls_ecp_group *grp,
355 const mbedtls_ecp_point *G,
356 mbedtls_mpi *xa,
357 mbedtls_ecp_point *Xa,
358 mbedtls_mpi *xb,
359 mbedtls_ecp_point *Xb,
360 const char *id,
361 unsigned char *buf,
362 size_t len,
363 size_t *olen,
364 int (*f_rng)(void *, unsigned char *, size_t),
365 void *p_rng )
366{
367 int ret;
368 unsigned char *p = buf;
369 const unsigned char *end = buf + len;
370
371 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, G, xa, Xa, id,
372 &p, end, f_rng, p_rng ) );
373 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, G, xb, Xb, id,
374 &p, end, f_rng, p_rng ) );
375
376 *olen = p - buf;
377
378cleanup:
379 return( ret );
380}
381
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200382#if defined(MBEDTLS_SELF_TEST)
383
384#if defined(MBEDTLS_PLATFORM_C)
385#include "mbedtls/platform.h"
386#else
387#include <stdio.h>
388#define mbedtls_printf printf
389#endif
390
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200391#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
392 !defined(MBEDTLS_SHA256_C)
393int mbedtls_ecjpake_self_test( int verbose )
394{
395 (void) verbose;
396 return( 0 );
397}
398#else
399
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200400static const unsigned char ecjpake_test_kkpp[] = {
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200401 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
402 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
403 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
404 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
405 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
406 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
407 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
408 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
409 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
410 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
411 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
412 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
413 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200414 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
415 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
416 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
417 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
418 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
419 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
420 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
421 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
422 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
423 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
424 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
425 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
426 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
427 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
428 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200429};
430
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200431/* For tests we don't need a secure RNG;
432 * use the LGC from Numerical Recipes for simplicity */
433static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
434{
435 static uint32_t x = 42;
436 (void) p;
437
438 while( len > 0 )
439 {
440 size_t use_len = len > 4 ? 4 : len;
441 x = 1664525 * x + 1013904223;
442 memcpy( out, &x, use_len );
443 out += use_len;
444 len -= use_len;
445 }
446
447 return( 0 );
448}
449
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200450#define TEST_ASSERT( x ) \
451 do { \
452 if( x ) \
453 ret = 0; \
454 else \
455 { \
456 ret = 1; \
457 goto cleanup; \
458 } \
459 } while( 0 )
460
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200461/*
462 * Checkup routine
463 */
464int mbedtls_ecjpake_self_test( int verbose )
465{
466 int ret;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200467 mbedtls_ecp_group grp;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200468 mbedtls_ecp_point Xa, Xb;
469 mbedtls_mpi xa, xb;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200470 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200471 unsigned char buf[1000];
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200472 size_t len;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200473
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200474 mbedtls_ecp_group_init( &grp );
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200475 mbedtls_ecp_point_init( &Xa );
476 mbedtls_ecp_point_init( &Xb );
477 mbedtls_mpi_init( &xa );
478 mbedtls_mpi_init( &xb );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200479
480 /* Common to all tests */
481 md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
482 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP256R1 ) );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200483
484 if( verbose != 0 )
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200485 mbedtls_printf( " ECJPAKE test #1 (kkpp read): " );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200486
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200487 TEST_ASSERT( ecjpake_kkpp_read( md_info, &grp, &grp.G,
488 &Xa, &Xb, "client",
489 ecjpake_test_kkpp,
490 sizeof( ecjpake_test_kkpp ) ) == 0 );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200491
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200492 /* Corrupt message */
493 memcpy( buf, ecjpake_test_kkpp, sizeof( ecjpake_test_kkpp ) );
494 buf[sizeof( ecjpake_test_kkpp ) - 1]--;
495 TEST_ASSERT( ecjpake_kkpp_read( md_info, &grp, &grp.G,
496 &Xa, &Xb, "client",
497 buf, sizeof( ecjpake_test_kkpp ) )
498 == MBEDTLS_ERR_ECP_VERIFY_FAILED );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200499
500 if( verbose != 0 )
501 mbedtls_printf( "passed\n" );
502
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200503 if( verbose != 0 )
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200504 mbedtls_printf( " ECJPAKE test #2 (kkpp write/read): " );
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200505
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200506 TEST_ASSERT( ecjpake_kkpp_write( md_info, &grp, &grp.G,
507 &xa, &Xa, &xb, &Xb, "client",
508 buf, sizeof( buf ), &len,
509 ecjpake_lgc, NULL ) == 0 );
510
511 TEST_ASSERT( ecjpake_kkpp_read( md_info, &grp, &grp.G,
512 &Xa, &Xb, "client",
513 buf, len ) == 0 );
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200514
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200515 if( verbose != 0 )
516 mbedtls_printf( "passed\n" );
517
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200518cleanup:
519 mbedtls_ecp_group_free( &grp );
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200520 mbedtls_ecp_point_free( &Xa );
521 mbedtls_ecp_point_free( &Xb );
522 mbedtls_mpi_free( &xa );
523 mbedtls_mpi_free( &xb );
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200524
525 if( ret != 0 )
526 {
527 if( verbose != 0 )
528 mbedtls_printf( "failed\n" );
529
530 ret = 1;
531 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200532
533 if( verbose != 0 )
534 mbedtls_printf( "\n" );
535
536 return( ret );
537}
538
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200539#undef TEST_ASSERT
540
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200541#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
542
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200543#endif /* MBEDTLS_SELF_TEST */
544
545#endif /* MBEDTLS_ECJPAKE_C */