afsplit.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * QEMU Crypto anti forensic information splitter
  3. *
  4. * Copyright (c) 2015-2016 Red Hat, Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef QCRYPTO_AFSPLIT_H
  20. #define QCRYPTO_AFSPLIT_H
  21. #include "crypto/hash.h"
  22. /**
  23. * This module implements the anti-forensic splitter that is specified
  24. * as part of the LUKS format:
  25. *
  26. * http://clemens.endorphin.org/cryptography
  27. * http://clemens.endorphin.org/TKS1-draft.pdf
  28. *
  29. * The core idea is to take a short piece of data (key material)
  30. * and process it to expand it to a much larger piece of data.
  31. * The expansion process is reversible, to obtain the original
  32. * short data. The key property of the expansion is that if any
  33. * byte in the larger data set is changed / missing, it should be
  34. * impossible to recreate the original short data.
  35. *
  36. * <example>
  37. * <title>Creating a large split key for storage</title>
  38. * <programlisting>
  39. * size_t nkey = 32;
  40. * uint32_t stripes = 32768; // To produce a 1 MB split key
  41. * uint8_t *masterkey = ....a 32-byte AES key...
  42. * uint8_t *splitkey;
  43. *
  44. * splitkey = g_new0(uint8_t, nkey * stripes);
  45. *
  46. * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALGO_SHA256,
  47. * nkey, stripes,
  48. * masterkey, splitkey, errp) < 0) {
  49. * g_free(splitkey);
  50. * g_free(masterkey);
  51. * return -1;
  52. * }
  53. *
  54. * ...store splitkey somewhere...
  55. *
  56. * g_free(splitkey);
  57. * g_free(masterkey);
  58. * </programlisting>
  59. * </example>
  60. *
  61. * <example>
  62. * <title>Retrieving a master key from storage</title>
  63. * <programlisting>
  64. * size_t nkey = 32;
  65. * uint32_t stripes = 32768; // To produce a 1 MB split key
  66. * uint8_t *masterkey;
  67. * uint8_t *splitkey = .... read in 1 MB of data...
  68. *
  69. * masterkey = g_new0(uint8_t, nkey);
  70. *
  71. * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALGO_SHA256,
  72. * nkey, stripes,
  73. * splitkey, masterkey, errp) < 0) {
  74. * g_free(splitkey);
  75. * g_free(masterkey);
  76. * return -1;
  77. * }
  78. *
  79. * ..decrypt data with masterkey...
  80. *
  81. * g_free(splitkey);
  82. * g_free(masterkey);
  83. * </programlisting>
  84. * </example>
  85. */
  86. /**
  87. * qcrypto_afsplit_encode:
  88. * @hash: the hash algorithm to use for data expansion
  89. * @blocklen: the size of @in in bytes
  90. * @stripes: the number of times to expand @in in size
  91. * @in: the master key to be expanded in size
  92. * @out: preallocated buffer to hold the split key
  93. * @errp: pointer to a NULL-initialized error object
  94. *
  95. * Split the data in @in, which is @blocklen bytes in
  96. * size, to form a larger piece of data @out, which is
  97. * @blocklen * @stripes bytes in size.
  98. *
  99. * Returns: 0 on success, -1 on error;
  100. */
  101. int qcrypto_afsplit_encode(QCryptoHashAlgo hash,
  102. size_t blocklen,
  103. uint32_t stripes,
  104. const uint8_t *in,
  105. uint8_t *out,
  106. Error **errp);
  107. /**
  108. * qcrypto_afsplit_decode:
  109. * @hash: the hash algorithm to use for data compression
  110. * @blocklen: the size of @out in bytes
  111. * @stripes: the number of times to decrease @in in size
  112. * @in: the split key to be recombined
  113. * @out: preallocated buffer to hold the master key
  114. * @errp: pointer to a NULL-initialized error object
  115. *
  116. * Join the data in @in, which is @blocklen * @stripes
  117. * bytes in size, to form the original small piece of
  118. * data @out, which is @blocklen bytes in size.
  119. *
  120. * Returns: 0 on success, -1 on error;
  121. */
  122. int qcrypto_afsplit_decode(QCryptoHashAlgo hash,
  123. size_t blocklen,
  124. uint32_t stripes,
  125. const uint8_t *in,
  126. uint8_t *out,
  127. Error **errp);
  128. #endif /* QCRYPTO_AFSPLIT_H */