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