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 "crypto/afsplit.h"
28 #include "crypto/random.h"
31 static void qcrypto_afsplit_xor(size_t blocklen
,
37 for (i
= 0; i
< blocklen
; i
++) {
38 out
[i
] = in1
[i
] ^ in2
[i
];
43 static int qcrypto_afsplit_hash(QCryptoHashAlgorithm hash
,
48 size_t digestlen
= qcrypto_hash_digest_len(hash
);
50 size_t hashcount
= blocklen
/ digestlen
;
51 size_t finallen
= blocklen
% digestlen
;
60 for (i
= 0; i
< hashcount
; i
++) {
63 uint32_t iv
= cpu_to_be32(i
);
66 .iov_len
= sizeof(iv
) },
67 { .iov_base
= block
+ (i
* digestlen
),
68 .iov_len
= (i
== (hashcount
- 1)) ? finallen
: digestlen
},
71 if (qcrypto_hash_bytesv(hash
,
79 assert(outlen
== digestlen
);
80 memcpy(block
+ (i
* digestlen
), out
,
81 (i
== (hashcount
- 1)) ? finallen
: digestlen
);
89 int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash
,
96 uint8_t *block
= g_new0(uint8_t, blocklen
);
100 for (i
= 0; i
< (stripes
- 1); i
++) {
101 if (qcrypto_random_bytes(out
+ (i
* blocklen
), blocklen
, errp
) < 0) {
105 qcrypto_afsplit_xor(blocklen
,
106 out
+ (i
* blocklen
),
109 if (qcrypto_afsplit_hash(hash
, blocklen
, block
,
114 qcrypto_afsplit_xor(blocklen
,
117 out
+ (i
* blocklen
));
126 int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash
,
133 uint8_t *block
= g_new0(uint8_t, blocklen
);
137 for (i
= 0; i
< (stripes
- 1); i
++) {
138 qcrypto_afsplit_xor(blocklen
,
142 if (qcrypto_afsplit_hash(hash
, blocklen
, block
,
148 qcrypto_afsplit_xor(blocklen
,