libgpuverify

Signature verification on GPUs (WiP)
Log | Files | Refs | README | LICENSE

main.c (7654B)


      1 /*
      2  * main.c
      3  * This file is part of lib-gpu-verify.
      4  *
      5  * lib-gpu-verify is free software: you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation, either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * lib-gpu-verify is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * Created by Cedric Zwahlen
     16  *
     17  */
     18 
     19 #include <stdio.h>
     20 #include <gcrypt.h>
     21 
     22 #include <pthread.h>
     23 #include <sys/stat.h>
     24 #include <sys/mman.h>
     25 #include <sys/fcntl.h>
     26 #include <unistd.h>
     27 
     28 #define NEED_LIBGCRYPT_VERSION "1.10.1"
     29 
     30 void gpuv_prepare_gcry(void) {
     31 
     32     gcry_control (GCRYCTL_SET_THREAD_CBS, 0);
     33 
     34     /* Version check should be the very first call because it
     35      makes sure that important subsystems are initialized.
     36      #define NEED_LIBGCRYPT_VERSION to the minimum required version. */
     37     if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
     38     {
     39         fprintf (stderr, "libgcrypt is too old (need %s, have %s)\n",
     40                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL));
     41         exit (2); }
     42     /* Disable secure memory.  */
     43     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
     44     /* ... If required, other initialization goes here.  */
     45     /* Tell Libgcrypt that initialization has completed. */
     46     gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
     47 
     48 }
     49 
     50 static unsigned long n = 0;
     51 
     52 void *signatures_for_key(void *vargp) {
     53     
     54     int *id = (int *)vargp;
     55     
     56     FILE *pkfile;
     57     FILE *msfile;
     58     
     59     char pk_name[128];
     60     char ms_name[128];
     61     
     62     sprintf(pk_name, "frag_publickey_%i.txt",*id);
     63     sprintf(ms_name, "frag_msgsig_%i.txt",*id);
     64 
     65     pkfile = fopen(pk_name, "w");
     66     msfile = fopen(ms_name, "w");
     67     
     68     
     69     // make a key
     70     char *template = "(genkey(rsa(nbits 4:2048)))";
     71     gcry_sexp_t parms;
     72 
     73     gcry_sexp_new(&parms, template, strlen(template), 1);
     74 
     75     gcry_sexp_t key;
     76 
     77     gcry_pk_genkey(&key,parms);
     78     
     79     gcry_mpi_t n_mpi;
     80     gcry_mpi_t e_mpi;
     81 
     82     gcry_sexp_extract_param(key,NULL,"n e",&n_mpi, &e_mpi, NULL);
     83     
     84     
     85     // e & n contain information about the public key, needed to verify the signatues later
     86     
     87     size_t n_len = 0;
     88     size_t e_len = 0;
     89     
     90     // that is a bit much
     91     unsigned char *nn = malloc(1028);
     92     unsigned char *ee = malloc(1028);
     93     
     94     memset(nn, 0, 1028);
     95     memset(ee, 0, 1028);
     96     
     97     gcry_mpi_print(GCRYMPI_FMT_HEX,nn,1028,&n_len,n_mpi);
     98     gcry_mpi_print(GCRYMPI_FMT_HEX,ee,1028,&e_len,e_mpi);
     99     
    100     fprintf(pkfile, "%s\n",nn);
    101     fprintf(pkfile, "%s\n",ee);
    102     fprintf(pkfile, "%lu\n",((*id + 1) * n) - 1); // this key is used for the signatures up to the index described by this number
    103     
    104     free(nn);
    105     free(ee);
    106     
    107     gcry_mpi_release(n_mpi);
    108     gcry_mpi_release(e_mpi);
    109     
    110    
    111     
    112     int len = 8;
    113     
    114     int i;
    115     for (i = 0; i < n; i++) {
    116         
    117         char buf[len];
    118         
    119         gcry_mpi_t m_mpi;
    120         
    121         gcry_create_nonce(buf, len);
    122         
    123         gcry_mpi_scan(&m_mpi, GCRYMPI_FMT_STD, buf, len, NULL);
    124         
    125         gcry_mpi_abs(m_mpi);
    126         
    127         gcry_sexp_t toSign;
    128         size_t errOff = 0;
    129         char *dataformat = "(data (flags raw) (value %m))";
    130 
    131         gcry_sexp_build(&toSign,&errOff,dataformat,m_mpi);
    132 
    133         gcry_sexp_t resSign;
    134 
    135         gcry_pk_sign(&resSign, toSign, key);
    136 
    137         gcry_mpi_t s_mpi;
    138 
    139         gcry_sexp_extract_param(resSign,NULL,"s",&s_mpi, NULL);
    140         
    141         // m_mpi contains the message, and s_mpi it's signature
    142         
    143         size_t m_len = 0;
    144         size_t s_len = 0;
    145         
    146         // that is a bit much
    147         unsigned char *mm = malloc(1028);
    148         unsigned char *ss = malloc(1028);
    149         
    150         memset(mm, 0, 1028);
    151         memset(ss, 0, 1028);
    152         
    153         gcry_mpi_print(GCRYMPI_FMT_HEX,mm,1028,&m_len,m_mpi);
    154         gcry_mpi_print(GCRYMPI_FMT_HEX,ss,1028,&s_len,s_mpi);
    155         
    156         fprintf(msfile, "%s\n",mm);
    157         fprintf(msfile, "%s\n",ss);
    158         
    159         free(mm);
    160         free(ss);
    161         
    162         gcry_mpi_release(s_mpi);
    163         gcry_mpi_release(m_mpi);
    164         
    165         gcry_sexp_release(toSign);
    166         gcry_sexp_release(resSign);
    167     }
    168     
    169     fclose(pkfile);
    170     fclose(msfile);
    171     
    172     gcry_sexp_release(parms);
    173     gcry_sexp_release(key);
    174     
    175     return NULL;
    176     
    177 }
    178 
    179 #define INCREMENT 8
    180 
    181 int main(int argc, const char * argv[]) {
    182     
    183     // the first argument says how many signatures we should create per public key, if there is no argument, let's say we make.. 4?
    184     
    185     n = 0;
    186     int pks = 1;
    187     
    188     // no arg
    189     if (argc == 1) {
    190         
    191         n = 4;
    192         
    193         // a number is expected
    194     } else if (argc == 2) {
    195        
    196         n = atoi(argv[1]);
    197         
    198     } else if (argc == 3) {
    199         
    200         n = atoi(argv[1]);
    201         pks = atoi(argv[2]);
    202         
    203     }
    204     
    205     if (n == 0 || pks == 0) {
    206         
    207         printf("invalid parameters");
    208         abort();
    209         
    210     }
    211     
    212     
    213     
    214     if (pks == 1) {
    215         printf("generating %lu signatures with the same key.\n",n);
    216     } else {
    217         
    218         pks = pks - (pks % INCREMENT);
    219         
    220         printf("generating %lu signatures with %i keys.\n",n * pks, pks);
    221     }
    222     
    223     gpuv_prepare_gcry();
    224     
    225     pthread_t *tid = malloc(pks * sizeof(pthread_t));
    226     // not the best, but it is safe
    227     int ids[pks];
    228     
    229     FILE *pkfile;
    230     FILE *msfile;
    231 
    232     pkfile = fopen("publickey.txt", "w");
    233     msfile = fopen("msgsig.txt", "w");
    234     
    235     int total = 0;
    236     
    237     for (int x = 0; x < (pks / INCREMENT); x++) {
    238         
    239         for (int i = total; i < (total + INCREMENT); i++) {
    240             ids[i] = i;
    241             int err = pthread_create(&tid[i], NULL, signatures_for_key, (void *)&ids[i]);
    242             if ( err != 0 )
    243                     printf("Error creating threads");
    244         }
    245         
    246         for (int j = total; j < (total + INCREMENT); j++) {
    247             int err = pthread_join(tid[j], NULL);
    248             if ( err != 0 )
    249                     printf("Error joining threads");
    250         }
    251         
    252         for (int k = total; k < (total + INCREMENT); k++) {
    253             
    254             struct stat pk_st, ms_st;
    255             
    256             char pk_name[128];
    257             char ms_name[128];
    258             
    259             sprintf(pk_name, "frag_publickey_%i.txt",k);
    260             sprintf(ms_name, "frag_msgsig_%i.txt",k);
    261             
    262             stat(pk_name, &pk_st);
    263             stat(ms_name, &ms_st);
    264             
    265             FILE * pk_fd = fopen(pk_name, "r");
    266             FILE * ms_fd = fopen(ms_name, "r");
    267             
    268             void *pk_buf = malloc(pk_st.st_size + 1);
    269             void *ms_buf = malloc(ms_st.st_size + 1);
    270            
    271             //char pk_buf[pk_st.st_size + 1];
    272             //char ms_buf[ms_st.st_size + 1];
    273             
    274             memset(pk_buf, 0, pk_st.st_size + 1);
    275             memset(ms_buf, 0, ms_st.st_size + 1);
    276             
    277             fread(pk_buf, 1, pk_st.st_size, pk_fd);
    278             fread(ms_buf, 1, ms_st.st_size, ms_fd);
    279             
    280             fprintf(pkfile, "%s",(char *)pk_buf);
    281             fprintf(msfile, "%s",(char *)ms_buf);
    282             
    283             free(pk_buf);
    284             free(ms_buf);
    285             
    286             unlink(pk_name);
    287             unlink(ms_name);
    288             
    289             fclose(pk_fd);
    290             fclose(ms_fd);
    291             
    292         }
    293         
    294         total += INCREMENT;
    295     }
    296     
    297     fclose(pkfile);
    298     fclose(msfile);
    299     
    300     free(tid);
    301     
    302     return 0;
    303 }