mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-09 00:07:57 -06:00
qcrypto-luks: extract store and load header
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
61dd8a9a52
commit
dde2c5afeb
1 changed files with 93 additions and 62 deletions
|
@ -409,6 +409,97 @@ qcrypto_block_luks_essiv_cipher(QCryptoCipherAlgorithm cipher,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stores the main LUKS header, taking care of endianess
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qcrypto_block_luks_store_header(QCryptoBlock *block,
|
||||||
|
QCryptoBlockWriteFunc writefunc,
|
||||||
|
void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
const QCryptoBlockLUKS *luks = block->opaque;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
size_t i;
|
||||||
|
g_autofree QCryptoBlockLUKSHeader *hdr_copy = NULL;
|
||||||
|
|
||||||
|
/* Create a copy of the header */
|
||||||
|
hdr_copy = g_new0(QCryptoBlockLUKSHeader, 1);
|
||||||
|
memcpy(hdr_copy, &luks->header, sizeof(QCryptoBlockLUKSHeader));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Everything on disk uses Big Endian (tm), so flip header fields
|
||||||
|
* before writing them
|
||||||
|
*/
|
||||||
|
cpu_to_be16s(&hdr_copy->version);
|
||||||
|
cpu_to_be32s(&hdr_copy->payload_offset_sector);
|
||||||
|
cpu_to_be32s(&hdr_copy->master_key_len);
|
||||||
|
cpu_to_be32s(&hdr_copy->master_key_iterations);
|
||||||
|
|
||||||
|
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
|
||||||
|
cpu_to_be32s(&hdr_copy->key_slots[i].active);
|
||||||
|
cpu_to_be32s(&hdr_copy->key_slots[i].iterations);
|
||||||
|
cpu_to_be32s(&hdr_copy->key_slots[i].key_offset_sector);
|
||||||
|
cpu_to_be32s(&hdr_copy->key_slots[i].stripes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write out the partition header and key slot headers */
|
||||||
|
writefunc(block, 0, (const uint8_t *)hdr_copy, sizeof(*hdr_copy),
|
||||||
|
opaque, &local_err);
|
||||||
|
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loads the main LUKS header,and byteswaps it to native endianess
|
||||||
|
* And run basic sanity checks on it
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
qcrypto_block_luks_load_header(QCryptoBlock *block,
|
||||||
|
QCryptoBlockReadFunc readfunc,
|
||||||
|
void *opaque,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
ssize_t rv;
|
||||||
|
size_t i;
|
||||||
|
QCryptoBlockLUKS *luks = block->opaque;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the entire LUKS header, minus the key material from
|
||||||
|
* the underlying device
|
||||||
|
*/
|
||||||
|
rv = readfunc(block, 0,
|
||||||
|
(uint8_t *)&luks->header,
|
||||||
|
sizeof(luks->header),
|
||||||
|
opaque,
|
||||||
|
errp);
|
||||||
|
if (rv < 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The header is always stored in big-endian format, so
|
||||||
|
* convert everything to native
|
||||||
|
*/
|
||||||
|
be16_to_cpus(&luks->header.version);
|
||||||
|
be32_to_cpus(&luks->header.payload_offset_sector);
|
||||||
|
be32_to_cpus(&luks->header.master_key_len);
|
||||||
|
be32_to_cpus(&luks->header.master_key_iterations);
|
||||||
|
|
||||||
|
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
|
||||||
|
be32_to_cpus(&luks->header.key_slots[i].active);
|
||||||
|
be32_to_cpus(&luks->header.key_slots[i].iterations);
|
||||||
|
be32_to_cpus(&luks->header.key_slots[i].key_offset_sector);
|
||||||
|
be32_to_cpus(&luks->header.key_slots[i].stripes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a key slot, and user password, this will attempt to unlock
|
* Given a key slot, and user password, this will attempt to unlock
|
||||||
* the master encryption key from the key slot.
|
* the master encryption key from the key slot.
|
||||||
|
@ -622,7 +713,6 @@ qcrypto_block_luks_open(QCryptoBlock *block,
|
||||||
{
|
{
|
||||||
QCryptoBlockLUKS *luks = NULL;
|
QCryptoBlockLUKS *luks = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
size_t i;
|
|
||||||
g_autofree uint8_t *masterkey = NULL;
|
g_autofree uint8_t *masterkey = NULL;
|
||||||
char *ivgen_name, *ivhash_name;
|
char *ivgen_name, *ivhash_name;
|
||||||
g_autofree char *password = NULL;
|
g_autofree char *password = NULL;
|
||||||
|
@ -644,30 +734,10 @@ qcrypto_block_luks_open(QCryptoBlock *block,
|
||||||
luks = g_new0(QCryptoBlockLUKS, 1);
|
luks = g_new0(QCryptoBlockLUKS, 1);
|
||||||
block->opaque = luks;
|
block->opaque = luks;
|
||||||
|
|
||||||
/* Read the entire LUKS header, minus the key material from
|
if (qcrypto_block_luks_load_header(block, readfunc, opaque, errp) < 0) {
|
||||||
* the underlying device */
|
|
||||||
if (readfunc(block, 0,
|
|
||||||
(uint8_t *)&luks->header,
|
|
||||||
sizeof(luks->header),
|
|
||||||
opaque,
|
|
||||||
errp) < 0) {
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The header is always stored in big-endian format, so
|
|
||||||
* convert everything to native */
|
|
||||||
be16_to_cpus(&luks->header.version);
|
|
||||||
be32_to_cpus(&luks->header.payload_offset_sector);
|
|
||||||
be32_to_cpus(&luks->header.master_key_len);
|
|
||||||
be32_to_cpus(&luks->header.master_key_iterations);
|
|
||||||
|
|
||||||
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].active);
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].iterations);
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].key_offset_sector);
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].stripes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(luks->header.magic, qcrypto_block_luks_magic,
|
if (memcmp(luks->header.magic, qcrypto_block_luks_magic,
|
||||||
QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) {
|
QCRYPTO_BLOCK_LUKS_MAGIC_LEN) != 0) {
|
||||||
error_setg(errp, "Volume is not in LUKS format");
|
error_setg(errp, "Volume is not in LUKS format");
|
||||||
|
@ -1216,46 +1286,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Everything on disk uses Big Endian, so flip header fields
|
if (qcrypto_block_luks_store_header(block, writefunc, opaque, errp) < 0) {
|
||||||
* before writing them */
|
|
||||||
cpu_to_be16s(&luks->header.version);
|
|
||||||
cpu_to_be32s(&luks->header.payload_offset_sector);
|
|
||||||
cpu_to_be32s(&luks->header.master_key_len);
|
|
||||||
cpu_to_be32s(&luks->header.master_key_iterations);
|
|
||||||
|
|
||||||
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
|
|
||||||
cpu_to_be32s(&luks->header.key_slots[i].active);
|
|
||||||
cpu_to_be32s(&luks->header.key_slots[i].iterations);
|
|
||||||
cpu_to_be32s(&luks->header.key_slots[i].key_offset_sector);
|
|
||||||
cpu_to_be32s(&luks->header.key_slots[i].stripes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Write out the partition header and key slot headers */
|
|
||||||
writefunc(block, 0,
|
|
||||||
(const uint8_t *)&luks->header,
|
|
||||||
sizeof(luks->header),
|
|
||||||
opaque,
|
|
||||||
&local_err);
|
|
||||||
|
|
||||||
/* Delay checking local_err until we've byte-swapped */
|
|
||||||
|
|
||||||
/* Byte swap the header back to native, in case we need
|
|
||||||
* to read it again later */
|
|
||||||
be16_to_cpus(&luks->header.version);
|
|
||||||
be32_to_cpus(&luks->header.payload_offset_sector);
|
|
||||||
be32_to_cpus(&luks->header.master_key_len);
|
|
||||||
be32_to_cpus(&luks->header.master_key_iterations);
|
|
||||||
|
|
||||||
for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) {
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].active);
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].iterations);
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].key_offset_sector);
|
|
||||||
be32_to_cpus(&luks->header.key_slots[i].stripes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue