798a74f871a435a6e9763ab10267fcfed6811192
[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
170   pub = bswabe_pub_unserialize(key->pub, 0);
171   msk = bswabe_msk_unserialize(pub, key->msk, 0);
172   prv = bswabe_keygen(pub, msk, attrs);
173   prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
174   prv_key->prv = bswabe_prv_serialize(prv);
175   prv_key->pub = bswabe_pub_serialize (pub);
176   GNUNET_assert (NULL != prv_key->prv);
177   bswabe_msk_free (msk);
178   return prv_key;
179 }
180
181 void
182 GNUNET_CRYPTO_cpabe_delete_key (struct GNUNET_CRYPTO_AbeKey *key)
183 {
184   g_byte_array_unref (key->prv);
185   g_byte_array_unref (key->pub);
186   GNUNET_free (key);
187 }
188
189 ssize_t
190 write_cpabe (void **result, GByteArray* cph_buf,
191              uint32_t file_len, GByteArray* aes_buf)
192 {
193   char *ptr;
194   uint32_t *len;
195   
196   *result = GNUNET_malloc (12 + cph_buf->len + aes_buf->len);
197   ptr = *result;
198   len = (uint32_t*) ptr;
199   *len = htonl (file_len);
200   ptr += 4;
201   len = (uint32_t*) ptr;
202   *len = htonl (aes_buf->len);
203   ptr += 4;
204   memcpy (ptr, aes_buf->data, aes_buf->len);
205   ptr += aes_buf->len;
206   len = (uint32_t*) ptr;
207   *len = htonl (cph_buf->len);
208   ptr += 4;
209   memcpy (ptr, cph_buf->data, cph_buf->len);
210   return 12 + cph_buf->len + aes_buf->len;
211 }
212
213 ssize_t
214 read_cpabe (const void *data, GByteArray** cph_buf, GByteArray** aes_buf)
215 {
216   int buf_len;
217   int tmp_len;
218   char *ptr;
219   uint32_t *len;
220
221   *cph_buf = g_byte_array_new();
222   *aes_buf = g_byte_array_new();
223   ptr = (char*)data;
224   len = (uint32_t*)ptr;
225   buf_len = ntohl (*len);
226   ptr += 4;
227   len = (uint32_t*)ptr;
228   tmp_len = ntohl (*len);
229   ptr += 4;
230   g_byte_array_set_size(*aes_buf, tmp_len);
231   memcpy((*aes_buf)->data, ptr, tmp_len);
232   ptr += tmp_len;
233   len = (uint32_t*)ptr;
234   tmp_len = ntohl (*len);
235   ptr += 4;
236   g_byte_array_set_size(*cph_buf, tmp_len);
237   memcpy((*cph_buf)->data, ptr, tmp_len);
238
239   return buf_len;
240 }
241
242 ssize_t
243 GNUNET_CRYPTO_cpabe_encrypt (const void *block,
244                              size_t size,
245                              char *policy,
246                              const struct GNUNET_CRYPTO_AbeMasterKey *key,
247                              void **result)
248 {
249   bswabe_pub_t* pub;
250   bswabe_cph_t* cph;
251   GByteArray* plt;
252   GByteArray* cph_buf;
253   GByteArray* aes_buf;
254   guint8 *data;
255   element_t m;
256   size_t payload_len;
257   ssize_t result_len;
258
259   pub = bswabe_pub_unserialize(key->pub, 0);
260   if( !(cph = bswabe_enc(pub, m, policy)) )
261     return GNUNET_SYSERR;
262   cph_buf = bswabe_cph_serialize(cph);
263   bswabe_cph_free(cph);
264   data = g_memdup (block, size);
265   plt = g_byte_array_new_take (data, size);
266   payload_len = plt->len;
267   aes_buf = aes_128_cbc_encrypt(plt, m);
268   g_byte_array_free(plt, 1);
269   element_clear(m);
270   result_len = write_cpabe(result, cph_buf, payload_len, aes_buf);
271   g_byte_array_free(cph_buf, 1);
272   g_byte_array_free(aes_buf, 1);
273   bswabe_pub_free (pub);
274   return result_len;
275 }
276
277 ssize_t
278 GNUNET_CRYPTO_cpabe_decrypt (const void *block,
279                        size_t size,
280                        const struct GNUNET_CRYPTO_AbeKey *key,
281                        void **result)
282 {
283   bswabe_pub_t* pub;
284   bswabe_prv_t* prv;
285   GByteArray* aes_buf;
286   GByteArray* plt;
287   GByteArray* cph_buf;
288   bswabe_cph_t* cph;
289   element_t m;
290   ssize_t pt_size;
291
292   pub = bswabe_pub_unserialize(key->pub, 0);
293   prv = bswabe_prv_unserialize(pub, key->prv, 0);
294   pt_size = read_cpabe(block, &cph_buf, &aes_buf);
295   cph = bswabe_cph_unserialize(pub, cph_buf, 0);
296   if( !bswabe_dec(pub, prv, cph, m) ) {
297     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
298                 "%s\n", bswabe_error());
299     return GNUNET_SYSERR;
300   }
301   bswabe_cph_free(cph);
302   plt = aes_128_cbc_decrypt(aes_buf, m);
303   g_byte_array_set_size(plt, size);
304   g_byte_array_free(aes_buf, 1);
305   *result = GNUNET_malloc (plt->len);
306   GNUNET_memcpy (*result, plt->data, plt->len);
307   bswabe_prv_free (prv);
308   bswabe_pub_free (pub);
309   return pt_size;
310 }
311
312 ssize_t
313 GNUNET_CRYPTO_cpabe_serialize_key (const struct GNUNET_CRYPTO_AbeKey *key,
314                                    void **result)
315 {
316   ssize_t len;
317
318   len = key->pub->len + key->prv->len + 12;
319   write_cpabe (result, key->pub, len, key->prv);
320
321   return len;
322 }
323
324 struct GNUNET_CRYPTO_AbeKey*
325 GNUNET_CRYPTO_cpabe_deserialize_key (const void *data,
326                                      size_t len)
327 {
328   struct GNUNET_CRYPTO_AbeKey *key;
329
330   key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
331   read_cpabe (data, &key->pub, &key->prv);
332
333   return key;
334 }
335
336 ssize_t
337 GNUNET_CRYPTO_cpabe_serialize_master_key (const struct GNUNET_CRYPTO_AbeMasterKey *key,
338                                           void **result)
339 {
340   ssize_t len;
341
342   len = key->pub->len + key->msk->len + 12;
343   write_cpabe (result, key->pub, len, key->msk);
344
345   return len;
346 }
347
348 struct GNUNET_CRYPTO_AbeMasterKey*
349 GNUNET_CRYPTO_cpabe_deserialize_master_key (const void *data,
350                                             size_t len)
351 {
352   struct GNUNET_CRYPTO_AbeMasterKey *key;
353
354   key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
355   read_cpabe (data, &key->pub, &key->msk);
356
357   return key;
358 }