00001 /* SVN FILE INFO 00002 * $Revision: 199 $ : Last Committed Revision 00003 * $Date: 2008年07月11日 10:33:31 -0700 (2008年7月11日) $ : Last Committed Date */ 00004 #include <stdio.h> 00005 #include "../include/mc_error.h" 00006 #include "xyssl-0.9/include/xyssl/dhm.h" 00007 #include "xyssl-0.9/include/xyssl/havege.h" 00008 #include "mc_dh.h" 00009 #include "asm_node.h" 00010 #ifndef _WIN32 00011 #include "config.h" 00012 #else 00013 #include "../winconfig.h" 00014 #endif 00015 00016 #ifdef MC_SECURITY 00017 00018 int dh_data_Destroy(dh_data_p dh_data) 00019 { 00020 /* This is buggy for some reason */ 00021 /* dhm_free(&(dh_data->dhm)); */ 00022 return 0; 00023 } 00024 00025 dh_data_p dh_data_Initialize(void) 00026 { 00027 int len; 00028 havege_state hs; 00029 char *buf; 00030 dh_data_p dh_data; 00031 00032 buf = (char*)malloc(sizeof(char) * 1024); 00033 CHECK_NULL(buf, exit(0);); 00034 dh_data = (dh_data_p)malloc(sizeof(dh_data_t)); 00035 CHECK_NULL(dh_data, exit(0);); 00036 00037 memset(dh_data, 0, sizeof(dh_data_t)); 00038 00039 /* Seed random num generator */ 00040 havege_init(&hs); 00041 00042 /* dh_GetKeyPair( &(dh_data.rsa) ); */ /* FIXME: Implement this later: 00043 it is too complicated for now */ 00044 dh_GetPrime( &(dh_data->dhm) ); 00045 00046 /* Set up dh parameters */ 00047 if ( 00048 dhm_make_params 00049 ( 00050 &(dh_data->dhm), 00051 havege_rand, 00052 &hs, 00053 buf, 00054 &len 00055 ) 00056 ) 00057 { 00058 fprintf(stderr, "Potentially fatal error. %s:%d\n",__FILE__,__LINE__); 00059 } 00060 00061 free(buf); 00062 return dh_data; 00063 } 00064 00065 dh_data_p dh_data_InitializeFromString(char* P, char* G, char* GY) 00066 { 00067 dh_data_p dh_data; 00068 00069 dh_data = (dh_data_p)malloc(sizeof(dh_data_t)); 00070 00071 memset(dh_data, 0, sizeof(dh_data_t)); 00072 00073 if ( mpi_read_string( &(dh_data->dhm.P), 16, P) ) { 00074 fprintf 00075 ( 00076 stderr, 00077 "Error initializing prime number P. %s:%d\n", 00078 __FILE__, __LINE__ 00079 ); 00080 goto cleanup; 00081 } 00082 if ( mpi_read_string( &(dh_data->dhm.G), 16, G) ) { 00083 fprintf 00084 ( 00085 stderr, 00086 "Error initializing. %s:%d\n", 00087 __FILE__, __LINE__ 00088 ); 00089 goto cleanup; 00090 } 00091 if ( mpi_read_string( &(dh_data->dhm.GY), 16, GY) ) { 00092 fprintf 00093 ( 00094 stderr, 00095 "Error initializing. %s:%d\n", 00096 __FILE__, __LINE__ 00097 ); 00098 goto cleanup; 00099 } 00100 00101 return dh_data; 00102 cleanup: 00103 free(dh_data); 00104 return NULL; 00105 } 00106 00107 #define DH_P_SIZE 1024 00108 #define GENERATOR "4" 00109 int dh_GenPrime(dhm_context* dhm) 00110 { 00111 mpi Q; 00112 havege_state hs; 00113 int ret; 00114 00115 mpi_init( &(dhm->G), &(dhm->P), &Q, NULL); 00116 mpi_read_string( &(dhm->G), 10, GENERATOR ); 00117 00118 /* Seed random number generator */ 00119 havege_init(&hs); 00120 /* 00121 * This can take a long time... 00122 */ 00123 if( ( ret = mpi_gen_prime( &(dhm->P), DH_P_SIZE, 1, 00124 havege_rand, &hs ) ) != 0 ) 00125 { 00126 printf( " failed\n ! mpi_gen_prime returned %08x\n\n", ret ); 00127 goto exit; 00128 } else 00129 { 00130 printf("Prime number successfully generated...\n"); 00131 } 00132 00133 /* Verify our prime number is prime */ 00134 if( ( ret = mpi_sub_int( &Q, &(dhm->P), 1 ) ) != 0 || 00135 ( ret = mpi_div_int( &Q, NULL, &Q, 2 ) ) != 0 || 00136 ( ret = mpi_is_prime( &Q ) ) != 0 ) 00137 { 00138 printf( " failed\n ! mpi_xx returned %08x\n\n", ret ); 00139 goto exit; 00140 } 00141 return MC_SUCCESS; 00142 00143 exit: 00144 mpi_free(&Q, NULL); 00145 return ret; 00146 } 00147 00148 int dh_GetPrime(dhm_context* dhm) 00149 { 00150 FILE* f; 00151 00152 char filename[200] = "dh_prime.txt"; 00153 char buf[80]; 00154 char *tmp; 00155 00156 int gen_prime = 0; 00157 int ret; 00158 00159 while 00160 ( 00161 (( f = fopen( "dh_prime.txt", "rb" ) ) == NULL) && 00162 gen_prime == 0 00163 ) 00164 { 00165 printf("Could not open %s for reading.\n", filename); 00166 printf("Would you like to:\n"); 00167 printf("\t1. Specify another file containing the prime number, or\n"); 00168 printf("\t2. Generate a new prime number? (May take some time)\n"); 00169 #ifndef _WIN32 00170 fgets(buf, sizeof(buf), stdin); /* FIXME: Why the HELL doesn't this work in windows???*/ 00171 #else 00172 gets(buf); 00173 #endif 00174 switch(buf[0]) 00175 { 00176 case '1': 00177 printf("Please enter filename: "); 00178 fgets(filename, sizeof(filename), stdin); 00179 break; 00180 case '2': 00181 ret = dh_GenPrime(dhm); 00182 gen_prime = 1; 00183 if(!ret) 00184 { 00185 printf("Would you like to save the generated prime number to a file?\n"); 00186 printf("y/n: "); 00187 #ifndef _WIN32 00188 fgets(buf, sizeof(buf), stdin); 00189 #else 00190 gets(buf); 00191 #endif 00192 switch(buf[0]) { 00193 case 'y': 00194 printf("Please enter filename [dh_prime.txt]: "); 00195 #ifndef _WIN32 00196 fgets(filename, sizeof(filename), stdin); 00197 #else 00198 gets(filename); 00199 #endif 00200 tmp = strrchr(filename, '\n'); 00201 if (tmp != NULL) { *tmp = '0円'; } 00202 if(filename[0] == '0円') { strcpy(filename, "dh_prime.txt"); } 00203 if ( (f=fopen(filename, "wb+")) == NULL) { 00204 break; 00205 } 00206 if( mpi_write_file( "P = ", &(dhm->P), 16, f ) || 00207 mpi_write_file( "G = ", &(dhm->G), 16, f ) ) { 00208 fprintf(stderr, "Error! %s:%d\n", __FILE__, __LINE__); 00209 } 00210 break; 00211 case 'n': 00212 printf("Not saving file...\n"); 00213 break; 00214 default: 00215 printf("Unknown option. Not saving file...\n"); 00216 break; 00217 } 00218 goto exit; 00219 } 00220 default: 00221 printf("Invalid option.\n"); 00222 break; 00223 } 00224 } 00225 00226 if( mpi_read_file( &(dhm->P), 16, f ) != 0 || 00227 mpi_read_file( &(dhm->G), 16, f ) != 0 ) 00228 { 00229 printf( " failed\n ! Invalid DH parameter file\n\n" ); 00230 goto exit; 00231 } 00232 00233 exit: 00234 if(f) fclose(f); 00235 return ret; 00236 } 00237 00238 /* Get rsa key pair */ 00239 int rsa_GetKeyPair(rsa_context* rsa) 00240 { 00241 FILE* f; 00242 00243 char filename[200]; 00244 char buf[80]; 00245 char* tmp; 00246 00247 int ret=0; 00248 00249 strcpy(filename, "rsa_priv.txt"); 00250 while( ( f = fopen( filename, "rb" ) ) == NULL ) 00251 { 00252 printf("Private key file: %s not found.\n", filename); 00253 printf("Would you like to:\n"); 00254 printf("\t1. Specify another filename? or\n"); 00255 printf("\t2. Generate a new private key file?\n"); 00256 fgets(buf, sizeof(buf), stdin); 00257 switch(buf[0]) { 00258 case '1': 00259 printf("Please enter filename: "); 00260 fgets(filename, sizeof(filename), stdin); 00261 while( (tmp = strchr(filename, '\n') ) != NULL ) { 00262 *tmp = '0円'; 00263 } 00264 break; 00265 case '2': 00266 rsa_GenKeyPair(rsa); 00267 break; 00268 default: 00269 printf("Incorrect Option.\n"); 00270 break; 00271 } 00272 } 00273 00274 if ( ( ret = rsa_read_private( rsa, f ) ) != 0 ){ 00275 printf( " failed\n ! rsa_read_private returned %08x\n\n", ret ); 00276 goto exit; 00277 } 00278 00279 exit: 00280 fclose( f ); 00281 return ret; 00282 } 00283 00284 int rsa_GenKeyPair(rsa_context* rsa) 00285 { 00286 /* FIXME: Does nothing for now. This function is not currently used */ 00287 return 0; 00288 } 00289 00290 #endif /*MC_SECURITY*/