mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
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>
This commit is contained in:
parent
cb730894ae
commit
5a95e0fccd
6 changed files with 490 additions and 0 deletions
135
include/crypto/afsplit.h
Normal file
135
include/crypto/afsplit.h
Normal file
|
@ -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__ */
|
Loading…
Add table
Add a link
Reference in a new issue