tighten formatting rules
[oweals/gnunet.git] / src / util / crypto_abe.c
1 /*
2      This file is part of GNUnet.  Copyright (C) 2001-2014 Christian Grothoff
3      (and other contributing authors)
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19
20  */
21
22 /**
23  * @file util/crypto_random.c
24  * @brief functions to gather random numbers
25  * @author Christian Grothoff
26  */
27
28
29 #include "platform.h"
30 #include <pbc/pbc.h>
31 #include <gabe.h>
32
33 #include "gnunet_crypto_lib.h"
34
35 struct GNUNET_CRYPTO_AbeMasterKey
36 {
37   gabe_pub_t*pub;
38   gabe_msk_t*msk;
39 };
40
41 struct GNUNET_CRYPTO_AbeKey
42 {
43   gabe_pub_t*pub;
44   gabe_prv_t*prv;
45 };
46
47 static int
48 init_aes (element_t k, int enc,
49           gcry_cipher_hd_t*handle,
50           struct GNUNET_CRYPTO_SymmetricSessionKey *key,
51           unsigned char*iv)
52 {
53   int rc;
54   int key_len;
55   unsigned char*key_buf;
56
57   key_len = element_length_in_bytes (k) < 33 ? 3 : element_length_in_bytes (k);
58   key_buf = (unsigned char*) malloc (key_len);
59   element_to_bytes (key_buf, k);
60
61   GNUNET_memcpy (key->aes_key,
62                  key_buf,
63                  GNUNET_CRYPTO_AES_KEY_LENGTH);
64   GNUNET_assert (0 ==
65                  gcry_cipher_open (handle, GCRY_CIPHER_AES256,
66                                    GCRY_CIPHER_MODE_CFB, 0));
67   rc = gcry_cipher_setkey (*handle,
68                            key->aes_key,
69                            sizeof(key->aes_key));
70   GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
71   memset (iv, 0, 16);  // TODO make reasonable
72   rc = gcry_cipher_setiv (*handle,
73                           iv,
74                           16);
75   GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
76
77   free (key_buf);
78   return rc;
79 }
80
81
82 static int
83 aes_128_cbc_encrypt (char*pt,
84                      int size,
85                      element_t k,
86                      char **ct)
87 {
88   gcry_cipher_hd_t handle;
89   struct GNUNET_CRYPTO_SymmetricSessionKey skey;
90   unsigned char iv[16];
91   char*buf;
92   int padding;
93   int buf_size;
94   uint8_t len[4];
95
96   init_aes (k, 1, &handle, &skey, iv);
97
98   /* TODO make less crufty */
99
100   /* stuff in real length (big endian) before padding */
101   len[0] = (size & 0xff000000) >> 24;
102   len[1] = (size & 0xff0000) >> 16;
103   len[2] = (size & 0xff00) >> 8;
104   len[3] = (size & 0xff) >> 0;
105   padding = 16 - ((4 + size) % 16);
106   buf_size = 4 + size + padding;
107   buf = GNUNET_malloc (buf_size);
108   GNUNET_memcpy (buf, len, 4);
109   GNUNET_memcpy (buf + 4, pt, size);
110   *ct = GNUNET_malloc (buf_size);
111
112   GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf,
113                                            buf_size));
114   gcry_cipher_close (handle);
115   // AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT);
116   GNUNET_free (buf);
117   return buf_size;
118 }
119
120
121 static int
122 aes_128_cbc_decrypt (char*ct,
123                      int size,
124                      element_t k,
125                      char **pt)
126 {
127   struct GNUNET_CRYPTO_SymmetricSessionKey skey;
128   gcry_cipher_hd_t handle;
129   unsigned char iv[16];
130   char*tmp;
131   uint32_t len;
132
133   init_aes (k, 1, &handle, &skey, iv);
134
135   tmp = GNUNET_malloc (size);
136
137   // AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT);
138   GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, ct, size));
139   gcry_cipher_close (handle);
140   /* TODO make less crufty */
141
142   /* get real length */
143   len = 0;
144   len = len
145         | ((tmp[0]) << 24) | ((tmp[1]) << 16)
146         | ((tmp[2]) << 8) | ((tmp[3]) << 0);
147   /* truncate any garbage from the padding */
148   *pt = GNUNET_malloc (len);
149   GNUNET_memcpy (*pt, tmp + 4, len);
150   GNUNET_free (tmp);
151   return len;
152 }
153
154
155 struct GNUNET_CRYPTO_AbeMasterKey*
156 GNUNET_CRYPTO_cpabe_create_master_key (void)
157 {
158   struct GNUNET_CRYPTO_AbeMasterKey*key;
159
160   key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
161   gabe_setup (&key->pub, &key->msk);
162   GNUNET_assert (NULL != key->pub);
163   GNUNET_assert (NULL != key->msk);
164   return key;
165 }
166
167
168 void
169 GNUNET_CRYPTO_cpabe_delete_master_key (struct GNUNET_CRYPTO_AbeMasterKey *key)
170 {
171   gabe_msk_free (key->msk);
172   gabe_pub_free (key->pub);
173   // GNUNET_free (key->msk);
174   // gabe_msk_free (key->msk); //For some reason free of pub implicit?
175   GNUNET_free (key);
176 }
177
178
179 struct GNUNET_CRYPTO_AbeKey*
180 GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key,
181                                 char **attrs)
182 {
183   struct GNUNET_CRYPTO_AbeKey *prv_key;
184   int size;
185   char *tmp;
186
187   prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
188   prv_key->prv = gabe_keygen (key->pub, key->msk, attrs);
189   size = gabe_pub_serialize (key->pub, &tmp);
190   prv_key->pub = gabe_pub_unserialize (tmp, size);
191   GNUNET_free (tmp);
192   GNUNET_assert (NULL != prv_key->prv);
193   return prv_key;
194 }
195
196
197 void
198 GNUNET_CRYPTO_cpabe_delete_key (struct GNUNET_CRYPTO_AbeKey *key,
199                                 int delete_pub)
200 {
201   // Memory management in gabe is buggy
202   gabe_prv_free (key->prv);
203   if (GNUNET_YES == delete_pub)
204     gabe_pub_free (key->pub);
205   GNUNET_free (key);
206 }
207
208
209 ssize_t
210 write_cpabe (void **result,
211              uint32_t file_len,
212              char*cph_buf,
213              int cph_buf_len,
214              char*aes_buf,
215              int aes_buf_len)
216 {
217   char *ptr;
218   uint32_t *len;
219
220   *result = GNUNET_malloc (12 + cph_buf_len + aes_buf_len);
221   ptr = *result;
222   len = (uint32_t*) ptr;
223   *len = htonl (file_len);
224   ptr += 4;
225   len = (uint32_t*) ptr;
226   *len = htonl (aes_buf_len);
227   ptr += 4;
228   GNUNET_memcpy (ptr, aes_buf, aes_buf_len);
229   ptr += aes_buf_len;
230   len = (uint32_t*) ptr;
231   *len = htonl (cph_buf_len);
232   ptr += 4;
233   GNUNET_memcpy (ptr, cph_buf, cph_buf_len);
234   return 12 + cph_buf_len + aes_buf_len;
235 }
236
237
238 ssize_t
239 read_cpabe (const void *data,
240             char**cph_buf,
241             int *cph_buf_len,
242             char**aes_buf,
243             int *aes_buf_len)
244 {
245   int buf_len;
246   char *ptr;
247   uint32_t *len;
248
249   ptr = (char*) data;
250   len = (uint32_t*) ptr;
251   buf_len = ntohl (*len);
252   ptr += 4;
253   len = (uint32_t*) ptr;
254   *aes_buf_len = ntohl (*len);
255   ptr += 4;
256   *aes_buf = GNUNET_malloc (*aes_buf_len);
257   GNUNET_memcpy (*aes_buf, ptr, *aes_buf_len);
258   ptr += *aes_buf_len;
259   len = (uint32_t*) ptr;
260   *cph_buf_len = ntohl (*len);
261   ptr += 4;
262   *cph_buf = GNUNET_malloc (*cph_buf_len);
263   GNUNET_memcpy (*cph_buf, ptr, *cph_buf_len);
264
265   return buf_len;
266 }
267
268
269 ssize_t
270 GNUNET_CRYPTO_cpabe_encrypt (const void *block,
271                              size_t size,
272                              const char *policy,
273                              const struct GNUNET_CRYPTO_AbeMasterKey *key,
274                              void **result)
275 {
276   gabe_cph_t*cph;
277   char*plt;
278   char*cph_buf;
279   char*aes_buf;
280   element_t m;
281   int cph_buf_len;
282   int aes_buf_len;
283   ssize_t result_len;
284
285   if (! (cph = gabe_enc (key->pub, m, (char*) policy)))
286     return GNUNET_SYSERR;
287   cph_buf_len = gabe_cph_serialize (cph,
288                                     &cph_buf);
289   gabe_cph_free (cph);
290   GNUNET_free (cph);
291   plt = GNUNET_memdup (block, size);
292   aes_buf_len = aes_128_cbc_encrypt (plt, size, m, &aes_buf);
293   GNUNET_free (plt);
294   element_clear (m);
295   result_len = write_cpabe (result, size, cph_buf, cph_buf_len, aes_buf,
296                             aes_buf_len);
297   GNUNET_free (cph_buf);
298   GNUNET_free (aes_buf);
299   return result_len;
300 }
301
302
303 ssize_t
304 GNUNET_CRYPTO_cpabe_decrypt (const void *block,
305                              size_t size,
306                              const struct GNUNET_CRYPTO_AbeKey *key,
307                              void **result)
308 {
309   char*aes_buf;
310   char*cph_buf;
311   gabe_cph_t*cph;
312   element_t m;
313   int cph_buf_size;
314   int aes_buf_size;
315   int plt_len;
316
317   read_cpabe (block, &cph_buf, &cph_buf_size, &aes_buf, &aes_buf_size);
318   cph = gabe_cph_unserialize (key->pub, cph_buf, cph_buf_size);
319   if (! gabe_dec (key->pub, key->prv, cph, m))
320   {
321     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
322                 "%s\n", gabe_error ());
323     GNUNET_free (aes_buf);
324     GNUNET_free (cph_buf);
325     gabe_cph_free (cph);
326     GNUNET_free (cph);
327     element_clear (m);
328     return GNUNET_SYSERR;
329   }
330   gabe_cph_free (cph);
331   GNUNET_free (cph);
332   plt_len = aes_128_cbc_decrypt (aes_buf, aes_buf_size, m, (char**) result);
333   GNUNET_free (cph_buf);
334   GNUNET_free (aes_buf);
335   element_clear (m);
336   // freeing is buggy in gabe
337   // gabe_prv_free (prv);
338   // gabe_pub_free (pub);
339   return plt_len;
340 }
341
342
343 ssize_t
344 GNUNET_CRYPTO_cpabe_serialize_key (const struct GNUNET_CRYPTO_AbeKey *key,
345                                    void **result)
346 {
347   ssize_t len;
348   char *pub;
349   char *prv;
350   int pub_len;
351   int prv_len;
352
353   pub_len = gabe_pub_serialize (key->pub, &pub);
354   prv_len = gabe_prv_serialize (key->prv, &prv);
355
356   len = pub_len + prv_len + 12;
357   write_cpabe (result, len, pub, pub_len, prv, prv_len);
358
359   GNUNET_free (pub);
360   GNUNET_free (prv);
361
362   return len;
363 }
364
365
366 struct GNUNET_CRYPTO_AbeKey*
367 GNUNET_CRYPTO_cpabe_deserialize_key (const void *data,
368                                      size_t len)
369 {
370   struct GNUNET_CRYPTO_AbeKey *key;
371   char *pub;
372   char *prv;
373   int prv_len;
374   int pub_len;
375
376   key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
377   read_cpabe (data,
378               &pub,
379               &pub_len,
380               &prv,
381               &prv_len);
382   key->pub = gabe_pub_unserialize (pub, pub_len);
383   key->prv = gabe_prv_unserialize (key->pub, prv, prv_len);
384
385   GNUNET_free (pub);
386   GNUNET_free (prv);
387   return key;
388 }
389
390
391 ssize_t
392 GNUNET_CRYPTO_cpabe_serialize_master_key (const struct
393                                           GNUNET_CRYPTO_AbeMasterKey *key,
394                                           void **result)
395 {
396   ssize_t len;
397   char *pub;
398   char *msk;
399   int pub_len;
400   int msk_len;
401
402   pub_len = gabe_pub_serialize (key->pub, &pub);
403   msk_len = gabe_msk_serialize (key->msk, &msk);
404
405   len = pub_len + msk_len + 12;
406   write_cpabe (result, len, pub, pub_len, msk, msk_len);
407
408   GNUNET_free (pub);
409   GNUNET_free (msk);
410
411   return len;
412 }
413
414
415 struct GNUNET_CRYPTO_AbeMasterKey*
416 GNUNET_CRYPTO_cpabe_deserialize_master_key (const void *data,
417                                             size_t len)
418 {
419   struct GNUNET_CRYPTO_AbeMasterKey *key;
420   char *msk;
421   char *pub;
422   int msk_len;
423   int pub_len;
424
425   key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
426   read_cpabe (data,
427               &pub,
428               &pub_len,
429               &msk,
430               &msk_len);
431   key->pub = gabe_pub_unserialize (pub, pub_len);
432   key->msk = gabe_msk_unserialize (key->pub, msk, msk_len);
433
434   GNUNET_free (pub);
435   GNUNET_free (msk);
436
437   return key;
438 }