Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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