unsigned char bits[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8];
};
+/**
+ * @brief type for ABE master keys
+ */
+struct GNUNET_CRYPTO_AbeMasterKey;
+
/* **************** Functions and Macros ************* */
const struct GNUNET_CRYPTO_RsaPublicKey *public_key);
+/**
+ * @ingroup crypto
+ * Create a new CP-ABE master key. Caller must free return value.
+ *
+ * @return fresh private key; free using #GNUNET_free
+ */
+struct GNUNET_CRYPTO_AbeMasterKey *
+GNUNET_CRYPTO_cpabe_create_master_key (void);
+
+/**
+ * @ingroup crypto
+ * Create a new CP-ABE key. Caller must free return value.
+ *
+ * @return fresh private key; free using #GNUNET_free
+ */
+struct GNUNET_CRYPTO_AbeKey *
+GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *msk,
+ char **attrs);
+
+
+/**
+ * @ingroup crypto
+ * Encrypt a block using sessionkey.
+ *
+ * @param block the block to encrypt
+ * @param size the size of the @a block
+ * @param sessionkey the key used to encrypt
+ * @param iv the initialization vector to use, use INITVALUE
+ * for streams.
+ * @return the size of the encrypted block, -1 for errors
+ */
+ssize_t
+GNUNET_CRYPTO_cpabe_encrypt (const void *block,
+ size_t size,
+ char *policy,
+ const struct GNUNET_CRYPTO_AbeMasterKey *key,
+ void **result);
+
+/**
+ * @ingroup crypto
+ * Encrypt a block using sessionkey.
+ *
+ * @param block the block to encrypt
+ * @param size the size of the @a block
+ * @param sessionkey the key used to encrypt
+ * @param iv the initialization vector to use, use INITVALUE
+ * for streams.
+ * @return the size of the encrypted block, -1 for errors
+ */
+ssize_t
+GNUNET_CRYPTO_cpabe_decrypt (const void *block,
+ size_t size,
+ const struct GNUNET_CRYPTO_AbeKey *key,
+ void **result);
+
+
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
--- /dev/null
+/*
+ This file is part of GNUnet. Copyright (C) 2001-2014 Christian Grothoff
+ (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+/**
+ * @file util/crypto_random.c
+ * @brief functions to gather random numbers
+ * @author Christian Grothoff
+ */
+
+
+#include "platform.h"
+#include <glib.h>
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+#include <pbc/pbc.h>
+#include <bswabe.h>
+
+#include "gnunet_crypto_lib.h"
+
+struct GNUNET_CRYPTO_AbeMasterKey
+{
+ GByteArray* pub;
+
+ GByteArray* msk;
+};
+
+struct GNUNET_CRYPTO_AbeKey
+{
+ GByteArray* pub;
+ GByteArray* prv;
+};
+
+static void
+init_aes( element_t k, int enc, AES_KEY* key, unsigned char* iv )
+{
+ int key_len;
+ unsigned char* key_buf;
+
+ key_len = element_length_in_bytes(k) < 17 ? 17 : element_length_in_bytes(k);
+ key_buf = (unsigned char*) malloc(key_len);
+ element_to_bytes(key_buf, k);
+
+ if( enc )
+ AES_set_encrypt_key(key_buf + 1, 128, key);
+ else
+ AES_set_decrypt_key(key_buf + 1, 128, key);
+ free(key_buf);
+
+ memset(iv, 0, 16);
+}
+
+static GByteArray*
+aes_128_cbc_encrypt( GByteArray* pt, element_t k )
+{
+ AES_KEY key;
+ unsigned char iv[16];
+ GByteArray* ct;
+ guint8 len[4];
+ guint8 zero;
+
+ init_aes(k, 1, &key, iv);
+
+ /* TODO make less crufty */
+
+ /* stuff in real length (big endian) before padding */
+ len[0] = (pt->len & 0xff000000)>>24;
+ len[1] = (pt->len & 0xff0000)>>16;
+ len[2] = (pt->len & 0xff00)>>8;
+ len[3] = (pt->len & 0xff)>>0;
+ g_byte_array_prepend(pt, len, 4);
+
+ /* pad out to multiple of 128 bit (16 byte) blocks */
+ zero = 0;
+ while( pt->len % 16 )
+ g_byte_array_append(pt, &zero, 1);
+
+ ct = g_byte_array_new();
+ g_byte_array_set_size(ct, pt->len);
+
+ AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT);
+
+ return ct;
+}
+
+static GByteArray*
+aes_128_cbc_decrypt( GByteArray* ct, element_t k )
+{
+ AES_KEY key;
+ unsigned char iv[16];
+ GByteArray* pt;
+ unsigned int len;
+
+ init_aes(k, 0, &key, iv);
+
+ pt = g_byte_array_new();
+ g_byte_array_set_size(pt, ct->len);
+
+ AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT);
+
+ /* TODO make less crufty */
+
+ /* get real length */
+ len = 0;
+ len = len
+ | ((pt->data[0])<<24) | ((pt->data[1])<<16)
+ | ((pt->data[2])<<8) | ((pt->data[3])<<0);
+ g_byte_array_remove_index(pt, 0);
+ g_byte_array_remove_index(pt, 0);
+ g_byte_array_remove_index(pt, 0);
+ g_byte_array_remove_index(pt, 0);
+
+ /* truncate any garbage from the padding */
+ g_byte_array_set_size(pt, len);
+
+ return pt;
+}
+
+struct GNUNET_CRYPTO_AbeMasterKey*
+GNUNET_CRYPTO_cpabe_create_master_key (void)
+{
+ struct GNUNET_CRYPTO_AbeMasterKey* key;
+ bswabe_msk_t* msk;
+ bswabe_pub_t* pub;
+ bswabe_setup(&pub, &msk);
+ key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
+ key->pub = bswabe_pub_serialize(pub);
+ key->msk = bswabe_msk_serialize(msk);
+ GNUNET_assert (NULL != key->pub);
+ GNUNET_assert (NULL != key->msk);
+ return key;
+}
+
+struct GNUNET_CRYPTO_AbeKey*
+GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key,
+ char **attrs)
+{
+ struct GNUNET_CRYPTO_AbeKey *prv_key;
+ bswabe_pub_t* pub;
+ bswabe_msk_t* msk;
+ bswabe_prv_t* prv;
+ gchar* pub_data;
+ gsize len;
+
+ pub = bswabe_pub_unserialize(key->pub, 0);
+ msk = bswabe_msk_unserialize(pub, key->msk, 0);
+ prv = bswabe_keygen(pub, msk, attrs);
+ prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
+ prv_key->prv = bswabe_prv_serialize(prv);
+ pub_data = g_strndup ((gchar*)key->pub->data,
+ key->pub->len);
+ len = key->pub->len;
+ prv_key->pub = g_byte_array_new_take ((guint8*)pub_data, len);
+ GNUNET_assert (NULL != prv_key->prv);
+ return prv_key;
+}
+
+ssize_t
+write_cpabe (void **result, GByteArray* cph_buf,
+ int file_len, GByteArray* aes_buf)
+{
+ char *ptr;
+ int i;
+ ssize_t size;
+ size = aes_buf->len + cph_buf->len + 12;
+ *result = GNUNET_malloc (size);
+ ptr = *result;
+ for(i=3; i >= 0; i--) {
+ *ptr = (file_len & 0xff<<(i*8))>>(i*8);
+ ptr++;
+ }
+ for(i=3; i >= 0; i--) {
+ *ptr = (aes_buf->len & 0xff<<(i*8))>>(i*8);
+ ptr++;
+ }
+ memcpy (ptr, aes_buf->data, aes_buf->len);
+ ptr += aes_buf->len;
+ for(i=3; i >= 0; i--) {
+ *ptr = (cph_buf->len & 0xff<<(i*8))>>(i*8);
+ ptr++;
+ }
+ memcpy (ptr, cph_buf->data, cph_buf->len);
+ return size;
+}
+
+ssize_t
+read_cpabe (const void *data, GByteArray** cph_buf, GByteArray** aes_buf)
+{
+ int i;
+ ssize_t buf_len;
+ ssize_t tmp_len;
+ char *ptr;
+
+ *cph_buf = g_byte_array_new();
+ *aes_buf = g_byte_array_new();
+ ptr = (char*)data;
+
+ buf_len = 0;
+ for(i=3; i >= 0; i--) {
+ buf_len |= *ptr<<(i*8);
+ ptr++;
+ }
+
+ tmp_len = 0;
+ for(i=3; i >= 0; i--) {
+ tmp_len |= *ptr<<(i*8);
+ ptr++;
+ }
+ g_byte_array_set_size(*aes_buf, tmp_len);
+ memcpy((*aes_buf)->data, ptr, tmp_len);
+ ptr += tmp_len;
+ tmp_len = 0;
+ for(i=3; i >= 0; i--) {
+ tmp_len |= *ptr<<(i*8);
+ ptr++;
+ }
+ g_byte_array_set_size(*cph_buf, tmp_len);
+ memcpy((*cph_buf)->data, ptr, tmp_len);
+
+ return buf_len;
+}
+
+ssize_t
+GNUNET_CRYPTO_cpabe_encrypt (const void *block,
+ size_t size,
+ char *policy,
+ const struct GNUNET_CRYPTO_AbeMasterKey *key,
+ void **result)
+{
+ bswabe_pub_t* pub;
+ bswabe_cph_t* cph;
+ GByteArray* plt;
+ GByteArray* cph_buf;
+ GByteArray* aes_buf;
+ guint8 *data;
+ element_t m;
+ size_t payload_len;
+ ssize_t result_len;
+ pub = bswabe_pub_unserialize(key->pub, 0);
+ if( !(cph = bswabe_enc(pub, m, policy)) )
+ return GNUNET_SYSERR;
+ cph_buf = bswabe_cph_serialize(cph);
+ bswabe_cph_free(cph);
+ data = g_memdup (block, size);
+ plt = g_byte_array_new_take (data, size);
+ payload_len = plt->len;
+ aes_buf = aes_128_cbc_encrypt(plt, m);
+ g_byte_array_free(plt, 1);
+ element_clear(m);
+ result_len = write_cpabe(result, cph_buf, payload_len, aes_buf);
+ g_byte_array_free(cph_buf, 1);
+ g_byte_array_free(aes_buf, 1);
+ return result_len;
+}
+
+ssize_t
+GNUNET_CRYPTO_cpabe_decrypt (const void *block,
+ size_t size,
+ const struct GNUNET_CRYPTO_AbeKey *key,
+ void **result)
+{
+ bswabe_pub_t* pub;
+ bswabe_prv_t* prv;
+ GByteArray* aes_buf;
+ GByteArray* plt;
+ GByteArray* cph_buf;
+ bswabe_cph_t* cph;
+ element_t m;
+ ssize_t pt_size;
+
+ pub = bswabe_pub_unserialize(key->pub, 0);
+ prv = bswabe_prv_unserialize(pub, key->prv, 0);
+ pt_size = read_cpabe(block, &cph_buf, &aes_buf);
+ cph = bswabe_cph_unserialize(pub, cph_buf, 0);
+ if( !bswabe_dec(pub, prv, cph, m) ) {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "%s\n", bswabe_error());
+ return GNUNET_SYSERR;
+ }
+ bswabe_cph_free(cph);
+ plt = aes_128_cbc_decrypt(aes_buf, m);
+ g_byte_array_set_size(plt, size);
+ g_byte_array_free(aes_buf, 1);
+ *result = GNUNET_malloc (plt->len);
+ GNUNET_memcpy (*result, plt->data, plt->len);
+
+ return pt_size;
+}
--- /dev/null
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2002, 2003, 2004, 2006 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+/**
+ * @author Martin Schanzenbach
+ * @file util/test_crypto_abe.c
+ * @brief test for ABE ciphers
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+
+#define TESTSTRING "Hello World!"
+
+static int
+testAbecipher ()
+{
+ struct GNUNET_CRYPTO_AbeMasterKey *msk;
+ struct GNUNET_CRYPTO_AbeKey *key;
+ char *result;
+ char **attrs;
+ int size;
+ char *res;
+ msk = GNUNET_CRYPTO_cpabe_create_master_key ();
+ size = GNUNET_CRYPTO_cpabe_encrypt (TESTSTRING, strlen (TESTSTRING) + 1,
+ "testattr", //Policy
+ msk,
+ (void*)&result);
+ GNUNET_assert (-1 != size);
+ attrs = GNUNET_malloc (2 * sizeof (char*));
+ attrs[0] = "testattr";
+ attrs[1] = NULL;
+ key = GNUNET_CRYPTO_cpabe_create_key (msk,
+ attrs);
+
+ size = GNUNET_CRYPTO_cpabe_decrypt (result, size,
+ key,
+ (void*)&res);
+ if (strlen (TESTSTRING) + 1 != size)
+ {
+ printf ("abeciphertest failed: decryptBlock returned %d\n", size);
+ return 1;
+ }
+ if (0 != strcmp (res, TESTSTRING))
+ {
+ printf ("abeciphertest failed: %s != %s\n", res, TESTSTRING);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int failureCount = 0;
+
+ GNUNET_log_setup ("test-crypto-abe", "WARNING", NULL);
+ failureCount += testAbecipher ();
+
+ if (failureCount != 0)
+ {
+ printf ("%d TESTS FAILED!\n", failureCount);
+ return -1;
+ }
+ return 0;
+}
+
+/* end of test_crypto_aes.c */