summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/Makefile.am24
-rw-r--r--src/util/crypto_abe.c400
-rw-r--r--src/util/test_crypto_abe.c86
3 files changed, 509 insertions, 1 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index c26e3e84b..cc9ff4745 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -119,11 +119,22 @@ libgnunetutil_la_LIBADD = \
119 $(LTLIBINTL) \ 119 $(LTLIBINTL) \
120 -lltdl $(Z_LIBS) -lunistring $(XLIB) 120 -lltdl $(Z_LIBS) -lunistring $(XLIB)
121 121
122if HAVE_PBC
123if HAVE_ABE
124libgnunetutil_la_SOURCES += \
125 crypto_abe.c
126libgnunetutil_la_LIBADD += \
127 $(ABE_LIBADD) \
128 -lgabe \
129 -lpbc \
130 -lglib-2.0
131endif
132endif
133
122libgnunetutil_la_LDFLAGS = \ 134libgnunetutil_la_LDFLAGS = \
123 $(GN_LIB_LDFLAGS) \ 135 $(GN_LIB_LDFLAGS) \
124 -version-info 13:0:0 136 -version-info 13:0:0
125 137
126
127libgnunetutil_taler_wallet_la_SOURCES = \ 138libgnunetutil_taler_wallet_la_SOURCES = \
128 common_allocation.c \ 139 common_allocation.c \
129 common_endian.c \ 140 common_endian.c \
@@ -553,6 +564,17 @@ test_speedup_SOURCES = \
553test_speedup_LDADD = \ 564test_speedup_LDADD = \
554 libgnunetutil.la 565 libgnunetutil.la
555 566
567if HAVE_PBC
568if HAVE_ABE
569test_crypto_abe_SOURCES = \
570 test_crypto_abe.c
571test_crypto_abe_LDADD = \
572 libgnunetutil.la
573check_PROGRAMS += \
574 test_crypto_abe
575endif
576endif
577
556perf_crypto_hash_SOURCES = \ 578perf_crypto_hash_SOURCES = \
557 perf_crypto_hash.c 579 perf_crypto_hash.c
558perf_crypto_hash_LDADD = \ 580perf_crypto_hash_LDADD = \
diff --git a/src/util/crypto_abe.c b/src/util/crypto_abe.c
new file mode 100644
index 000000000..899965159
--- /dev/null
+++ b/src/util/crypto_abe.c
@@ -0,0 +1,400 @@
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 <pbc/pbc.h>
31#include <gabe.h>
32
33#include "gnunet_crypto_lib.h"
34
35struct GNUNET_CRYPTO_AbeMasterKey
36{
37 gabe_pub_t* pub;
38 gabe_msk_t* msk;
39};
40
41struct GNUNET_CRYPTO_AbeKey
42{
43 gabe_pub_t* pub;
44 gabe_prv_t* prv;
45};
46
47static int
48init_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 memcpy (key->aes_key, key_buf, GNUNET_CRYPTO_AES_KEY_LENGTH);
62 GNUNET_assert (0 ==
63 gcry_cipher_open (handle, GCRY_CIPHER_AES256,
64 GCRY_CIPHER_MODE_CFB, 0));
65 rc = gcry_cipher_setkey (*handle,
66 key->aes_key,
67 sizeof (key->aes_key));
68 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
69 memset (iv, 0, 16); //TODO make reasonable
70 rc = gcry_cipher_setiv (*handle,
71 iv,
72 16);
73 GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
74
75 free(key_buf);
76 return rc;
77}
78
79static int
80aes_128_cbc_encrypt( char* pt,
81 int size,
82 element_t k,
83 char **ct )
84{
85 gcry_cipher_hd_t handle;
86 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
87 unsigned char iv[16];
88 char* buf;
89 int padding;
90 int buf_size;
91 uint8_t len[4];
92 init_aes(k, 1, &handle, &skey, iv);
93
94 /* TODO make less crufty */
95
96 /* stuff in real length (big endian) before padding */
97 len[0] = (size & 0xff000000)>>24;
98 len[1] = (size & 0xff0000)>>16;
99 len[2] = (size & 0xff00)>>8;
100 len[3] = (size & 0xff)>>0;
101 padding = 16 - ((4+size) % 16);
102 buf_size = 4 + size + padding;
103 buf = GNUNET_malloc (buf_size);
104 GNUNET_memcpy (buf, len, 4);
105 GNUNET_memcpy (buf+4, pt, size);
106 *ct = GNUNET_malloc (buf_size);
107
108 GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf, buf_size));
109 gcry_cipher_close (handle);
110 //AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT);
111
112 return buf_size;
113}
114
115static int
116aes_128_cbc_decrypt( char* ct,
117 int size,
118 element_t k,
119 char **pt )
120{
121 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
122 gcry_cipher_hd_t handle;
123 unsigned char iv[16];
124 char* tmp;
125 uint32_t len;
126
127 init_aes(k, 1, &handle, &skey, iv);
128
129 tmp = GNUNET_malloc (size);
130
131 //AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT);
132 GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, ct, size));
133 gcry_cipher_close (handle);
134 /* TODO make less crufty */
135
136 /* get real length */
137 len = 0;
138 len = len
139 | ((tmp[0])<<24) | ((tmp[1])<<16)
140 | ((tmp[2])<<8) | ((tmp[3])<<0);
141 /* truncate any garbage from the padding */
142 *pt = GNUNET_malloc (len);
143 GNUNET_memcpy (*pt, tmp+4, len);
144 GNUNET_free (tmp);
145 return len;
146}
147
148struct GNUNET_CRYPTO_AbeMasterKey*
149GNUNET_CRYPTO_cpabe_create_master_key (void)
150{
151 struct GNUNET_CRYPTO_AbeMasterKey* key;
152 key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
153 gabe_setup(&key->pub, &key->msk);
154 GNUNET_assert (NULL != key->pub);
155 GNUNET_assert (NULL != key->msk);
156 return key;
157}
158
159void
160GNUNET_CRYPTO_cpabe_delete_master_key (struct GNUNET_CRYPTO_AbeMasterKey *key)
161{
162 gabe_msk_free (key->msk); //For some reason free of pub implicit?
163 GNUNET_free (key);
164}
165
166struct GNUNET_CRYPTO_AbeKey*
167GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key,
168 char **attrs)
169{
170 struct GNUNET_CRYPTO_AbeKey *prv_key;
171 int size;
172 char *tmp;
173
174 prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
175 prv_key->prv = gabe_keygen(key->pub, key->msk, attrs);
176 size = gabe_pub_serialize(key->pub, &tmp);
177 prv_key->pub = gabe_pub_unserialize(tmp, size);
178 GNUNET_assert (NULL != prv_key->prv);
179 return prv_key;
180}
181
182void
183GNUNET_CRYPTO_cpabe_delete_key (struct GNUNET_CRYPTO_AbeKey *key)
184{
185 //Memory management in gabe is buggy
186 //gabe_prv_free (prv);
187 GNUNET_free (key);
188}
189
190ssize_t
191write_cpabe (void **result,
192 uint32_t file_len,
193 char* cph_buf,
194 int cph_buf_len,
195 char* aes_buf,
196 int aes_buf_len)
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, 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, cph_buf_len);
215 return 12 + cph_buf_len + aes_buf_len;
216}
217
218ssize_t
219read_cpabe (const void *data,
220 char** cph_buf,
221 int *cph_buf_len,
222 char** aes_buf,
223 int *aes_buf_len)
224{
225 int buf_len;
226 char *ptr;
227 uint32_t *len;
228
229 ptr = (char*)data;
230 len = (uint32_t*)ptr;
231 buf_len = ntohl (*len);
232 ptr += 4;
233 len = (uint32_t*)ptr;
234 *aes_buf_len = ntohl (*len);
235 ptr += 4;
236 *aes_buf = GNUNET_malloc (*aes_buf_len);
237 memcpy(*aes_buf, ptr, *aes_buf_len);
238 ptr += *aes_buf_len;
239 len = (uint32_t*)ptr;
240 *cph_buf_len = ntohl (*len);
241 ptr += 4;
242 *cph_buf = GNUNET_malloc (*cph_buf_len);
243 memcpy(*cph_buf, ptr, *cph_buf_len);
244
245 return buf_len;
246}
247
248ssize_t
249GNUNET_CRYPTO_cpabe_encrypt (const void *block,
250 size_t size,
251 const char *policy,
252 const struct GNUNET_CRYPTO_AbeMasterKey *key,
253 void **result)
254{
255 gabe_cph_t* cph;
256 char* plt;
257 char* cph_buf;
258 char* aes_buf;
259 element_t m;
260 int cph_buf_len;
261 int aes_buf_len;
262 ssize_t result_len;
263
264 if( !(cph = gabe_enc(key->pub, m, (char*)policy)) )
265 return GNUNET_SYSERR;
266 cph_buf_len = gabe_cph_serialize(cph,
267 &cph_buf);
268 gabe_cph_free(cph);
269 plt = GNUNET_memdup (block, size);
270 aes_buf_len = aes_128_cbc_encrypt(plt, size, m, &aes_buf);
271 GNUNET_free (plt);
272 element_clear(m);
273 result_len = write_cpabe(result, size, cph_buf, cph_buf_len, aes_buf, aes_buf_len);
274 GNUNET_free(cph_buf);
275 GNUNET_free(aes_buf);
276 return result_len;
277}
278
279ssize_t
280GNUNET_CRYPTO_cpabe_decrypt (const void *block,
281 size_t size,
282 const struct GNUNET_CRYPTO_AbeKey *key,
283 void **result)
284{
285 char* aes_buf;
286 char* cph_buf;
287 gabe_cph_t* cph;
288 element_t m;
289 int cph_buf_size;
290 int aes_buf_size;
291 int plt_len;
292
293 read_cpabe(block, &cph_buf, &cph_buf_size, &aes_buf, &aes_buf_size);
294 cph = gabe_cph_unserialize(key->pub, cph_buf, cph_buf_size);
295 if( !gabe_dec(key->pub, key->prv, cph, m) ) {
296 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
297 "%s\n", gabe_error());
298 gabe_cph_free(cph);
299 return GNUNET_SYSERR;
300 }
301 gabe_cph_free(cph);
302 plt_len = aes_128_cbc_decrypt(aes_buf, aes_buf_size, m, (char**)result);
303 //freeing is buggy in gabe
304 //gabe_prv_free (prv);
305 //gabe_pub_free (pub);
306 return plt_len;
307}
308
309ssize_t
310GNUNET_CRYPTO_cpabe_serialize_key (const struct GNUNET_CRYPTO_AbeKey *key,
311 void **result)
312{
313 ssize_t len;
314 char *pub;
315 char *prv;
316 int pub_len;
317 int prv_len;
318
319 pub_len = gabe_pub_serialize (key->pub, &pub);
320 prv_len = gabe_prv_serialize (key->prv, &prv);
321
322 len = pub_len + prv_len + 12;
323 write_cpabe (result, len, pub, pub_len, prv, prv_len);
324
325 GNUNET_free (pub);
326 GNUNET_free (prv);
327
328 return len;
329}
330
331struct GNUNET_CRYPTO_AbeKey*
332GNUNET_CRYPTO_cpabe_deserialize_key (const void *data,
333 size_t len)
334{
335 struct GNUNET_CRYPTO_AbeKey *key;
336 char *pub;
337 char *prv;
338 int prv_len;
339 int pub_len;
340
341 key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
342 read_cpabe (data,
343 &pub,
344 &pub_len,
345 &prv,
346 &prv_len);
347 key->pub = gabe_pub_unserialize (pub, pub_len);
348 key->prv = gabe_prv_unserialize (key->pub, prv, prv_len);
349
350 GNUNET_free (pub);
351 GNUNET_free (prv);
352 return key;
353}
354
355ssize_t
356GNUNET_CRYPTO_cpabe_serialize_master_key (const struct GNUNET_CRYPTO_AbeMasterKey *key,
357 void **result)
358{
359 ssize_t len;
360 char *pub;
361 char *msk;
362 int pub_len;
363 int msk_len;
364
365 pub_len = gabe_pub_serialize (key->pub, &pub);
366 msk_len = gabe_msk_serialize (key->msk, &msk);
367
368 len = pub_len + msk_len + 12;
369 write_cpabe (result, len, pub, pub_len, msk, msk_len);
370
371 GNUNET_free (pub);
372 GNUNET_free (msk);
373
374 return len;
375}
376
377struct GNUNET_CRYPTO_AbeMasterKey*
378GNUNET_CRYPTO_cpabe_deserialize_master_key (const void *data,
379 size_t len)
380{
381 struct GNUNET_CRYPTO_AbeMasterKey *key;
382 char *msk;
383 char *pub;
384 int msk_len;
385 int pub_len;
386
387 key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
388 read_cpabe (data,
389 &pub,
390 &pub_len,
391 &msk,
392 &msk_len);
393 key->pub = gabe_pub_unserialize (pub, pub_len);
394 key->msk = gabe_msk_unserialize (key->pub, msk, msk_len);
395
396 GNUNET_free (pub);
397 GNUNET_free (msk);
398
399 return key;
400}
diff --git a/src/util/test_crypto_abe.c b/src/util/test_crypto_abe.c
new file mode 100644
index 000000000..cb36dccae
--- /dev/null
+++ b/src/util/test_crypto_abe.c
@@ -0,0 +1,86 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2002, 2003, 2004, 2006 GNUnet e.V.
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 * @author Martin Schanzenbach
23 * @file util/test_crypto_abe.c
24 * @brief test for ABE ciphers
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28
29#define TESTSTRING "Hello World!"
30
31static int
32testAbecipher ()
33{
34 struct GNUNET_CRYPTO_AbeMasterKey *msk;
35 struct GNUNET_CRYPTO_AbeKey *key;
36 char *result;
37 char **attrs;
38 int size;
39 char *res;
40 msk = GNUNET_CRYPTO_cpabe_create_master_key ();
41 size = GNUNET_CRYPTO_cpabe_encrypt (TESTSTRING, strlen (TESTSTRING) + 1,
42 "testattr", //Policy
43 msk,
44 (void*)&result);
45 GNUNET_assert (-1 != size);
46 attrs = GNUNET_malloc (2 * sizeof (char*));
47 attrs[0] = "testattr";
48 attrs[1] = NULL;
49 key = GNUNET_CRYPTO_cpabe_create_key (msk,
50 attrs);
51
52 size = GNUNET_CRYPTO_cpabe_decrypt (result, size,
53 key,
54 (void*)&res);
55 if (strlen (TESTSTRING) + 1 != size)
56 {
57 printf ("abeciphertest failed: decryptBlock returned %d\n", size);
58 return 1;
59 }
60 if (0 != strcmp (res, TESTSTRING))
61 {
62 printf ("abeciphertest failed: %s != %s\n", res, TESTSTRING);
63 return 1;
64 }
65 else
66 return 0;
67}
68
69
70int
71main (int argc, char *argv[])
72{
73 int failureCount = 0;
74
75 GNUNET_log_setup ("test-crypto-abe", "WARNING", NULL);
76 failureCount += testAbecipher ();
77
78 if (failureCount != 0)
79 {
80 printf ("%d TESTS FAILED!\n", failureCount);
81 return -1;
82 }
83 return 0;
84}
85
86/* end of test_crypto_aes.c */