2 * QEMU Crypto anti forensic information splitter
4 * Copyright (c) 2015-2016 Red Hat, Inc.
6 * Derived from cryptsetup package lib/luks1/af.c
8 * Copyright (C) 2004, Clemens Fruhwirth <clemens@endorphin.org>
9 * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 #include "qemu/osdep.h"
27 #include "qemu/bswap.h"
28 #include "crypto/afsplit.h"
29 #include "crypto/random.h"
32 static void qcrypto_afsplit_xor(size_t blocklen
,
38 for (i
= 0; i
< blocklen
; i
++) {
39 out
[i
] = in1
[i
] ^ in2
[i
];
44 static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash
,
49 size_t digestlen
= qcrypto_hash_digest_len(hash
);
51 size_t hashcount
= blocklen
/ digestlen
;
52 size_t finallen
= blocklen
% digestlen
;
61 for (i
= 0; i
< hashcount
; i
++) {
64 uint32_t iv
= cpu_to_be32(i
);
67 .iov_len
= sizeof(iv
) },
68 { .iov_base
= block
+ (i
* digestlen
),
69 .iov_len
= (i
== (hashcount
- 1)) ? finallen
: digestlen
},
72 if (qcrypto_hash_bytesv(hash
,
80 assert(outlen
== digestlen
);
81 memcpy(block
+ (i
* digestlen
), out
,
82 (i
== (hashcount
- 1)) ? finallen
: digestlen
);
90 int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash
,
97 uint8_t *block
= g_new0(uint8_t, blocklen
);
101 for (i
= 0; i
< (stripes
- 1); i
++) {
102 if (qcrypto_random_bytes(out
+ (i
* blocklen
), blocklen
, errp
) < 0) {
106 qcrypto_afsplit_xor(blocklen
,
107 out
+ (i
* blocklen
),
110 if (qcrypto_afsplit_hash(hash
, blocklen
, block
,
115 qcrypto_afsplit_xor(blocklen
,
118 out
+ (i
* blocklen
));
127 int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash
,
134 uint8_t *block
= g_new0(uint8_t, blocklen
);
138 for (i
= 0; i
< (stripes
- 1); i
++) {
139 qcrypto_afsplit_xor(blocklen
,
143 if (qcrypto_afsplit_hash(hash
, blocklen
, block
,
149 qcrypto_afsplit_xor(blocklen
,