aboutsummaryrefslogtreecommitdiff
path: root/include/crypto
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2015-10-23 16:14:25 +0100
committerDaniel P. Berrange <berrange@redhat.com>2016-03-17 14:41:14 +0000
commit5a95e0fccdad951d8779fca459c20649c8b0cbb4 (patch)
treefcd700502387cce6fbaba2ad6489f18a74eaf7e9 /include/crypto
parentcb730894ae284965e03a40eabbf623b87206777b (diff)
crypto: add support for anti-forensic split algorithm
The LUKS format specifies an anti-forensic split algorithm which is used to artificially expand the size of the key material on disk. This is an implementation of that algorithm. Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'include/crypto')
-rw-r--r--include/crypto/afsplit.h135
1 files changed, 135 insertions, 0 deletions
diff --git a/include/crypto/afsplit.h b/include/crypto/afsplit.h
new file mode 100644
index 0000000000..4cc4ca4b38
--- /dev/null
+++ b/include/crypto/afsplit.h
@@ -0,0 +1,135 @@
+/*
+ * QEMU Crypto anti forensic information splitter
+ *
+ * Copyright (c) 2015-2016 Red Hat, Inc.
+ *
+ * This library 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef QCRYPTO_AFSPLIT_H__
+#define QCRYPTO_AFSPLIT_H__
+
+#include "crypto/hash.h"
+
+/**
+ * This module implements the anti-forensic splitter that is specified
+ * as part of the LUKS format:
+ *
+ * http://clemens.endorphin.org/cryptography
+ * http://clemens.endorphin.org/TKS1-draft.pdf
+ *
+ * The core idea is to take a short piece of data (key material)
+ * and process it to expand it to a much larger piece of data.
+ * The expansion process is reversible, to obtain the original
+ * short data. The key property of the expansion is that if any
+ * byte in the larger data set is changed / missing, it should be
+ * impossible to recreate the original short data.
+ *
+ * <example>
+ * <title>Creating a large split key for storage</title>
+ * <programlisting>
+ * size_t nkey = 32;
+ * uint32_t stripes = 32768; // To produce a 1 MB split key
+ * uint8_t *masterkey = ....a 32-byte AES key...
+ * uint8_t *splitkey;
+ *
+ * splitkey = g_new0(uint8_t, nkey * stripes);
+ *
+ * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALG_SHA256,
+ * nkey, stripes,
+ * masterkey, splitkey, errp) < 0) {
+ * g_free(splitkey);
+ * g_free(masterkey);
+ * return -1;
+ * }
+ *
+ * ...store splitkey somewhere...
+ *
+ * g_free(splitkey);
+ * g_free(masterkey);
+ * </programlisting>
+ * </example>
+ *
+ * <example>
+ * <title>Retrieving a master key from storage</title>
+ * <programlisting>
+ * size_t nkey = 32;
+ * uint32_t stripes = 32768; // To produce a 1 MB split key
+ * uint8_t *masterkey;
+ * uint8_t *splitkey = .... read in 1 MB of data...
+ *
+ * masterkey = g_new0(uint8_t, nkey);
+ *
+ * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALG_SHA256,
+ * nkey, stripes,
+ * splitkey, masterkey, errp) < 0) {
+ * g_free(splitkey);
+ * g_free(masterkey);
+ * return -1;
+ * }
+ *
+ * ..decrypt data with masterkey...
+ *
+ * g_free(splitkey);
+ * g_free(masterkey);
+ * </programlisting>
+ * </example>
+ */
+
+/**
+ * qcrypto_afsplit_encode:
+ * @hash: the hash algorithm to use for data expansion
+ * @blocklen: the size of @in in bytes
+ * @stripes: the number of times to expand @in in size
+ * @in: the master key to be expanded in size
+ * @out: preallocated buffer to hold the split key
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Split the data in @in, which is @blocklen bytes in
+ * size, to form a larger piece of data @out, which is
+ * @blocklen * @stripes bytes in size.
+ *
+ * Returns: 0 on success, -1 on error;
+ */
+int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash,
+ size_t blocklen,
+ uint32_t stripes,
+ const uint8_t *in,
+ uint8_t *out,
+ Error **errp);
+
+/**
+ * qcrypto_afsplit_decode:
+ * @hash: the hash algorithm to use for data compression
+ * @blocklen: the size of @out in bytes
+ * @stripes: the number of times to decrease @in in size
+ * @in: the split key to be recombined
+ * @out: preallocated buffer to hold the master key
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Join the data in @in, which is @blocklen * @stripes
+ * bytes in size, to form the original small piece of
+ * data @out, which is @blocklen bytes in size.
+ *
+ * Returns: 0 on success, -1 on error;
+ */
+int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash,
+ size_t blocklen,
+ uint32_t stripes,
+ const uint8_t *in,
+ uint8_t *out,
+ Error **errp);
+
+#endif /* QCRYPTO_AFSPLIT_H__ */