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 #ifndef _CRT_SECURE_NO_DEPRECATE
00027 #define _CRT_SECURE_NO_DEPRECATE 1
00028 #endif
00029
00030 #include <string.h>
00031
00032 #include "xyssl/dhm.h"
00033
00034
00035
00036
00037 static int dhm_read_bignum( mpi *X,
00038 unsigned char **p,
00039 unsigned char *end )
00040 {
00041 int ret, n;
00042
00043 if( end - *p < 2 )
00044 return( ERR_DHM_BAD_INPUT_DATA );
00045
00046 n = ( (*p)[0] << 8 ) | (*p)[1];
00047 (*p) += 2;
00048
00049 if( (int)( end - *p ) < n )
00050 return( ERR_DHM_BAD_INPUT_DATA );
00051
00052 if( ( ret = mpi_read_binary( X, *p, n ) ) != 0 )
00053 return( ERR_DHM_READ_PARAMS_FAILED | ret );
00054
00055 (*p) += n;
00056
00057 return( 0 );
00058 }
00059
00060
00061
00062
00063 int dhm_read_params( dhm_context *ctx,
00064 unsigned char **p,
00065 unsigned char *end )
00066 {
00067 int ret, n;
00068
00069 memset( ctx, 0, sizeof( dhm_context ) );
00070
00071 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
00072 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
00073 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
00074 return( ret );
00075
00076 ctx->len = ( mpi_msb( &ctx->P ) + 7 ) >> 3;
00077
00078 if( end - *p < 2 )
00079 return( ERR_DHM_BAD_INPUT_DATA );
00080
00081 n = ( (*p)[0] << 8 ) | (*p)[1];
00082 (*p) += 2;
00083
00084 if( end != *p + n )
00085 return( ERR_DHM_BAD_INPUT_DATA );
00086
00087 return( 0 );
00088 }
00089
00090
00091
00092
00093 int dhm_make_params( dhm_context *ctx,
00094 int (*rng_f)(void *), void *rng_d,
00095 unsigned char *output, int *olen )
00096 {
00097 int i, ret, n, n1, n2, n3;
00098 unsigned char *p;
00099
00100
00101
00102
00103 n = 48 / sizeof( t_int );
00104 CHK( mpi_grow( &ctx->X, n ) );
00105
00106 p = (unsigned char *) ctx->X.p;
00107 for( i = 0; i < ciL * ctx->X.n; i++ )
00108 *p++ = rng_f( rng_d );
00109
00110 while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
00111 mpi_shift_r( &ctx->X, 1 );
00112
00113 CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
00114 &ctx->P , &ctx->RP ) );
00115
00116
00117
00118
00119 #define DHM_MPI_EXPORT(X,n) \
00120 CHK( mpi_write_binary( X, p + 2, &n ) ); \
00121 *p++ = ( n >> 8 ); *p++ = n; p += n;
00122
00123 n1 = ( mpi_msb( &ctx->P ) + 7 ) >> 3;
00124 n2 = ( mpi_msb( &ctx->G ) + 7 ) >> 3;
00125 n3 = ( mpi_msb( &ctx->GX ) + 7 ) >> 3;
00126
00127 p = output;
00128 DHM_MPI_EXPORT( &ctx->P , n1 );
00129 DHM_MPI_EXPORT( &ctx->G , n2 );
00130 DHM_MPI_EXPORT( &ctx->GX, n3 );
00131
00132 *olen = p - output;
00133
00134 ctx->len = n1;
00135
00136 cleanup:
00137
00138 if( ret != 0 )
00139 return( ret | ERR_DHM_MAKE_PARAMS_FAILED );
00140
00141 return( 0 );
00142 }
00143
00144
00145
00146
00147 int dhm_read_public( dhm_context *ctx,
00148 unsigned char *input, int ilen )
00149 {
00150 int ret;
00151
00152 if( ctx == NULL || ilen < 1 || ilen > ctx->len )
00153 return( ERR_DHM_BAD_INPUT_DATA );
00154
00155 if( ( ret = mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
00156 return( ERR_DHM_READ_PUBLIC_FAILED | ret );
00157
00158 return( 0 );
00159 }
00160
00161
00162
00163
00164 int dhm_make_public( dhm_context *ctx,
00165 unsigned char *output, int olen,
00166 int (*rng_f)(void *), void *rng_d )
00167 {
00168 int ret, i, n;
00169 unsigned char *p;
00170
00171 if( ctx == NULL || olen < 1 || olen > ctx->len )
00172 return( ERR_DHM_BAD_INPUT_DATA );
00173
00174
00175
00176
00177 n = 48 / sizeof( t_int );
00178 CHK( mpi_grow( &ctx->X, n ) );
00179
00180 p = (unsigned char *) ctx->X.p;
00181 for( i = 0; i < ciL * ctx->X.n; i++ )
00182 *p++ = rng_f( rng_d );
00183
00184 while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
00185 mpi_shift_r( &ctx->X, 1 );
00186
00187 CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
00188 &ctx->P , &ctx->RP ) );
00189
00190 CHK( mpi_write_binary( &ctx->GX, output, &olen ) );
00191
00192 cleanup:
00193
00194 if( ret != 0 )
00195 return( ERR_DHM_MAKE_PUBLIC_FAILED | ret );
00196
00197 return( 0 );
00198 }
00199
00200
00201
00202
00203 int dhm_calc_secret( dhm_context *ctx,
00204 unsigned char *output, int *olen )
00205 {
00206 int ret;
00207
00208 if( ctx == NULL || *olen < ctx->len )
00209 return( ERR_DHM_BAD_INPUT_DATA );
00210
00211 CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X,
00212 &ctx->P, &ctx->RP ) );
00213
00214 *olen = ( mpi_msb( &ctx->K ) + 7 ) >> 3;
00215
00216 CHK( mpi_write_binary( &ctx->K, output, olen ) );
00217
00218 cleanup:
00219
00220 if( ret != 0 )
00221 return( ERR_DHM_CALC_SECRET_FAILED | ret );
00222
00223 return( 0 );
00224 }
00225
00226
00227
00228
00229 void dhm_free( dhm_context *ctx )
00230 {
00231 mpi_free( &ctx->RP, &ctx->K, &ctx->GY,
00232 &ctx->GX, &ctx->X, &ctx->G,
00233 &ctx->P, NULL );
00234 }
00235
00236 static const char _dhm_src[] = "_dhm_src";
00237
00238 #if defined(SELF_TEST)
00239 #endif
00240
00241
00242
00243 int dhm_self_test( int verbose )
00244 {
00245 return( verbose = 0 );
00246 }