/home/dko/projects/mobilec/trunk/src/security/mc_dh.c

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

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4