Tools to make secret sharing easier.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

641 lines
16 KiB

  1. /*
  2. * gfsecret - Secret sharing tools
  3. * Copyright (C) 2016 Damien Goutte-Gattat
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #include "secret.h"
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <assert.h>
  26. #include <gcrypt.h>
  27. #include <libgfshare.h>
  28. #include <xmem.h>
  29. #include "util.h"
  30. /** @file secret.c
  31. * Secret splitting module.
  32. *
  33. * How to use this module to split a secret.
  34. *
  35. * Create a secret object and fills it with the secret data:
  36. * \code
  37. * gfsec_secret_t *secret = gfsec_secret_new();
  38. * gfsec_secret_set_secret_file(secret, filename);
  39. * \endcode
  40. *
  41. * Create share objects describing the shares to split the
  42. * secret into, and add them to the secret object:
  43. * \code
  44. * gfsec_share_t *share = gfsec_share_new();
  45. * gfsec_share_set_info(share, GFSEC_SHARE_NUMBER_AUTOASSIGN,
  46. * GFSEC_SCHEME_FILE, authority, path, NULL);
  47. * gfsec_secret_add_share(secret, share);
  48. * \endcode
  49. *
  50. * Actually split the secret and write the shares' data:
  51. * \code
  52. * gfsec_secret_split(secret, threshold);
  53. * for ( int i = 0; i < secret->n_shares; i++ ) {
  54. * gfsec_share_t *share = secret->shares[i];
  55. * write_data_somewhere(share->data, share->len);
  56. * }
  57. * \endcode
  58. *
  59. *
  60. * How to use this module to reconstitute a secret.
  61. *
  62. * Create a secret object:
  63. * \code
  64. * gfsec_secret_t *secret = gfsec_secret_new();
  65. * secret->threshold = threshold;
  66. * \endcode
  67. *
  68. * Create share objects describing the shares, and add them
  69. * to the secret object:
  70. * \code
  71. * gfsec_share_t *share = gfsec_share_new();
  72. * gfsec_share_set_info(share, share_number, GFSEC_SCHEME_FILE,
  73. * authority, path, hash);
  74. * \endcode
  75. *
  76. * Fill the shares with data if available:
  77. * \code
  78. * gfsec_share_set_data(share, data, len);
  79. * \endcode
  80. *
  81. * Actually reconstitute the secret:
  82. * \code
  83. * if ( gfsec_secret_can_recombine(secret) ) {
  84. * gfsec_secret_recombine(secret);
  85. * do_something_with_secret(secret->data, secret->len);
  86. * }
  87. * \endcode
  88. *
  89. */
  90. /**
  91. * Fills a buffer with random data.
  92. * This function is used internally by libgfshare.
  93. *
  94. * @param buffer The buffer to fill.
  95. * @param len The buffer size.
  96. */
  97. static void
  98. gfsec_fill_rand(unsigned char *buffer, unsigned int len)
  99. {
  100. gcry_randomize(buffer, len, GCRY_STRONG_RANDOM);
  101. }
  102. /**
  103. * Initializes a new share object.
  104. *
  105. * @return The share object.
  106. */
  107. gfsec_share_t *
  108. gfsec_share_new(void)
  109. {
  110. gfsec_share_t *s;
  111. s = xmalloc(sizeof(gfsec_share_t));
  112. s->number = GFSEC_SHARE_NUMBER_AUTOASSIGN;
  113. s->scheme = GFSEC_SCHEME_FILE;
  114. s->authority = NULL;
  115. s->path = NULL;
  116. s->len = 0;
  117. s->data = NULL;
  118. s->hash = NULL;
  119. return s;
  120. }
  121. /**
  122. * Fills the fields of a share object.
  123. * Note that all strings are copied to newly allocated buffers.
  124. * The gfsec_share_free function takes care of freeing those buffers.
  125. *
  126. * @param share The share object;
  127. * @param number The share number; should be between 1 and 255
  128. * (inclusive) for a normal share, 0 for a share
  129. * which contains the whole secret, or
  130. * GFSEC_SHARE_NUMBER_AUTOASSIGN to let the
  131. * gfsec_secret_split function assign a share
  132. * number automatically;
  133. * @param scheme The scheme of the URI locating the share;
  134. * @param authority The authority part of the URI (may be NULL);
  135. * @param path The path part of the URI (may be NULL);
  136. * @param hash A buffer containing a SHA-256 hash of the
  137. * share's data (may be NULL).
  138. */
  139. void
  140. gfsec_share_set_info(gfsec_share_t *share,
  141. unsigned char number,
  142. gfsec_scheme_t scheme,
  143. const char *authority,
  144. const char *path,
  145. const unsigned char *hash)
  146. {
  147. assert(share != NULL);
  148. share->number = number;
  149. share->scheme = scheme;
  150. if ( authority )
  151. share->authority = xstrdup(authority);
  152. if ( path )
  153. share->path = xstrdup(path);
  154. if ( hash )
  155. memcpy(share->hash, hash, 32);
  156. }
  157. /**
  158. * Fills a share object with the corresponding data.
  159. * If the share object specifies a hash value, the data are
  160. * checked against this hash, and GFSEC_ERR_INVALID_SHARE is
  161. * returned if the checksum fails.
  162. *
  163. * @param share The share object.
  164. * @param data The buffer containing the data; only the pointer
  165. * is copied, not the buffer itself, and it will be
  166. * freed when the gfsec_share_free function is called;
  167. * @param len The size of the data buffer.
  168. *
  169. * @return 0 if successfull, or GFSEC_ERR_INVALID_SHARE is the
  170. * data does not match the share's expected hash.
  171. */
  172. int
  173. gfsec_share_set_data(gfsec_share_t *share,
  174. unsigned char *data,
  175. size_t len)
  176. {
  177. int ret;
  178. assert(share != NULL);
  179. assert(data != NULL);
  180. share->data = data;
  181. share->len = len;
  182. ret = 0;
  183. if ( share->hash ) {
  184. unsigned char hash[32];
  185. gcry_md_hash_buffer(GCRY_MD_SHA256, hash, data, len);
  186. if ( memcmp(share->hash, hash, 32) != 0 ) {
  187. ret = GFSEC_ERR_INVALID_SHARE;
  188. share->data = NULL;
  189. share->len = 0;
  190. }
  191. }
  192. return ret;
  193. }
  194. /**
  195. * Gets the URI representing the location of a share.
  196. *
  197. * @param share The share object.
  198. * @param buffer The buffer to write the URI into.
  199. * @param len The size of the buffer.
  200. *
  201. * @return The number of characters written into the buffer.
  202. */
  203. int
  204. gfsec_share_get_uri(gfsec_share_t *share,
  205. char *buffer,
  206. size_t len)
  207. {
  208. static char *schemes[] = { "file://", "uuid://", "label://", "mtp://" };
  209. int ret;
  210. assert(share != NULL);
  211. assert(buffer != NULL);
  212. ret = snprintf(buffer, len, "%s%s%s",
  213. schemes[share->scheme],
  214. share->authority ? share->authority : "",
  215. share->path);
  216. return ret;
  217. }
  218. /**
  219. * Frees a share object and all of its buffers.
  220. *
  221. * @param share The share object.
  222. */
  223. void
  224. gfsec_share_free(gfsec_share_t *share)
  225. {
  226. assert(share != NULL);
  227. if ( share->authority )
  228. free(share->authority);
  229. if ( share->path )
  230. free(share->path);
  231. if ( share->data )
  232. free(share->data);
  233. if ( share->hash )
  234. free(share->hash);
  235. free(share);
  236. }
  237. /**
  238. * Initializes a new secret object.
  239. *
  240. * @return The secret object.
  241. */
  242. gfsec_secret_t *
  243. gfsec_secret_new(void)
  244. {
  245. gfsec_secret_t *s;
  246. s = xmalloc(sizeof(*s));
  247. s->filename = NULL;
  248. s->data = NULL;
  249. s->len = 0;
  250. s->n_shares = 0;
  251. s->max_shares = 0;
  252. s->threshold = 0;
  253. s->shares = NULL;
  254. s->full_share = NULL;
  255. s->can_combine = 0;
  256. return s;
  257. }
  258. /**
  259. * Sets the secret to be splitted.
  260. *
  261. * @param secret The secret object.
  262. * @param filename The location of the file to read the secret from.
  263. *
  264. * @return 0 if successful, or one of the GFSEC_ERR_SYSTEM_ERROR if
  265. * an I/O error occured.
  266. */
  267. int
  268. gfsec_secret_set_secret_file(gfsec_secret_t *secret,
  269. const char *filename)
  270. {
  271. assert(secret != NULL);
  272. assert(filename != NULL);
  273. secret->filename = xstrdup(filename);
  274. if ( ! (secret->data = read_file(filename, &(secret->len),
  275. GFSEC_SECRET_MAX_SIZE)) )
  276. return GFSEC_ERR_SYSTEM_ERROR;
  277. return 0;
  278. }
  279. /**
  280. * Adds a share to a secret object.
  281. *
  282. * @param secret The secret object.
  283. * @param share The share to add.
  284. *
  285. * @return 0 if successful, or GFSEC_ERR_TOO_MANY_SHARES if the
  286. * secret object already has the maximal number of shares allowed.
  287. */
  288. int
  289. gfsec_secret_add_share(gfsec_secret_t *secret, gfsec_share_t *share)
  290. {
  291. assert(secret != NULL);
  292. assert(share != NULL);
  293. if ( secret->n_shares >= secret->max_shares ) {
  294. size_t new_max;
  295. new_max = secret->max_shares + 10;
  296. if ( new_max > 255 ) {
  297. new_max = 255;
  298. if ( secret->n_shares >= new_max )
  299. return GFSEC_ERR_TOO_MANY_SHARES;
  300. }
  301. secret->shares = xrealloc(secret->shares, new_max * sizeof(gfsec_share_t *));
  302. secret->max_shares = new_max;
  303. }
  304. if ( share->number == GFSEC_SHARE_NUMBER_AUTOASSIGN ) {
  305. unsigned nr, u;
  306. char *tmp;
  307. do {
  308. nr = (random() & 0xFF00) >> 8;
  309. if ( nr == 0 )
  310. nr = 1;
  311. for ( u = 0; u < secret->n_shares; u++ )
  312. if ( secret->shares[u]->number == nr )
  313. nr = 0;
  314. } while ( nr == 0 );
  315. share->number = nr;
  316. xasprintf(&tmp, "%s.%03d", share->path, nr);
  317. free(share->path);
  318. share->path = tmp;
  319. }
  320. secret->shares[secret->n_shares++] = share;
  321. return 0;
  322. }
  323. /**
  324. * Checks if the secret can be reconstituted.
  325. * Note that it is mandatory to call this function prior to calling
  326. * the gfsec_secret_combine function.
  327. *
  328. * @param secret The secret object.
  329. *
  330. * @return
  331. * - 0 if the secret can be reconstituted;
  332. * - GFSEC_ERR_INVALID_LENGTH if not all shares have the same length;
  333. * - GFSEC_ERR_NOT_ENOUGH_SHARES if not enough shares are available.
  334. */
  335. int
  336. gfsec_secret_can_combine(gfsec_secret_t *secret)
  337. {
  338. unsigned u, avail_shares;
  339. gfsec_share_t *share;
  340. assert(secret != NULL);
  341. for ( u = 0, avail_shares = 0; u < secret->n_shares; u++ ) {
  342. share = secret->shares[u];
  343. if ( share->data ) {
  344. if ( secret->len == 0 )
  345. secret->len = share->len;
  346. else if ( secret->len != share->len )
  347. return GFSEC_ERR_INVALID_LENGTH;
  348. if ( gfsec_share_is_full(share) )
  349. secret->full_share = share;
  350. else
  351. avail_shares += 1;
  352. }
  353. }
  354. if ( ! secret->full_share && avail_shares < secret->threshold )
  355. return GFSEC_ERR_NOT_ENOUGH_SHARES;
  356. secret->can_combine = 1;
  357. return 0;
  358. }
  359. /**
  360. * Reconstitutes the secret.
  361. * The reconstituted secret will be stored in the data field of
  362. * the secret object.
  363. *
  364. * @param secret The secret object.
  365. *
  366. * @return
  367. * - 0 if successful;
  368. * - GFSEC_ERR_INVALID_CALL if called improperly (either
  369. * gfsec_secret_can_recombine has not been called previously,
  370. * or it has been called but has found the secret could not be
  371. * reconstituted);
  372. * - GFSEC_ERR_SYSTEM_ERROR if an error occured in Libgfshare.
  373. */
  374. int
  375. gfsec_secret_combine(gfsec_secret_t *secret)
  376. {
  377. gfsec_share_t *share;
  378. unsigned u;
  379. assert(secret != NULL);
  380. if ( ! secret->can_combine )
  381. return GFSEC_ERR_INVALID_CALL;
  382. secret->data = xmalloc(secret->len);
  383. if ( gfshare_fill_rand == NULL )
  384. gfshare_fill_rand = gfsec_fill_rand;
  385. if ( secret->full_share )
  386. memcpy(secret->data, secret->full_share->data, secret->len);
  387. else {
  388. gfshare_ctx *ctx;
  389. unsigned char sharenrs[255];
  390. unsigned v;
  391. for ( u = v = 0; u < secret->n_shares; u++ ) {
  392. share = secret->shares[u];
  393. if ( share->data && ! gfsec_share_is_full(share) )
  394. sharenrs[v++] = share->number;
  395. }
  396. if ( ! (ctx= gfshare_ctx_init_dec(sharenrs, v, secret->len)) )
  397. return GFSEC_ERR_SYSTEM_ERROR;
  398. for ( u = v = 0; u < secret->n_shares; u++ ) {
  399. share = secret->shares[u];
  400. if ( share->data && ! gfsec_share_is_full(share) )
  401. gfshare_ctx_dec_giveshare(ctx, v++, share->data);
  402. }
  403. gfshare_ctx_dec_extract(ctx, secret->data);
  404. gfshare_ctx_free(ctx);
  405. }
  406. return 0;
  407. }
  408. /**
  409. * Gets the number of partial shares in the secret object.
  410. */
  411. static unsigned
  412. gfsec_secret_get_partial_share_count(gfsec_secret_t *secret)
  413. {
  414. unsigned u, n;
  415. for ( u = n = 0; u < secret->n_shares; u++ )
  416. if ( ! gfsec_share_is_full(secret->shares[u]) )
  417. n += 1;
  418. return n;
  419. }
  420. /**
  421. * Splits the secret and fills the shares accordingly.
  422. *
  423. * @param secret The secret object.
  424. * @param threshold The minimal number of shares needed to
  425. * reconstitute the secret.
  426. *
  427. * @return
  428. * - 0 if successful;
  429. * - GFSEC_ERR_NOT_ENOUGH_SHARES if the secret object does not define
  430. * enough shares to satisfy the desired threshold;
  431. * - GFSEC_ERR_SYSTEM_ERROR if an error occured in Libgfshare or
  432. * Libgcrypt.
  433. */
  434. int
  435. gfsec_secret_split(gfsec_secret_t *secret, unsigned char threshold)
  436. {
  437. gfshare_ctx *ctx;
  438. gcry_md_hd_t md;
  439. gfsec_share_t *share;
  440. unsigned char sharenrs[255];
  441. unsigned u, v, n;
  442. int rc;
  443. assert(secret != NULL);
  444. n = gfsec_secret_get_partial_share_count(secret);
  445. if ( threshold >= n )
  446. return GFSEC_ERR_NOT_ENOUGH_SHARES;
  447. secret->threshold = threshold;
  448. if ( gfshare_fill_rand == NULL )
  449. gfshare_fill_rand = gfsec_fill_rand;
  450. for ( u = v = rc = 0; u < secret->n_shares; u++ ) {
  451. share = secret->shares[u];
  452. if ( ! gfsec_share_is_full(share) )
  453. sharenrs[v++] = share->number;
  454. share->data = xmalloc(secret->len);
  455. share->hash = xmalloc(32);
  456. share->len = secret->len;
  457. }
  458. if ( ! (ctx = gfshare_ctx_init_enc(sharenrs, n, threshold, secret->len)) )
  459. rc = GFSEC_ERR_SYSTEM_ERROR;
  460. if ( rc == 0 && gcry_md_open(&md, GCRY_MD_SHA256, 0) != 0 )
  461. rc = GFSEC_ERR_SYSTEM_ERROR;
  462. if ( rc == 0 ) {
  463. gfshare_ctx_enc_setsecret(ctx, secret->data);
  464. for ( u = v = 0; u < secret->n_shares; u++ ) {
  465. share = secret->shares[u];
  466. if ( ! gfsec_share_is_full(share) )
  467. gfshare_ctx_enc_getshare(ctx, v++, share->data);
  468. else
  469. memcpy(share->data, secret->data, secret->len);
  470. gcry_md_write(md, share->data, share->len);
  471. memcpy(share->hash, gcry_md_read(md, 0), 32);
  472. gcry_md_reset(md);
  473. }
  474. }
  475. else {
  476. for ( u = v = 0; u < secret->n_shares; u++ ) {
  477. share = secret->shares[u];
  478. if ( share->data ) {
  479. free(share->data);
  480. share->data = NULL;
  481. }
  482. if ( share->hash ) {
  483. free(share->hash);
  484. share->hash = NULL;
  485. }
  486. }
  487. }
  488. if ( ctx )
  489. gfshare_ctx_free(ctx);
  490. if ( md )
  491. gcry_md_close(md);
  492. return rc;
  493. }
  494. /**
  495. * Frees a secret object and the associated shares.
  496. *
  497. * @param secret The secret object.
  498. */
  499. void
  500. gfsec_secret_free(gfsec_secret_t *secret)
  501. {
  502. unsigned u;
  503. assert(secret != NULL);
  504. if ( secret->filename )
  505. free(secret->filename);
  506. if ( secret->data )
  507. free(secret->data);
  508. for ( u = 0; u < secret->n_shares; u++ )
  509. gfsec_share_free(secret->shares[u]);
  510. if ( secret->shares )
  511. free(secret->shares);
  512. free(secret);
  513. }
  514. /**
  515. * Translates a GFSEC_ERR_* error code into an error string.
  516. *
  517. * @param err The error code.
  518. *
  519. * @return A statically allocated string containing the error
  520. * message.
  521. */
  522. const char *
  523. gfsec_error_string(int err)
  524. {
  525. const char *msg;
  526. switch ( err ) {
  527. #define GFSEC_ERROR(symbol, value, message) \
  528. case GFSEC_ERR_##symbol: \
  529. msg = message; \
  530. break;
  531. #include "gfsec-errors.h"
  532. #undef GFSEC_ERROR
  533. default: /* Should not happen. */
  534. msg = "Unknown error";
  535. break;
  536. }
  537. return msg;
  538. }