00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "polarssl/config.h"
00034
00035 #if defined(POLARSSL_ECDH_C)
00036
00037 #include "polarssl/ecdh.h"
00038
00039
00040
00041
00042 int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q,
00043 int (*f_rng)(void *, unsigned char *, size_t),
00044 void *p_rng )
00045 {
00046 return ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
00047 }
00048
00049
00050
00051
00052 int ecdh_compute_shared( ecp_group *grp, mpi *z,
00053 const ecp_point *Q, const mpi *d,
00054 int (*f_rng)(void *, unsigned char *, size_t),
00055 void *p_rng )
00056 {
00057 int ret;
00058 ecp_point P;
00059
00060 ecp_point_init( &P );
00061
00062
00063
00064
00065 MPI_CHK( ecp_check_pubkey( grp, Q ) );
00066
00067 MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
00068
00069 if( ecp_is_zero( &P ) )
00070 {
00071 ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
00072 goto cleanup;
00073 }
00074
00075 MPI_CHK( mpi_copy( z, &P.X ) );
00076
00077 cleanup:
00078 ecp_point_free( &P );
00079
00080 return( ret );
00081 }
00082
00083
00084
00085
00086 void ecdh_init( ecdh_context *ctx )
00087 {
00088 memset( ctx, 0, sizeof( ecdh_context ) );
00089 }
00090
00091
00092
00093
00094 void ecdh_free( ecdh_context *ctx )
00095 {
00096 if( ctx == NULL )
00097 return;
00098
00099 ecp_group_free( &ctx->grp );
00100 mpi_free ( &ctx->d );
00101 ecp_point_free( &ctx->Q );
00102 ecp_point_free( &ctx->Qp );
00103 mpi_free ( &ctx->z );
00104 ecp_point_free( &ctx->Vi );
00105 ecp_point_free( &ctx->Vf );
00106 mpi_free ( &ctx->_d );
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 int ecdh_make_params( ecdh_context *ctx, size_t *olen,
00117 unsigned char *buf, size_t blen,
00118 int (*f_rng)(void *, unsigned char *, size_t),
00119 void *p_rng )
00120 {
00121 int ret;
00122 size_t grp_len, pt_len;
00123
00124 if( ctx == NULL || ctx->grp.pbits == 0 )
00125 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00126
00127 if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
00128 != 0 )
00129 return( ret );
00130
00131 if( ( ret = ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) )
00132 != 0 )
00133 return( ret );
00134
00135 buf += grp_len;
00136 blen -= grp_len;
00137
00138 if( ( ret = ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
00139 &pt_len, buf, blen ) ) != 0 )
00140 return( ret );
00141
00142 *olen = grp_len + pt_len;
00143 return 0;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 int ecdh_read_params( ecdh_context *ctx,
00154 const unsigned char **buf, const unsigned char *end )
00155 {
00156 int ret;
00157
00158 if( ( ret = ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 )
00159 return( ret );
00160
00161 if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
00162 != 0 )
00163 return( ret );
00164
00165 return 0;
00166 }
00167
00168
00169
00170
00171 int ecdh_make_public( ecdh_context *ctx, size_t *olen,
00172 unsigned char *buf, size_t blen,
00173 int (*f_rng)(void *, unsigned char *, size_t),
00174 void *p_rng )
00175 {
00176 int ret;
00177
00178 if( ctx == NULL || ctx->grp.pbits == 0 )
00179 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00180
00181 if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
00182 != 0 )
00183 return( ret );
00184
00185 return ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
00186 olen, buf, blen );
00187 }
00188
00189
00190
00191
00192 int ecdh_read_public( ecdh_context *ctx,
00193 const unsigned char *buf, size_t blen )
00194 {
00195 if( ctx == NULL )
00196 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00197
00198 return ecp_tls_read_point( &ctx->grp, &ctx->Qp, &buf, blen );
00199 }
00200
00201
00202
00203
00204 int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
00205 unsigned char *buf, size_t blen,
00206 int (*f_rng)(void *, unsigned char *, size_t),
00207 void *p_rng )
00208 {
00209 int ret;
00210
00211 if( ctx == NULL )
00212 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00213
00214 if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d,
00215 f_rng, p_rng ) ) != 0 )
00216 {
00217 return( ret );
00218 }
00219
00220 if( mpi_size( &ctx->z ) > blen )
00221 return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
00222
00223 *olen = ctx->grp.nbits / 8 + ( ( ctx->grp.nbits % 8 ) != 0 );
00224 return mpi_write_binary( &ctx->z, buf, *olen );
00225 }
00226
00227
00228 #if defined(POLARSSL_SELF_TEST)
00229
00230
00231
00232
00233 int ecdh_self_test( int verbose )
00234 {
00235 return( verbose++ );
00236 }
00237
00238 #endif
00239
00240 #endif