crypto_abe.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. This file is part of GNUnet. Copyright (C) 2001-2014 Christian Grothoff
  3. (and other contributing authors)
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/crypto_random.c
  18. * @brief functions to gather random numbers
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include <pbc/pbc.h>
  23. #include <gabe.h>
  24. #include "gnunet_crypto_lib.h"
  25. struct GNUNET_CRYPTO_AbeMasterKey
  26. {
  27. gabe_pub_t*pub;
  28. gabe_msk_t*msk;
  29. };
  30. struct GNUNET_CRYPTO_AbeKey
  31. {
  32. gabe_pub_t*pub;
  33. gabe_prv_t*prv;
  34. };
  35. static int
  36. init_aes (element_t k, int enc,
  37. gcry_cipher_hd_t*handle,
  38. struct GNUNET_CRYPTO_SymmetricSessionKey *key,
  39. unsigned char*iv)
  40. {
  41. int rc;
  42. int key_len;
  43. unsigned char*key_buf;
  44. key_len = element_length_in_bytes (k) < 33 ? 3 : element_length_in_bytes (k);
  45. key_buf = (unsigned char *) malloc (key_len);
  46. element_to_bytes (key_buf, k);
  47. GNUNET_memcpy (key->aes_key,
  48. key_buf,
  49. GNUNET_CRYPTO_AES_KEY_LENGTH);
  50. GNUNET_assert (0 ==
  51. gcry_cipher_open (handle, GCRY_CIPHER_AES256,
  52. GCRY_CIPHER_MODE_CFB, 0));
  53. rc = gcry_cipher_setkey (*handle,
  54. key->aes_key,
  55. sizeof(key->aes_key));
  56. GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
  57. memset (iv, 0, 16); // TODO make reasonable
  58. rc = gcry_cipher_setiv (*handle,
  59. iv,
  60. 16);
  61. GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
  62. free (key_buf);
  63. return rc;
  64. }
  65. static int
  66. aes_128_cbc_encrypt (char*pt,
  67. int size,
  68. element_t k,
  69. char **ct)
  70. {
  71. gcry_cipher_hd_t handle;
  72. struct GNUNET_CRYPTO_SymmetricSessionKey skey;
  73. unsigned char iv[16];
  74. char*buf;
  75. int padding;
  76. int buf_size;
  77. uint8_t len[4];
  78. init_aes (k, 1, &handle, &skey, iv);
  79. /* TODO make less crufty */
  80. /* stuff in real length (big endian) before padding */
  81. len[0] = (size & 0xff000000) >> 24;
  82. len[1] = (size & 0xff0000) >> 16;
  83. len[2] = (size & 0xff00) >> 8;
  84. len[3] = (size & 0xff) >> 0;
  85. padding = 16 - ((4 + size) % 16);
  86. buf_size = 4 + size + padding;
  87. buf = GNUNET_malloc (buf_size);
  88. GNUNET_memcpy (buf, len, 4);
  89. GNUNET_memcpy (buf + 4, pt, size);
  90. *ct = GNUNET_malloc (buf_size);
  91. GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf,
  92. buf_size));
  93. gcry_cipher_close (handle);
  94. // AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT);
  95. GNUNET_free (buf);
  96. return buf_size;
  97. }
  98. static int
  99. aes_128_cbc_decrypt (char*ct,
  100. int size,
  101. element_t k,
  102. char **pt)
  103. {
  104. struct GNUNET_CRYPTO_SymmetricSessionKey skey;
  105. gcry_cipher_hd_t handle;
  106. unsigned char iv[16];
  107. char*tmp;
  108. uint32_t len;
  109. init_aes (k, 1, &handle, &skey, iv);
  110. tmp = GNUNET_malloc (size);
  111. // AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT);
  112. GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, ct, size));
  113. gcry_cipher_close (handle);
  114. /* TODO make less crufty */
  115. /* get real length */
  116. len = 0;
  117. len = len
  118. | ((tmp[0]) << 24) | ((tmp[1]) << 16)
  119. | ((tmp[2]) << 8) | ((tmp[3]) << 0);
  120. /* truncate any garbage from the padding */
  121. *pt = GNUNET_malloc (len);
  122. GNUNET_memcpy (*pt, tmp + 4, len);
  123. GNUNET_free (tmp);
  124. return len;
  125. }
  126. struct GNUNET_CRYPTO_AbeMasterKey*
  127. GNUNET_CRYPTO_cpabe_create_master_key (void)
  128. {
  129. struct GNUNET_CRYPTO_AbeMasterKey*key;
  130. key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
  131. gabe_setup (&key->pub, &key->msk);
  132. GNUNET_assert (NULL != key->pub);
  133. GNUNET_assert (NULL != key->msk);
  134. return key;
  135. }
  136. void
  137. GNUNET_CRYPTO_cpabe_delete_master_key (struct GNUNET_CRYPTO_AbeMasterKey *key)
  138. {
  139. gabe_msk_free (key->msk);
  140. gabe_pub_free (key->pub);
  141. // GNUNET_free (key->msk);
  142. // gabe_msk_free (key->msk); //For some reason free of pub implicit?
  143. GNUNET_free (key);
  144. }
  145. struct GNUNET_CRYPTO_AbeKey*
  146. GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key,
  147. char **attrs)
  148. {
  149. struct GNUNET_CRYPTO_AbeKey *prv_key;
  150. int size;
  151. char *tmp;
  152. prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
  153. prv_key->prv = gabe_keygen (key->pub, key->msk, attrs);
  154. size = gabe_pub_serialize (key->pub, &tmp);
  155. prv_key->pub = gabe_pub_unserialize (tmp, size);
  156. GNUNET_free (tmp);
  157. GNUNET_assert (NULL != prv_key->prv);
  158. return prv_key;
  159. }
  160. void
  161. GNUNET_CRYPTO_cpabe_delete_key (struct GNUNET_CRYPTO_AbeKey *key,
  162. int delete_pub)
  163. {
  164. // Memory management in gabe is buggy
  165. gabe_prv_free (key->prv);
  166. if (GNUNET_YES == delete_pub)
  167. gabe_pub_free (key->pub);
  168. GNUNET_free (key);
  169. }
  170. ssize_t
  171. write_cpabe (void **result,
  172. uint32_t file_len,
  173. char*cph_buf,
  174. int cph_buf_len,
  175. char*aes_buf,
  176. int aes_buf_len)
  177. {
  178. char *ptr;
  179. uint32_t *len;
  180. *result = GNUNET_malloc (12 + cph_buf_len + aes_buf_len);
  181. ptr = *result;
  182. len = (uint32_t *) ptr;
  183. *len = htonl (file_len);
  184. ptr += 4;
  185. len = (uint32_t *) ptr;
  186. *len = htonl (aes_buf_len);
  187. ptr += 4;
  188. GNUNET_memcpy (ptr, aes_buf, aes_buf_len);
  189. ptr += aes_buf_len;
  190. len = (uint32_t *) ptr;
  191. *len = htonl (cph_buf_len);
  192. ptr += 4;
  193. GNUNET_memcpy (ptr, cph_buf, cph_buf_len);
  194. return 12 + cph_buf_len + aes_buf_len;
  195. }
  196. ssize_t
  197. read_cpabe (const void *data,
  198. char**cph_buf,
  199. int *cph_buf_len,
  200. char**aes_buf,
  201. int *aes_buf_len)
  202. {
  203. int buf_len;
  204. char *ptr;
  205. uint32_t *len;
  206. ptr = (char *) data;
  207. len = (uint32_t *) ptr;
  208. buf_len = ntohl (*len);
  209. ptr += 4;
  210. len = (uint32_t *) ptr;
  211. *aes_buf_len = ntohl (*len);
  212. ptr += 4;
  213. *aes_buf = GNUNET_malloc (*aes_buf_len);
  214. GNUNET_memcpy (*aes_buf, ptr, *aes_buf_len);
  215. ptr += *aes_buf_len;
  216. len = (uint32_t *) ptr;
  217. *cph_buf_len = ntohl (*len);
  218. ptr += 4;
  219. *cph_buf = GNUNET_malloc (*cph_buf_len);
  220. GNUNET_memcpy (*cph_buf, ptr, *cph_buf_len);
  221. return buf_len;
  222. }
  223. ssize_t
  224. GNUNET_CRYPTO_cpabe_encrypt (const void *block,
  225. size_t size,
  226. const char *policy,
  227. const struct GNUNET_CRYPTO_AbeMasterKey *key,
  228. void **result)
  229. {
  230. gabe_cph_t*cph;
  231. char*plt;
  232. char*cph_buf;
  233. char*aes_buf;
  234. element_t m;
  235. int cph_buf_len;
  236. int aes_buf_len;
  237. ssize_t result_len;
  238. if (! (cph = gabe_enc (key->pub, m, (char *) policy)))
  239. return GNUNET_SYSERR;
  240. cph_buf_len = gabe_cph_serialize (cph,
  241. &cph_buf);
  242. gabe_cph_free (cph);
  243. GNUNET_free (cph);
  244. plt = GNUNET_memdup (block, size);
  245. aes_buf_len = aes_128_cbc_encrypt (plt, size, m, &aes_buf);
  246. GNUNET_free (plt);
  247. element_clear (m);
  248. result_len = write_cpabe (result, size, cph_buf, cph_buf_len, aes_buf,
  249. aes_buf_len);
  250. GNUNET_free (cph_buf);
  251. GNUNET_free (aes_buf);
  252. return result_len;
  253. }
  254. ssize_t
  255. GNUNET_CRYPTO_cpabe_decrypt (const void *block,
  256. size_t size,
  257. const struct GNUNET_CRYPTO_AbeKey *key,
  258. void **result)
  259. {
  260. char*aes_buf;
  261. char*cph_buf;
  262. gabe_cph_t*cph;
  263. element_t m;
  264. int cph_buf_size;
  265. int aes_buf_size;
  266. int plt_len;
  267. read_cpabe (block, &cph_buf, &cph_buf_size, &aes_buf, &aes_buf_size);
  268. cph = gabe_cph_unserialize (key->pub, cph_buf, cph_buf_size);
  269. if (! gabe_dec (key->pub, key->prv, cph, m))
  270. {
  271. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  272. "%s\n", gabe_error ());
  273. GNUNET_free (aes_buf);
  274. GNUNET_free (cph_buf);
  275. gabe_cph_free (cph);
  276. GNUNET_free (cph);
  277. element_clear (m);
  278. return GNUNET_SYSERR;
  279. }
  280. gabe_cph_free (cph);
  281. GNUNET_free (cph);
  282. plt_len = aes_128_cbc_decrypt (aes_buf, aes_buf_size, m, (char **) result);
  283. GNUNET_free (cph_buf);
  284. GNUNET_free (aes_buf);
  285. element_clear (m);
  286. // freeing is buggy in gabe
  287. // gabe_prv_free (prv);
  288. // gabe_pub_free (pub);
  289. return plt_len;
  290. }
  291. ssize_t
  292. GNUNET_CRYPTO_cpabe_serialize_key (const struct GNUNET_CRYPTO_AbeKey *key,
  293. void **result)
  294. {
  295. ssize_t len;
  296. char *pub;
  297. char *prv;
  298. int pub_len;
  299. int prv_len;
  300. pub_len = gabe_pub_serialize (key->pub, &pub);
  301. prv_len = gabe_prv_serialize (key->prv, &prv);
  302. len = pub_len + prv_len + 12;
  303. write_cpabe (result, len, pub, pub_len, prv, prv_len);
  304. GNUNET_free (pub);
  305. GNUNET_free (prv);
  306. return len;
  307. }
  308. struct GNUNET_CRYPTO_AbeKey*
  309. GNUNET_CRYPTO_cpabe_deserialize_key (const void *data,
  310. size_t len)
  311. {
  312. struct GNUNET_CRYPTO_AbeKey *key;
  313. char *pub;
  314. char *prv;
  315. int prv_len;
  316. int pub_len;
  317. key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey);
  318. read_cpabe (data,
  319. &pub,
  320. &pub_len,
  321. &prv,
  322. &prv_len);
  323. key->pub = gabe_pub_unserialize (pub, pub_len);
  324. key->prv = gabe_prv_unserialize (key->pub, prv, prv_len);
  325. GNUNET_free (pub);
  326. GNUNET_free (prv);
  327. return key;
  328. }
  329. ssize_t
  330. GNUNET_CRYPTO_cpabe_serialize_master_key (const struct
  331. GNUNET_CRYPTO_AbeMasterKey *key,
  332. void **result)
  333. {
  334. ssize_t len;
  335. char *pub;
  336. char *msk;
  337. int pub_len;
  338. int msk_len;
  339. pub_len = gabe_pub_serialize (key->pub, &pub);
  340. msk_len = gabe_msk_serialize (key->msk, &msk);
  341. len = pub_len + msk_len + 12;
  342. write_cpabe (result, len, pub, pub_len, msk, msk_len);
  343. GNUNET_free (pub);
  344. GNUNET_free (msk);
  345. return len;
  346. }
  347. struct GNUNET_CRYPTO_AbeMasterKey*
  348. GNUNET_CRYPTO_cpabe_deserialize_master_key (const void *data,
  349. size_t len)
  350. {
  351. struct GNUNET_CRYPTO_AbeMasterKey *key;
  352. char *msk;
  353. char *pub;
  354. int msk_len;
  355. int pub_len;
  356. key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey);
  357. read_cpabe (data,
  358. &pub,
  359. &pub_len,
  360. &msk,
  361. &msk_len);
  362. key->pub = gabe_pub_unserialize (pub, pub_len);
  363. key->msk = gabe_msk_unserialize (key->pub, msk, msk_len);
  364. GNUNET_free (pub);
  365. GNUNET_free (msk);
  366. return key;
  367. }