Merge branch 'abe' into identity_abe
[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
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
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 <glib.h>
31 #include <openssl/aes.h>
32 #include <openssl/sha.h>
33 #include <pbc/pbc.h>
34 #include <bswabe.h>
35
36 #include "gnunet_crypto_lib.h"
37
38 struct GNUNET_CRYPTO_AbeMasterKey
39 {
40   GByteArray* pub;
41
42   GByteArray* msk;
43 };
44
45 struct GNUNET_CRYPTO_AbeKey
46 {
47   GByteArray* pub;
48   GByteArray* prv;
49 };
50
51 static void
52 init_aes( element_t k, int enc, AES_KEY* key, unsigned char* iv )
53 {
54   int key_len;
55   unsigned char* key_buf;
56
57   key_len = element_length_in_bytes(k) < 17 ? 17 : element_length_in_bytes(k);
58   key_buf = (unsigned char*) malloc(key_len);
59   element_to_bytes(key_buf, k);
60
61   if( enc )
62     AES_set_encrypt_key(key_buf + 1, 128, key);
63   else
64     AES_set_decrypt_key(key_buf + 1, 128, key);
65   free(key_buf);
66
67   memset(iv, 0, 16);
68 }
69
70 static GByteArray*
71 aes_128_cbc_encrypt( GByteArray* pt, element_t k )
72 {
73   AES_KEY key;
74   unsigned char iv[16];
75   GByteArray* ct;
76   guint8 len[4];
77   guint8 zero;
78
79   init_aes(k, 1, &key, iv);
80
81   /* TODO make less crufty */
82
83   /* stuff in real length (big endian) before padding */
84   len[0] = (pt->len & 0xff000000)>>24;
85   len[1] = (pt->len & 0xff0000)>>16;
86   len[2] = (pt->len & 0xff00)>>8;
87   len[3] = (pt->len & 0xff)>>0;
88   g_byte_array_prepend(pt, len, 4);
89
90   /* pad out to multiple of 128 bit (16 byte) blocks */
91   zero = 0;
92   while( pt->len % 16 )
93     g_byte_array_append(pt, &zero, 1);
94
95   ct = g_byte_array_new();
96   g_byte_array_set_size(ct, pt->len);
97
98   AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT);
99
100   return ct;
101 }
102
103 static GByteArray*
104 aes_128_cbc_decrypt( GByteArray* ct, element_t k )
105 {
106   AES_KEY key;
107   unsigned char iv[16];
108   GByteArray* pt;
109   unsigned int len;
110
111   init_aes(k, 0, &key, iv);
112
113   pt = g_byte_array_new();
114   g_byte_array_set_size(pt, ct->len);
115
116   AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT);
117
118   /* TODO make less crufty */
119   
120   /* get real length */
121   len = 0;
122   len = len
123     | ((pt->data[0])<<24) | ((pt->data[1])<<16)
124     | ((pt->data[2])<<8)  | ((pt->data[3])<<0);
125   g_byte_array_remove_index(pt, 0);
126   g_byte_array_remove_index(pt, 0);
127   g_byte_array_remove_index(pt, 0);
128   g_byte_array_remove_index(pt, 0);
129
130   /* truncate any garbage from the padding */
131   g_byte_array_set_size(pt, len);
132
133   return pt;
134 }
135
136 struct GNUNET_CRYPTO_AbeMasterKey*
137 GNUNET_CRYPTO_cpabe_create_master_key (void)
138 {
139   struct GNUNET_CRYPTO_AbeMasterKey* key;
140   bswabe_msk_t* msk;
141   bswabe_pub_t* pub;
142   bswabe_setup(&pub, &msk);
143   key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
144   key->pub = bswabe_pub_serialize(pub);
145   key->msk = bswabe_msk_serialize(msk);
146   GNUNET_assert (NULL != key->pub);
147   GNUNET_assert (NULL != key->msk);
148   bswabe_pub_free (pub);
149   bswabe_msk_free (msk);
150   return key;
151 }
152
153 void
154 GNUNET_CRYPTO_cpabe_delete_master_key (struct GNUNET_CRYPTO_AbeMasterKey *key)
155 {
156   g_byte_array_unref (key->msk);
157   g_byte_array_unref (key->pub);
158   GNUNET_free (key);
159 }
160
161 struct GNUNET_CRYPTO_AbeKey*
162 GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key,
163                              char **attrs)
164 {
165   struct GNUNET_CRYPTO_AbeKey *prv_key;
166   bswabe_pub_t* pub;
167   bswabe_msk_t* msk;
168   bswabe_prv_t* prv;
169   gsize len;
170
171   pub = bswabe_pub_unserialize(key->pub, 0);
172   msk = bswabe_msk_unserialize(pub, key->msk, 0);
173   prv = bswabe_keygen(pub, msk, attrs);
174   prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
175   prv_key->prv = bswabe_prv_serialize(prv);
176   len = key->pub->len;
177   printf ("Keylen %lu\n", len);
178   prv_key->pub = bswabe_pub_serialize (pub);
179   GNUNET_assert (NULL != prv_key->prv);
180   bswabe_prv_free (prv);
181   bswabe_pub_free (pub);
182   bswabe_msk_free (msk);
183   return prv_key;
184 }
185
186 void
187 GNUNET_CRYPTO_cpabe_delete_key (struct GNUNET_CRYPTO_AbeKey *key)
188 {
189   g_byte_array_unref (key->prv);
190   g_byte_array_unref (key->pub);
191   GNUNET_free (key);
192 }
193
194 ssize_t
195 write_cpabe (void **result, GByteArray* cph_buf,
196              uint32_t file_len, GByteArray* aes_buf)
197 {
198   char *ptr;
199   uint32_t *len;
200   
201   *result = GNUNET_malloc (12 + cph_buf->len + aes_buf->len);
202   ptr = *result;
203   len = (uint32_t*) ptr;
204   *len = htonl (file_len);
205   ptr += 4;
206   len = (uint32_t*) ptr;
207   *len = htonl (aes_buf->len);
208   ptr += 4;
209   memcpy (ptr, aes_buf->data, aes_buf->len);
210   ptr += aes_buf->len;
211   len = (uint32_t*) ptr;
212   *len = htonl (cph_buf->len);
213   ptr += 4;
214   memcpy (ptr, cph_buf->data, cph_buf->len);
215   return 12 + cph_buf->len + aes_buf->len;
216 }
217
218 ssize_t
219 read_cpabe (const void *data, GByteArray** cph_buf, GByteArray** aes_buf)
220 {
221   int buf_len;
222   int tmp_len;
223   char *ptr;
224   uint32_t *len;
225
226   *cph_buf = g_byte_array_new();
227   *aes_buf = g_byte_array_new();
228   ptr = (char*)data;
229   len = (uint32_t*)ptr;
230   buf_len = ntohl (*len);
231   ptr += 4;
232   len = (uint32_t*)ptr;
233   tmp_len = ntohl (*len);
234   ptr += 4;
235   g_byte_array_set_size(*aes_buf, tmp_len);
236   memcpy((*aes_buf)->data, ptr, tmp_len);
237   ptr += tmp_len;
238   len = (uint32_t*)ptr;
239   tmp_len = ntohl (*len);
240   ptr += 4;
241   g_byte_array_set_size(*cph_buf, tmp_len);
242   memcpy((*cph_buf)->data, ptr, tmp_len);
243
244   return buf_len;
245 }
246
247 ssize_t
248 GNUNET_CRYPTO_cpabe_encrypt (const void *block,
249                              size_t size,
250                              char *policy,
251                              const struct GNUNET_CRYPTO_AbeMasterKey *key,
252                              void **result)
253 {
254   bswabe_pub_t* pub;
255   bswabe_cph_t* cph;
256   GByteArray* plt;
257   GByteArray* cph_buf;
258   GByteArray* aes_buf;
259   guint8 *data;
260   element_t m;
261   size_t payload_len;
262   ssize_t result_len;
263
264   pub = bswabe_pub_unserialize(key->pub, 0);
265   if( !(cph = bswabe_enc(pub, m, policy)) )
266     return GNUNET_SYSERR;
267   cph_buf = bswabe_cph_serialize(cph);
268   bswabe_cph_free(cph);
269   data = g_memdup (block, size);
270   plt = g_byte_array_new_take (data, size);
271   payload_len = plt->len;
272   aes_buf = aes_128_cbc_encrypt(plt, m);
273   g_byte_array_free(plt, 1);
274   element_clear(m);
275   result_len = write_cpabe(result, cph_buf, payload_len, aes_buf);
276   g_byte_array_free(cph_buf, 1);
277   g_byte_array_free(aes_buf, 1);
278   bswabe_pub_free (pub);
279   return result_len;
280 }
281
282 ssize_t
283 GNUNET_CRYPTO_cpabe_decrypt (const void *block,
284                        size_t size,
285                        const struct GNUNET_CRYPTO_AbeKey *key,
286                        void **result)
287 {
288   bswabe_pub_t* pub;
289   bswabe_prv_t* prv;
290   GByteArray* aes_buf;
291   GByteArray* plt;
292   GByteArray* cph_buf;
293   bswabe_cph_t* cph;
294   element_t m;
295   ssize_t pt_size;
296
297   pub = bswabe_pub_unserialize(key->pub, 0);
298   prv = bswabe_prv_unserialize(pub, key->prv, 0);
299   pt_size = read_cpabe(block, &cph_buf, &aes_buf);
300   cph = bswabe_cph_unserialize(pub, cph_buf, 0);
301   if( !bswabe_dec(pub, prv, cph, m) ) {
302     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
303                 "%s\n", bswabe_error());
304     return GNUNET_SYSERR;
305   }
306   bswabe_cph_free(cph);
307   plt = aes_128_cbc_decrypt(aes_buf, m);
308   g_byte_array_set_size(plt, size);
309   g_byte_array_free(aes_buf, 1);
310   *result = GNUNET_malloc (plt->len);
311   GNUNET_memcpy (*result, plt->data, plt->len);
312   bswabe_prv_free (prv);
313   bswabe_pub_free (pub);
314   return pt_size;
315 }
316
317 ssize_t
318 GNUNET_CRYPTO_cpabe_serialize_key (const struct GNUNET_CRYPTO_AbeKey *key,
319                                    void **result)
320 {
321   ssize_t len;
322
323   len = key->pub->len + key->prv->len + 12;
324   write_cpabe (result, key->pub, len, key->prv);
325
326   return len;
327 }
328
329 struct GNUNET_CRYPTO_AbeKey*
330 GNUNET_CRYPTO_cpabe_deserialize_key (const void *data,
331                                      size_t len)
332 {
333   struct GNUNET_CRYPTO_AbeKey *key;
334
335   key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
336   read_cpabe (data, &key->pub, &key->prv);
337
338   return key;
339 }
340
341 ssize_t
342 GNUNET_CRYPTO_cpabe_serialize_master_key (const struct GNUNET_CRYPTO_AbeMasterKey *key,
343                                           void **result)
344 {
345   ssize_t len;
346
347   len = key->pub->len + key->msk->len + 12;
348   write_cpabe (result, key->pub, len, key->msk);
349
350   return len;
351 }
352
353 struct GNUNET_CRYPTO_AbeMasterKey*
354 GNUNET_CRYPTO_cpabe_deserialize_master_key (const void *data,
355                                             size_t len)
356 {
357   struct GNUNET_CRYPTO_AbeMasterKey *key;
358
359   key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
360   read_cpabe (data, &key->pub, &key->msk);
361
362   return key;
363 }