]> AND Private Git Repository - Cipher_code.git/blob - OneRoundIoT/openssl/openssl_evp_chacha20_poly1305.c
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Merge branch 'master' of ssh://info.iut-bm.univ-fcomte.fr/Cipher_code
[Cipher_code.git] / OneRoundIoT / openssl / openssl_evp_chacha20_poly1305.c
1 //gcc pixmap_io.c  -c
2 //gcc openssl_evp.c pixmap_io.o -o  openssl_evp -I /usr/include/openssl/ -lcrypto -O3 -std=c99 
3
4
5 #include <openssl/conf.h>
6 #include <openssl/evp.h>
7 #include <openssl/err.h>
8 #include <openssl/ssl.h>
9 #include <openssl/bio.h>
10 #include <openssl/cmac.h>
11 #include <string.h>
12 #include <sys/time.h>
13 #include "pixmap_io.h"
14
15 typedef unsigned char   uchar;
16
17 int nb_test=1;
18 int ctr=0;
19
20 double TimeStart()
21 {
22   struct timeval tstart;
23   gettimeofday(&tstart,0);
24   return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) );
25 }
26
27 double TimeStop(double t)
28 {
29   struct timeval tend;
30
31   gettimeofday(&tend,0);
32   t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t;
33   return (t);
34 }
35
36
37 void printBytes(unsigned char *buf, size_t len) {
38   for(int i=0; i<len; i++) {
39     printf("%02x ", buf[i]);
40   }
41   printf("\n");
42 }
43
44
45 void handleErrors(void)
46 {
47   ERR_print_errors_fp(stderr);
48   abort();
49 }
50
51
52 int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
53             unsigned char *iv, unsigned char *ciphertext, int ctr, int index)
54 {
55   CMAC_CTX *ctx;
56
57   int len;
58
59   int ciphertext_len;
60
61   /* Create and initialise the context */
62   if(!(ctx = CMAC_CTX_new())) handleErrors();
63
64   /* Initialise the encryption operation. IMPORTANT - ensure you use a key
65    * and IV size appropriate for your cipher
66    * In this example we are using 256 bit AES (i.e. a 256 bit key). The
67    * IV size for *most* modes is the same as the block size. For AES this
68    * is 128 bits */
69   //static double  time=0;
70   //double t=0;
71   //t=TimeStart();
72   //256
73   //avant ecb
74   if(ctr) {
75     if(1 != CMAC_Init(ctx, key, 32, EVP_chacha20_poly1305(), NULL))
76       handleErrors();
77   }
78   else
79     if(1 != CMAC_Init(ctx, key, 32, EVP_chacha20_poly1305(), NULL))
80         handleErrors();
81   size_t mactlen;
82 unsigned char mact[16] = {0}; 
83   //time+=TimeStop(t);
84   //printf("Time init %f\n",time);
85
86   
87 //  int cipherBlockSize = EVP_CIPHER_CTX_block_size(ctx);  
88 //  printf("INFO(evp_encrypt): block size: %d\n", cipherBlockSize);
89
90   
91   /* Provide the message to be encrypted, and obtain the encrypted output.
92    * EVP_EncryptUpdate can be called multiple times if necessary
93    */
94
95 /*
96   static double  time=0;
97   double t=0;
98   t=TimeStart();
99 */
100   for(int i=0;i<nb_test;i++)
101   {  
102   
103       if(1 != CMAC_Update(ctx,  plaintext, plaintext_len))
104       handleErrors();
105     ciphertext_len = len;
106     
107   }
108 /*  time+=TimeStop(t);
109   // if(index==nb_test-1)
110   printf("Time encrypt %f\n",time);
111     
112 */
113
114   
115   /* Finalise the encryption. Further ciphertext bytes may be written at
116    * this stage.
117    */
118   if(1 != CMAC_Final(ctx,  mact, &mactlen)) handleErrors();
119   ciphertext_len += len;
120
121   //  printBytes(mact, mactlen);
122   
123   /* Clean up */
124   CMAC_CTX_free(ctx);
125
126   return ciphertext_len;
127 }
128
129 int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
130             unsigned char *iv, unsigned char *plaintext, int ctr, int index)
131 {
132   EVP_CIPHER_CTX *ctx;
133
134   int len;
135
136   int plaintext_len;
137
138   /* Create and initialise the context */
139   if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
140
141   /* Initialise the decryption operation. IMPORTANT - ensure you use a key
142    * and IV size appropriate for your cipher
143    * In this example we are using 256 bit AES (i.e. a 256 bit key). The
144    * IV size for *most* modes is the same as the block size. For AES this
145    * is 128 bits */
146
147   //256
148
149   //avant => ecb
150   if(ctr) {
151     if(1 != EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, iv))
152       handleErrors();
153   }
154   else
155       if(1 != EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, iv))
156     handleErrors();
157
158   /* Provide the message to be decrypted, and obtain the plaintext output.
159    * EVP_DecryptUpdate can be called multiple times if necessary
160    */
161   
162 /*  static double time=0;
163   double t=0;
164   t=TimeStart();
165 */
166   for(int i=0;i<nb_test;i++)
167   {  
168     plaintext_len = 0;
169     if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
170       handleErrors();
171     plaintext_len = len;
172   }
173 /*  time+=TimeStop(t);
174 //  if(index==nb_test-1)
175     printf("Time decrypt %f\n",time);
176 */
177
178   
179   /* Finalise the decryption. Further plaintext bytes may be written at
180    * this stage.
181    */
182   if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) handleErrors();
183   plaintext_len += len;
184
185   
186   
187   /* Clean up */
188   EVP_CIPHER_CTX_free(ctx);
189
190   return plaintext_len;
191 }
192
193
194 int main (int argc, char** argv)
195 {
196   /* Set up the key and iv. Do I need to say to not hard code these in a
197    * real application? :-)
198    */
199
200   int size_buf=1;
201   int lena=0;
202   int change=0;
203    
204   for(int i=1; i<argc; i++){
205     if(strncmp(argv[i],"nb",2)==0)    nb_test = atoi(&(argv[i][2]));    //nb of test         
206     if(strncmp(argv[i],"ctr",3)==0) ctr = atoi(&(argv[i][3]));          //CTR ? 1  otherwise CBC like
207     if(strncmp(argv[i],"sizebuf",7)==0) size_buf = atoi(&(argv[i][7]));          //SIZE of the buffer
208     if(strncmp(argv[i],"lena",4)==0) lena = atoi(&(argv[i][4]));          //Use Lena or buffer
209     if(strncmp(argv[i],"c",1)==0) change = atoi(&(argv[i][1]));          //Use Lena or buffer
210   }
211
212 /*  printf("nb times %d\n",nb_test);
213   printf("ctr %d\n",ctr);
214   printf("lena %d\n",lena);
215   printf("size_buf %d\n",size_buf);
216 */
217
218
219
220   
221   /* A 256 bit key */
222 //  unsigned char *key = (unsigned char *)"01234567890123456789012345678901";
223   unsigned char *key = (unsigned char *)"0123456789012345";
224   
225   /* A 128 bit IV */
226   unsigned char *iv = (unsigned char *)"0123456789012345";
227
228   /* Message to be encrypted */
229
230   /* Buffer for ciphertext. Ensure the buffer is long enough for the
231    * ciphertext which may be longer than the plaintext, dependant on the
232    * algorithm and mode
233    */
234
235   int width;
236   int height;
237   uchar *data_R, *data_G, *data_B;
238   int imsize;
239   uchar *buffer;
240
241
242   if(lena==1) {
243     load_RGB_pixmap("lena.ppm", &width, &height, &data_R, &data_G, &data_B);
244     imsize=width*height*3;
245 //  load_RGB_pixmap("No_ecb_mode_picture.ppm", &width, &height, &data_R, &data_G, &data_B);
246   }
247   else {
248     width=size_buf;
249     height=size_buf;
250     imsize=width*height;
251     buffer=malloc(imsize*sizeof(uchar));
252     for(int i=0;i<imsize;i++) {
253       buffer[i]=lrand48();
254     }
255   }
256   
257
258
259   int oneD=width*height;
260   uchar *plaintext = malloc(imsize+1000);   //add that for cbc
261   if(lena) {
262     for(int i=0;i<oneD;i++) {
263       plaintext[i]=data_R[i];
264       plaintext[oneD+i]=data_G[i];
265       plaintext[2*oneD+i]=data_B[i];
266     }
267   }
268   else
269   {
270      for(int i=0;i<oneD;i++) {
271        plaintext[i]=buffer[i];
272     }
273   }
274
275    if(change==1) {
276     
277     plaintext[4]++;
278   }
279   if(change==2) {
280     
281     plaintext[9]++;
282   }
283
284
285   uchar *ciphertext = malloc(imsize+1000); //add that for cbc
286
287   /* Buffer for the decrypted text */
288   uchar *decryptedtext = malloc(imsize+1000); //add that for cbc
289
290   int decryptedtext_len, ciphertext_len;
291
292   /* Initialise the library */
293 /*  ERR_load_crypto_strings();
294   OpenSSL_add_all_algorithms();
295   OPENSSL_config(NULL);
296 */
297
298
299   double time_encrypt=0;
300   double time_decrypt=0;
301   double t=TimeStart();
302
303   
304   /* Encrypt the plaintext */
305
306
307   int i;
308
309 //  for(i=0;i<nb_test;i++)
310   {  
311     ciphertext_len = encrypt (plaintext, imsize, key, iv,
312                               ciphertext, ctr, i );
313   }
314
315  time_encrypt+=TimeStop(t);
316
317 // printf("Time encrypt %f\n",time);
318  printf("%e\t",(double)imsize*nb_test/time_encrypt);
319
320  /*
321  if(lena) {
322    for(int i=0;i<oneD;i++) {
323      data_R[i]=ciphertext[i];
324      data_G[i]=ciphertext[oneD+i];
325      data_B[i]=ciphertext[2*oneD+i];
326    }
327    store_RGB_pixmap("lena2.ppm", data_R, data_G, data_B, width, height);
328  }
329  */
330 /*  
331   t=0;
332   t=TimeStart();
333
334   //for(int i=0;i<nb_test;i++)
335   {  
336     // Decrypt the ciphertext 
337     decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv,
338                                 decryptedtext,ctr, i);
339   }
340
341  time_decrypt+=TimeStop(t);
342
343  //printf("Time decrypt %f\n",time);
344  printf("%f\t",(double)imsize*nb_test/time_decrypt);
345
346  if(lena) {
347    for(int i=0;i<oneD;i++) {
348      data_R[i]=decryptedtext[i];
349      data_G[i]=decryptedtext[oneD+i];
350      data_B[i]=decryptedtext[2*oneD+i];
351    }
352    store_RGB_pixmap("lena3.ppm", data_R, data_G, data_B, width, height);
353  }
354  else {
355    int equal=1;
356    for(int i=0;i<imsize;i++) {
357      //cout<<(int)buffer[i]<<endl;
358      if(buffer[i]!=decryptedtext[i]) {
359        equal=0;
360      }
361    }
362 //   printf("RESULT CORRECT: %d\n",equal);
363  }
364 */  
365
366   /* Clean up */
367   EVP_cleanup();
368   ERR_free_strings();
369
370   return 0;
371 }