diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-07-08 18:30:01 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-07-08 18:30:01 +0200 |
commit | 9d601af559af4e7ad7ed818da499fa22ebfa5ae6 (patch) | |
tree | fd13071285ad1d50dd26821a312ab3fc226ee4f7 /src/util/crypto_abe.c | |
parent | 4e2fafb606f98f71aa404b9d0a55bc3b39f90418 (diff) | |
download | gnunet-9d601af559af4e7ad7ed818da499fa22ebfa5ae6.tar.gz gnunet-9d601af559af4e7ad7ed818da499fa22ebfa5ae6.zip |
-add ABE crypto module
Diffstat (limited to 'src/util/crypto_abe.c')
-rw-r--r-- | src/util/crypto_abe.c | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/src/util/crypto_abe.c b/src/util/crypto_abe.c new file mode 100644 index 000000000..d004220d1 --- /dev/null +++ b/src/util/crypto_abe.c | |||
@@ -0,0 +1,305 @@ | |||
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 | return key; | ||
149 | } | ||
150 | |||
151 | struct GNUNET_CRYPTO_AbeKey* | ||
152 | GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key, | ||
153 | char **attrs) | ||
154 | { | ||
155 | struct GNUNET_CRYPTO_AbeKey *prv_key; | ||
156 | bswabe_pub_t* pub; | ||
157 | bswabe_msk_t* msk; | ||
158 | bswabe_prv_t* prv; | ||
159 | gchar* pub_data; | ||
160 | gsize len; | ||
161 | |||
162 | pub = bswabe_pub_unserialize(key->pub, 0); | ||
163 | msk = bswabe_msk_unserialize(pub, key->msk, 0); | ||
164 | prv = bswabe_keygen(pub, msk, attrs); | ||
165 | prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey); | ||
166 | prv_key->prv = bswabe_prv_serialize(prv); | ||
167 | pub_data = g_strndup ((gchar*)key->pub->data, | ||
168 | key->pub->len); | ||
169 | len = key->pub->len; | ||
170 | prv_key->pub = g_byte_array_new_take ((guint8*)pub_data, len); | ||
171 | GNUNET_assert (NULL != prv_key->prv); | ||
172 | return prv_key; | ||
173 | } | ||
174 | |||
175 | ssize_t | ||
176 | write_cpabe (void **result, GByteArray* cph_buf, | ||
177 | int file_len, GByteArray* aes_buf) | ||
178 | { | ||
179 | char *ptr; | ||
180 | int i; | ||
181 | ssize_t size; | ||
182 | size = aes_buf->len + cph_buf->len + 12; | ||
183 | *result = GNUNET_malloc (size); | ||
184 | ptr = *result; | ||
185 | for(i=3; i >= 0; i--) { | ||
186 | *ptr = (file_len & 0xff<<(i*8))>>(i*8); | ||
187 | ptr++; | ||
188 | } | ||
189 | for(i=3; i >= 0; i--) { | ||
190 | *ptr = (aes_buf->len & 0xff<<(i*8))>>(i*8); | ||
191 | ptr++; | ||
192 | } | ||
193 | memcpy (ptr, aes_buf->data, aes_buf->len); | ||
194 | ptr += aes_buf->len; | ||
195 | for(i=3; i >= 0; i--) { | ||
196 | *ptr = (cph_buf->len & 0xff<<(i*8))>>(i*8); | ||
197 | ptr++; | ||
198 | } | ||
199 | memcpy (ptr, cph_buf->data, cph_buf->len); | ||
200 | return size; | ||
201 | } | ||
202 | |||
203 | ssize_t | ||
204 | read_cpabe (const void *data, GByteArray** cph_buf, GByteArray** aes_buf) | ||
205 | { | ||
206 | int i; | ||
207 | ssize_t buf_len; | ||
208 | ssize_t tmp_len; | ||
209 | char *ptr; | ||
210 | |||
211 | *cph_buf = g_byte_array_new(); | ||
212 | *aes_buf = g_byte_array_new(); | ||
213 | ptr = (char*)data; | ||
214 | |||
215 | buf_len = 0; | ||
216 | for(i=3; i >= 0; i--) { | ||
217 | buf_len |= *ptr<<(i*8); | ||
218 | ptr++; | ||
219 | } | ||
220 | |||
221 | tmp_len = 0; | ||
222 | for(i=3; i >= 0; i--) { | ||
223 | tmp_len |= *ptr<<(i*8); | ||
224 | ptr++; | ||
225 | } | ||
226 | g_byte_array_set_size(*aes_buf, tmp_len); | ||
227 | memcpy((*aes_buf)->data, ptr, tmp_len); | ||
228 | ptr += tmp_len; | ||
229 | tmp_len = 0; | ||
230 | for(i=3; i >= 0; i--) { | ||
231 | tmp_len |= *ptr<<(i*8); | ||
232 | ptr++; | ||
233 | } | ||
234 | g_byte_array_set_size(*cph_buf, tmp_len); | ||
235 | memcpy((*cph_buf)->data, ptr, tmp_len); | ||
236 | |||
237 | return buf_len; | ||
238 | } | ||
239 | |||
240 | ssize_t | ||
241 | GNUNET_CRYPTO_cpabe_encrypt (const void *block, | ||
242 | size_t size, | ||
243 | char *policy, | ||
244 | const struct GNUNET_CRYPTO_AbeMasterKey *key, | ||
245 | void **result) | ||
246 | { | ||
247 | bswabe_pub_t* pub; | ||
248 | bswabe_cph_t* cph; | ||
249 | GByteArray* plt; | ||
250 | GByteArray* cph_buf; | ||
251 | GByteArray* aes_buf; | ||
252 | guint8 *data; | ||
253 | element_t m; | ||
254 | size_t payload_len; | ||
255 | ssize_t result_len; | ||
256 | pub = bswabe_pub_unserialize(key->pub, 0); | ||
257 | if( !(cph = bswabe_enc(pub, m, policy)) ) | ||
258 | return GNUNET_SYSERR; | ||
259 | cph_buf = bswabe_cph_serialize(cph); | ||
260 | bswabe_cph_free(cph); | ||
261 | data = g_memdup (block, size); | ||
262 | plt = g_byte_array_new_take (data, size); | ||
263 | payload_len = plt->len; | ||
264 | aes_buf = aes_128_cbc_encrypt(plt, m); | ||
265 | g_byte_array_free(plt, 1); | ||
266 | element_clear(m); | ||
267 | result_len = write_cpabe(result, cph_buf, payload_len, aes_buf); | ||
268 | g_byte_array_free(cph_buf, 1); | ||
269 | g_byte_array_free(aes_buf, 1); | ||
270 | return result_len; | ||
271 | } | ||
272 | |||
273 | ssize_t | ||
274 | GNUNET_CRYPTO_cpabe_decrypt (const void *block, | ||
275 | size_t size, | ||
276 | const struct GNUNET_CRYPTO_AbeKey *key, | ||
277 | void **result) | ||
278 | { | ||
279 | bswabe_pub_t* pub; | ||
280 | bswabe_prv_t* prv; | ||
281 | GByteArray* aes_buf; | ||
282 | GByteArray* plt; | ||
283 | GByteArray* cph_buf; | ||
284 | bswabe_cph_t* cph; | ||
285 | element_t m; | ||
286 | ssize_t pt_size; | ||
287 | |||
288 | pub = bswabe_pub_unserialize(key->pub, 0); | ||
289 | prv = bswabe_prv_unserialize(pub, key->prv, 0); | ||
290 | pt_size = read_cpabe(block, &cph_buf, &aes_buf); | ||
291 | cph = bswabe_cph_unserialize(pub, cph_buf, 0); | ||
292 | if( !bswabe_dec(pub, prv, cph, m) ) { | ||
293 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
294 | "%s\n", bswabe_error()); | ||
295 | return GNUNET_SYSERR; | ||
296 | } | ||
297 | bswabe_cph_free(cph); | ||
298 | plt = aes_128_cbc_decrypt(aes_buf, m); | ||
299 | g_byte_array_set_size(plt, size); | ||
300 | g_byte_array_free(aes_buf, 1); | ||
301 | *result = GNUNET_malloc (plt->len); | ||
302 | GNUNET_memcpy (*result, plt->data, plt->len); | ||
303 | |||
304 | return pt_size; | ||
305 | } | ||