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