mbedtls ported to mbed-classic
Fork of mbedtls by
Embed:
(wiki syntax)
Show/hide line numbers
ecjpake.c
00001 /* 00002 * Elliptic curve J-PAKE 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 /* 00023 * References in the code are to the Thread v1.0 Specification, 00024 * available to members of the Thread Group http://threadgroup.org/ 00025 */ 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "mbedtls/config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #if defined(MBEDTLS_ECJPAKE_C) 00034 00035 #include "mbedtls/ecjpake.h" 00036 00037 #include <string.h> 00038 00039 /* 00040 * Convert a mbedtls_ecjpake_role to identifier string 00041 */ 00042 static const char * const ecjpake_id[] = { 00043 "client", 00044 "server" 00045 }; 00046 00047 #define ID_MINE ( ecjpake_id[ ctx->role ] ) 00048 #define ID_PEER ( ecjpake_id[ 1 - ctx->role ] ) 00049 00050 /* 00051 * Initialize context 00052 */ 00053 void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ) 00054 { 00055 if( ctx == NULL ) 00056 return; 00057 00058 ctx->md_info = NULL; 00059 mbedtls_ecp_group_init( &ctx->grp ); 00060 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; 00061 00062 mbedtls_ecp_point_init( &ctx->Xm1 ); 00063 mbedtls_ecp_point_init( &ctx->Xm2 ); 00064 mbedtls_ecp_point_init( &ctx->Xp1 ); 00065 mbedtls_ecp_point_init( &ctx->Xp2 ); 00066 mbedtls_ecp_point_init( &ctx->Xp ); 00067 00068 mbedtls_mpi_init( &ctx->xm1 ); 00069 mbedtls_mpi_init( &ctx->xm2 ); 00070 mbedtls_mpi_init( &ctx->s ); 00071 } 00072 00073 /* 00074 * Free context 00075 */ 00076 void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ) 00077 { 00078 if( ctx == NULL ) 00079 return; 00080 00081 ctx->md_info = NULL; 00082 mbedtls_ecp_group_free( &ctx->grp ); 00083 00084 mbedtls_ecp_point_free( &ctx->Xm1 ); 00085 mbedtls_ecp_point_free( &ctx->Xm2 ); 00086 mbedtls_ecp_point_free( &ctx->Xp1 ); 00087 mbedtls_ecp_point_free( &ctx->Xp2 ); 00088 mbedtls_ecp_point_free( &ctx->Xp ); 00089 00090 mbedtls_mpi_free( &ctx->xm1 ); 00091 mbedtls_mpi_free( &ctx->xm2 ); 00092 mbedtls_mpi_free( &ctx->s ); 00093 } 00094 00095 /* 00096 * Setup context 00097 */ 00098 int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, 00099 mbedtls_ecjpake_role role, 00100 mbedtls_md_type_t hash, 00101 mbedtls_ecp_group_id curve, 00102 const unsigned char *secret, 00103 size_t len ) 00104 { 00105 int ret; 00106 00107 ctx->role = role; 00108 00109 if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL ) 00110 return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); 00111 00112 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) ); 00113 00114 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) ); 00115 00116 cleanup: 00117 if( ret != 0 ) 00118 mbedtls_ecjpake_free( ctx ); 00119 00120 return( ret ); 00121 } 00122 00123 /* 00124 * Check if context is ready for use 00125 */ 00126 int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ) 00127 { 00128 if( ctx->md_info == NULL || 00129 ctx->grp.id == MBEDTLS_ECP_DP_NONE || 00130 ctx->s.p == NULL ) 00131 { 00132 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00133 } 00134 00135 return( 0 ); 00136 } 00137 00138 /* 00139 * Write a point plus its length to a buffer 00140 */ 00141 static int ecjpake_write_len_point( unsigned char **p, 00142 const unsigned char *end, 00143 const mbedtls_ecp_group *grp, 00144 const int pf, 00145 const mbedtls_ecp_point *P ) 00146 { 00147 int ret; 00148 size_t len; 00149 00150 /* Need at least 4 for length plus 1 for point */ 00151 if( end < *p || end - *p < 5 ) 00152 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); 00153 00154 ret = mbedtls_ecp_point_write_binary( grp, P, pf, 00155 &len, *p + 4, end - ( *p + 4 ) ); 00156 if( ret != 0 ) 00157 return( ret ); 00158 00159 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF ); 00160 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF ); 00161 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF ); 00162 (*p)[3] = (unsigned char)( ( len ) & 0xFF ); 00163 00164 *p += 4 + len; 00165 00166 return( 0 ); 00167 } 00168 00169 /* 00170 * Size of the temporary buffer for ecjpake_hash: 00171 * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) 00172 */ 00173 #define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 ) 00174 00175 /* 00176 * Compute hash for ZKP (7.4.2.2.2.1) 00177 */ 00178 static int ecjpake_hash( const mbedtls_md_info_t *md_info, 00179 const mbedtls_ecp_group *grp, 00180 const int pf, 00181 const mbedtls_ecp_point *G, 00182 const mbedtls_ecp_point *V, 00183 const mbedtls_ecp_point *X, 00184 const char *id, 00185 mbedtls_mpi *h ) 00186 { 00187 int ret; 00188 unsigned char buf[ECJPAKE_HASH_BUF_LEN]; 00189 unsigned char *p = buf; 00190 const unsigned char *end = buf + sizeof( buf ); 00191 const size_t id_len = strlen( id ); 00192 unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 00193 00194 /* Write things to temporary buffer */ 00195 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) ); 00196 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) ); 00197 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) ); 00198 00199 if( end - p < 4 ) 00200 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); 00201 00202 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF ); 00203 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF ); 00204 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF ); 00205 *p++ = (unsigned char)( ( id_len ) & 0xFF ); 00206 00207 if( end < p || (size_t)( end - p ) < id_len ) 00208 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); 00209 00210 memcpy( p, id, id_len ); 00211 p += id_len; 00212 00213 /* Compute hash */ 00214 mbedtls_md( md_info, buf, p - buf, hash ); 00215 00216 /* Turn it into an integer mod n */ 00217 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash, 00218 mbedtls_md_get_size( md_info ) ) ); 00219 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) ); 00220 00221 cleanup: 00222 return( ret ); 00223 } 00224 00225 /* 00226 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) 00227 */ 00228 static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info, 00229 const mbedtls_ecp_group *grp, 00230 const int pf, 00231 const mbedtls_ecp_point *G, 00232 const mbedtls_ecp_point *X, 00233 const char *id, 00234 const unsigned char **p, 00235 const unsigned char *end ) 00236 { 00237 int ret; 00238 mbedtls_ecp_point V, VV; 00239 mbedtls_mpi r, h; 00240 size_t r_len; 00241 00242 mbedtls_ecp_point_init( &V ); 00243 mbedtls_ecp_point_init( &VV ); 00244 mbedtls_mpi_init( &r ); 00245 mbedtls_mpi_init( &h ); 00246 00247 /* 00248 * struct { 00249 * ECPoint V; 00250 * opaque r<1..2^8-1>; 00251 * } ECSchnorrZKP; 00252 */ 00253 if( end < *p ) 00254 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00255 00256 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) ); 00257 00258 if( end < *p || (size_t)( end - *p ) < 1 ) 00259 { 00260 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 00261 goto cleanup; 00262 } 00263 00264 r_len = *(*p)++; 00265 00266 if( end < *p || (size_t)( end - *p ) < r_len ) 00267 { 00268 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 00269 goto cleanup; 00270 } 00271 00272 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) ); 00273 *p += r_len; 00274 00275 /* 00276 * Verification 00277 */ 00278 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); 00279 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp, 00280 &VV, &h, X, &r, G ) ); 00281 00282 if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 ) 00283 { 00284 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; 00285 goto cleanup; 00286 } 00287 00288 cleanup: 00289 mbedtls_ecp_point_free( &V ); 00290 mbedtls_ecp_point_free( &VV ); 00291 mbedtls_mpi_free( &r ); 00292 mbedtls_mpi_free( &h ); 00293 00294 return( ret ); 00295 } 00296 00297 /* 00298 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) 00299 */ 00300 static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, 00301 const mbedtls_ecp_group *grp, 00302 const int pf, 00303 const mbedtls_ecp_point *G, 00304 const mbedtls_mpi *x, 00305 const mbedtls_ecp_point *X, 00306 const char *id, 00307 unsigned char **p, 00308 const unsigned char *end, 00309 int (*f_rng)(void *, unsigned char *, size_t), 00310 void *p_rng ) 00311 { 00312 int ret; 00313 mbedtls_ecp_point V; 00314 mbedtls_mpi v; 00315 mbedtls_mpi h; /* later recycled to hold r */ 00316 size_t len; 00317 00318 if( end < *p ) 00319 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); 00320 00321 mbedtls_ecp_point_init( &V ); 00322 mbedtls_mpi_init( &v ); 00323 mbedtls_mpi_init( &h ); 00324 00325 /* Compute signature */ 00326 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, 00327 G, &v, &V, f_rng, p_rng ) ); 00328 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); 00329 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */ 00330 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */ 00331 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */ 00332 00333 /* Write it out */ 00334 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V, 00335 pf, &len, *p, end - *p ) ); 00336 *p += len; 00337 00338 len = mbedtls_mpi_size( &h ); /* actually r */ 00339 if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 ) 00340 { 00341 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 00342 goto cleanup; 00343 } 00344 00345 *(*p)++ = (unsigned char)( len & 0xFF ); 00346 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */ 00347 *p += len; 00348 00349 cleanup: 00350 mbedtls_ecp_point_free( &V ); 00351 mbedtls_mpi_free( &v ); 00352 mbedtls_mpi_free( &h ); 00353 00354 return( ret ); 00355 } 00356 00357 /* 00358 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof 00359 * Output: verified public key X 00360 */ 00361 static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info, 00362 const mbedtls_ecp_group *grp, 00363 const int pf, 00364 const mbedtls_ecp_point *G, 00365 mbedtls_ecp_point *X, 00366 const char *id, 00367 const unsigned char **p, 00368 const unsigned char *end ) 00369 { 00370 int ret; 00371 00372 if( end < *p ) 00373 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); 00374 00375 /* 00376 * struct { 00377 * ECPoint X; 00378 * ECSchnorrZKP zkp; 00379 * } ECJPAKEKeyKP; 00380 */ 00381 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) ); 00382 if( mbedtls_ecp_is_zero( X ) ) 00383 { 00384 ret = MBEDTLS_ERR_ECP_INVALID_KEY; 00385 goto cleanup; 00386 } 00387 00388 MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) ); 00389 00390 cleanup: 00391 return( ret ); 00392 } 00393 00394 /* 00395 * Generate an ECJPAKEKeyKP 00396 * Output: the serialized structure, plus private/public key pair 00397 */ 00398 static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info, 00399 const mbedtls_ecp_group *grp, 00400 const int pf, 00401 const mbedtls_ecp_point *G, 00402 mbedtls_mpi *x, 00403 mbedtls_ecp_point *X, 00404 const char *id, 00405 unsigned char **p, 00406 const unsigned char *end, 00407 int (*f_rng)(void *, unsigned char *, size_t), 00408 void *p_rng ) 00409 { 00410 int ret; 00411 size_t len; 00412 00413 if( end < *p ) 00414 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); 00415 00416 /* Generate key (7.4.2.3.1) and write it out */ 00417 MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X, 00418 f_rng, p_rng ) ); 00419 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X, 00420 pf, &len, *p, end - *p ) ); 00421 *p += len; 00422 00423 /* Generate and write proof */ 00424 MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id, 00425 p, end, f_rng, p_rng ) ); 00426 00427 cleanup: 00428 return( ret ); 00429 } 00430 00431 /* 00432 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs 00433 * Ouputs: verified peer public keys Xa, Xb 00434 */ 00435 static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, 00436 const mbedtls_ecp_group *grp, 00437 const int pf, 00438 const mbedtls_ecp_point *G, 00439 mbedtls_ecp_point *Xa, 00440 mbedtls_ecp_point *Xb, 00441 const char *id, 00442 const unsigned char *buf, 00443 size_t len ) 00444 { 00445 int ret; 00446 const unsigned char *p = buf; 00447 const unsigned char *end = buf + len; 00448 00449 /* 00450 * struct { 00451 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; 00452 * } ECJPAKEKeyKPPairList; 00453 */ 00454 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) ); 00455 MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) ); 00456 00457 if( p != end ) 00458 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 00459 00460 cleanup: 00461 return( ret ); 00462 } 00463 00464 /* 00465 * Generate a ECJPAKEKeyKPPairList 00466 * Outputs: the serialized structure, plus two private/public key pairs 00467 */ 00468 static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info, 00469 const mbedtls_ecp_group *grp, 00470 const int pf, 00471 const mbedtls_ecp_point *G, 00472 mbedtls_mpi *xm1, 00473 mbedtls_ecp_point *Xa, 00474 mbedtls_mpi *xm2, 00475 mbedtls_ecp_point *Xb, 00476 const char *id, 00477 unsigned char *buf, 00478 size_t len, 00479 size_t *olen, 00480 int (*f_rng)(void *, unsigned char *, size_t), 00481 void *p_rng ) 00482 { 00483 int ret; 00484 unsigned char *p = buf; 00485 const unsigned char *end = buf + len; 00486 00487 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id, 00488 &p, end, f_rng, p_rng ) ); 00489 MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id, 00490 &p, end, f_rng, p_rng ) ); 00491 00492 *olen = p - buf; 00493 00494 cleanup: 00495 return( ret ); 00496 } 00497 00498 /* 00499 * Read and process the first round message 00500 */ 00501 int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, 00502 const unsigned char *buf, 00503 size_t len ) 00504 { 00505 return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format, 00506 &ctx->grp.G , 00507 &ctx->Xp1, &ctx->Xp2, ID_PEER, 00508 buf, len ) ); 00509 } 00510 00511 /* 00512 * Generate and write the first round message 00513 */ 00514 int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, 00515 unsigned char *buf, size_t len, size_t *olen, 00516 int (*f_rng)(void *, unsigned char *, size_t), 00517 void *p_rng ) 00518 { 00519 return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format, 00520 &ctx->grp.G , 00521 &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, 00522 ID_MINE, buf, len, olen, f_rng, p_rng ) ); 00523 } 00524 00525 /* 00526 * Compute the sum of three points R = A + B + C 00527 */ 00528 static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, 00529 const mbedtls_ecp_point *A, 00530 const mbedtls_ecp_point *B, 00531 const mbedtls_ecp_point *C ) 00532 { 00533 int ret; 00534 mbedtls_mpi one; 00535 00536 mbedtls_mpi_init( &one ); 00537 00538 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); 00539 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) ); 00540 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) ); 00541 00542 cleanup: 00543 mbedtls_mpi_free( &one ); 00544 00545 return( ret ); 00546 } 00547 00548 /* 00549 * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) 00550 */ 00551 int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, 00552 const unsigned char *buf, 00553 size_t len ) 00554 { 00555 int ret; 00556 const unsigned char *p = buf; 00557 const unsigned char *end = buf + len; 00558 mbedtls_ecp_group grp; 00559 mbedtls_ecp_point G; /* C: GB, S: GA */ 00560 00561 mbedtls_ecp_group_init( &grp ); 00562 mbedtls_ecp_point_init( &G ); 00563 00564 /* 00565 * Server: GA = X3 + X4 + X1 (7.4.2.6.1) 00566 * Client: GB = X1 + X2 + X3 (7.4.2.5.1) 00567 * Unified: G = Xm1 + Xm2 + Xp1 00568 * We need that before parsing in order to check Xp as we read it 00569 */ 00570 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, 00571 &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) ); 00572 00573 /* 00574 * struct { 00575 * ECParameters curve_params; // only client reading server msg 00576 * ECJPAKEKeyKP ecjpake_key_kp; 00577 * } Client/ServerECJPAKEParams; 00578 */ 00579 if( ctx->role == MBEDTLS_ECJPAKE_CLIENT ) 00580 { 00581 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) ); 00582 if( grp.id != ctx->grp.id ) 00583 { 00584 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; 00585 goto cleanup; 00586 } 00587 } 00588 00589 MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp, 00590 ctx->point_format, 00591 &G, &ctx->Xp, ID_PEER, &p, end ) ); 00592 00593 if( p != end ) 00594 { 00595 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 00596 goto cleanup; 00597 } 00598 00599 cleanup: 00600 mbedtls_ecp_group_free( &grp ); 00601 mbedtls_ecp_point_free( &G ); 00602 00603 return( ret ); 00604 } 00605 00606 /* 00607 * Compute R = +/- X * S mod N, taking care not to leak S 00608 */ 00609 static int ecjpake_mul_secret( mbedtls_mpi *R, int sign, 00610 const mbedtls_mpi *X, 00611 const mbedtls_mpi *S, 00612 const mbedtls_mpi *N, 00613 int (*f_rng)(void *, unsigned char *, size_t), 00614 void *p_rng ) 00615 { 00616 int ret; 00617 mbedtls_mpi b; /* Blinding value, then s + N * blinding */ 00618 00619 mbedtls_mpi_init( &b ); 00620 00621 /* b = s + rnd-128-bit * N */ 00622 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) ); 00623 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) ); 00624 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) ); 00625 00626 /* R = sign * X * b mod N */ 00627 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) ); 00628 R->s *= sign; 00629 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) ); 00630 00631 cleanup: 00632 mbedtls_mpi_free( &b ); 00633 00634 return( ret ); 00635 } 00636 00637 /* 00638 * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) 00639 */ 00640 int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, 00641 unsigned char *buf, size_t len, size_t *olen, 00642 int (*f_rng)(void *, unsigned char *, size_t), 00643 void *p_rng ) 00644 { 00645 int ret; 00646 mbedtls_ecp_point G; /* C: GA, S: GB */ 00647 mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ 00648 mbedtls_mpi xm; /* C: xc, S: xs */ 00649 unsigned char *p = buf; 00650 const unsigned char *end = buf + len; 00651 size_t ec_len; 00652 00653 mbedtls_ecp_point_init( &G ); 00654 mbedtls_ecp_point_init( &Xm ); 00655 mbedtls_mpi_init( &xm ); 00656 00657 /* 00658 * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) 00659 * 00660 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA 00661 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB 00662 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G 00663 */ 00664 MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, 00665 &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) ); 00666 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s, 00667 &ctx->grp.N , f_rng, p_rng ) ); 00668 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) ); 00669 00670 /* 00671 * Now write things out 00672 * 00673 * struct { 00674 * ECParameters curve_params; // only server writing its message 00675 * ECJPAKEKeyKP ecjpake_key_kp; 00676 * } Client/ServerECJPAKEParams; 00677 */ 00678 if( ctx->role == MBEDTLS_ECJPAKE_SERVER ) 00679 { 00680 if( end < p ) 00681 { 00682 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 00683 goto cleanup; 00684 } 00685 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len, 00686 p, end - p ) ); 00687 p += ec_len; 00688 } 00689 00690 if( end < p ) 00691 { 00692 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 00693 goto cleanup; 00694 } 00695 MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm, 00696 ctx->point_format, &ec_len, p, end - p ) ); 00697 p += ec_len; 00698 00699 MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp, 00700 ctx->point_format, 00701 &G, &xm, &Xm, ID_MINE, 00702 &p, end, f_rng, p_rng ) ); 00703 00704 *olen = p - buf; 00705 00706 cleanup: 00707 mbedtls_ecp_point_free( &G ); 00708 mbedtls_ecp_point_free( &Xm ); 00709 mbedtls_mpi_free( &xm ); 00710 00711 return( ret ); 00712 } 00713 00714 /* 00715 * Derive PMS (7.4.2.7 / 7.4.2.8) 00716 */ 00717 int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, 00718 unsigned char *buf, size_t len, size_t *olen, 00719 int (*f_rng)(void *, unsigned char *, size_t), 00720 void *p_rng ) 00721 { 00722 int ret; 00723 mbedtls_ecp_point K; 00724 mbedtls_mpi m_xm2_s, one; 00725 unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; 00726 size_t x_bytes; 00727 00728 *olen = mbedtls_md_get_size( ctx->md_info ); 00729 if( len < *olen ) 00730 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); 00731 00732 mbedtls_ecp_point_init( &K ); 00733 mbedtls_mpi_init( &m_xm2_s ); 00734 mbedtls_mpi_init( &one ); 00735 00736 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); 00737 00738 /* 00739 * Client: K = ( Xs - X4 * x2 * s ) * x2 00740 * Server: K = ( Xc - X2 * x4 * s ) * x4 00741 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 00742 */ 00743 MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, 00744 &ctx->grp.N , f_rng, p_rng ) ); 00745 MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, 00746 &one, &ctx->Xp, 00747 &m_xm2_s, &ctx->Xp2 ) ); 00748 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, 00749 f_rng, p_rng ) ); 00750 00751 /* PMS = SHA-256( K.X ) */ 00752 x_bytes = ( ctx->grp.pbits + 7 ) / 8; 00753 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X , kx, x_bytes ) ); 00754 MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) ); 00755 00756 cleanup: 00757 mbedtls_ecp_point_free( &K ); 00758 mbedtls_mpi_free( &m_xm2_s ); 00759 mbedtls_mpi_free( &one ); 00760 00761 return( ret ); 00762 } 00763 00764 #undef ID_MINE 00765 #undef ID_PEER 00766 00767 00768 #if defined(MBEDTLS_SELF_TEST) 00769 00770 #if defined(MBEDTLS_PLATFORM_C) 00771 #include "mbedtls/platform.h" 00772 #else 00773 #include <stdio.h> 00774 #define mbedtls_printf printf 00775 #endif 00776 00777 #if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ 00778 !defined(MBEDTLS_SHA256_C) 00779 int mbedtls_ecjpake_self_test( int verbose ) 00780 { 00781 (void) verbose; 00782 return( 0 ); 00783 } 00784 #else 00785 00786 static const unsigned char ecjpake_test_password[] = { 00787 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, 00788 0x65, 0x73, 0x74 00789 }; 00790 00791 static const unsigned char ecjpake_test_x1[] = { 00792 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 00793 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 00794 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 00795 }; 00796 00797 static const unsigned char ecjpake_test_x2[] = { 00798 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 00799 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 00800 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 00801 }; 00802 00803 static const unsigned char ecjpake_test_x3[] = { 00804 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 00805 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 00806 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 00807 }; 00808 00809 static const unsigned char ecjpake_test_x4[] = { 00810 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 00811 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 00812 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 00813 }; 00814 00815 static const unsigned char ecjpake_test_cli_one[] = { 00816 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, 00817 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, 00818 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, 00819 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, 00820 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, 00821 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, 00822 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, 00823 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, 00824 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, 00825 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, 00826 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, 00827 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, 00828 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, 00829 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, 00830 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, 00831 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, 00832 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, 00833 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, 00834 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, 00835 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, 00836 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, 00837 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, 00838 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, 00839 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, 00840 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, 00841 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, 00842 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, 00843 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 00844 }; 00845 00846 static const unsigned char ecjpake_test_srv_one[] = { 00847 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 00848 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 00849 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 00850 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 00851 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 00852 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, 00853 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, 00854 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, 00855 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, 00856 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, 00857 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, 00858 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, 00859 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, 00860 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, 00861 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, 00862 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, 00863 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, 00864 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, 00865 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, 00866 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, 00867 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, 00868 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, 00869 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, 00870 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, 00871 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, 00872 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, 00873 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, 00874 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 00875 }; 00876 00877 static const unsigned char ecjpake_test_srv_two[] = { 00878 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, 00879 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, 00880 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, 00881 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, 00882 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, 00883 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, 00884 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, 00885 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, 00886 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, 00887 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, 00888 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, 00889 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, 00890 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, 00891 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c 00892 }; 00893 00894 static const unsigned char ecjpake_test_cli_two[] = { 00895 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, 00896 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, 00897 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, 00898 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, 00899 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, 00900 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, 00901 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, 00902 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, 00903 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, 00904 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, 00905 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, 00906 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, 00907 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, 00908 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c 00909 }; 00910 00911 static const unsigned char ecjpake_test_pms[] = { 00912 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, 00913 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, 00914 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 00915 }; 00916 00917 /* Load my private keys and generate the correponding public keys */ 00918 static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, 00919 const unsigned char *xm1, size_t len1, 00920 const unsigned char *xm2, size_t len2 ) 00921 { 00922 int ret; 00923 00924 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) ); 00925 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) ); 00926 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1, 00927 &ctx->grp.G , NULL, NULL ) ); 00928 MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2, 00929 &ctx->grp.G , NULL, NULL ) ); 00930 00931 cleanup: 00932 return( ret ); 00933 } 00934 00935 /* For tests we don't need a secure RNG; 00936 * use the LGC from Numerical Recipes for simplicity */ 00937 static int ecjpake_lgc( void *p, unsigned char *out, size_t len ) 00938 { 00939 static uint32_t x = 42; 00940 (void) p; 00941 00942 while( len > 0 ) 00943 { 00944 size_t use_len = len > 4 ? 4 : len; 00945 x = 1664525 * x + 1013904223; 00946 memcpy( out, &x, use_len ); 00947 out += use_len; 00948 len -= use_len; 00949 } 00950 00951 return( 0 ); 00952 } 00953 00954 #define TEST_ASSERT( x ) \ 00955 do { \ 00956 if( x ) \ 00957 ret = 0; \ 00958 else \ 00959 { \ 00960 ret = 1; \ 00961 goto cleanup; \ 00962 } \ 00963 } while( 0 ) 00964 00965 /* 00966 * Checkup routine 00967 */ 00968 int mbedtls_ecjpake_self_test( int verbose ) 00969 { 00970 int ret; 00971 mbedtls_ecjpake_context cli; 00972 mbedtls_ecjpake_context srv; 00973 unsigned char buf[512], pms[32]; 00974 size_t len, pmslen; 00975 00976 mbedtls_ecjpake_init( &cli ); 00977 mbedtls_ecjpake_init( &srv ); 00978 00979 if( verbose != 0 ) 00980 mbedtls_printf( " ECJPAKE test #0 (setup): " ); 00981 00982 TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT, 00983 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1 , 00984 ecjpake_test_password, 00985 sizeof( ecjpake_test_password ) ) == 0 ); 00986 00987 TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER, 00988 MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1 , 00989 ecjpake_test_password, 00990 sizeof( ecjpake_test_password ) ) == 0 ); 00991 00992 if( verbose != 0 ) 00993 mbedtls_printf( "passed\n" ); 00994 00995 if( verbose != 0 ) 00996 mbedtls_printf( " ECJPAKE test #1 (random handshake): " ); 00997 00998 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli, 00999 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01000 01001 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 ); 01002 01003 TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv, 01004 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01005 01006 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 ); 01007 01008 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv, 01009 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01010 01011 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 ); 01012 01013 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, 01014 pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 ); 01015 01016 TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli, 01017 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01018 01019 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 ); 01020 01021 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, 01022 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01023 01024 TEST_ASSERT( len == pmslen ); 01025 TEST_ASSERT( memcmp( buf, pms, len ) == 0 ); 01026 01027 if( verbose != 0 ) 01028 mbedtls_printf( "passed\n" ); 01029 01030 if( verbose != 0 ) 01031 mbedtls_printf( " ECJPAKE test #2 (reference handshake): " ); 01032 01033 /* Simulate generation of round one */ 01034 MBEDTLS_MPI_CHK( ecjpake_test_load( &cli, 01035 ecjpake_test_x1, sizeof( ecjpake_test_x1 ), 01036 ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) ); 01037 01038 MBEDTLS_MPI_CHK( ecjpake_test_load( &srv, 01039 ecjpake_test_x3, sizeof( ecjpake_test_x3 ), 01040 ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) ); 01041 01042 /* Read round one */ 01043 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, 01044 ecjpake_test_cli_one, 01045 sizeof( ecjpake_test_cli_one ) ) == 0 ); 01046 01047 TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, 01048 ecjpake_test_srv_one, 01049 sizeof( ecjpake_test_srv_one ) ) == 0 ); 01050 01051 /* Skip generation of round two, read round two */ 01052 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, 01053 ecjpake_test_srv_two, 01054 sizeof( ecjpake_test_srv_two ) ) == 0 ); 01055 01056 TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, 01057 ecjpake_test_cli_two, 01058 sizeof( ecjpake_test_cli_two ) ) == 0 ); 01059 01060 /* Server derives PMS */ 01061 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, 01062 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01063 01064 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); 01065 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); 01066 01067 memset( buf, 0, len ); /* Avoid interferences with next step */ 01068 01069 /* Client derives PMS */ 01070 TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, 01071 buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); 01072 01073 TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); 01074 TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); 01075 01076 if( verbose != 0 ) 01077 mbedtls_printf( "passed\n" ); 01078 01079 cleanup: 01080 mbedtls_ecjpake_free( &cli ); 01081 mbedtls_ecjpake_free( &srv ); 01082 01083 if( ret != 0 ) 01084 { 01085 if( verbose != 0 ) 01086 mbedtls_printf( "failed\n" ); 01087 01088 ret = 1; 01089 } 01090 01091 if( verbose != 0 ) 01092 mbedtls_printf( "\n" ); 01093 01094 return( ret ); 01095 } 01096 01097 #undef TEST_ASSERT 01098 01099 #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */ 01100 01101 #endif /* MBEDTLS_SELF_TEST */ 01102 01103 #endif /* MBEDTLS_ECJPAKE_C */
Generated on Tue Jul 12 2022 12:52:43 by
![doxygen](doxygen.png)