ecjpake.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. /*
  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. * References in the code are to the Thread v1.0 Specification,
  23. * available to members of the Thread Group http://threadgroup.org/
  24. */
  25. #if !defined(MBEDTLS_CONFIG_FILE)
  26. #include "mbedtls/config.h"
  27. #else
  28. #include MBEDTLS_CONFIG_FILE
  29. #endif
  30. #if defined(MBEDTLS_ECJPAKE_C)
  31. #include "mbedtls/ecjpake.h"
  32. #include "mbedtls/platform_util.h"
  33. #include <string.h>
  34. #if !defined(MBEDTLS_ECJPAKE_ALT)
  35. /* Parameter validation macros based on platform_util.h */
  36. #define ECJPAKE_VALIDATE_RET( cond ) \
  37. MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
  38. #define ECJPAKE_VALIDATE( cond ) \
  39. MBEDTLS_INTERNAL_VALIDATE( cond )
  40. /*
  41. * Convert a mbedtls_ecjpake_role to identifier string
  42. */
  43. static const char * const ecjpake_id[] = {
  44. "client",
  45. "server"
  46. };
  47. #define ID_MINE ( ecjpake_id[ ctx->role ] )
  48. #define ID_PEER ( ecjpake_id[ 1 - ctx->role ] )
  49. /*
  50. * Initialize context
  51. */
  52. void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx )
  53. {
  54. ECJPAKE_VALIDATE( ctx != NULL );
  55. ctx->md_info = NULL;
  56. mbedtls_ecp_group_init( &ctx->grp );
  57. ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
  58. mbedtls_ecp_point_init( &ctx->Xm1 );
  59. mbedtls_ecp_point_init( &ctx->Xm2 );
  60. mbedtls_ecp_point_init( &ctx->Xp1 );
  61. mbedtls_ecp_point_init( &ctx->Xp2 );
  62. mbedtls_ecp_point_init( &ctx->Xp );
  63. mbedtls_mpi_init( &ctx->xm1 );
  64. mbedtls_mpi_init( &ctx->xm2 );
  65. mbedtls_mpi_init( &ctx->s );
  66. }
  67. /*
  68. * Free context
  69. */
  70. void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx )
  71. {
  72. if( ctx == NULL )
  73. return;
  74. ctx->md_info = NULL;
  75. mbedtls_ecp_group_free( &ctx->grp );
  76. mbedtls_ecp_point_free( &ctx->Xm1 );
  77. mbedtls_ecp_point_free( &ctx->Xm2 );
  78. mbedtls_ecp_point_free( &ctx->Xp1 );
  79. mbedtls_ecp_point_free( &ctx->Xp2 );
  80. mbedtls_ecp_point_free( &ctx->Xp );
  81. mbedtls_mpi_free( &ctx->xm1 );
  82. mbedtls_mpi_free( &ctx->xm2 );
  83. mbedtls_mpi_free( &ctx->s );
  84. }
  85. /*
  86. * Setup context
  87. */
  88. int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
  89. mbedtls_ecjpake_role role,
  90. mbedtls_md_type_t hash,
  91. mbedtls_ecp_group_id curve,
  92. const unsigned char *secret,
  93. size_t len )
  94. {
  95. int ret;
  96. ECJPAKE_VALIDATE_RET( ctx != NULL );
  97. ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
  98. role == MBEDTLS_ECJPAKE_SERVER );
  99. ECJPAKE_VALIDATE_RET( secret != NULL || len == 0 );
  100. ctx->role = role;
  101. if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL )
  102. return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
  103. MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) );
  104. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) );
  105. cleanup:
  106. if( ret != 0 )
  107. mbedtls_ecjpake_free( ctx );
  108. return( ret );
  109. }
  110. /*
  111. * Check if context is ready for use
  112. */
  113. int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx )
  114. {
  115. ECJPAKE_VALIDATE_RET( ctx != NULL );
  116. if( ctx->md_info == NULL ||
  117. ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
  118. ctx->s.p == NULL )
  119. {
  120. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  121. }
  122. return( 0 );
  123. }
  124. /*
  125. * Write a point plus its length to a buffer
  126. */
  127. static int ecjpake_write_len_point( unsigned char **p,
  128. const unsigned char *end,
  129. const mbedtls_ecp_group *grp,
  130. const int pf,
  131. const mbedtls_ecp_point *P )
  132. {
  133. int ret;
  134. size_t len;
  135. /* Need at least 4 for length plus 1 for point */
  136. if( end < *p || end - *p < 5 )
  137. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  138. ret = mbedtls_ecp_point_write_binary( grp, P, pf,
  139. &len, *p + 4, end - ( *p + 4 ) );
  140. if( ret != 0 )
  141. return( ret );
  142. (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
  143. (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
  144. (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
  145. (*p)[3] = (unsigned char)( ( len ) & 0xFF );
  146. *p += 4 + len;
  147. return( 0 );
  148. }
  149. /*
  150. * Size of the temporary buffer for ecjpake_hash:
  151. * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
  152. */
  153. #define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 )
  154. /*
  155. * Compute hash for ZKP (7.4.2.2.2.1)
  156. */
  157. static int ecjpake_hash( const mbedtls_md_info_t *md_info,
  158. const mbedtls_ecp_group *grp,
  159. const int pf,
  160. const mbedtls_ecp_point *G,
  161. const mbedtls_ecp_point *V,
  162. const mbedtls_ecp_point *X,
  163. const char *id,
  164. mbedtls_mpi *h )
  165. {
  166. int ret;
  167. unsigned char buf[ECJPAKE_HASH_BUF_LEN];
  168. unsigned char *p = buf;
  169. const unsigned char *end = buf + sizeof( buf );
  170. const size_t id_len = strlen( id );
  171. unsigned char hash[MBEDTLS_MD_MAX_SIZE];
  172. /* Write things to temporary buffer */
  173. MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) );
  174. MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) );
  175. MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) );
  176. if( end - p < 4 )
  177. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  178. *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
  179. *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
  180. *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
  181. *p++ = (unsigned char)( ( id_len ) & 0xFF );
  182. if( end < p || (size_t)( end - p ) < id_len )
  183. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  184. memcpy( p, id, id_len );
  185. p += id_len;
  186. /* Compute hash */
  187. MBEDTLS_MPI_CHK( mbedtls_md( md_info, buf, p - buf, hash ) );
  188. /* Turn it into an integer mod n */
  189. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
  190. mbedtls_md_get_size( md_info ) ) );
  191. MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
  192. cleanup:
  193. return( ret );
  194. }
  195. /*
  196. * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
  197. */
  198. static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
  199. const mbedtls_ecp_group *grp,
  200. const int pf,
  201. const mbedtls_ecp_point *G,
  202. const mbedtls_ecp_point *X,
  203. const char *id,
  204. const unsigned char **p,
  205. const unsigned char *end )
  206. {
  207. int ret;
  208. mbedtls_ecp_point V, VV;
  209. mbedtls_mpi r, h;
  210. size_t r_len;
  211. mbedtls_ecp_point_init( &V );
  212. mbedtls_ecp_point_init( &VV );
  213. mbedtls_mpi_init( &r );
  214. mbedtls_mpi_init( &h );
  215. /*
  216. * struct {
  217. * ECPoint V;
  218. * opaque r<1..2^8-1>;
  219. * } ECSchnorrZKP;
  220. */
  221. if( end < *p )
  222. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  223. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) );
  224. if( end < *p || (size_t)( end - *p ) < 1 )
  225. {
  226. ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  227. goto cleanup;
  228. }
  229. r_len = *(*p)++;
  230. if( end < *p || (size_t)( end - *p ) < r_len )
  231. {
  232. ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  233. goto cleanup;
  234. }
  235. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) );
  236. *p += r_len;
  237. /*
  238. * Verification
  239. */
  240. MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
  241. MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp,
  242. &VV, &h, X, &r, G ) );
  243. if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 )
  244. {
  245. ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
  246. goto cleanup;
  247. }
  248. cleanup:
  249. mbedtls_ecp_point_free( &V );
  250. mbedtls_ecp_point_free( &VV );
  251. mbedtls_mpi_free( &r );
  252. mbedtls_mpi_free( &h );
  253. return( ret );
  254. }
  255. /*
  256. * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
  257. */
  258. static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
  259. const mbedtls_ecp_group *grp,
  260. const int pf,
  261. const mbedtls_ecp_point *G,
  262. const mbedtls_mpi *x,
  263. const mbedtls_ecp_point *X,
  264. const char *id,
  265. unsigned char **p,
  266. const unsigned char *end,
  267. int (*f_rng)(void *, unsigned char *, size_t),
  268. void *p_rng )
  269. {
  270. int ret;
  271. mbedtls_ecp_point V;
  272. mbedtls_mpi v;
  273. mbedtls_mpi h; /* later recycled to hold r */
  274. size_t len;
  275. if( end < *p )
  276. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  277. mbedtls_ecp_point_init( &V );
  278. mbedtls_mpi_init( &v );
  279. mbedtls_mpi_init( &h );
  280. /* Compute signature */
  281. MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp,
  282. G, &v, &V, f_rng, p_rng ) );
  283. MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) );
  284. MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */
  285. MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */
  286. MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */
  287. /* Write it out */
  288. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V,
  289. pf, &len, *p, end - *p ) );
  290. *p += len;
  291. len = mbedtls_mpi_size( &h ); /* actually r */
  292. if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 )
  293. {
  294. ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
  295. goto cleanup;
  296. }
  297. *(*p)++ = (unsigned char)( len & 0xFF );
  298. MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
  299. *p += len;
  300. cleanup:
  301. mbedtls_ecp_point_free( &V );
  302. mbedtls_mpi_free( &v );
  303. mbedtls_mpi_free( &h );
  304. return( ret );
  305. }
  306. /*
  307. * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
  308. * Output: verified public key X
  309. */
  310. static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
  311. const mbedtls_ecp_group *grp,
  312. const int pf,
  313. const mbedtls_ecp_point *G,
  314. mbedtls_ecp_point *X,
  315. const char *id,
  316. const unsigned char **p,
  317. const unsigned char *end )
  318. {
  319. int ret;
  320. if( end < *p )
  321. return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
  322. /*
  323. * struct {
  324. * ECPoint X;
  325. * ECSchnorrZKP zkp;
  326. * } ECJPAKEKeyKP;
  327. */
  328. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) );
  329. if( mbedtls_ecp_is_zero( X ) )
  330. {
  331. ret = MBEDTLS_ERR_ECP_INVALID_KEY;
  332. goto cleanup;
  333. }
  334. MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) );
  335. cleanup:
  336. return( ret );
  337. }
  338. /*
  339. * Generate an ECJPAKEKeyKP
  340. * Output: the serialized structure, plus private/public key pair
  341. */
  342. static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
  343. const mbedtls_ecp_group *grp,
  344. const int pf,
  345. const mbedtls_ecp_point *G,
  346. mbedtls_mpi *x,
  347. mbedtls_ecp_point *X,
  348. const char *id,
  349. unsigned char **p,
  350. const unsigned char *end,
  351. int (*f_rng)(void *, unsigned char *, size_t),
  352. void *p_rng )
  353. {
  354. int ret;
  355. size_t len;
  356. if( end < *p )
  357. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  358. /* Generate key (7.4.2.3.1) and write it out */
  359. MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X,
  360. f_rng, p_rng ) );
  361. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X,
  362. pf, &len, *p, end - *p ) );
  363. *p += len;
  364. /* Generate and write proof */
  365. MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id,
  366. p, end, f_rng, p_rng ) );
  367. cleanup:
  368. return( ret );
  369. }
  370. /*
  371. * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
  372. * Ouputs: verified peer public keys Xa, Xb
  373. */
  374. static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
  375. const mbedtls_ecp_group *grp,
  376. const int pf,
  377. const mbedtls_ecp_point *G,
  378. mbedtls_ecp_point *Xa,
  379. mbedtls_ecp_point *Xb,
  380. const char *id,
  381. const unsigned char *buf,
  382. size_t len )
  383. {
  384. int ret;
  385. const unsigned char *p = buf;
  386. const unsigned char *end = buf + len;
  387. /*
  388. * struct {
  389. * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
  390. * } ECJPAKEKeyKPPairList;
  391. */
  392. MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) );
  393. MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) );
  394. if( p != end )
  395. ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  396. cleanup:
  397. return( ret );
  398. }
  399. /*
  400. * Generate a ECJPAKEKeyKPPairList
  401. * Outputs: the serialized structure, plus two private/public key pairs
  402. */
  403. static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
  404. const mbedtls_ecp_group *grp,
  405. const int pf,
  406. const mbedtls_ecp_point *G,
  407. mbedtls_mpi *xm1,
  408. mbedtls_ecp_point *Xa,
  409. mbedtls_mpi *xm2,
  410. mbedtls_ecp_point *Xb,
  411. const char *id,
  412. unsigned char *buf,
  413. size_t len,
  414. size_t *olen,
  415. int (*f_rng)(void *, unsigned char *, size_t),
  416. void *p_rng )
  417. {
  418. int ret;
  419. unsigned char *p = buf;
  420. const unsigned char *end = buf + len;
  421. MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id,
  422. &p, end, f_rng, p_rng ) );
  423. MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id,
  424. &p, end, f_rng, p_rng ) );
  425. *olen = p - buf;
  426. cleanup:
  427. return( ret );
  428. }
  429. /*
  430. * Read and process the first round message
  431. */
  432. int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
  433. const unsigned char *buf,
  434. size_t len )
  435. {
  436. ECJPAKE_VALIDATE_RET( ctx != NULL );
  437. ECJPAKE_VALIDATE_RET( buf != NULL );
  438. return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format,
  439. &ctx->grp.G,
  440. &ctx->Xp1, &ctx->Xp2, ID_PEER,
  441. buf, len ) );
  442. }
  443. /*
  444. * Generate and write the first round message
  445. */
  446. int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
  447. unsigned char *buf, size_t len, size_t *olen,
  448. int (*f_rng)(void *, unsigned char *, size_t),
  449. void *p_rng )
  450. {
  451. ECJPAKE_VALIDATE_RET( ctx != NULL );
  452. ECJPAKE_VALIDATE_RET( buf != NULL );
  453. ECJPAKE_VALIDATE_RET( olen != NULL );
  454. ECJPAKE_VALIDATE_RET( f_rng != NULL );
  455. return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format,
  456. &ctx->grp.G,
  457. &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2,
  458. ID_MINE, buf, len, olen, f_rng, p_rng ) );
  459. }
  460. /*
  461. * Compute the sum of three points R = A + B + C
  462. */
  463. static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
  464. const mbedtls_ecp_point *A,
  465. const mbedtls_ecp_point *B,
  466. const mbedtls_ecp_point *C )
  467. {
  468. int ret;
  469. mbedtls_mpi one;
  470. mbedtls_mpi_init( &one );
  471. MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
  472. MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) );
  473. MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) );
  474. cleanup:
  475. mbedtls_mpi_free( &one );
  476. return( ret );
  477. }
  478. /*
  479. * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
  480. */
  481. int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
  482. const unsigned char *buf,
  483. size_t len )
  484. {
  485. int ret;
  486. const unsigned char *p = buf;
  487. const unsigned char *end = buf + len;
  488. mbedtls_ecp_group grp;
  489. mbedtls_ecp_point G; /* C: GB, S: GA */
  490. ECJPAKE_VALIDATE_RET( ctx != NULL );
  491. ECJPAKE_VALIDATE_RET( buf != NULL );
  492. mbedtls_ecp_group_init( &grp );
  493. mbedtls_ecp_point_init( &G );
  494. /*
  495. * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
  496. * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
  497. * Unified: G = Xm1 + Xm2 + Xp1
  498. * We need that before parsing in order to check Xp as we read it
  499. */
  500. MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
  501. &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) );
  502. /*
  503. * struct {
  504. * ECParameters curve_params; // only client reading server msg
  505. * ECJPAKEKeyKP ecjpake_key_kp;
  506. * } Client/ServerECJPAKEParams;
  507. */
  508. if( ctx->role == MBEDTLS_ECJPAKE_CLIENT )
  509. {
  510. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) );
  511. if( grp.id != ctx->grp.id )
  512. {
  513. ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
  514. goto cleanup;
  515. }
  516. }
  517. MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp,
  518. ctx->point_format,
  519. &G, &ctx->Xp, ID_PEER, &p, end ) );
  520. if( p != end )
  521. {
  522. ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
  523. goto cleanup;
  524. }
  525. cleanup:
  526. mbedtls_ecp_group_free( &grp );
  527. mbedtls_ecp_point_free( &G );
  528. return( ret );
  529. }
  530. /*
  531. * Compute R = +/- X * S mod N, taking care not to leak S
  532. */
  533. static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
  534. const mbedtls_mpi *X,
  535. const mbedtls_mpi *S,
  536. const mbedtls_mpi *N,
  537. int (*f_rng)(void *, unsigned char *, size_t),
  538. void *p_rng )
  539. {
  540. int ret;
  541. mbedtls_mpi b; /* Blinding value, then s + N * blinding */
  542. mbedtls_mpi_init( &b );
  543. /* b = s + rnd-128-bit * N */
  544. MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) );
  545. MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) );
  546. MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) );
  547. /* R = sign * X * b mod N */
  548. MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) );
  549. R->s *= sign;
  550. MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) );
  551. cleanup:
  552. mbedtls_mpi_free( &b );
  553. return( ret );
  554. }
  555. /*
  556. * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
  557. */
  558. int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
  559. unsigned char *buf, size_t len, size_t *olen,
  560. int (*f_rng)(void *, unsigned char *, size_t),
  561. void *p_rng )
  562. {
  563. int ret;
  564. mbedtls_ecp_point G; /* C: GA, S: GB */
  565. mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
  566. mbedtls_mpi xm; /* C: xc, S: xs */
  567. unsigned char *p = buf;
  568. const unsigned char *end = buf + len;
  569. size_t ec_len;
  570. ECJPAKE_VALIDATE_RET( ctx != NULL );
  571. ECJPAKE_VALIDATE_RET( buf != NULL );
  572. ECJPAKE_VALIDATE_RET( olen != NULL );
  573. ECJPAKE_VALIDATE_RET( f_rng != NULL );
  574. mbedtls_ecp_point_init( &G );
  575. mbedtls_ecp_point_init( &Xm );
  576. mbedtls_mpi_init( &xm );
  577. /*
  578. * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
  579. *
  580. * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
  581. * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
  582. * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
  583. */
  584. MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G,
  585. &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) );
  586. MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s,
  587. &ctx->grp.N, f_rng, p_rng ) );
  588. MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) );
  589. /*
  590. * Now write things out
  591. *
  592. * struct {
  593. * ECParameters curve_params; // only server writing its message
  594. * ECJPAKEKeyKP ecjpake_key_kp;
  595. * } Client/ServerECJPAKEParams;
  596. */
  597. if( ctx->role == MBEDTLS_ECJPAKE_SERVER )
  598. {
  599. if( end < p )
  600. {
  601. ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
  602. goto cleanup;
  603. }
  604. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len,
  605. p, end - p ) );
  606. p += ec_len;
  607. }
  608. if( end < p )
  609. {
  610. ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
  611. goto cleanup;
  612. }
  613. MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm,
  614. ctx->point_format, &ec_len, p, end - p ) );
  615. p += ec_len;
  616. MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp,
  617. ctx->point_format,
  618. &G, &xm, &Xm, ID_MINE,
  619. &p, end, f_rng, p_rng ) );
  620. *olen = p - buf;
  621. cleanup:
  622. mbedtls_ecp_point_free( &G );
  623. mbedtls_ecp_point_free( &Xm );
  624. mbedtls_mpi_free( &xm );
  625. return( ret );
  626. }
  627. /*
  628. * Derive PMS (7.4.2.7 / 7.4.2.8)
  629. */
  630. int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
  631. unsigned char *buf, size_t len, size_t *olen,
  632. int (*f_rng)(void *, unsigned char *, size_t),
  633. void *p_rng )
  634. {
  635. int ret;
  636. mbedtls_ecp_point K;
  637. mbedtls_mpi m_xm2_s, one;
  638. unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
  639. size_t x_bytes;
  640. ECJPAKE_VALIDATE_RET( ctx != NULL );
  641. ECJPAKE_VALIDATE_RET( buf != NULL );
  642. ECJPAKE_VALIDATE_RET( olen != NULL );
  643. ECJPAKE_VALIDATE_RET( f_rng != NULL );
  644. *olen = mbedtls_md_get_size( ctx->md_info );
  645. if( len < *olen )
  646. return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
  647. mbedtls_ecp_point_init( &K );
  648. mbedtls_mpi_init( &m_xm2_s );
  649. mbedtls_mpi_init( &one );
  650. MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
  651. /*
  652. * Client: K = ( Xs - X4 * x2 * s ) * x2
  653. * Server: K = ( Xc - X2 * x4 * s ) * x4
  654. * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
  655. */
  656. MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s,
  657. &ctx->grp.N, f_rng, p_rng ) );
  658. MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K,
  659. &one, &ctx->Xp,
  660. &m_xm2_s, &ctx->Xp2 ) );
  661. MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K,
  662. f_rng, p_rng ) );
  663. /* PMS = SHA-256( K.X ) */
  664. x_bytes = ( ctx->grp.pbits + 7 ) / 8;
  665. MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) );
  666. MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) );
  667. cleanup:
  668. mbedtls_ecp_point_free( &K );
  669. mbedtls_mpi_free( &m_xm2_s );
  670. mbedtls_mpi_free( &one );
  671. return( ret );
  672. }
  673. #undef ID_MINE
  674. #undef ID_PEER
  675. #endif /* ! MBEDTLS_ECJPAKE_ALT */
  676. #if defined(MBEDTLS_SELF_TEST)
  677. #if defined(MBEDTLS_PLATFORM_C)
  678. #include "mbedtls/platform.h"
  679. #else
  680. #include <stdio.h>
  681. #define mbedtls_printf printf
  682. #endif
  683. #if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
  684. !defined(MBEDTLS_SHA256_C)
  685. int mbedtls_ecjpake_self_test( int verbose )
  686. {
  687. (void) verbose;
  688. return( 0 );
  689. }
  690. #else
  691. static const unsigned char ecjpake_test_password[] = {
  692. 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74,
  693. 0x65, 0x73, 0x74
  694. };
  695. static const unsigned char ecjpake_test_x1[] = {
  696. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
  697. 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  698. 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
  699. };
  700. static const unsigned char ecjpake_test_x2[] = {
  701. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
  702. 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  703. 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
  704. };
  705. static const unsigned char ecjpake_test_x3[] = {
  706. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
  707. 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
  708. 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
  709. };
  710. static const unsigned char ecjpake_test_x4[] = {
  711. 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
  712. 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
  713. 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
  714. };
  715. static const unsigned char ecjpake_test_cli_one[] = {
  716. 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
  717. 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
  718. 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
  719. 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
  720. 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
  721. 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
  722. 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
  723. 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
  724. 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
  725. 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
  726. 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
  727. 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
  728. 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
  729. 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
  730. 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
  731. 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
  732. 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
  733. 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
  734. 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
  735. 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
  736. 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
  737. 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
  738. 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
  739. 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
  740. 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
  741. 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
  742. 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
  743. 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
  744. };
  745. static const unsigned char ecjpake_test_srv_one[] = {
  746. 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
  747. 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
  748. 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
  749. 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
  750. 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
  751. 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
  752. 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
  753. 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
  754. 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
  755. 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
  756. 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
  757. 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
  758. 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
  759. 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
  760. 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
  761. 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
  762. 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
  763. 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
  764. 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
  765. 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
  766. 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
  767. 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
  768. 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
  769. 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
  770. 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
  771. 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
  772. 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
  773. 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
  774. };
  775. static const unsigned char ecjpake_test_srv_two[] = {
  776. 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
  777. 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
  778. 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
  779. 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
  780. 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
  781. 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
  782. 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
  783. 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
  784. 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
  785. 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
  786. 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
  787. 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
  788. 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
  789. 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
  790. };
  791. static const unsigned char ecjpake_test_cli_two[] = {
  792. 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
  793. 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
  794. 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
  795. 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
  796. 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
  797. 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
  798. 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
  799. 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
  800. 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
  801. 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
  802. 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
  803. 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
  804. 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
  805. 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
  806. };
  807. static const unsigned char ecjpake_test_pms[] = {
  808. 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7,
  809. 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9,
  810. 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
  811. };
  812. /* Load my private keys and generate the corresponding public keys */
  813. static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
  814. const unsigned char *xm1, size_t len1,
  815. const unsigned char *xm2, size_t len2 )
  816. {
  817. int ret;
  818. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
  819. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
  820. MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1,
  821. &ctx->grp.G, NULL, NULL ) );
  822. MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2,
  823. &ctx->grp.G, NULL, NULL ) );
  824. cleanup:
  825. return( ret );
  826. }
  827. /* For tests we don't need a secure RNG;
  828. * use the LGC from Numerical Recipes for simplicity */
  829. static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
  830. {
  831. static uint32_t x = 42;
  832. (void) p;
  833. while( len > 0 )
  834. {
  835. size_t use_len = len > 4 ? 4 : len;
  836. x = 1664525 * x + 1013904223;
  837. memcpy( out, &x, use_len );
  838. out += use_len;
  839. len -= use_len;
  840. }
  841. return( 0 );
  842. }
  843. #define TEST_ASSERT( x ) \
  844. do { \
  845. if( x ) \
  846. ret = 0; \
  847. else \
  848. { \
  849. ret = 1; \
  850. goto cleanup; \
  851. } \
  852. } while( 0 )
  853. /*
  854. * Checkup routine
  855. */
  856. int mbedtls_ecjpake_self_test( int verbose )
  857. {
  858. int ret;
  859. mbedtls_ecjpake_context cli;
  860. mbedtls_ecjpake_context srv;
  861. unsigned char buf[512], pms[32];
  862. size_t len, pmslen;
  863. mbedtls_ecjpake_init( &cli );
  864. mbedtls_ecjpake_init( &srv );
  865. if( verbose != 0 )
  866. mbedtls_printf( " ECJPAKE test #0 (setup): " );
  867. TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT,
  868. MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
  869. ecjpake_test_password,
  870. sizeof( ecjpake_test_password ) ) == 0 );
  871. TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER,
  872. MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1,
  873. ecjpake_test_password,
  874. sizeof( ecjpake_test_password ) ) == 0 );
  875. if( verbose != 0 )
  876. mbedtls_printf( "passed\n" );
  877. if( verbose != 0 )
  878. mbedtls_printf( " ECJPAKE test #1 (random handshake): " );
  879. TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli,
  880. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  881. TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 );
  882. TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv,
  883. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  884. TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 );
  885. TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv,
  886. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  887. TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 );
  888. TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
  889. pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 );
  890. TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli,
  891. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  892. TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 );
  893. TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
  894. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  895. TEST_ASSERT( len == pmslen );
  896. TEST_ASSERT( memcmp( buf, pms, len ) == 0 );
  897. if( verbose != 0 )
  898. mbedtls_printf( "passed\n" );
  899. if( verbose != 0 )
  900. mbedtls_printf( " ECJPAKE test #2 (reference handshake): " );
  901. /* Simulate generation of round one */
  902. MBEDTLS_MPI_CHK( ecjpake_test_load( &cli,
  903. ecjpake_test_x1, sizeof( ecjpake_test_x1 ),
  904. ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) );
  905. MBEDTLS_MPI_CHK( ecjpake_test_load( &srv,
  906. ecjpake_test_x3, sizeof( ecjpake_test_x3 ),
  907. ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) );
  908. /* Read round one */
  909. TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv,
  910. ecjpake_test_cli_one,
  911. sizeof( ecjpake_test_cli_one ) ) == 0 );
  912. TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli,
  913. ecjpake_test_srv_one,
  914. sizeof( ecjpake_test_srv_one ) ) == 0 );
  915. /* Skip generation of round two, read round two */
  916. TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli,
  917. ecjpake_test_srv_two,
  918. sizeof( ecjpake_test_srv_two ) ) == 0 );
  919. TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv,
  920. ecjpake_test_cli_two,
  921. sizeof( ecjpake_test_cli_two ) ) == 0 );
  922. /* Server derives PMS */
  923. TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv,
  924. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  925. TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
  926. TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
  927. memset( buf, 0, len ); /* Avoid interferences with next step */
  928. /* Client derives PMS */
  929. TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli,
  930. buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 );
  931. TEST_ASSERT( len == sizeof( ecjpake_test_pms ) );
  932. TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 );
  933. if( verbose != 0 )
  934. mbedtls_printf( "passed\n" );
  935. cleanup:
  936. mbedtls_ecjpake_free( &cli );
  937. mbedtls_ecjpake_free( &srv );
  938. if( ret != 0 )
  939. {
  940. if( verbose != 0 )
  941. mbedtls_printf( "failed\n" );
  942. ret = 1;
  943. }
  944. if( verbose != 0 )
  945. mbedtls_printf( "\n" );
  946. return( ret );
  947. }
  948. #undef TEST_ASSERT
  949. #endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
  950. #endif /* MBEDTLS_SELF_TEST */
  951. #endif /* MBEDTLS_ECJPAKE_C */